| 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 075c8f993f5da2332a185895ee210b8e68d8155c..7d62ac074be7ddfca2ba322c4000f41433c8118f 100644
|
| --- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
|
| +++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
|
| @@ -11,12 +11,154 @@
|
| #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 <libdrm/i915_drm.h>
|
| +#include <libdrm/intel_bufmgr.h>
|
| +#include <xf86drm.h>
|
| +#include <X11/Xlib.h>
|
| +#include <X11/Xlibint.h>
|
| +#include <X11/extensions/Xext.h>
|
| +#include <X11/extensions/extutil.h>
|
| +#include <X11/extensions/dri2proto.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) {
|
| + TRACE_EVENT_INSTANT0("zcopy", "open dri device failed",
|
| + TRACE_EVENT_SCOPE_THREAD);
|
| + return False;
|
| + }
|
| +
|
| + drm_magic_t magic;
|
| + if (drmGetMagic(dri_fd, &magic)) {
|
| + close(dri_fd);
|
| + TRACE_EVENT_INSTANT0("zcopy", "drmGetMagic failed",
|
| + TRACE_EVENT_SCOPE_THREAD);
|
| + 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_EVENT_INSTANT0("zcopy", "authentication failed",
|
| + TRACE_EVENT_SCOPE_THREAD);
|
| + } else {
|
| + bufmgr = drm_intel_bufmgr_gem_init(dri_fd, 2048); //XXX what is this number?
|
| + if (!bufmgr) {
|
| + TRACE_EVENT_INSTANT0("zcopy", "gem_init failed",
|
| + TRACE_EVENT_SCOPE_THREAD);
|
| + }
|
| + }
|
| +
|
| + return bufmgr != NULL;
|
| +}
|
| +
|
| +static void *AllocTexture(unsigned width, unsigned height, 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.
|
| + // The checks here will catch some problems, but maybe not all.
|
| + uint32_t tiling, want;
|
| + unsigned long pitch;
|
| +
|
| + if ((width % 4) || (height % 2)) {
|
| + TRACE_EVENT_INSTANT2("zcopy", "can't handle texure size",
|
| + TRACE_EVENT_SCOPE_THREAD,
|
| + "width", width,
|
| + "height", height);
|
| + return NULL;
|
| + }
|
| +
|
| + tiling = want = GetZCopy() == 'u' ? I915_TILING_NONE : I915_TILING_Y;
|
| + drm_intel_bo *bo = drm_intel_bo_alloc_tiled(bufmgr, "region", width, height,
|
| + bpp, &tiling, &pitch, 0);
|
| +
|
| + if (tiling != want) {
|
| + TRACE_EVENT_INSTANT2("zcopy", "did not get requested tiling",
|
| + TRACE_EVENT_SCOPE_THREAD,
|
| + "width", width,
|
| + "height", height);
|
| + drm_intel_bo_unreference(bo);
|
| + return NULL;
|
| + }
|
| +
|
| + if (pitch != width * 4) {
|
| + TRACE_EVENT_INSTANT2("zcopy", "did not get expected pitch",
|
| + TRACE_EVENT_SCOPE_THREAD,
|
| + "width", width,
|
| + "height", height);
|
| + drm_intel_bo_unreference(bo);
|
| + return NULL;
|
| + }
|
| +
|
| + return bo;
|
| +}
|
| +
|
| +} // namespace foobar
|
|
|
| namespace content {
|
|
|
| @@ -379,6 +521,27 @@ scoped_ptr<gfx::GpuMemoryBuffer>
|
| if (!GpuMemoryBufferImpl::IsFormatValid(internalformat))
|
| return scoped_ptr<gfx::GpuMemoryBuffer>();
|
|
|
| +#if defined(OS_LINUX) || defined(OS_CHROMEOS)
|
| + if (GetZCopy()) {
|
| + if (!GpuMemoryBufferImplFoobar::IsFormatSupported(internalformat)) {
|
| + TRACE_EVENT_INSTANT0("zcopy", "can't handle texure format",
|
| + TRACE_EVENT_SCOPE_THREAD);
|
| + } else if (foobar::OpenDri()) {
|
| + // 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_object) {
|
| + scoped_ptr<GpuMemoryBufferImplFoobar> foobar_buffer(
|
| + new GpuMemoryBufferImplFoobar(gfx::Size(width, height),
|
| + 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());
|
|
|