Index: content/browser/gpu/browser_gpu_channel_host_factory.cc |
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc |
index 59e390bb867084cbf4e7e60119e5ff75cf01dd0d..fb0c35cf20a4edfad01404d118ce4d2e6906f1aa 100644 |
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc |
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc |
@@ -11,12 +11,126 @@ |
#include "content/browser/gpu/gpu_process_host.h" |
#include "content/browser/gpu/gpu_surface_tracker.h" |
#include "content/common/child_process_host_impl.h" |
+#include "content/common/gpu/client/gpu_memory_buffer_impl_foobar.h" |
#include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h" |
#include "content/common/gpu/gpu_messages.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/gpu_data_manager.h" |
#include "content/public/common/content_client.h" |
#include "ipc/ipc_forwarding_message_filter.h" |
+#include "ui/gfx/x/x11_types.h" |
+ |
+extern char GetZCopy(); |
+ |
+namespace foobar { |
+ |
+extern "C" { |
+#include <fcntl.h> |
+#include <X11/Xlib.h> |
+#include <X11/Xlibint.h> |
+#include <X11/extensions/Xext.h> |
+#include <X11/extensions/extutil.h> |
+#include <X11/extensions/dri2proto.h> |
+#include <xf86drm.h> |
+#include <libdrm/i915_drm.h> |
+#include <libdrm/intel_bufmgr.h> |
+} |
+ |
+static char dri2ExtensionName[] = DRI2_NAME; |
+static XExtensionInfo *dri2Info; |
+ |
+static /* const */ XExtensionHooks dri2ExtensionHooks = { |
+ NULL, /* create_gc */ |
+ NULL, /* copy_gc */ |
+ NULL, /* flush_gc */ |
+ NULL, /* free_gc */ |
+ NULL, /* create_font */ |
+ NULL, /* free_font */ |
+ NULL, /* 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) |
+ |
+static int dri_fd = -1; |
+static drm_intel_bufmgr *bufmgr = NULL; |
+ |
+static Bool OpenDri() { |
+ if (bufmgr) return True; |
+ |
+ dri_fd = open("/dev/dri/card0", O_RDWR); |
+ if (dri_fd < 0) { |
+ perror("open dri"); |
+ return False; |
+ } |
+ |
+ drm_magic_t magic; |
+ if (drmGetMagic(dri_fd, &magic)) { |
+ close(dri_fd); |
+ TRACE_EVENT0("zcopy", "drmGetMagic failed"); |
+ return False; |
+ } |
+ |
+ Display *dpy = (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->window = DefaultRootWindow(dpy); |
+ req->magic = magic; |
+ |
+ if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { |
+ dri_fd = -1; |
+ } |
+ UnlockDisplay(dpy); |
+ SyncHandle(); |
+ |
+ if (dri_fd < 0 || !rep.authenticated) { |
+ close(dri_fd); |
+ TRACE_EVENT0("zcopy", "authentication failed"); |
+ } else { |
+ bufmgr = drm_intel_bufmgr_gem_init(dri_fd, 2048); //XXX what is this number? |
+ if (!bufmgr) { |
+ TRACE_EVENT0("zcopy", "gem_init failed"); |
+ } |
+ } |
+ |
+ return bufmgr != NULL; |
+} |
+ |
+static void *AllocTexture(unsigned w, unsigned h, unsigned bpp) { |
+ // Figuring out how much memory to allocate for a texture is pretty |
+ // complicated due to padding and alignment concerns, and mipmaps, to |
+ // name a few reasons. |
+ // There's a lot of logic in the mesa i965 driver to handle it, which |
+ // is one of the drawbacks to allocating the texture memory here. |
+ // These asserts will catch some problems, but maybe not all. |
+ uint32_t tiling = I915_TILING_NONE; |
+ unsigned long pitch; |
+ |
+ assert(w % 4 == 0); |
+ assert(h % 2 == 0); |
+ drm_intel_bo *bo = drm_intel_bo_alloc_tiled(bufmgr, "region", w, h, bpp, |
+ &tiling, &pitch, 0); |
+ assert(tiling == I915_TILING_NONE); |
+ assert(pitch == w * 4); |
+ return bo; |
+} |
+ |
+} |
namespace content { |
@@ -375,6 +489,26 @@ scoped_ptr<gfx::GpuMemoryBuffer> |
if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) |
return scoped_ptr<gfx::GpuMemoryBuffer>(); |
+#if 1 // defined(OS_LINUX) |
+ if (GetZCopy()) { |
+ if ((width % 4) || (height % 2)) { |
+ TRACE_EVENT0("zcopy", "can't handle texure size"); |
+ } else if (!GpuMemoryBufferImplFoobar::IsFormatSupported(internalformat)) { |
+ TRACE_EVENT0("zcopy", "can't handle texure format"); |
+ } else if (foobar::OpenDri()) { |
+ scoped_ptr<GpuMemoryBufferImplFoobar> foobar_buffer( |
+ new GpuMemoryBufferImplFoobar(gfx::Size(width, height), |
+ internalformat)); |
+ // This object needs to be created somehow. Can be something |
+ // platform/driver specific. |
+ void *foobar_object = foobar::AllocTexture(width, height, |
+ GpuMemoryBufferImpl::BytesPerPixel(internalformat)); |
+ if (foobar_buffer->InitializeFromFoobarObject(foobar_object)) |
+ return foobar_buffer.PassAs<gfx::GpuMemoryBuffer>(); |
+ } |
+ } |
+#endif |
+ |
size_t size = width * height * |
GpuMemoryBufferImpl::BytesPerPixel(internalformat); |
scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); |