| 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 7f8e66dc6cb8c084a871bef94248e0f80fe13bdf..62b3ce5b90bcddf8dff8754c95710f0af39dfd8a 100644
|
| --- a/content/browser/renderer_host/image_transport_factory.cc
|
| +++ b/content/browser/renderer_host/image_transport_factory.cc
|
| @@ -11,16 +11,21 @@
|
| #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/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"
|
| @@ -214,6 +219,136 @@ class CompositorSwapClient
|
| DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient);
|
| };
|
|
|
| +class BrowserCompositorOutputSurface;
|
| +
|
| +// Directs vsync updates to the appropriate BrowserCompositorOutputSurface.
|
| +class BrowserCompositorOutputSurfaceProxy :
|
| + public base::RefCountedThreadSafe<BrowserCompositorOutputSurfaceProxy> {
|
| + public:
|
| + BrowserCompositorOutputSurfaceProxy()
|
| + : message_handler_set_(false) {
|
| + }
|
| +
|
| + void AddSurface(BrowserCompositorOutputSurface* surface, int surface_id) {
|
| + if (!message_handler_set_) {
|
| + uint32 messages_to_filter[] = {GpuHostMsg_UpdateVSyncParameters::ID};
|
| + BrowserGpuChannelHostFactory::instance()->SetHandlerForControlMessages(
|
| + messages_to_filter,
|
| + arraysize(messages_to_filter),
|
| + base::Bind(&BrowserCompositorOutputSurfaceProxy::OnMessageReceived,
|
| + this),
|
| + MessageLoop::current()->message_loop_proxy());
|
| + message_handler_set_ = true;
|
| + }
|
| + surface_map_.AddWithID(surface, surface_id);
|
| + }
|
| +
|
| + void RemoveSurface(int surface_id) {
|
| + surface_map_.Remove(surface_id);
|
| + }
|
| +
|
| + private:
|
| + 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);
|
| +
|
| + friend class
|
| + base::RefCountedThreadSafe<BrowserCompositorOutputSurfaceProxy>;
|
| + ~BrowserCompositorOutputSurfaceProxy() {}
|
| + IDMap<BrowserCompositorOutputSurface> surface_map_;
|
| + bool message_handler_set_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(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,
|
| + BrowserCompositorOutputSurfaceProxy* output_surface_proxy)
|
| + : context3D_(context),
|
| + surface_id_(surface_id),
|
| + client_(NULL),
|
| + output_surface_proxy_(output_surface_proxy) {
|
| + DetachFromThread();
|
| + }
|
| +
|
| + virtual ~BrowserCompositorOutputSurface() {
|
| + DCHECK(CalledOnValidThread());
|
| + if (!client_)
|
| + return;
|
| + output_surface_proxy_->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;
|
| + output_surface_proxy_->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 {
|
| + }
|
| +
|
| + 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);
|
| + }
|
| +
|
| + private:
|
| + scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3D_;
|
| + int surface_id_;
|
| + Capabilities capabilities_;
|
| + WebKit::WebCompositorOutputSurfaceClient* client_;
|
| + scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_;
|
| +};
|
| +
|
| +void BrowserCompositorOutputSurfaceProxy::OnUpdateVSyncParameters(
|
| + int surface_id, base::TimeTicks timebase, base::TimeDelta interval) {
|
| + BrowserCompositorOutputSurface* surface = surface_map_.Lookup(surface_id);
|
| + if (surface)
|
| + surface->OnUpdateVSyncParameters(timebase, interval);
|
| +}
|
| +
|
| class GpuProcessTransportFactory :
|
| public ui::ContextFactory,
|
| public ImageTransportFactory,
|
| @@ -221,27 +356,33 @@ class GpuProcessTransportFactory :
|
| public:
|
| GpuProcessTransportFactory()
|
| : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) {
|
| + output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy();
|
| }
|
|
|
| virtual ~GpuProcessTransportFactory() {
|
| DCHECK(per_compositor_data_.empty());
|
| }
|
|
|
| - virtual WebKit::WebGraphicsContext3D* CreateContext(
|
| - ui::Compositor* compositor) OVERRIDE {
|
| - PerCompositorData* data = per_compositor_data_[compositor];
|
| - if (!data)
|
| - data = CreatePerCompositorData(compositor);
|
| - return CreateContextCommon(data->swap_client->AsWeakPtr(),
|
| - data->surface_id);
|
| - }
|
| -
|
| virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext()
|
| OVERRIDE {
|
| base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client;
|
| return CreateContextCommon(swap_client, 0);
|
| }
|
|
|
| + virtual WebKit::WebCompositorOutputSurface* CreateOutputSurface(
|
| + ui::Compositor* compositor) OVERRIDE {
|
| + PerCompositorData* data = per_compositor_data_[compositor];
|
| + if (!data)
|
| + data = CreatePerCompositorData(compositor);
|
| + WebGraphicsContext3DCommandBufferImpl* context =
|
| + CreateContextCommon(data->swap_client->AsWeakPtr(),
|
| + data->surface_id);
|
| + return new BrowserCompositorOutputSurface(
|
| + context,
|
| + per_compositor_data_[compositor]->surface_id,
|
| + output_surface_proxy_);
|
| + }
|
| +
|
| virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE {
|
| PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
|
| if (it == per_compositor_data_.end())
|
| @@ -462,6 +603,7 @@ class GpuProcessTransportFactory :
|
| scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context_;
|
| ObserverList<ImageTransportFactoryObserver> observer_list_;
|
| base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_;
|
| + scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory);
|
| };
|
|
|