summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 17:46:23 +0000
committerkbr@google.com <kbr@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-04 17:46:23 +0000
commit77e74dbed3b57987515c260b651b72cec15825dc (patch)
tree66685b53d127093075f720f99fbb0869ab74c01d /chrome/browser
parent1ad13a2d0dd8d03b50e6fbadd6a26ea72712d2d9 (diff)
downloadchromium_src-77e74dbed3b57987515c260b651b72cec15825dc.zip
chromium_src-77e74dbed3b57987515c260b651b72cec15825dc.tar.gz
chromium_src-77e74dbed3b57987515c260b651b72cec15825dc.tar.bz2
Initial port of accelerated compositor to Mac OS X 10.6. Reused
infrastructure added for Pepper 3D and Core Animation plugins to render the compositor's output. The implementation allocates a fake "plugin window handle" on the browser side which is the "root" handle, containing the compositor's output, and which, if present, is drawn before any other accelerated plugin instances. Added messages from GPU process to browser process for handling window resizing and presentation of output. Added support to GGL for "view" contexts on Mac OS X, used only for the accelerated compositor, and requiring explicit resize notifications. The remainder of this port will go into the WebKit repository under https://bugs.webkit.org/show_bug.cgi?id=43398 after this for dependency reasons. Tested manually with CSS 3D and WebGL demos. Several stability and correctness issues remain and will be addressed in following CLs; however, the current code works for the majority of basic use cases including switching between accelerated compositing on and off, and scrolling of content. BUG=38969 TEST=none Review URL: http://codereview.chromium.org/3067026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54923 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/gpu_process_host.cc37
-rw-r--r--chrome/browser/gpu_process_host.h7
-rw-r--r--chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc43
-rw-r--r--chrome/browser/renderer_host/accelerated_surface_container_manager_mac.h22
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc3
-rw-r--r--chrome/browser/renderer_host/render_widget_host.h1
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h2
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h9
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm28
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.cc4
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h3
11 files changed, 141 insertions, 18 deletions
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 2f774fd..19b0993 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -10,6 +10,8 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/gpu_process_host_ui_shim.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/gpu_messages.h"
@@ -165,6 +167,11 @@ void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply)
#if defined(OS_LINUX)
IPC_MESSAGE_HANDLER(GpuHostMsg_GetViewXID, OnGetViewXID)
+#elif defined(OS_MACOSX)
+ IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSetIOSurface,
+ OnAcceleratedSurfaceSetIOSurface)
+ IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
+ OnAcceleratedSurfaceBuffersSwapped)
#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
@@ -195,6 +202,36 @@ void GpuProcessHost::OnGetViewXID(gfx::NativeViewId id, unsigned long* xid) {
*xid = 0;
}
}
+
+#elif defined(OS_MACOSX)
+void GpuProcessHost::OnAcceleratedSurfaceSetIOSurface(
+ const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params) {
+ RenderViewHost* host = RenderViewHost::FromID(params.renderer_id,
+ params.render_view_id);
+ if (!host)
+ return;
+ RenderWidgetHostView* view = host->view();
+ if (!view)
+ return;
+ view->AcceleratedSurfaceSetIOSurface(params.window,
+ params.width,
+ params.height,
+ params.identifier);
+}
+
+void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
+ int32 renderer_id,
+ int32 render_view_id,
+ gfx::PluginWindowHandle window) {
+ RenderViewHost* host = RenderViewHost::FromID(renderer_id,
+ render_view_id);
+ if (!host)
+ return;
+ RenderWidgetHostView* view = host->view();
+ if (!view)
+ return;
+ view->AcceleratedSurfaceBuffersSwapped(window);
+}
#endif
void GpuProcessHost::ReplyToRenderer(
diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h
index c81b565..ddc10a4 100644
--- a/chrome/browser/gpu_process_host.h
+++ b/chrome/browser/gpu_process_host.h
@@ -16,6 +16,7 @@
#include "gfx/native_widget_types.h"
class CommandBufferProxy;
+struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params;
namespace IPC {
struct ChannelHandle;
@@ -87,6 +88,12 @@ class GpuProcessHost : public BrowserChildProcessHost {
void OnSynchronizeReply();
#if defined(OS_LINUX)
void OnGetViewXID(gfx::NativeViewId id, unsigned long* xid);
+#elif defined(OS_MACOSX)
+ void OnAcceleratedSurfaceSetIOSurface(
+ const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params);
+ void OnAcceleratedSurfaceBuffersSwapped(int32 renderer_id,
+ int32 render_view_id,
+ gfx::PluginWindowHandle window);
#endif
void ReplyToRenderer(const IPC::ChannelHandle& channel,
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc b/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc
index c8be132..96f09be 100644
--- a/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc
+++ b/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.cc
@@ -9,36 +9,59 @@
#include "webkit/glue/plugins/webplugin.h"
AcceleratedSurfaceContainerManagerMac::AcceleratedSurfaceContainerManagerMac()
- : current_id_(0) {
+ : current_id_(0),
+ root_container_(NULL) {
}
gfx::PluginWindowHandle
AcceleratedSurfaceContainerManagerMac::AllocateFakePluginWindowHandle(
- bool opaque) {
+ bool opaque, bool root) {
AcceleratedSurfaceContainerMac* container =
new AcceleratedSurfaceContainerMac(this, opaque);
gfx::PluginWindowHandle res =
static_cast<gfx::PluginWindowHandle>(++current_id_);
plugin_window_to_container_map_.insert(std::make_pair(res, container));
+ if (root) {
+ root_container_ = container;
+ }
return res;
}
void AcceleratedSurfaceContainerManagerMac::DestroyFakePluginWindowHandle(
gfx::PluginWindowHandle id) {
AcceleratedSurfaceContainerMac* container = MapIDToContainer(id);
- if (container)
+ if (container) {
+ if (container == root_container_)
+ root_container_ = NULL;
delete container;
+ }
plugin_window_to_container_map_.erase(id);
}
+bool AcceleratedSurfaceContainerManagerMac::HasRootContainer() {
+ return root_container_ != NULL;
+}
+
void AcceleratedSurfaceContainerManagerMac::SetSizeAndIOSurface(
gfx::PluginWindowHandle id,
int32 width,
int32 height,
uint64 io_surface_identifier) {
AcceleratedSurfaceContainerMac* container = MapIDToContainer(id);
- if (container)
+ if (container) {
container->SetSizeAndIOSurface(width, height, io_surface_identifier);
+ if (container == root_container_) {
+ // Fake up a WebPluginGeometry for the root window to set the
+ // container's size; we will never get a notification from the
+ // browser about the root window, only plugins.
+ webkit_glue::WebPluginGeometry geom;
+ gfx::Rect rect(0, 0, width, height);
+ geom.window_rect = rect;
+ geom.clip_rect = rect;
+ geom.visible = true;
+ container->MoveTo(geom);
+ }
+ }
}
void AcceleratedSurfaceContainerManagerMac::SetSizeAndTransportDIB(
@@ -58,7 +81,8 @@ void AcceleratedSurfaceContainerManagerMac::MovePluginContainer(
container->MoveTo(move);
}
-void AcceleratedSurfaceContainerManagerMac::Draw(CGLContextObj context) {
+void AcceleratedSurfaceContainerManagerMac::Draw(CGLContextObj context,
+ bool draw_root_container) {
// Clean up old texture objects. This is essentially a pre-emptive
// cleanup, as the resources will be released when the OpenGL
// context associated with the CAOpenGLLayer is destroyed. However,
@@ -85,11 +109,18 @@ void AcceleratedSurfaceContainerManagerMac::Draw(CGLContextObj context) {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ // Draw the root container, if any, first.
+ if (draw_root_container && root_container_) {
+ root_container_->Draw(context);
+ }
+
for (PluginWindowToContainerMap::const_iterator i =
plugin_window_to_container_map_.begin();
i != plugin_window_to_container_map_.end(); ++i) {
AcceleratedSurfaceContainerMac* container = i->second;
- container->Draw(context);
+ if (container != root_container_) {
+ container->Draw(context);
+ }
}
// Unbind any texture from the texture target to ensure that the
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.h b/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.h
index 8ccd3ca..7b49ccc 100644
--- a/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.h
+++ b/chrome/browser/renderer_host/accelerated_surface_container_manager_mac.h
@@ -28,11 +28,17 @@ class AcceleratedSurfaceContainerManagerMac {
// Allocates a new "fake" PluginWindowHandle, which is used as the
// key for the other operations.
- gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque);
+ gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque,
+ bool root);
// Destroys a fake PluginWindowHandle and associated storage.
void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle id);
+ // Indicates whether a "root" PluginWindowHandle has been allocated,
+ // which means that we are using accelerated compositing and should
+ // short-circuit the normal drawing process.
+ bool HasRootContainer();
+
// Sets the size and backing store of the plugin instance. There are two
// versions: the IOSurface version is used on systems where the IOSurface
// API is supported (Mac OS X 10.6 and later); the TransportDIB is used on
@@ -52,7 +58,8 @@ class AcceleratedSurfaceContainerManagerMac {
// Draws all of the managed plugin containers into the given OpenGL
// context, which must already be current.
- void Draw(CGLContextObj context);
+ void Draw(CGLContextObj context,
+ bool draw_root_container);
// Causes the next Draw call on each container to trigger a texture upload.
// Should be called any time the drawing context has changed.
@@ -73,6 +80,17 @@ class AcceleratedSurfaceContainerManagerMac {
PluginWindowToContainerMap;
PluginWindowToContainerMap plugin_window_to_container_map_;
+ // The "root" container, which is only used to draw the output of
+ // the accelerated compositor if it is active. Currently,
+ // accelerated plugins (Core Animation and Pepper 3D) are drawn on
+ // top of the page's contents rather than transformed and composited
+ // with the rest of the page. At some point we would like them to be
+ // treated uniformly with other page elements; when this is done,
+ // the separate treatment of the root container can go away because
+ // there will only be one container active when the accelerated
+ // compositor is active.
+ AcceleratedSurfaceContainerMac* root_container_;
+
// A list of OpenGL textures waiting to be deleted
std::vector<GLuint> textures_pending_deletion_;
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 749d4c9..109e0f8 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -970,11 +970,12 @@ void RenderWidgetHost::OnMsgGetRootWindowRect(gfx::NativeViewId window_id,
void RenderWidgetHost::OnAllocateFakePluginWindowHandle(
bool opaque,
+ bool root,
gfx::PluginWindowHandle* id) {
// TODO(kbr): similar potential issue here as in OnMsgCreatePluginContainer.
// Possibly less of an issue because this is only used for the GPU plugin.
if (view_) {
- *id = view_->AllocateFakePluginWindowHandle(opaque);
+ *id = view_->AllocateFakePluginWindowHandle(opaque, root);
} else {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h
index 5296516..12a986d 100644
--- a/chrome/browser/renderer_host/render_widget_host.h
+++ b/chrome/browser/renderer_host/render_widget_host.h
@@ -501,6 +501,7 @@ class RenderWidgetHost : public IPC::Channel::Listener,
void OnMsgGetWindowRect(gfx::NativeViewId window_id, gfx::Rect* results);
void OnMsgGetRootWindowRect(gfx::NativeViewId window_id, gfx::Rect* results);
void OnAllocateFakePluginWindowHandle(bool opaque,
+ bool root,
gfx::PluginWindowHandle* id);
void OnDestroyFakePluginWindowHandle(gfx::PluginWindowHandle id);
void OnAcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index 4c7a16f..c4e4f00 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -197,7 +197,7 @@ class RenderWidgetHostView {
// Methods associated with GPU-accelerated plug-in instances.
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(
- bool opaque) = 0;
+ bool opaque, bool root) = 0;
virtual void DestroyFakePluginWindowHandle(
gfx::PluginWindowHandle window) = 0;
virtual void AcceleratedSurfaceSetIOSurface(
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h
index af457b3..86396ff 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h
@@ -62,7 +62,8 @@ class RWHVMEditCommandHelper;
NSWindow* lastWindow_; // weak
- // The Core Animation layer, if any, hosting the accelerated plugins' output.
+ // The Core Animation layer, if any, hosting the accelerated
+ // plugins' and accelerated compositor's output.
scoped_nsobject<CALayer> acceleratedPluginLayer_;
// Variables used by our implementaion of the NSTextInput protocol.
@@ -227,8 +228,10 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView {
const webkit_glue::WebAccessibility& tree);
virtual void OnAccessibilityFocusChange(int acc_obj_id);
virtual void OnAccessibilityObjectStateChange(int acc_obj_id);
- // Methods associated with GPU-accelerated plug-in instances.
- virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque);
+ // Methods associated with GPU-accelerated plug-in instances and the
+ // accelerated compositor.
+ virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(bool opaque,
+ bool root);
virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
virtual void AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
int32 width,
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index 9512d64..647eba6 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -613,11 +613,12 @@ void RenderWidgetHostViewMac::KillSelf() {
}
gfx::PluginWindowHandle
-RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque) {
+RenderWidgetHostViewMac::AllocateFakePluginWindowHandle(bool opaque,
+ bool root) {
// Make sure we have a layer for the plugin to draw into.
[cocoa_view_ ensureAcceleratedPluginLayer];
- return plugin_container_manager_.AllocateFakePluginWindowHandle(opaque);
+ return plugin_container_manager_.AllocateFakePluginWindowHandle(opaque, root);
}
void RenderWidgetHostViewMac::DestroyFakePluginWindowHandle(
@@ -650,6 +651,12 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB(
void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped(
gfx::PluginWindowHandle window) {
[cocoa_view_ drawAcceleratedPluginLayer];
+ if (GetRenderWidgetHost()->is_gpu_rendering_active()) {
+ // Additionally dirty the entire region of the view to make AppKit
+ // and Core Animation think that our CALayer needs to repaint
+ // itself.
+ [cocoa_view_ setNeedsDisplayInRect:[cocoa_view_ frame]];
+ }
}
void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstances(
@@ -664,7 +671,8 @@ void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstances(
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- plugin_container_manager_.Draw(context);
+ plugin_container_manager_.Draw(
+ context, GetRenderWidgetHost()->is_gpu_rendering_active());
}
void RenderWidgetHostViewMac::AcceleratedSurfaceContextChanged() {
@@ -1165,6 +1173,15 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
return;
}
+ if (renderWidgetHostView_->render_widget_host_->is_gpu_rendering_active()) {
+ // In this mode the accelerated plugin layer is considered to be
+ // opaque. We do not want its contents to be blended with anything
+ // underneath it.
+ acceleratedPluginLayer_.get().opaque = YES;
+ [acceleratedPluginLayer_.get() setNeedsDisplay];
+ return;
+ }
+
DCHECK(
renderWidgetHostView_->render_widget_host_->process()->HasConnection());
DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_);
@@ -1279,6 +1296,11 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
renderWidgetHostView_->whiteout_start_time_ = base::TimeTicks::Now();
}
+ // If we get here then the accelerated plugin layer is not supposed
+ // to be considered opaque -- plugins overlay the browser's normal
+ // painting.
+ acceleratedPluginLayer_.get().opaque = NO;
+
// This helps keep accelerated plugins' output in better sync with the
// window as it resizes.
[acceleratedPluginLayer_.get() setNeedsDisplay];
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.cc b/chrome/browser/renderer_host/test/test_render_view_host.cc
index f5883ed..5409ecc 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.cc
+++ b/chrome/browser/renderer_host/test/test_render_view_host.cc
@@ -123,7 +123,9 @@ void TestRenderWidgetHostView::SetActive(bool active) {
}
gfx::PluginWindowHandle
-TestRenderWidgetHostView::AllocateFakePluginWindowHandle(bool opaque) {
+TestRenderWidgetHostView::AllocateFakePluginWindowHandle(
+ bool opaque,
+ bool root) {
return NULL;
}
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index b4971bd..53e10dd 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -94,7 +94,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
virtual void SetWindowVisibility(bool visible) {}
virtual void WindowFrameChanged() {}
virtual gfx::PluginWindowHandle AllocateFakePluginWindowHandle(
- bool opaque);
+ bool opaque,
+ bool root);
virtual void DestroyFakePluginWindowHandle(gfx::PluginWindowHandle window);
virtual void AcceleratedSurfaceSetIOSurface(gfx::PluginWindowHandle window,
int32 width,