Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Unified Diff: content/browser/gpu/dri_buffer_manager.cc

Issue 288343004: working copy of "zero_copy" Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/gpu/dri_buffer_manager.h ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/gpu/dri_buffer_manager.cc
===================================================================
--- content/browser/gpu/dri_buffer_manager.cc (revision 0)
+++ content/browser/gpu/dri_buffer_manager.cc (revision 0)
@@ -0,0 +1,240 @@
+// Copyright (c) 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 "content/browser/gpu/dri_buffer_manager.h"
+
+extern "C" {
+#include <fcntl.h>
+#include </home/marius/mesa_ander/src/gbm/main/gbm.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/dri2proto.h>
+#include <xf86drm.h>
+}
+
+#include "base/logging.h"
+#include "ui/gfx/x/x11_types.h"
+//#define USE_DMA_BUF_MMAP
+//#define __DEBUG__
+namespace content {
+
+const char kDefaultGraphicsCardPath[] = "/dev/dri/card0";
+static char dri2ExtensionName[] = DRI2_NAME;
+static XExtensionInfo *dri2Info;
+static XEXT_GENERATE_CLOSE_DISPLAY(DRI2CloseDisplay, dri2Info)
+static /* const */ XExtensionHooks dri2ExtensionHooks = {
+ NULL, // create_gc
+ NULL, // copy_gc
+ NULL, // flush_gc
+ NULL, // free_gc
+ NULL, // create_font
+ NULL, // free_font
+ DRI2CloseDisplay, // close_display
+ NULL, // wire_to_event
+ NULL, // event_to_wire
+ NULL, // error
+ NULL, // error_string
+};
+
+static XEXT_GENERATE_FIND_DISPLAY(DRI2FindDisplay, dri2Info,
+ dri2ExtensionName,
+ &dri2ExtensionHooks,
+ 0,
+ NULL)
+int DRIBufferManager::fd_ = 0;
+struct gbm_device* DRIBufferManager::gbm_ = NULL;
+
+DRIBufferManager::DRIBufferManager() /*: fd_(0),
+ gbm_(NULL)*/ {
+ AuthConnection();
+}
+
+DRIBufferManager::~DRIBufferManager() {
+ if (gbm_)
+ gbm_device_destroy(gbm_);
+ close(fd_);
+}
+
+void DRIBufferManager::CreateBuffer(int width,
+ int height,
+ gfx::GpuMemoryBufferHandle& handle) {
+ //DCHECK(fd_);
+ if (fd_ <= 0) {
+ if(!AuthConnection()) {
+ fprintf(stderr, "\nAuthConnection failed!\n");
+ return;
+ }
+ fprintf(stderr, "\n CONNECTION ready!\n");
+ }
+ if (!gbm_) {
+ gbm_ = gbm_create_device(fd_);
+ //fprintf(stderr, "\nGBM CREATED %d\n", fd_);
+ if (!gbm_) {
+ LOG(ERROR) << "DRIBufferManager: Failed to create GBM device.";
+ return;
+ }
+ }
+ #if defined(USE_DMA_BUF_MMAP)
+ if (!IsMmapSupported()) {
+ fprintf(stderr, "\nMMAP Is NOT SUPPORTED!\n");
+ fflush(stderr);
+ return;
+ }
+ #endif
+ // TODO(kalyan): how do we free this buffer?
+ struct gbm_bo* tex_bo = gbm_bo_create(gbm_,
+ width,
+ height,
+ GBM_BO_FORMAT_ARGB8888,
+ GBM_BO_USE_MAP);
+ if (!tex_bo) {
+ LOG(ERROR) << "DRIBufferManager: Failed to allocate buffer.";
+ fprintf(stderr, "\nDRIBufferManager: Failed to allocate buffer.");
+ return;
+ }
+
+ int dma_buf_handle;
+ /*
+ gbm_bo_export(tex_bo,
+ GBM_BO_IMPORT_DMA_BUF,
+ reinterpret_cast<void**>(&dma_buf_handle),
+ GBM_BO_USE_MAP);
+ */
+ dma_buf_handle = gbm_bo_get_fd(tex_bo);
+ handle.type = gfx::DMA_BUFFER;
+ handle.card_handle.fd = fd_;
+ handle.handle.fd = dma_buf_handle;
+ handle.stride = gbm_bo_get_stride(tex_bo);
+ DCHECK( handle.stride > width);
+
+#ifdef __DEBUG__
+ fprintf(stderr, "\nDRIBufferManager::CreateBuffer(%d,%d,%d)=%d\n", width, height, handle.stride, dma_buf_handle);
+ fflush(stderr);
+#endif
+
+}
+
+bool DRIBufferManager::AuthConnection() {
+ // TODO(Kalyan): we would need to check for dri3 support when using GLX.
+ fd_ = open(kDefaultGraphicsCardPath, O_RDWR);
+ if (fd_ <= 0) {
+ return false;
+ }
+
+ drm_magic_t magic;
+ if (drmGetMagic(fd_, &magic)) {
+ close(fd_);
+ return false;
+ }
+
+ Display *dpy = reinterpret_cast<Display *>(gfx::GetXDisplay());
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2AuthenticateReq *req;
+ xDRI2AuthenticateReply rep;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+ LockDisplay(dpy);
+ GetReq(DRI2Authenticate, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2Authenticate;
+ req->magic = magic;
+ req->window = DefaultRootWindow(dpy);
+ if (!_XReply(dpy, reinterpret_cast<xReply *>(&rep), 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return false;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (!rep.authenticated) {
+ close(fd_);
+ return false;
+ }
+
+ return true;
+}
+
+bool DRIBufferManager::IsMmapSupported() {
+ static bool dma_buf_mmap_supported = true;
+ static bool check_done = false;
+ if (check_done)
+ return dma_buf_mmap_supported;
+
+ fprintf(stderr, "\nCHECK!\n");
+ fflush(stderr);
+ check_done = true;
+ struct gbm_bo* temp_bo = gbm_bo_create(gbm_,
+ 1,
+ 1,
+ GBM_BO_FORMAT_ARGB8888,
+ GBM_BO_USE_MAP);
+
+ int temp;
+ /*
+ gbm_bo_export(temp_bo,
+ GBM_BO_IMPORT_DMA_BUF,
+ reinterpret_cast<void**>(&temp),
+ GBM_BO_USE_MAP);
+ */
+ temp = gbm_bo_get_fd(temp_bo);
+
+ int stride = gbm_bo_get_stride(temp_bo);
+
+ // Check if platform supports mmap with proc_read.
+ if (!MmapDmaBuf(temp, PROT_READ, stride)) {
+ LOG(ERROR) << "DRIBufferManager: Cannot mmap dma_buf"
+ << "handle with PROT_READ.";
+ dma_buf_mmap_supported = false;
+ }
+
+ // Check if platform supports mmap with proc_write.
+ if (!MmapDmaBuf(temp, PROT_WRITE, stride)) {
+ LOG(ERROR) << "DRIBufferManager: Cannot mmap dma_buf"
+ << "handle with PROT_WRITE.";
+ dma_buf_mmap_supported = false;
+ }
+
+ // Check if platform supports mmap with proc_write and proc_read.
+
+ if (!MmapDmaBuf(temp, (PROT_READ | PROT_WRITE), stride)) {
+ LOG(ERROR) << "DRIBufferManager: Cannot mmap dma_buf"
+ << "handle with PROT_READ | PROT_WRITE.";
+ dma_buf_mmap_supported = false;
+ }
+
+ gbm_bo_destroy(temp_bo);
+ close(temp);
+ return dma_buf_mmap_supported;
+}
+
+bool DRIBufferManager::MmapDmaBuf(int dma_buf_id, int proc, int stride) {
+ void* temp_map = mmap(NULL,
+ stride,
+ proc,
+ MAP_SHARED,
+ dma_buf_id,
+ 0);
+
+ if (temp_map == MAP_FAILED) {
+ LOG(ERROR) << "DRIBufferManager: Cannot mmap dma_buf handle.";
+ return false;
+ }
+
+ if (munmap(temp_map, stride) == -1) {
+ LOG(ERROR) << "DRIBufferManager: Cannot munmap dma_buf handle.";
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace content
« no previous file with comments | « content/browser/gpu/dri_buffer_manager.h ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698