Chromium Code Reviews| Index: ui/ozone/platform/drm/gpu/client_native_pixmap_vgem.cc | 
| diff --git a/ui/ozone/platform/drm/gpu/client_native_pixmap_vgem.cc b/ui/ozone/platform/drm/gpu/client_native_pixmap_vgem.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..e127bcdae60aebf17e16aad538fd448bd336b456 | 
| --- /dev/null | 
| +++ b/ui/ozone/platform/drm/gpu/client_native_pixmap_vgem.cc | 
| @@ -0,0 +1,90 @@ | 
| +// Copyright 2015 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/client_native_pixmap_vgem.h" | 
| + | 
| +#include <fcntl.h> | 
| +#include <sys/mman.h> | 
| +#include <vgem_drm.h> | 
| +#include <xf86drm.h> | 
| + | 
| +#include "base/trace_event/trace_event.h" | 
| + | 
| +namespace ui { | 
| + | 
| +// static | 
| +scoped_ptr<ClientNativePixmap> ClientNativePixmapVgem::ImportFromDmabuf( | 
| + int vgem_fd, | 
| + int dmabuf_fd, | 
| + const gfx::Size& size, | 
| + int stride) { | 
| + DCHECK_GE(vgem_fd, 0); | 
| + DCHECK_GE(dmabuf_fd, 0); | 
| + uint32_t vgem_bo_handle = 0; | 
| + int ret = drmPrimeFDToHandle(vgem_fd, dmabuf_fd, &vgem_bo_handle); | 
| + if (ret) { | 
| 
 
reveman
2015/08/13 14:03:58
can we DCHECK(!ret) instead?
 
reveman
2015/08/13 15:15:58
ping?
 
dshwang
2015/08/13 15:45:28
ah, I missed. Done.
BTW,Android and IOS return nu
 
reveman
2015/08/13 17:16:43
Yes, that's not ideal and we should change those i
 
 | 
| + PLOG(ERROR) << "drmPrimeFDToHandle failed, handle:" << vgem_bo_handle; | 
| 
 
reveman
2015/08/13 15:15:58
btw, logging the vgem_bo_handle after failure seem
 
dshwang
2015/08/13 15:45:28
always 0. done.
 
 | 
| + return nullptr; | 
| + } | 
| + return make_scoped_ptr( | 
| + new ClientNativePixmapVgem(vgem_fd, vgem_bo_handle, size, stride)); | 
| +} | 
| + | 
| +ClientNativePixmapVgem::ClientNativePixmapVgem(int vgem_fd, | 
| + uint32_t vgem_bo_handle, | 
| + const gfx::Size& size, | 
| + int stride) | 
| + : vgem_fd_(vgem_fd), | 
| + vgem_bo_handle_(vgem_bo_handle), | 
| + size_(size), | 
| + stride_(stride), | 
| + data_(nullptr) { | 
| + DCHECK(vgem_bo_handle_); | 
| +} | 
| + | 
| +ClientNativePixmapVgem::~ClientNativePixmapVgem() { | 
| + DCHECK(!data_); | 
| + struct drm_gem_close close = {0}; | 
| + close.handle = vgem_bo_handle_; | 
| + int ret = drmIoctl(vgem_fd_, DRM_IOCTL_GEM_CLOSE, &close); | 
| + DCHECK(!ret) << "fail to free a vgem buffer."; | 
| +} | 
| + | 
| +bool ClientNativePixmapVgem::Map(void** data) { | 
| + TRACE_EVENT0("gpu", "ClientNativePixmapVgem::Map"); | 
| + DCHECK(!data_); | 
| + struct drm_mode_map_dumb mmap_arg = {0}; | 
| + mmap_arg.handle = vgem_bo_handle_; | 
| + | 
| + int ret = drmIoctl(vgem_fd_, DRM_IOCTL_VGEM_MODE_MAP_DUMB, &mmap_arg); | 
| + if (ret) { | 
| 
 
reveman
2015/08/13 14:03:58
What is the reason for this failing? I guess runni
 
reveman
2015/08/13 15:15:58
ping?
 
dshwang
2015/08/13 15:45:28
yes, mostly oom. I followed Android code. Now I ad
 
 | 
| + PLOG(ERROR) << "fail to map a vgem buffer."; | 
| + return false; | 
| + } | 
| + DCHECK(mmap_arg.offset); | 
| + | 
| + size_t size = stride_ * size_.height(); | 
| + data_ = mmap(nullptr, size, (PROT_READ | PROT_WRITE), MAP_SHARED, vgem_fd_, | 
| + mmap_arg.offset); | 
| + DCHECK_NE(data_, MAP_FAILED); | 
| + *data = data_; | 
| + return true; | 
| +} | 
| + | 
| +void ClientNativePixmapVgem::Unmap() { | 
| + TRACE_EVENT0("gpu", "ClientNativePixmapVgem::Unmap"); | 
| + DCHECK(data_); | 
| + | 
| + // TODO(dshwang): keep it consistently mapped, and unmap it in dtor. | 
| + size_t size = stride_ * size_.height(); | 
| + int ret = munmap(data_, size); | 
| + DCHECK(!ret) << "fail to munmap a vgem buffer."; | 
| + data_ = nullptr; | 
| +} | 
| + | 
| +void ClientNativePixmapVgem::GetStride(int* stride) const { | 
| + *stride = stride_; | 
| +} | 
| + | 
| +} // namespace ui |