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