OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" | 5 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/threading/thread_restrictions.h" | 9 #include "base/threading/thread_restrictions.h" |
10 #include "content/browser/gpu/gpu_data_manager_impl.h" | 10 #include "content/browser/gpu/gpu_data_manager_impl.h" |
11 #include "content/browser/gpu/gpu_process_host.h" | 11 #include "content/browser/gpu/gpu_process_host.h" |
12 #include "content/browser/gpu/gpu_surface_tracker.h" | 12 #include "content/browser/gpu/gpu_surface_tracker.h" |
13 #include "content/common/child_process_host_impl.h" | 13 #include "content/common/child_process_host_impl.h" |
| 14 #include "content/common/gpu/client/gpu_memory_buffer_impl_foobar.h" |
14 #include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h" | 15 #include "content/common/gpu/client/gpu_memory_buffer_impl_shm.h" |
15 #include "content/common/gpu/gpu_messages.h" | 16 #include "content/common/gpu/gpu_messages.h" |
16 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
17 #include "content/public/browser/gpu_data_manager.h" | 18 #include "content/public/browser/gpu_data_manager.h" |
18 #include "content/public/common/content_client.h" | 19 #include "content/public/common/content_client.h" |
19 #include "ipc/ipc_forwarding_message_filter.h" | 20 #include "ipc/ipc_forwarding_message_filter.h" |
| 21 #include "ui/gfx/x/x11_types.h" |
| 22 |
| 23 extern char GetZCopy(); |
| 24 |
| 25 namespace foobar { |
| 26 |
| 27 extern "C" { |
| 28 #include <fcntl.h> |
| 29 #include <X11/Xlib.h> |
| 30 #include <X11/Xlibint.h> |
| 31 #include <X11/extensions/Xext.h> |
| 32 #include <X11/extensions/extutil.h> |
| 33 #include <X11/extensions/dri2proto.h> |
| 34 #include <xf86drm.h> |
| 35 #include <libdrm/i915_drm.h> |
| 36 #include <libdrm/intel_bufmgr.h> |
| 37 } |
| 38 |
| 39 static char dri2ExtensionName[] = DRI2_NAME; |
| 40 static XExtensionInfo *dri2Info; |
| 41 |
| 42 static /* const */ XExtensionHooks dri2ExtensionHooks = { |
| 43 NULL, /* create_gc */ |
| 44 NULL, /* copy_gc */ |
| 45 NULL, /* flush_gc */ |
| 46 NULL, /* free_gc */ |
| 47 NULL, /* create_font */ |
| 48 NULL, /* free_font */ |
| 49 NULL, /* close_display */ |
| 50 NULL, /* wire_to_event */ |
| 51 NULL, /* event_to_wire */ |
| 52 NULL, /* error */ |
| 53 NULL, /* error_string */ |
| 54 }; |
| 55 |
| 56 static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, |
| 57 dri2Info, |
| 58 dri2ExtensionName, |
| 59 &dri2ExtensionHooks, |
| 60 0, NULL) |
| 61 |
| 62 static int dri_fd = -1; |
| 63 static drm_intel_bufmgr *bufmgr = NULL; |
| 64 |
| 65 static Bool OpenDri() { |
| 66 if (bufmgr) return True; |
| 67 |
| 68 dri_fd = open("/dev/dri/card0", O_RDWR); |
| 69 if (dri_fd < 0) { |
| 70 perror("open dri"); |
| 71 return False; |
| 72 } |
| 73 |
| 74 drm_magic_t magic; |
| 75 if (drmGetMagic(dri_fd, &magic)) { |
| 76 close(dri_fd); |
| 77 TRACE_EVENT0("zcopy", "drmGetMagic failed"); |
| 78 return False; |
| 79 } |
| 80 |
| 81 Display *dpy = (Display *) gfx::GetXDisplay(); |
| 82 XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
| 83 xDRI2AuthenticateReq *req; |
| 84 xDRI2AuthenticateReply rep; |
| 85 |
| 86 XextCheckExtension(dpy, info, dri2ExtensionName, False); |
| 87 |
| 88 LockDisplay(dpy); |
| 89 GetReq(DRI2Authenticate, req); |
| 90 req->reqType = info->codes->major_opcode; |
| 91 req->dri2ReqType = X_DRI2Authenticate; |
| 92 req->window = DefaultRootWindow(dpy); |
| 93 req->magic = magic; |
| 94 |
| 95 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { |
| 96 dri_fd = -1; |
| 97 } |
| 98 UnlockDisplay(dpy); |
| 99 SyncHandle(); |
| 100 |
| 101 if (dri_fd < 0 || !rep.authenticated) { |
| 102 close(dri_fd); |
| 103 TRACE_EVENT0("zcopy", "authentication failed"); |
| 104 } else { |
| 105 bufmgr = drm_intel_bufmgr_gem_init(dri_fd, 2048); //XXX what is this number? |
| 106 if (!bufmgr) { |
| 107 TRACE_EVENT0("zcopy", "gem_init failed"); |
| 108 } |
| 109 } |
| 110 |
| 111 return bufmgr != NULL; |
| 112 } |
| 113 |
| 114 static void *AllocTexture(unsigned w, unsigned h, unsigned bpp) { |
| 115 // Figuring out how much memory to allocate for a texture is pretty |
| 116 // complicated due to padding and alignment concerns, and mipmaps, to |
| 117 // name a few reasons. |
| 118 // There's a lot of logic in the mesa i965 driver to handle it, which |
| 119 // is one of the drawbacks to allocating the texture memory here. |
| 120 // These asserts will catch some problems, but maybe not all. |
| 121 uint32_t tiling = I915_TILING_NONE; |
| 122 unsigned long pitch; |
| 123 |
| 124 assert(w % 4 == 0); |
| 125 assert(h % 2 == 0); |
| 126 drm_intel_bo *bo = drm_intel_bo_alloc_tiled(bufmgr, "region", w, h, bpp, |
| 127 &tiling, &pitch, 0); |
| 128 assert(tiling == I915_TILING_NONE); |
| 129 assert(pitch == w * 4); |
| 130 return bo; |
| 131 } |
| 132 |
| 133 } |
20 | 134 |
21 namespace content { | 135 namespace content { |
22 | 136 |
23 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; | 137 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; |
24 | 138 |
25 BrowserGpuChannelHostFactory::CreateRequest::CreateRequest() | 139 BrowserGpuChannelHostFactory::CreateRequest::CreateRequest() |
26 : event(true, false), | 140 : event(true, false), |
27 gpu_host_id(0), | 141 gpu_host_id(0), |
28 route_id(MSG_ROUTING_NONE) { | 142 route_id(MSG_ROUTING_NONE) { |
29 } | 143 } |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 } | 482 } |
369 | 483 |
370 scoped_ptr<gfx::GpuMemoryBuffer> | 484 scoped_ptr<gfx::GpuMemoryBuffer> |
371 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer( | 485 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer( |
372 size_t width, | 486 size_t width, |
373 size_t height, | 487 size_t height, |
374 unsigned internalformat) { | 488 unsigned internalformat) { |
375 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) | 489 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) |
376 return scoped_ptr<gfx::GpuMemoryBuffer>(); | 490 return scoped_ptr<gfx::GpuMemoryBuffer>(); |
377 | 491 |
| 492 #if 1 // defined(OS_LINUX) |
| 493 if (GetZCopy()) { |
| 494 if ((width % 4) || (height % 2)) { |
| 495 TRACE_EVENT0("zcopy", "can't handle texure size"); |
| 496 } else if (!GpuMemoryBufferImplFoobar::IsFormatSupported(internalformat)) { |
| 497 TRACE_EVENT0("zcopy", "can't handle texure format"); |
| 498 } else if (foobar::OpenDri()) { |
| 499 scoped_ptr<GpuMemoryBufferImplFoobar> foobar_buffer( |
| 500 new GpuMemoryBufferImplFoobar(gfx::Size(width, height), |
| 501 internalformat)); |
| 502 // This object needs to be created somehow. Can be something |
| 503 // platform/driver specific. |
| 504 void *foobar_object = foobar::AllocTexture(width, height, |
| 505 GpuMemoryBufferImpl::BytesPerPixel(internalformat)); |
| 506 if (foobar_buffer->InitializeFromFoobarObject(foobar_object)) |
| 507 return foobar_buffer.PassAs<gfx::GpuMemoryBuffer>(); |
| 508 } |
| 509 } |
| 510 #endif |
| 511 |
378 size_t size = width * height * | 512 size_t size = width * height * |
379 GpuMemoryBufferImpl::BytesPerPixel(internalformat); | 513 GpuMemoryBufferImpl::BytesPerPixel(internalformat); |
380 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); | 514 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); |
381 if (!shm->CreateAnonymous(size)) | 515 if (!shm->CreateAnonymous(size)) |
382 return scoped_ptr<gfx::GpuMemoryBuffer>(); | 516 return scoped_ptr<gfx::GpuMemoryBuffer>(); |
383 | 517 |
384 scoped_ptr<GpuMemoryBufferImplShm> buffer( | 518 scoped_ptr<GpuMemoryBufferImplShm> buffer( |
385 new GpuMemoryBufferImplShm(gfx::Size(width, height), internalformat)); | 519 new GpuMemoryBufferImplShm(gfx::Size(width, height), internalformat)); |
386 if (!buffer->InitializeFromSharedMemory(shm.Pass())) | 520 if (!buffer->InitializeFromSharedMemory(shm.Pass())) |
387 return scoped_ptr<gfx::GpuMemoryBuffer>(); | 521 return scoped_ptr<gfx::GpuMemoryBuffer>(); |
(...skipping 29 matching lines...) Expand all Loading... |
417 filter->AddRoute(MSG_ROUTING_CONTROL, handler); | 551 filter->AddRoute(MSG_ROUTING_CONTROL, handler); |
418 | 552 |
419 GetIOLoopProxy()->PostTask( | 553 GetIOLoopProxy()->PostTask( |
420 FROM_HERE, | 554 FROM_HERE, |
421 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, | 555 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, |
422 gpu_host_id_, | 556 gpu_host_id_, |
423 filter)); | 557 filter)); |
424 } | 558 } |
425 | 559 |
426 } // namespace content | 560 } // namespace content |
OLD | NEW |