| Index: ui/ozone/platform/drm/gpu/vgem_pixmap.cc
|
| diff --git a/ui/ozone/platform/drm/gpu/vgem_pixmap.cc b/ui/ozone/platform/drm/gpu/vgem_pixmap.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2f1294fc7d2d0615282c019b6dde3d5697c971be
|
| --- /dev/null
|
| +++ b/ui/ozone/platform/drm/gpu/vgem_pixmap.cc
|
| @@ -0,0 +1,129 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ui/ozone/platform/drm/gpu/vgem_pixmap.h"
|
| +
|
| +#include <fcntl.h>
|
| +#include <sys/mman.h>
|
| +#include <xf86drm.h>
|
| +
|
| +#include "base/trace_event/trace_event.h"
|
| +#include "ui/ozone/public/surface_factory_ozone.h"
|
| +
|
| +namespace ui {
|
| +
|
| +namespace {
|
| +
|
| +size_t StrideInBytes(size_t width, SurfaceFactoryOzone::BufferFormat format) {
|
| + switch (format) {
|
| + case SurfaceFactoryOzone::BGRA_8888:
|
| + case SurfaceFactoryOzone::RGBX_8888:
|
| + return width * 4;
|
| + case SurfaceFactoryOzone::UNKNOWN:
|
| + NOTREACHED();
|
| + }
|
| + NOTREACHED();
|
| + return 0;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +VgemPixmap::VgemPixmap(base::FileDescriptor handle,
|
| + base::FileDescriptor vgem_handle,
|
| + gfx::Size size,
|
| + SurfaceFactoryOzone::BufferFormat format,
|
| + BufferUsage usage)
|
| + : vgem_bo_handle_(0),
|
| + vgem_fd_(vgem_handle),
|
| + size_(size),
|
| + format_(format),
|
| + usage_(usage),
|
| + stride_(StrideInBytes(size_.width(), format_)),
|
| + mmap_ptr_(nullptr) {
|
| + if (usage_ == MAP) {
|
| + DCHECK(vgem_fd_.fd > 0);
|
| + DCHECK(handle.fd > 0);
|
| + dma_buf_.reset(handle.fd);
|
| + }
|
| +}
|
| +
|
| +bool VgemPixmap::Initialize() {
|
| + if (usage_ == SCANOUT)
|
| + return true;
|
| +
|
| + DCHECK(vgem_fd_.fd);
|
| + int ret = drmPrimeFDToHandle(vgem_fd_.fd, dma_buf_.get(), &vgem_bo_handle_);
|
| + if (ret) {
|
| + LOG(ERROR) << "drmPrimeFDToHandle failed, handle:" << vgem_bo_handle_;
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +VgemPixmap::~VgemPixmap() {
|
| + if (vgem_bo_handle_) {
|
| + DCHECK_EQ(usage_, MAP);
|
| + struct drm_mode_destroy_dumb destroy;
|
| + memset(&destroy, 0, sizeof(destroy));
|
| + destroy.handle = vgem_bo_handle_;
|
| + int ret = drmIoctl(vgem_fd_.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
|
| + if (!ret)
|
| + LOG(ERROR) << "fail to free a vgem buffer. error:" << ret;
|
| + vgem_bo_handle_ = 0;
|
| + }
|
| +}
|
| +
|
| +void* VgemPixmap::GetEGLClientBuffer() {
|
| + return nullptr;
|
| +}
|
| +
|
| +int VgemPixmap::GetDmaBufFd() {
|
| + return dma_buf_.get();
|
| +}
|
| +
|
| +int VgemPixmap::GetDmaBufPitch() {
|
| + return stride_;
|
| +}
|
| +
|
| +NativePixmap::BufferUsage VgemPixmap::GetBufferUsage() const {
|
| + return usage_;
|
| +}
|
| +
|
| +void* VgemPixmap::Map() {
|
| + TRACE_EVENT0("gpu", "VgemPixmap::Map");
|
| + DCHECK(!mmap_ptr_);
|
| + DCHECK(!vgem_bo_handle_);
|
| + DCHECK_EQ(usage_, MAP);
|
| +
|
| + struct drm_mode_map_dumb mmap_arg;
|
| + memset(&mmap_arg, 0, sizeof(mmap_arg));
|
| + mmap_arg.handle = vgem_bo_handle_;
|
| +
|
| + int ret = drmIoctl(vgem_fd_.fd, DRM_IOCTL_MODE_MAP_DUMB, &mmap_arg);
|
| + if (ret) {
|
| + LOG(ERROR) << "fail to map a vgem buffer. error:" << ret;
|
| + return nullptr;
|
| + }
|
| + DCHECK(mmap_arg.offset);
|
| +
|
| + size_t size = stride_ * size_.height();
|
| + mmap_ptr_ = mmap(nullptr, size, (PROT_READ | PROT_WRITE), MAP_SHARED,
|
| + vgem_fd_.fd, mmap_arg.offset);
|
| + DCHECK(mmap_ptr_ != MAP_FAILED);
|
| + return mmap_ptr_;
|
| +}
|
| +
|
| +void VgemPixmap::Unmap() {
|
| + TRACE_EVENT0("gpu", "VgemPixmap::Unmap");
|
| + DCHECK(mmap_ptr_);
|
| + DCHECK(!vgem_bo_handle_);
|
| + DCHECK_EQ(usage_, MAP);
|
| +
|
| + size_t size = stride_ * size_.height();
|
| + int ret = munmap(mmap_ptr_, size);
|
| + DCHECK(!ret);
|
| + mmap_ptr_ = nullptr;
|
| +}
|
| +
|
| +} // namespace ui
|
|
|