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 4de531a912c721ffae42c9e7ea5c926b3d5fc3e7..a7f0befa04d883adef1b346d383a16834652ccd1 100644 |
| --- a/content/browser/renderer_host/image_transport_factory.cc |
| +++ b/content/browser/renderer_host/image_transport_factory.cc |
| @@ -11,16 +11,22 @@ |
| #include "base/command_line.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/observer_list.h" |
| +#include "base/threading/non_thread_safe.h" |
| #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
| #include "content/browser/gpu/gpu_data_manager_impl.h" |
| +#include "content/browser/gpu/gpu_process_host.h" |
| #include "content/browser/gpu/gpu_surface_tracker.h" |
| #include "content/common/gpu/client/gl_helper.h" |
| #include "content/common/gpu/client/gpu_channel_host.h" |
| #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
| +#include "content/common/gpu/gpu_messages.h" |
| #include "content/common/gpu/gpu_process_launch_causes.h" |
| #include "content/common/webkitplatformsupport_impl.h" |
| +#include "content/public/browser/browser_thread.h" |
|
jonathan.backer
2012/10/26 20:31:03
still need this?
ajuma
2012/10/29 17:02:26
No. Removed.
|
| #include "content/public/common/content_switches.h" |
| #include "gpu/ipc/command_buffer_proxy.h" |
| +#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurface.h" |
| +#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurfaceClient.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsContext3D.h" |
| #include "ui/compositor/compositor.h" |
| #include "ui/compositor/compositor_setup.h" |
| @@ -220,6 +226,154 @@ class CompositorSwapClient |
| DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient); |
| }; |
| +class BrowserCompositorOutputSurfaceProxy; |
| + |
| +// Adapts a WebGraphicsContext3DCommandBufferImpl into a |
| +// WebCompositorOutputSurface that also handles vsync parameter updates |
| +// arriving from the GPU process. |
| +class BrowserCompositorOutputSurface : |
| + public WebKit::WebCompositorOutputSurface, |
| + public base::NonThreadSafe { |
| + public: |
| + explicit BrowserCompositorOutputSurface( |
| + WebGraphicsContext3DCommandBufferImpl* context, |
| + int surface_id) |
| + : context3D_(context) |
| + , surface_id_(surface_id) |
| + , client_(NULL) { |
| + DetachFromThread(); |
| + } |
| + |
| + virtual ~BrowserCompositorOutputSurface() { |
| + DCHECK(CalledOnValidThread()); |
| + if (!client_) |
| + return; |
| + BrowserCompositorOutputSurfaceProxy::GetInstance()->RemoveSurface( |
| + surface_id_); |
| + } |
| + |
| + virtual bool bindToClient( |
| + WebKit::WebCompositorOutputSurfaceClient* client) OVERRIDE { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(client); |
| + DCHECK(!client_); |
| + if (context3D_.get()) { |
| + if (!context3D_->makeContextCurrent()) |
| + return false; |
| + } |
| + |
| + client_ = client; |
| + BrowserCompositorOutputSurfaceProxy::GetInstance()->AddSurface(this, |
| + surface_id_); |
| + return true; |
| + } |
| + |
| + virtual const Capabilities& capabilities() const OVERRIDE { |
| + DCHECK(CalledOnValidThread()); |
| + return capabilities_; |
| + } |
| + |
| + virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE { |
| + DCHECK(CalledOnValidThread()); |
| + return context3D_.get(); |
| + } |
| + |
| + virtual void sendFrameToParentCompositor( |
| + const WebKit::WebCompositorFrame&) OVERRIDE { |
| + } |
| + |
| + static void TerminateProxy() { |
| + BrowserCompositorOutputSurfaceProxy::Terminate(); |
| + } |
| + |
| + private: |
| + // Directs vsync updates to the appropriate BrowserCompositorOutputSurface. |
| + class BrowserCompositorOutputSurfaceProxy { |
|
jonathan.backer
2012/10/26 20:31:03
Why an inner class? We're in an anon namespace no?
ajuma
2012/10/29 17:02:26
Yes. Made this a non-inner class now.
|
| + public: |
| + static BrowserCompositorOutputSurfaceProxy* GetInstance() { |
|
jonathan.backer
2012/10/26 20:31:03
Singletons are generally frowned upon (we do have
ajuma
2012/10/29 17:02:26
Done.
|
| + if (!instance_) |
| + instance_ = new BrowserCompositorOutputSurfaceProxy(); |
| + return instance_; |
| + } |
| + |
| + static void Terminate() { |
| + if (instance_) { |
| + delete instance_; |
| + instance_ = NULL; |
| + } |
| + } |
| + |
| + void AddSurface(BrowserCompositorOutputSurface* surface, int surface_id) { |
| + surface_map_.AddWithID(surface, surface_id); |
| + } |
| + |
| + void RemoveSurface(int surface_id) { |
| + surface_map_.Remove(surface_id); |
| + } |
| + |
| + private: |
| + BrowserCompositorOutputSurfaceProxy() { |
| + uint32 messages_to_filter[] = {GpuHostMsg_UpdateVSyncParameters::ID}; |
| + BrowserGpuChannelHostFactory::instance()->SetHandlerForControlMessages( |
| + messages_to_filter, |
| + arraysize(messages_to_filter), |
| + base::Bind(&BrowserCompositorOutputSurfaceProxy:: |
| + OnMessageReceivedStatic), |
|
jonathan.backer
2012/10/26 20:31:03
Can we bind OnMessageReceived to this and eliminat
ajuma
2012/10/29 17:02:26
Done.
|
| + MessageLoop::current()->message_loop_proxy()); |
| + } |
| + |
| + static void OnMessageReceivedStatic(const IPC::Message& message) { |
| + if (instance_) { |
| + instance_->OnMessageReceived(message); |
| + } |
| + } |
| + |
| + void OnMessageReceived(const IPC::Message& message) { |
| + IPC_BEGIN_MESSAGE_MAP(BrowserCompositorOutputSurfaceProxy, message) |
| + IPC_MESSAGE_HANDLER(GpuHostMsg_UpdateVSyncParameters, |
| + OnUpdateVSyncParameters); |
| + IPC_END_MESSAGE_MAP() |
| + } |
| + |
| + void OnUpdateVSyncParameters( |
| + int surface_id, base::TimeTicks timebase, base::TimeDelta interval) { |
| + BrowserCompositorOutputSurface* surface = surface_map_.Lookup(surface_id); |
| + if (surface) |
| + surface->OnUpdateVSyncParameters(timebase, interval); |
| + } |
| + |
| + friend class |
| + base::RefCountedThreadSafe<BrowserCompositorOutputSurfaceProxy>; |
| + ~BrowserCompositorOutputSurfaceProxy() {} |
| + IDMap<BrowserCompositorOutputSurface> surface_map_; |
| + |
| + static BrowserCompositorOutputSurfaceProxy* instance_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(BrowserCompositorOutputSurfaceProxy); |
| + }; |
| + |
| + void OnUpdateVSyncParameters( |
| + base::TimeTicks timebase, base::TimeDelta interval) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(client_); |
| + double monotonicTimebase = timebase.ToInternalValue() / |
| + static_cast<double>(base::Time::kMicrosecondsPerSecond); |
| + double intervalInSeconds = interval.ToInternalValue() / |
| + static_cast<double>(base::Time::kMicrosecondsPerSecond); |
| + client_->onVSyncParametersChanged(monotonicTimebase, intervalInSeconds); |
| + } |
| + |
| + scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3D_; |
| + int surface_id_; |
| + Capabilities capabilities_; |
| + WebKit::WebCompositorOutputSurfaceClient* client_; |
| +}; |
| + |
| +// static |
| +BrowserCompositorOutputSurface::BrowserCompositorOutputSurfaceProxy* |
| + BrowserCompositorOutputSurface::BrowserCompositorOutputSurfaceProxy:: |
| + instance_ = NULL; |
| + |
| class GpuProcessTransportFactory : |
|
jonathan.backer
2012/10/26 20:31:03
Maybe this can own the BrowserCompositorOutputSurf
ajuma
2012/10/29 17:02:26
Done.
|
| public ui::ContextFactory, |
| public ImageTransportFactory, |
| @@ -233,7 +387,7 @@ class GpuProcessTransportFactory : |
| DCHECK(per_compositor_data_.empty()); |
| } |
| - virtual WebKit::WebGraphicsContext3D* CreateContext( |
| + virtual WebGraphicsContext3DCommandBufferImpl* CreateContext( |
| ui::Compositor* compositor) OVERRIDE { |
| PerCompositorData* data = per_compositor_data_[compositor]; |
| if (!data) |
| @@ -248,6 +402,14 @@ class GpuProcessTransportFactory : |
| return CreateContextCommon(swap_client, 0); |
| } |
| + virtual WebKit::WebCompositorOutputSurface* CreateOutputSurface( |
| + ui::Compositor* compositor) OVERRIDE { |
| + WebGraphicsContext3DCommandBufferImpl* context = CreateContext(compositor); |
| + return new BrowserCompositorOutputSurface( |
| + context, |
| + per_compositor_data_[compositor]->surface_id); |
| + } |
| + |
| virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE { |
| PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); |
| if (it == per_compositor_data_.end()) |
| @@ -507,6 +669,7 @@ void ImageTransportFactory::Terminate() { |
| ui::ContextFactory::SetInstance(NULL); |
| delete g_factory; |
| g_factory = NULL; |
| + BrowserCompositorOutputSurface::TerminateProxy(); |
| } |
| // static |