summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc5
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h7
-rw-r--r--content/common/view_messages.h5
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/renderer/gpu/compositor_output_surface.cc100
-rw-r--r--content/renderer/gpu/compositor_output_surface.h60
-rw-r--r--content/renderer/gpu/compositor_thread.h2
-rw-r--r--content/renderer/render_thread_impl.cc13
-rw-r--r--content/renderer/render_thread_impl.h10
-rw-r--r--content/renderer/render_view_impl.cc108
-rw-r--r--content/renderer/render_view_impl.h7
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