| 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());
|
|
|