diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/render_widget_host_impl.cc | 5 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_impl.h | 7 | ||||
-rw-r--r-- | content/common/view_messages.h | 5 | ||||
-rw-r--r-- | content/content_renderer.gypi | 2 | ||||
-rw-r--r-- | content/renderer/gpu/compositor_output_surface.cc | 100 | ||||
-rw-r--r-- | content/renderer/gpu/compositor_output_surface.h | 60 | ||||
-rw-r--r-- | content/renderer/gpu/compositor_thread.h | 2 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.cc | 13 | ||||
-rw-r--r-- | content/renderer/render_thread_impl.h | 10 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 108 | ||||
-rw-r--r-- | content/renderer/render_view_impl.h | 7 |
11 files changed, 276 insertions, 43 deletions
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 3d44fc4..0f21484 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -1072,6 +1072,11 @@ void RenderWidgetHostImpl::SetDeviceScaleFactor(float scale) { Send(new ViewMsg_SetDeviceScaleFactor(GetRoutingID(), scale)); } +void RenderWidgetHostImpl::UpdateVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval) { + Send(new ViewMsg_UpdateVSyncParameters(GetRoutingID(), timebase, interval)); +} + void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status, int exit_code) { // Clearing this flag causes us to re-create the renderer when recovering diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index f224355..0c6842a 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -358,6 +358,13 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, // locked. bool GotResponseToLockMouseRequest(bool allowed); + // Tells the RenderWidget about the latest vsync parameters. + // Note: Make sure the timebase was obtained using + // base::TimeTicks::HighResNow. Using the non-high res timer will result in + // incorrect synchronization across processes. + virtual void UpdateVSyncParameters(base::TimeTicks timebase, + base::TimeDelta interval); + // Called by the view in response to AcceleratedSurfaceBuffersSwapped or // AcceleratedSurfacePostSubBuffer. static void AcknowledgeBufferPresent( diff --git a/content/common/view_messages.h b/content/common/view_messages.h index da41ea2..042bff4 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -1581,6 +1581,11 @@ IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateRect, // which may get delayed until the browser's UI unblocks. IPC_MESSAGE_ROUTED0(ViewHostMsg_UpdateIsDelayed) +// Sent by the renderer when the parameters for vsync alignment have changed. +IPC_MESSAGE_ROUTED2(ViewMsg_UpdateVSyncParameters, + base::TimeTicks /* timebase */, + base::TimeDelta /* interval */) + // Sent by the renderer when accelerated compositing is enabled or disabled to // notify the browser whether or not is should do painting. IPC_MESSAGE_ROUTED1(ViewHostMsg_DidActivateAcceleratedCompositing, diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 0c0e94d..42b967a 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -80,6 +80,8 @@ 'renderer/gamepad_shared_memory_reader.h', 'renderer/geolocation_dispatcher.cc', 'renderer/geolocation_dispatcher.h', + 'renderer/gpu/compositor_output_surface.cc', + 'renderer/gpu/compositor_output_surface.h', 'renderer/gpu/compositor_thread.cc', 'renderer/gpu/compositor_thread.h', 'renderer/gpu/input_event_filter.cc', diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc new file mode 100644 index 0000000..93e0fd5 --- /dev/null +++ b/content/renderer/gpu/compositor_output_surface.cc @@ -0,0 +1,100 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/gpu/compositor_output_surface.h" + +#include "base/message_loop_proxy.h" +#include "content/common/view_messages.h" +#include "content/renderer/render_thread_impl.h" +#include "ipc/ipc_forwarding_message_filter.h" +#include "ipc/ipc_sync_channel.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurfaceClient.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h" + +using WebKit::WebGraphicsContext3D; + +//------------------------------------------------------------------------------ + +// static +IPC::ForwardingMessageFilter* CompositorOutputSurface::CreateFilter( + base::TaskRunner* target_task_runner) +{ + uint32 messages_to_filter[] = {ViewMsg_UpdateVSyncParameters::ID}; + return new IPC::ForwardingMessageFilter( + messages_to_filter, arraysize(messages_to_filter), + target_task_runner); +} + +CompositorOutputSurface::CompositorOutputSurface( + int32 routing_id, + WebGraphicsContext3D* context3D) + : output_surface_filter_( + RenderThreadImpl::current()->compositor_output_surface_filter()) + , client_(NULL) + , routing_id_(routing_id) + , context3D_(context3D) { + DCHECK(output_surface_filter_); + capabilities_.hasParentCompositor = false; + DetachFromThread(); +} + +CompositorOutputSurface::~CompositorOutputSurface() { + DCHECK(CalledOnValidThread()); + if (!client_) + return; + output_surface_filter_->RemoveRoute(routing_id_); +} + +const WebKit::WebCompositorOutputSurface::Capabilities& + CompositorOutputSurface::capabilities() const { + DCHECK(CalledOnValidThread()); + return capabilities_; +} + +bool CompositorOutputSurface::bindToClient( + WebKit::WebCompositorOutputSurfaceClient* client) { + DCHECK(CalledOnValidThread()); + DCHECK(!client_); + if (!context3D_->makeContextCurrent()) + return false; + + client_ = client; + + output_surface_filter_->AddRoute( + routing_id_, + base::Bind(&CompositorOutputSurface::OnMessageReceived, + base::Unretained(this))); + + return true; +} + +WebGraphicsContext3D* CompositorOutputSurface::context3D() const { + DCHECK(CalledOnValidThread()); + return context3D_.get(); +} + +void CompositorOutputSurface::sendFrameToParentCompositor( + const WebKit::WebCompositorFrame&) { + DCHECK(CalledOnValidThread()); + NOTREACHED(); +} + +void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) { + DCHECK(CalledOnValidThread()); + IPC_BEGIN_MESSAGE_MAP(CompositorOutputSurface, message) + IPC_MESSAGE_HANDLER(ViewMsg_UpdateVSyncParameters, OnUpdateVSyncParameters); + IPC_END_MESSAGE_MAP() +} + +void CompositorOutputSurface::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); +} diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h new file mode 100644 index 0000000..3f4ed88 --- /dev/null +++ b/content/renderer/gpu/compositor_output_surface.h @@ -0,0 +1,60 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_GPU_COMPOSITOR_OUTPUT_SURFACE_H_ +#define CONTENT_RENDERER_GPU_COMPOSITOR_OUTPUT_SURFACE_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" +#include "base/threading/non_thread_safe.h" +#include "base/time.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurface.h" + +namespace base { + class TaskRunner; +} + +namespace IPC { + class ForwardingMessageFilter; + class Message; + class SyncChannel; +} + +// This class can be created only on the main thread, but then becomes pinned +// to a fixed thread when bindToClient is called. +class CompositorOutputSurface + : NON_EXPORTED_BASE(public WebKit::WebCompositorOutputSurface) + , NON_EXPORTED_BASE(public base::NonThreadSafe) { + public: + static IPC::ForwardingMessageFilter* CreateFilter( + base::TaskRunner* target_task_runner); + + CompositorOutputSurface(int32 routing_id, + WebKit::WebGraphicsContext3D* context3d); + virtual ~CompositorOutputSurface(); + + // WebCompositorOutputSurface implementation. + virtual bool bindToClient( + WebKit::WebCompositorOutputSurfaceClient* client) OVERRIDE; + virtual const Capabilities& capabilities() const OVERRIDE; + virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE; + virtual void sendFrameToParentCompositor( + const WebKit::WebCompositorFrame&) OVERRIDE; + + private: + void OnMessageReceived(const IPC::Message& message); + void OnUpdateVSyncParameters( + base::TimeTicks timebase, base::TimeDelta interval); + + scoped_refptr<IPC::ForwardingMessageFilter> output_surface_filter_; + WebKit::WebCompositorOutputSurfaceClient* client_; + int routing_id_; + Capabilities capabilities_; + scoped_ptr<WebKit::WebGraphicsContext3D> context3D_; +}; + +#endif // CONTENT_RENDERER_GPU_COMPOSITOR_OUTPUT_SURFACE_H_ + diff --git a/content/renderer/gpu/compositor_thread.h b/content/renderer/gpu/compositor_thread.h index ed38a37..aeebd98 100644 --- a/content/renderer/gpu/compositor_thread.h +++ b/content/renderer/gpu/compositor_thread.h @@ -40,6 +40,8 @@ class CompositorThread { webkit_glue::WebThreadImpl* GetWebThread() { return &thread_; } + MessageLoop* message_loop() { return thread_.message_loop(); } + private: // Callback only from the compositor's thread. void RemoveInputHandler(int routing_id); diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index c33a671..6bdc9b6 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -56,6 +56,7 @@ #include "content/renderer/dom_storage/webstoragearea_impl.h" #include "content/renderer/dom_storage/webstoragenamespace_impl.h" #include "content/renderer/gpu/compositor_thread.h" +#include "content/renderer/gpu/compositor_output_surface.h" #include "content/renderer/gpu/gpu_benchmarking_extension.h" #include "content/renderer/media/audio_hardware.h" #include "content/renderer/media/audio_input_message_filter.h" @@ -70,6 +71,7 @@ #include "content/renderer/renderer_webkitplatformsupport_impl.h" #include "grit/content_resources.h" #include "ipc/ipc_channel_handle.h" +#include "ipc/ipc_forwarding_message_filter.h" #include "ipc/ipc_platform_file.h" #include "media/base/media.h" #include "net/base/net_errors.h" @@ -312,6 +314,9 @@ RenderThreadImpl::~RenderThreadImpl() { if (file_thread_.get()) file_thread_->Stop(); + RemoveFilter(compositor_output_surface_filter_.get()); + compositor_output_surface_filter_ = NULL; + if (compositor_initialized_) { WebKit::WebCompositor::shutdown(); compositor_initialized_ = false; @@ -519,6 +524,14 @@ void RenderThreadImpl::EnsureWebKitInitialized() { } compositor_initialized_ = true; + MessageLoop* output_surface_loop = enable ? + compositor_thread_->message_loop() : + MessageLoop::current(); + + compositor_output_surface_filter_ = CompositorOutputSurface::CreateFilter( + output_surface_loop->message_loop_proxy()); + AddFilter(compositor_output_surface_filter_.get()); + WebScriptController::enableV8SingleThreadMode(); RenderThreadImpl::RegisterSchemes(); diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index dfcdb65..d39fb9e 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h @@ -52,6 +52,10 @@ class ScopedCOMInitializer; } } +namespace IPC { +class ForwardingMessageFilter; +} + namespace content { class AudioRendererMixerManager; class MediaStreamCenter; @@ -162,6 +166,10 @@ class CONTENT_EXPORT RenderThreadImpl : public content::RenderThread, void DoNotSuspendWebKitSharedTimer(); void DoNotNotifyWebKitOfModalLoop(); + IPC::ForwardingMessageFilter* compositor_output_surface_filter() const { + return compositor_output_surface_filter_.get(); + } + // Will be NULL if threaded compositing has not been enabled. CompositorThread* compositor_thread() const { return compositor_thread_.get(); @@ -298,6 +306,8 @@ class CONTENT_EXPORT RenderThreadImpl : public content::RenderThread, bool compositor_initialized_; scoped_ptr<CompositorThread> compositor_thread_; + scoped_refptr<IPC::ForwardingMessageFilter> compositor_output_surface_filter_; + scoped_ptr<content::old::BrowserPluginRegistry> browser_plugin_registry_; ObserverList<content::RenderProcessObserver> observers_; diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index f2c7716e..fd64efb 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -69,6 +69,7 @@ #include "content/renderer/external_popup_menu.h" #include "content/renderer/geolocation_dispatcher.h" #include "content/renderer/gpu/compositor_thread.h" +#include "content/renderer/gpu/compositor_output_surface.h" #include "content/renderer/idle_user_detector.h" #include "content/renderer/input_tag_speech_dispatcher.h" #include "content/renderer/java/java_bridge_dispatcher.h" @@ -108,6 +109,7 @@ #include "net/base/escape.h" #include "net/base/net_errors.h" #include "net/http/http_util.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurface.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMMessageEvent.h" @@ -1759,49 +1761,28 @@ WebStorageNamespace* RenderViewImpl::createSessionStorageNamespace( return new WebStorageNamespaceImpl(session_storage_namespace_id_); } -WebGraphicsContext3D* RenderViewImpl::createGraphicsContext3D( - const WebGraphicsContext3D::Attributes& attributes) { - if (!webview()) +WebKit::WebCompositorOutputSurface* RenderViewImpl::createOutputSurface() { + // TODO(aelias): if force-software-mode is on, create an output surface + // without a 3D context. + + // Explicitly disable antialiasing for the compositor. As of the time of + // this writing, the only platform that supported antialiasing for the + // compositor was Mac OS X, because the on-screen OpenGL context creation + // code paths on Windows and Linux didn't yet have multisampling support. + // Mac OS X essentially always behaves as though it's rendering offscreen. + // Multisampling has a heavy cost especially on devices with relatively low + // fill rate like most notebooks, and the Mac implementation would need to + // be optimized to resolve directly into the IOSurface shared between the + // GPU and browser processes. For these reasons and to avoid platform + // disparities we explicitly disable antialiasing. + WebKit::WebGraphicsContext3D::Attributes attributes; + attributes.antialias = false; + attributes.shareResources = true; + WebGraphicsContext3D* context = CreateGraphicsContext3D(attributes); + if (!context) return NULL; - if (GetGuestToEmbedderChannel()) { - WebGraphicsContext3DCommandBufferImpl* context = - GetGuestToEmbedderChannel()->CreateWebGraphicsContext3D( - this, attributes, false); - if (!guest_pp_instance()) { - guest_uninitialized_context_ = context; - guest_attributes_ = attributes; - } - return context; - } - - // The WebGraphicsContext3DInProcessImpl code path is used for - // layout tests (though not through this code) as well as for - // debugging and bringing up new ports. - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessWebGL)) { - return webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView( - attributes, true); - } else { - GURL url; - if (webview()->mainFrame()) - url = GURL(webview()->mainFrame()->document().url()); - else - url = GURL("chrome://gpu/RenderViewImpl::createGraphicsContext3D"); - - scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( - new WebGraphicsContext3DCommandBufferImpl( - surface_id(), - url, - RenderThreadImpl::current(), - AsWeakPtr())); - - if (!context->Initialize( - attributes, - false /* bind generates resources */, - content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) - return NULL; - return context.release(); - } + return new CompositorOutputSurface(routing_id(), context); } void RenderViewImpl::didAddMessageToConsole( @@ -3576,6 +3557,51 @@ void RenderViewImpl::CheckPreferredSize() { preferred_size_)); } +WebGraphicsContext3D* RenderViewImpl::CreateGraphicsContext3D( + const WebGraphicsContext3D::Attributes& attributes) { + if (!webview()) + return NULL; + + if (GetGuestToEmbedderChannel()) { + WebGraphicsContext3DCommandBufferImpl* context = + GetGuestToEmbedderChannel()->CreateWebGraphicsContext3D( + this, attributes, false); + if (!guest_pp_instance()) { + guest_uninitialized_context_ = context; + guest_attributes_ = attributes; + } + return context; + } + + // The WebGraphicsContext3DInProcessImpl code path is used for + // layout tests (though not through this code) as well as for + // debugging and bringing up new ports. + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessWebGL)) { + return webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView( + attributes, true); + } else { + GURL url; + if (webview()->mainFrame()) + url = GURL(webview()->mainFrame()->document().url()); + else + url = GURL("chrome://gpu/RenderViewImpl::createGraphicsContext3D"); + + scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( + new WebGraphicsContext3DCommandBufferImpl( + surface_id(), + url, + RenderThreadImpl::current(), + AsWeakPtr())); + + if (!context->Initialize( + attributes, + false /* bind generates resources */, + content::CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) + return NULL; + return context.release(); + } +} + void RenderViewImpl::EnsureMediaStreamImpl() { if (!RenderThreadImpl::current()) // Will be NULL during unit tests. return; diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 18918d6..f72aa73 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -138,6 +138,7 @@ class WebMediaPlayerManagerAndroid; namespace WebKit { class WebApplicationCacheHost; class WebApplicationCacheHostClient; +class WebCompositorOutputSurface; class WebDOMMessageEvent; class WebDataSource; class WebDragData; @@ -431,8 +432,7 @@ class RenderViewImpl : public RenderWidget, WebKit::WebExternalPopupMenuClient* popup_menu_client); virtual WebKit::WebStorageNamespace* createSessionStorageNamespace( unsigned quota); - virtual WebKit::WebGraphicsContext3D* createGraphicsContext3D( - const WebKit::WebGraphicsContext3D::Attributes& attributes); + virtual WebKit::WebCompositorOutputSurface* createOutputSurface() OVERRIDE; virtual void didAddMessageToConsole( const WebKit::WebConsoleMessage& message, const WebKit::WebString& source_name, @@ -1036,6 +1036,9 @@ class RenderViewImpl : public RenderWidget, // Check whether the preferred size has changed. void CheckPreferredSize(); + WebKit::WebGraphicsContext3D* CreateGraphicsContext3D( + const WebKit::WebGraphicsContext3D::Attributes& attributes); + void EnsureMediaStreamImpl(); // This callback is triggered when DownloadFavicon completes, either |