Chromium Code Reviews| Index: content/browser/renderer_host/image_transport_factory.cc |
| diff --git a/content/browser/renderer_host/image_transport_factory.cc b/content/browser/renderer_host/image_transport_factory.cc |
| index ba45309f8d990cfe0539c320d0291f8b06491df1..c29f2c346554caa9485188b432558835a10141c5 100644 |
| --- a/content/browser/renderer_host/image_transport_factory.cc |
| +++ b/content/browser/renderer_host/image_transport_factory.cc |
| @@ -31,6 +31,8 @@ |
| #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" |
| #include "third_party/khronos/GLES2/gl2.h" |
| #include "third_party/khronos/GLES2/gl2ext.h" |
| +#include "third_party/skia/include/gpu/GrContext.h" |
| +#include "third_party/skia/include/gpu/gl/GrGLInterface.h" |
| #include "ui/compositor/compositor.h" |
| #include "ui/compositor/compositor_setup.h" |
| #include "ui/compositor/test_web_graphics_context_3d.h" |
| @@ -366,6 +368,50 @@ void BrowserCompositorOutputSurfaceProxy::OnUpdateVSyncParameters( |
| surface->OnUpdateVSyncParameters(timebase, interval); |
| } |
| +// TODO(danakj): Go directly to GPU process instead of through WGC3D. |
| +class GrContextMemoryManager |
| + : public WebKit::WebGraphicsContext3D:: |
| + WebGraphicsMemoryAllocationChangedCallbackCHROMIUM { |
| + public: |
| + GrContextMemoryManager( |
| + WebKit::WebGraphicsContext3D* context3d, GrContext* gr_context) |
| + : context3d_(context3d), |
| + gr_context_(gr_context) { |
| + |
| + gr_context_->setTextureCacheLimits( |
| + kMaxGaneshTextureCacheCount, kMaxGaneshTextureCacheBytes); |
| + context3d_->setMemoryAllocationChangedCallbackCHROMIUM(this); |
| + } |
| + ~GrContextMemoryManager() { |
| + context3d_->setMemoryAllocationChangedCallbackCHROMIUM(NULL); |
| + } |
| + |
| + virtual void onMemoryAllocationChanged( |
| + WebKit::WebGraphicsMemoryAllocation allocation) OVERRIDE { |
| + if (!gr_context_) |
| + return; |
| + |
| + if (!allocation.gpuResourceSizeInBytes) { |
| + gr_context_->freeGpuResources(); |
| + gr_context_->setTextureCacheLimits(0, 0); |
| + } else { |
| + gr_context_->setTextureCacheLimits( |
| + kMaxGaneshTextureCacheCount, kMaxGaneshTextureCacheBytes); |
| + } |
| + } |
| + |
| + private: |
| + // The limit of the number of textures we hold in the GrContext's |
| + // bitmap->texture cache. |
| + static const int kMaxGaneshTextureCacheCount = 2048; |
| + // The limit of the bytes allocated toward textures in the GrContext's |
| + // bitmap->texture cache. |
| + static const size_t kMaxGaneshTextureCacheBytes = 96 * 1024 * 1024; |
| + |
| + WebKit::WebGraphicsContext3D* context3d_; |
| + GrContext* gr_context_; |
| +}; |
| + |
| class GpuProcessTransportFactory |
| : public ui::ContextFactory, |
| public ImageTransportFactory, |
| @@ -400,6 +446,41 @@ class GpuProcessTransportFactory |
| output_surface_proxy_); |
| } |
| + WebKit::WebGraphicsContext3D* CreateOrGetOffscreenSkiaContextForMainThread() { |
| + CreateOrGetOffscreenContextCommon( |
| + &offscreen_skia_context_main_thread, |
| + &offscreen_skia_gr_context_main_thread, |
| + &offscreen_skia_gr_context_memory_manager_main_thread); |
| + return offscreen_skia_context_main_thread.get(); |
| + } |
| + |
| + WebKit::WebGraphicsContext3D* |
| + CreateOrGetOffscreenSkiaContextForCompositorThread() { |
| + CreateOrGetOffscreenContextCommon( |
| + &offscreen_skia_context_compositor_thread, |
| + &offscreen_skia_gr_context_compositor_thread, |
| + &offscreen_skia_gr_context_memory_manager_compositor_thread); |
| + return offscreen_skia_context_compositor_thread.get(); |
| + } |
| + |
| + GrContext* CreateOrGetOffscreenSkiaGrContextForMainThread() { |
| + CreateOrGetOffscreenSkiaContextForMainThread(); |
| + CreateOrGetGrContextCommon( |
| + offscreen_skia_context_main_thread.get(), |
| + &offscreen_skia_gr_context_main_thread, |
| + &offscreen_skia_gr_context_memory_manager_main_thread); |
| + return offscreen_skia_gr_context_main_thread.get(); |
| + } |
| + |
| + GrContext* CreateOrGetOffscreenSkiaGrContextForCompositorThread() { |
| + CreateOrGetOffscreenSkiaContextForCompositorThread(); |
| + CreateOrGetGrContextCommon( |
| + offscreen_skia_context_compositor_thread.get(), |
| + &offscreen_skia_gr_context_compositor_thread, |
| + &offscreen_skia_gr_context_memory_manager_compositor_thread); |
| + return offscreen_skia_gr_context_compositor_thread.get(); |
| + } |
| + |
| virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE { |
| PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); |
| if (it == per_compositor_data_.end()) |
| @@ -560,6 +641,46 @@ class GpuProcessTransportFactory |
| return context.release(); |
| } |
| + void CreateOrGetOffscreenContextCommon( |
| + scoped_ptr<WebKit::WebGraphicsContext3D>* context3d, |
| + skia::RefPtr<GrContext>* gr_context, |
| + scoped_ptr<GrContextMemoryManager>* gr_context_memory_manager) { |
| + if ((*context3d)) { |
| + if (!(*context3d)->makeContextCurrent() || |
| + (*context3d)->getGraphicsResetStatusARB()) { |
| + gr_context_memory_manager->reset(); |
| + if ((*gr_context)) |
| + (*gr_context)->contextDestroyed(); |
| + gr_context->clear(); |
| + context3d->reset(); |
| + } |
| + } |
| + |
| + if (!(*context3d)) |
| + (*context3d) = make_scoped_ptr(CreateOffscreenContext()); |
|
piman
2013/02/05 22:42:48
nit: context3d->reset(CreateOffscreenContext()) is
danakj
2013/02/05 22:56:00
Done.
|
| + } |
| + |
| + void CreateOrGetGrContextCommon( |
| + WebKit::WebGraphicsContext3D* context3d, |
| + skia::RefPtr<GrContext>* gr_context, |
| + scoped_ptr<GrContextMemoryManager>* gr_context_memory_manager) { |
| + if (!context3d) |
| + return; |
| + if (*gr_context) |
| + return; |
| + |
| + skia::RefPtr<GrGLInterface> interface = skia::AdoptRef( |
| + context3d->createGrGLInterface()); |
| + *gr_context = skia::AdoptRef(GrContext::Create( |
| + kOpenGL_Shaders_GrEngine, |
| + reinterpret_cast<GrPlatform3DContext>(interface.get()))); |
|
piman
2013/02/05 22:42:48
/cry on the reinterpret_cast
danakj
2013/02/05 22:56:00
Ya... more incoming as well :X
|
| + |
| + if (*gr_context) { |
| + *gr_context_memory_manager = make_scoped_ptr(new GrContextMemoryManager( |
|
piman
2013/02/05 22:42:48
nit: can also use reset(...) here
danakj
2013/02/05 22:56:00
Done.
|
| + context3d, gr_context->get())); |
| + } |
| + } |
| + |
| void CreateSharedContextLazy() { |
| if (shared_context_.get()) |
| return; |
| @@ -598,6 +719,17 @@ class GpuProcessTransportFactory |
| base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; |
| scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; |
| + // Per-process data. |
| + scoped_ptr<WebKit::WebGraphicsContext3D> offscreen_skia_context_main_thread; |
|
piman
2013/02/05 22:42:48
Could we reuse the shared_context_ for the main th
danakj
2013/02/05 22:56:00
I don't know, it looks like something that is crea
|
| + scoped_ptr<WebKit::WebGraphicsContext3D> |
| + offscreen_skia_context_compositor_thread; |
| + skia::RefPtr<GrContext> offscreen_skia_gr_context_main_thread; |
| + skia::RefPtr<GrContext> offscreen_skia_gr_context_compositor_thread; |
| + scoped_ptr<GrContextMemoryManager> |
| + offscreen_skia_gr_context_memory_manager_main_thread; |
| + scoped_ptr<GrContextMemoryManager> |
| + offscreen_skia_gr_context_memory_manager_compositor_thread; |
| + |
| DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); |
| }; |