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 <libdrm/i915_drm.h> |
| 30 #include <libdrm/intel_bufmgr.h> |
| 31 #include <xf86drm.h> |
| 32 #include <X11/Xlib.h> |
| 33 #include <X11/Xlibint.h> |
| 34 #include <X11/extensions/Xext.h> |
| 35 #include <X11/extensions/extutil.h> |
| 36 #include <X11/extensions/dri2proto.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 TRACE_EVENT_INSTANT0("zcopy", "open dri device failed", |
| 71 TRACE_EVENT_SCOPE_THREAD); |
| 72 return False; |
| 73 } |
| 74 |
| 75 drm_magic_t magic; |
| 76 if (drmGetMagic(dri_fd, &magic)) { |
| 77 close(dri_fd); |
| 78 TRACE_EVENT_INSTANT0("zcopy", "drmGetMagic failed", |
| 79 TRACE_EVENT_SCOPE_THREAD); |
| 80 return False; |
| 81 } |
| 82 |
| 83 Display *dpy = (Display *) gfx::GetXDisplay(); |
| 84 XExtDisplayInfo *info = DRI2FindDisplay(dpy); |
| 85 xDRI2AuthenticateReq *req; |
| 86 xDRI2AuthenticateReply rep; |
| 87 |
| 88 XextCheckExtension(dpy, info, dri2ExtensionName, False); |
| 89 |
| 90 LockDisplay(dpy); |
| 91 GetReq(DRI2Authenticate, req); |
| 92 req->reqType = info->codes->major_opcode; |
| 93 req->dri2ReqType = X_DRI2Authenticate; |
| 94 req->window = DefaultRootWindow(dpy); |
| 95 req->magic = magic; |
| 96 |
| 97 if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { |
| 98 dri_fd = -1; |
| 99 } |
| 100 UnlockDisplay(dpy); |
| 101 SyncHandle(); |
| 102 |
| 103 if (dri_fd < 0 || !rep.authenticated) { |
| 104 close(dri_fd); |
| 105 TRACE_EVENT_INSTANT0("zcopy", "authentication failed", |
| 106 TRACE_EVENT_SCOPE_THREAD); |
| 107 } else { |
| 108 bufmgr = drm_intel_bufmgr_gem_init(dri_fd, 2048); //XXX what is this number? |
| 109 if (!bufmgr) { |
| 110 TRACE_EVENT_INSTANT0("zcopy", "gem_init failed", |
| 111 TRACE_EVENT_SCOPE_THREAD); |
| 112 } |
| 113 } |
| 114 |
| 115 return bufmgr != NULL; |
| 116 } |
| 117 |
| 118 static void *AllocTexture(unsigned width, unsigned height, unsigned bpp) { |
| 119 // Figuring out how much memory to allocate for a texture is pretty |
| 120 // complicated due to padding and alignment concerns, and mipmaps, to |
| 121 // name a few reasons. |
| 122 // There's a lot of logic in the mesa i965 driver to handle it, which |
| 123 // is one of the drawbacks to allocating the texture memory here. |
| 124 // The checks here will catch some problems, but maybe not all. |
| 125 uint32_t tiling, want; |
| 126 unsigned long pitch; |
| 127 |
| 128 if ((width % 4) || (height % 2)) { |
| 129 TRACE_EVENT_INSTANT2("zcopy", "can't handle texure size", |
| 130 TRACE_EVENT_SCOPE_THREAD, |
| 131 "width", width, |
| 132 "height", height); |
| 133 return NULL; |
| 134 } |
| 135 |
| 136 tiling = want = GetZCopy() == 'u' ? I915_TILING_NONE : I915_TILING_Y; |
| 137 drm_intel_bo *bo = drm_intel_bo_alloc_tiled(bufmgr, "region", width, height, |
| 138 bpp, &tiling, &pitch, 0); |
| 139 |
| 140 if (tiling != want) { |
| 141 TRACE_EVENT_INSTANT2("zcopy", "did not get requested tiling", |
| 142 TRACE_EVENT_SCOPE_THREAD, |
| 143 "width", width, |
| 144 "height", height); |
| 145 drm_intel_bo_unreference(bo); |
| 146 return NULL; |
| 147 } |
| 148 |
| 149 if (pitch != width * 4) { |
| 150 TRACE_EVENT_INSTANT2("zcopy", "did not get expected pitch", |
| 151 TRACE_EVENT_SCOPE_THREAD, |
| 152 "width", width, |
| 153 "height", height); |
| 154 drm_intel_bo_unreference(bo); |
| 155 return NULL; |
| 156 } |
| 157 |
| 158 return bo; |
| 159 } |
| 160 |
| 161 } // namespace foobar |
20 | 162 |
21 namespace content { | 163 namespace content { |
22 | 164 |
23 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; | 165 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; |
24 | 166 |
25 BrowserGpuChannelHostFactory::CreateRequest::CreateRequest() | 167 BrowserGpuChannelHostFactory::CreateRequest::CreateRequest() |
26 : event(true, false), | 168 : event(true, false), |
27 gpu_host_id(0), | 169 gpu_host_id(0), |
28 route_id(MSG_ROUTING_NONE) { | 170 route_id(MSG_ROUTING_NONE) { |
29 } | 171 } |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 514 } |
373 | 515 |
374 scoped_ptr<gfx::GpuMemoryBuffer> | 516 scoped_ptr<gfx::GpuMemoryBuffer> |
375 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer( | 517 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer( |
376 size_t width, | 518 size_t width, |
377 size_t height, | 519 size_t height, |
378 unsigned internalformat) { | 520 unsigned internalformat) { |
379 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) | 521 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat)) |
380 return scoped_ptr<gfx::GpuMemoryBuffer>(); | 522 return scoped_ptr<gfx::GpuMemoryBuffer>(); |
381 | 523 |
| 524 #if defined(OS_LINUX) || defined(OS_CHROMEOS) |
| 525 if (GetZCopy()) { |
| 526 if (!GpuMemoryBufferImplFoobar::IsFormatSupported(internalformat)) { |
| 527 TRACE_EVENT_INSTANT0("zcopy", "can't handle texure format", |
| 528 TRACE_EVENT_SCOPE_THREAD); |
| 529 } else if (foobar::OpenDri()) { |
| 530 // This object needs to be created somehow. Can be something |
| 531 // platform/driver specific. |
| 532 void *foobar_object = foobar::AllocTexture(width, height, |
| 533 GpuMemoryBufferImpl::BytesPerPixel(internalformat)); |
| 534 if (foobar_object) { |
| 535 scoped_ptr<GpuMemoryBufferImplFoobar> foobar_buffer( |
| 536 new GpuMemoryBufferImplFoobar(gfx::Size(width, height), |
| 537 internalformat)); |
| 538 if (foobar_buffer->InitializeFromFoobarObject(foobar_object)) |
| 539 return foobar_buffer.PassAs<gfx::GpuMemoryBuffer>(); |
| 540 } |
| 541 } |
| 542 } |
| 543 #endif |
| 544 |
382 size_t size = width * height * | 545 size_t size = width * height * |
383 GpuMemoryBufferImpl::BytesPerPixel(internalformat); | 546 GpuMemoryBufferImpl::BytesPerPixel(internalformat); |
384 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); | 547 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory()); |
385 if (!shm->CreateAnonymous(size)) | 548 if (!shm->CreateAnonymous(size)) |
386 return scoped_ptr<gfx::GpuMemoryBuffer>(); | 549 return scoped_ptr<gfx::GpuMemoryBuffer>(); |
387 | 550 |
388 scoped_ptr<GpuMemoryBufferImplShm> buffer( | 551 scoped_ptr<GpuMemoryBufferImplShm> buffer( |
389 new GpuMemoryBufferImplShm(gfx::Size(width, height), internalformat)); | 552 new GpuMemoryBufferImplShm(gfx::Size(width, height), internalformat)); |
390 if (!buffer->InitializeFromSharedMemory(shm.Pass())) | 553 if (!buffer->InitializeFromSharedMemory(shm.Pass())) |
391 return scoped_ptr<gfx::GpuMemoryBuffer>(); | 554 return scoped_ptr<gfx::GpuMemoryBuffer>(); |
(...skipping 29 matching lines...) Expand all Loading... |
421 filter->AddRoute(MSG_ROUTING_CONTROL, handler); | 584 filter->AddRoute(MSG_ROUTING_CONTROL, handler); |
422 | 585 |
423 GetIOLoopProxy()->PostTask( | 586 GetIOLoopProxy()->PostTask( |
424 FROM_HERE, | 587 FROM_HERE, |
425 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, | 588 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, |
426 gpu_host_id_, | 589 gpu_host_id_, |
427 filter)); | 590 filter)); |
428 } | 591 } |
429 | 592 |
430 } // namespace content | 593 } // namespace content |
OLD | NEW |