diff options
Diffstat (limited to 'content/browser/renderer_host')
14 files changed, 532 insertions, 76 deletions
diff --git a/content/browser/renderer_host/accelerated_surface_container_linux.cc b/content/browser/renderer_host/accelerated_surface_container_linux.cc new file mode 100644 index 0000000..00019f6 --- /dev/null +++ b/content/browser/renderer_host/accelerated_surface_container_linux.cc @@ -0,0 +1,397 @@ +// Copyright (c) 2011 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/browser/renderer_host/accelerated_surface_container_linux.h" + +#include <X11/Xlib.h> +#include <X11/extensions/Xcomposite.h> + +#include "base/lazy_instance.h" +#include "base/memory/scoped_ptr.h" +#include "third_party/angle/include/EGL/egl.h" +#include "third_party/angle/include/EGL/eglext.h" +#include "ui/gfx/gl/gl_bindings.h" +#include "ui/gfx/gl/gl_implementation.h" +#include "ui/gfx/gl/gl_surface_egl.h" +#include "ui/gfx/gl/gl_surface_glx.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/transform.h" + +namespace { + +class AcceleratedSurfaceContainerLinuxEGL + : public AcceleratedSurfaceContainerLinux { + public: + explicit AcceleratedSurfaceContainerLinuxEGL(const gfx::Size& size); + + virtual bool Initialize(uint64* surface_id) OVERRIDE; + + // TextureGL implementation + virtual void Draw(const ui::TextureDrawParams& params, + const gfx::Rect& clip_bounds_in_texture) OVERRIDE; + + private: + virtual ~AcceleratedSurfaceContainerLinuxEGL(); + + void* image_; + + DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerLinuxEGL); +}; + +class AcceleratedSurfaceContainerLinuxGLX + : public AcceleratedSurfaceContainerLinux { + public: + explicit AcceleratedSurfaceContainerLinuxGLX(const gfx::Size& size); + + virtual bool Initialize(uint64* surface_id) OVERRIDE; + + // TextureGL implementation + virtual void Draw(const ui::TextureDrawParams& params, + const gfx::Rect& clip_bounds_in_texture) OVERRIDE; + + protected: + static bool InitializeOneOff(); + + static base::LazyInstance<GLXFBConfig> fbconfig_; + + private: + virtual ~AcceleratedSurfaceContainerLinuxGLX(); + + XID pixmap_; + XID glx_pixmap_; + + DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerLinuxGLX); +}; + +class AcceleratedSurfaceContainerLinuxOSMesa + : public AcceleratedSurfaceContainerLinux { + public: + explicit AcceleratedSurfaceContainerLinuxOSMesa(const gfx::Size& size); + + virtual bool Initialize(uint64* surface_id) OVERRIDE; + + // TextureGL implementation + virtual void Draw(const ui::TextureDrawParams& params, + const gfx::Rect& clip_bounds_in_texture) OVERRIDE; + + // Some implementations of this class use shared memory, this gives the handle + // to the shared buffer, which is part of the surface container. + // When shared memory is not used, this will return + // TransportDIB::DefaultHandleValue(). + virtual TransportDIB::Handle Handle() const OVERRIDE; + + private: + virtual ~AcceleratedSurfaceContainerLinuxOSMesa(); + + scoped_ptr<TransportDIB> shared_mem_; + + DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerLinuxOSMesa); +}; + +class ScopedPtrXFree { + public: + void operator()(void* x) const { + ::XFree(x); + } +}; + +// static +base::LazyInstance<GLXFBConfig> AcceleratedSurfaceContainerLinuxGLX::fbconfig_( + base::LINKER_INITIALIZED); + +AcceleratedSurfaceContainerLinuxEGL::AcceleratedSurfaceContainerLinuxEGL( + const gfx::Size& size) + : AcceleratedSurfaceContainerLinux(size), + image_(NULL) { +} + +bool AcceleratedSurfaceContainerLinuxEGL::Initialize(uint64* surface_id) { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + instance->MakeSharedContextCurrent(); + + image_ = eglCreateImageKHR( + gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_id), NULL); + + glGenTextures(1, &texture_id_); + glBindTexture(GL_TEXTURE_2D, texture_id_); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); + glFlush(); + + return true; +} + +AcceleratedSurfaceContainerLinuxEGL::~AcceleratedSurfaceContainerLinuxEGL() { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + instance->MakeSharedContextCurrent(); + + eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_); + glFlush(); +} + +void AcceleratedSurfaceContainerLinuxEGL::Draw( + const ui::TextureDrawParams& params, + const gfx::Rect& clip_bounds_in_texture) { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + + ui::TextureDrawParams modified_params = params; + modified_params.vertically_flipped = true; + + DrawInternal(*instance->program_no_swizzle(), + modified_params, + clip_bounds_in_texture); +} + +AcceleratedSurfaceContainerLinuxGLX::AcceleratedSurfaceContainerLinuxGLX( + const gfx::Size& size) + : AcceleratedSurfaceContainerLinux(size), + pixmap_(0), + glx_pixmap_(0) { +} + +bool AcceleratedSurfaceContainerLinuxGLX::Initialize(uint64* surface_id) { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + instance->MakeSharedContextCurrent(); + + if (!AcceleratedSurfaceContainerLinuxGLX::InitializeOneOff()) + return false; + + // Create pixmap from window. + // We receive a window here rather than a pixmap directly because drivers + // require (or required) that the pixmap used to create the GL texture be + // created in the same process as the texture. + Display* dpy = static_cast<Display*>(instance->GetDisplay()); + pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_id); + + // Wrap the pixmap in a GLXPixmap + const int pixmapAttribs[] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, + 0 + }; + + glx_pixmap_ = glXCreatePixmap( + dpy, fbconfig_.Get(), pixmap_, pixmapAttribs); + + // Create texture. + glGenTextures(1, &texture_id_); + glBindTexture(GL_TEXTURE_2D, texture_id_); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + return true; +} + +AcceleratedSurfaceContainerLinuxGLX::~AcceleratedSurfaceContainerLinuxGLX() { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + instance->MakeSharedContextCurrent(); + + Display* dpy = static_cast<Display*>(instance->GetDisplay()); + if (glx_pixmap_) + glXDestroyGLXPixmap(dpy, glx_pixmap_); + if (pixmap_) + XFreePixmap(dpy, pixmap_); +} + +void AcceleratedSurfaceContainerLinuxGLX::Draw( + const ui::TextureDrawParams& params, + const gfx::Rect& clip_bounds_in_texture) { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + + Display* dpy = static_cast<Display*>(instance->GetDisplay()); + + glBindTexture(GL_TEXTURE_2D, texture_id_); + glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); + DrawInternal(*instance->program_no_swizzle(), + params, + clip_bounds_in_texture); + glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); +} + +// static +bool AcceleratedSurfaceContainerLinuxGLX::InitializeOneOff() +{ + static bool initialized = false; + if (initialized) + return true; + + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + + Display* dpy = static_cast<Display*>(instance->GetDisplay()); + int event_base, error_base; + if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { + int major = 0, minor = 2; + XCompositeQueryVersion(dpy, &major, &minor); + if (major == 0 && minor < 2) { + LOG(ERROR) << "Pixmap from window not supported."; + return false; + } + } + + // Wrap the pixmap in a GLXPixmap + int screen = DefaultScreen(dpy); + XWindowAttributes gwa; + XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa); + unsigned int visualid = XVisualIDFromVisual(gwa.visual); + + int nfbconfigs, config; + scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs( + glXGetFBConfigs(dpy, screen, &nfbconfigs)); + + for (config = 0; config < nfbconfigs; config++) { + XVisualInfo* visinfo = glXGetVisualFromFBConfig( + dpy, fbconfigs.get()[config]); + if (!visinfo || visinfo->visualid != visualid) + continue; + + int value; + glXGetFBConfigAttrib(dpy, + fbconfigs.get()[config], + GLX_DRAWABLE_TYPE, + &value); + if (!(value & GLX_PIXMAP_BIT)) + continue; + + glXGetFBConfigAttrib(dpy, + fbconfigs.get()[config], + GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value); + if (!(value & GLX_TEXTURE_2D_BIT_EXT)) + continue; + + glXGetFBConfigAttrib(dpy, + fbconfigs.get()[config], + GLX_BIND_TO_TEXTURE_RGB_EXT, + &value); + if (value == GL_FALSE) + continue; + + break; + } + + if (config == nfbconfigs) { + LOG(ERROR) + << "Could not find configuration suitable for binding a pixmap " + << "as a texture."; + return false; + } + + fbconfig_.Get() = fbconfigs.get()[config]; + + initialized = true; + return initialized; +} + +AcceleratedSurfaceContainerLinuxOSMesa::AcceleratedSurfaceContainerLinuxOSMesa( + const gfx::Size& size) + : AcceleratedSurfaceContainerLinux(size) { +} + +bool AcceleratedSurfaceContainerLinuxOSMesa::Initialize(uint64* surface_id) { + static uint32 next_id = 1; + + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + instance->MakeSharedContextCurrent(); + + // We expect to make the id here, so don't want the other end giving us one + DCHECK_EQ(*surface_id, static_cast<uint64>(0)); + + // It's possible that this ID gneration could clash with IDs from other + // AcceleratedSurfaceContainerLinux* objects, however we should never have + // ids active from more than one type at the same time, so we have free + // reign of the id namespace. + *surface_id = next_id++; + + shared_mem_.reset( + TransportDIB::Create(size_.GetArea() * 4, // GL_RGBA=4 B/px + *surface_id)); + // Create texture. + glGenTextures(1, &texture_id_); + glBindTexture(GL_TEXTURE_2D, texture_id_); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // we generate the ID to be used here. + return true; +} + +void AcceleratedSurfaceContainerLinuxOSMesa::Draw( + const ui::TextureDrawParams& params, + const gfx::Rect& clip_bounds_in_texture) { + ui::SharedResources* instance = ui::SharedResources::GetInstance(); + DCHECK(instance); + + if (shared_mem_.get()) { + glBindTexture(GL_TEXTURE_2D, texture_id_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + size_.width(), size_.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory()); + + DrawInternal(*instance->program_no_swizzle(), + params, + clip_bounds_in_texture); + } +} + +TransportDIB::Handle AcceleratedSurfaceContainerLinuxOSMesa::Handle() const { + if (shared_mem_.get()) + return shared_mem_->handle(); + else + return TransportDIB::DefaultHandleValue(); +} + +AcceleratedSurfaceContainerLinuxOSMesa:: + ~AcceleratedSurfaceContainerLinuxOSMesa() { +} + +} // namespace + +AcceleratedSurfaceContainerLinux::AcceleratedSurfaceContainerLinux( + const gfx::Size& size) : TextureGL(size) { +} + +TransportDIB::Handle AcceleratedSurfaceContainerLinux::Handle() const { + return TransportDIB::DefaultHandleValue(); +} + +// static +AcceleratedSurfaceContainerLinux* +AcceleratedSurfaceContainerLinux::CreateAcceleratedSurfaceContainer( + const gfx::Size& size) { + switch (gfx::GetGLImplementation()) { + case gfx::kGLImplementationDesktopGL: + return new AcceleratedSurfaceContainerLinuxGLX(size); + case gfx::kGLImplementationEGLGLES2: + return new AcceleratedSurfaceContainerLinuxEGL(size); + case gfx::kGLImplementationOSMesaGL: + return new AcceleratedSurfaceContainerLinuxOSMesa(size); + default: + NOTREACHED(); + return NULL; + } +} + +void AcceleratedSurfaceContainerLinux::SetCanvas( + const SkCanvas& canvas, + const gfx::Point& origin, + const gfx::Size& overall_size) { + NOTREACHED(); +} + diff --git a/content/browser/renderer_host/render_widget_host_mac.cc b/content/browser/renderer_host/render_widget_host_mac.cc index e264b93..014caec 100644 --- a/content/browser/renderer_host/render_widget_host_mac.cc +++ b/content/browser/renderer_host/render_widget_host_mac.cc @@ -4,6 +4,7 @@ #include "content/browser/renderer_host/render_widget_host.h" #include "content/browser/renderer_host/render_widget_host_view.h" +#include "content/common/gpu/gpu_messages.h" void RenderWidgetHost::OnMsgPluginFocusChanged(bool focused, int plugin_id) { if (view_) @@ -64,7 +65,9 @@ void RenderWidgetHost::OnAcceleratedSurfaceBuffersSwapped( // This code path could be updated to implement flow control for // updating of accelerated plugins as well. However, if we add support // for composited plugins then this is not necessary. - view_->AcceleratedSurfaceBuffersSwapped(window, surface_id, - 0, 0, 0); + GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; + params.window = window; + params.surface_id = surface_id; + view_->AcceleratedSurfaceBuffersSwapped(params, 0); } } diff --git a/content/browser/renderer_host/render_widget_host_view.h b/content/browser/renderer_host/render_widget_host_view.h index ac2cac7..b8fd0d6 100644 --- a/content/browser/renderer_host/render_widget_host_view.h +++ b/content/browser/renderer_host/render_widget_host_view.h @@ -26,6 +26,8 @@ #include "ui/gfx/rect.h" #include "ui/gfx/surface/transport_dib.h" +struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params; + class BackingStore; class RenderProcessHost; class RenderWidgetHost; @@ -184,6 +186,14 @@ class RenderWidgetHostView { // Called when accelerated compositing state changes. virtual void OnAcceleratedCompositingStateChange() = 0; + // |params.window| and |params.surface_id| indicate which accelerated + // surface's buffers swapped. |params.renderer_id| and |params.route_id| + // are used to formulate a reply to the GPU process to prevent it from getting + // too far ahead. They may all be zero, in which case no flow control is + // enforced; this case is currently used for accelerated plugins. + virtual void AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) = 0; #if defined(OS_MACOSX) // Tells the view whether or not to accept first responder status. If |flag| @@ -240,17 +250,6 @@ class RenderWidgetHostView { int32 width, int32 height, TransportDIB::Handle transport_dib) = 0; - // |window| and |surface_id| indicate which accelerated surface's - // buffers swapped. |renderer_id| and |route_id| are used to formulate - // a reply to the GPU process to prevent it from getting too far ahead. - // They may all be zero, in which case no flow control is enforced; - // this case is currently used for accelerated plugins. - virtual void AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, - int gpu_host_id) = 0; #endif #if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) @@ -259,10 +258,6 @@ class RenderWidgetHostView { int32 height, uint64* surface_id, TransportDIB::Handle* surface_handle) = 0; - virtual void AcceleratedSurfaceBuffersSwapped( - uint64 surface_id, - int32 route_id, - int gpu_host_id) = 0; virtual void AcceleratedSurfaceRelease(uint64 surface_id) = 0; #endif diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index fe07237..c680595 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -285,45 +285,48 @@ BackingStore* RenderWidgetHostViewAura::AllocBackingStore( void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() { } - -#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) -void RenderWidgetHostViewAura::AcceleratedSurfaceNew( - int32 width, - int32 height, - uint64* surface_id, - TransportDIB::Handle* surface_handle) { - scoped_refptr<AcceleratedSurfaceContainerLinux> surface( - AcceleratedSurfaceContainerLinux::Create(gfx::Size(width, height))); - if (!surface->Initialize(surface_id)) { - LOG(ERROR) << "Failed to create AcceleratedSurfaceContainer"; - return; - } - *surface_handle = surface->Handle(); - - accelerated_surface_containers_[*surface_id] = surface; -} - void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped( - uint64 surface_id, - int32 route_id, + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, int gpu_host_id) { +#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) window_->layer()->SetExternalTexture( - accelerated_surface_containers_[surface_id]->GetTexture()); + accelerated_surface_containers_[params.surface_id]->GetTexture()); glFlush(); if (!window_->layer()->GetCompositor()) { // We have no compositor, so we have no way to display the surface - AcknowledgeSwapBuffers(route_id, gpu_host_id); // Must still send the ACK + // Must still send the ACK. + AcknowledgeSwapBuffers(params.route_id, gpu_host_id); } else { window_->layer()->ScheduleDraw(); // Add sending an ACK to the list of things to do OnCompositingEnded on_compositing_ended_callbacks_.push_back( - base::Bind(AcknowledgeSwapBuffers, route_id, gpu_host_id)); + base::Bind(AcknowledgeSwapBuffers, params.route_id, gpu_host_id)); ui::Compositor* compositor = window_->layer()->GetCompositor(); if (!compositor->HasObserver(this)) compositor->AddObserver(this); } +#else + NOTREACHED(); +#endif +} + +#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) +void RenderWidgetHostViewAura::AcceleratedSurfaceNew( + int32 width, + int32 height, + uint64* surface_id, + TransportDIB::Handle* surface_handle) { + scoped_refptr<AcceleratedSurfaceContainerLinux> surface( + AcceleratedSurfaceContainerLinux::Create(gfx::Size(width, height))); + if (!surface->Initialize(surface_id)) { + LOG(ERROR) << "Failed to create AcceleratedSurfaceContainer"; + return; + } + *surface_handle = surface->Handle(); + + accelerated_surface_containers_[*surface_id] = surface; } void RenderWidgetHostViewAura::AcceleratedSurfaceRelease(uint64 surface_id) { diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 495b69b..e654164 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -70,16 +70,15 @@ class CONTENT_EXPORT RenderWidgetHostViewAura : public RenderWidgetHostView, virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE; virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE; virtual void OnAcceleratedCompositingStateChange() OVERRIDE; + virtual void AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) OVERRIDE; #if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) virtual void AcceleratedSurfaceNew( int32 width, int32 height, uint64* surface_id, TransportDIB::Handle* surface_handle) OVERRIDE; - virtual void AcceleratedSurfaceBuffersSwapped( - uint64 surface_id, - int32 route_id, - int gpu_host_id) OVERRIDE; virtual void AcceleratedSurfaceRelease(uint64 surface_id) OVERRIDE; #endif virtual void SetBackground(const SkBitmap& background) OVERRIDE; diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc index 7fa23c7..8385b7e1 100644 --- a/content/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc @@ -1005,6 +1005,12 @@ BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( gtk_widget_get_visual(view_.get())->depth); } +void RenderWidgetHostViewGtk::AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) { + NOTREACHED(); +} + void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) { RenderWidgetHostView::SetBackground(background); host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.h b/content/browser/renderer_host/render_widget_host_view_gtk.h index 7de7cbcd..39837e5 100644 --- a/content/browser/renderer_host/render_widget_host_view_gtk.h +++ b/content/browser/renderer_host/render_widget_host_view_gtk.h @@ -95,6 +95,9 @@ class CONTENT_EXPORT RenderWidgetHostViewGtk : public RenderWidgetHostView, virtual void ShowingContextMenu(bool showing) OVERRIDE; virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE; virtual void OnAcceleratedCompositingStateChange() OVERRIDE; + virtual void AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) OVERRIDE; virtual void SetBackground(const SkBitmap& background) OVERRIDE; virtual void CreatePluginContainer(gfx::PluginWindowHandle id) OVERRIDE; virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) OVERRIDE; diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index b674a37..304640c 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -258,10 +258,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { int32 height, TransportDIB::Handle transport_dib) OVERRIDE; virtual void AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, int gpu_host_id) OVERRIDE; virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE; virtual gfx::Rect GetRootWindowBounds() OVERRIDE; diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index 6fae1a3..2f2aa1c 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -865,28 +865,26 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( } void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, int gpu_host_id) { TRACE_EVENT0("browser", "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - AcceleratedPluginView* view = ViewForPluginWindowHandle(window); + AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); DCHECK(view); if (view) { - plugin_container_manager_.SetSurfaceWasPaintedTo(window, surface_id); + plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, + params.surface_id); // The surface is hidden until its first paint, to not show gargabe. - if (plugin_container_manager_.SurfaceShouldBeVisible(window)) + if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) [view setHidden:NO]; [view drawView]; } - if (renderer_id != 0 || route_id != 0) { - AcknowledgeSwapBuffers(renderer_id, - route_id, + if (params.renderer_id != 0 || params.route_id != 0) { + AcknowledgeSwapBuffers(params.renderer_id, + params.route_id, gpu_host_id); } } diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index bca8d95..6cb2d77 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm @@ -7,6 +7,7 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/renderer_host/test_render_view_host.h" +#include "content/common/gpu/gpu_messages.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/test/cocoa_test_event_utils.h" #import "ui/base/test/ui_cocoa_test_helper.h" @@ -57,8 +58,9 @@ class RenderWidgetHostViewMacTest : public RenderViewHostTestHarness { // The accelerated view isn't shown until it has a valid rect and has been // painted to. - rwhv_mac_->AcceleratedSurfaceBuffersSwapped(accelerated_handle, - 0, 0, 0, 0); + GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; + params.window = accelerated_handle; + rwhv_mac_->AcceleratedSurfaceBuffersSwapped(params, 0); webkit::npapi::WebPluginGeometry geom; gfx::Rect rect(0, 0, w, h); geom.window = accelerated_handle; diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 59257b0..3c87933 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "base/bind.h" #include "base/command_line.h" #include "base/i18n/rtl.h" #include "base/metrics/histogram.h" @@ -19,11 +20,14 @@ #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_state.h" #include "content/browser/accessibility/browser_accessibility_win.h" +#include "content/browser/gpu/gpu_process_host.h" +#include "content/browser/gpu/gpu_process_host_ui_shim.h" #include "content/browser/plugin_process_host.h" #include "content/browser/renderer_host/backing_store.h" #include "content/browser/renderer_host/backing_store_win.h" #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/renderer_host/render_widget_host.h" +#include "content/common/gpu/gpu_messages.h" #include "content/common/plugin_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" @@ -54,6 +58,8 @@ #include "webkit/plugins/npapi/webplugin.h" #include "webkit/plugins/npapi/webplugin_delegate_impl.h" +#pragma comment(lib, "d3d9.lib") + using base::TimeDelta; using base::TimeTicks; using content::BrowserThread; @@ -203,6 +209,21 @@ LRESULT CALLBACK PluginWrapperWindowProc(HWND window, unsigned int message, return ::DefWindowProc(window, message, wparam, lparam); } +void SendToGpuProcessHost(int gpu_host_id, IPC::Message* message) { + GpuProcessHost* gpu_process_host = GpuProcessHost::FromID(gpu_host_id); + if (!gpu_process_host) { + delete message; + return; + } + + gpu_process_host->Send(message); +} + +void PostTaskOnIOThread(const tracked_objects::Location& from_here, + base::Closure task) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, task); +} + bool DecodeZoomGesture(HWND hwnd, const GESTUREINFO& gi, content::PageZoom* zoom, POINT* zoom_center) { @@ -338,6 +359,9 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { UnlockMouse(); ResetTooltip(); + + if (accelerated_surface_) + accelerated_surface_->Destroy(); } void RenderWidgetHostViewWin::CreateWnd(HWND parent) { @@ -1956,8 +1980,14 @@ static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message, } void RenderWidgetHostViewWin::ScheduleComposite() { - if (render_widget_host_) - render_widget_host_->ScheduleComposite(); + // If we have a previous frame then present it immediately. Otherwise request + // a new frame be composited. + if (accelerated_surface_.get()) { + accelerated_surface_->Present(); + } else { + if (render_widget_host_) + render_widget_host_->ScheduleComposite(); + } } // Creates a HWND within the RenderWidgetHostView that will serve as a host @@ -2053,6 +2083,27 @@ void RenderWidgetHostViewWin::OnAcceleratedCompositingStateChange() { } } +void RenderWidgetHostViewWin::AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) { + if (!accelerated_surface_.get() && compositor_host_window_) { + accelerated_surface_ = new AcceleratedSurface(compositor_host_window_); + accelerated_surface_->Initialize(); + } + + base::Closure acknowledge_task = + base::Bind(SendToGpuProcessHost, + gpu_host_id, + new AcceleratedSurfaceMsg_BuffersSwappedACK(params.route_id)); + + accelerated_surface_->AsyncPresentAndAcknowledge( + params.size, + params.surface_id, + base::Bind(PostTaskOnIOThread, + FROM_HERE, + acknowledge_task)); +} + void RenderWidgetHostViewWin::SetAccessibilityFocus(int acc_obj_id) { if (!render_widget_host_) return; diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h index 061eba9..b55e7cc 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.h +++ b/content/browser/renderer_host/render_widget_host_view_win.h @@ -27,6 +27,7 @@ #include "ui/base/win/ime_input.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/point.h" +#include "ui/gfx/surface/accelerated_surface_win.h" #include "webkit/glue/webcursor.h" class BackingStore; @@ -201,6 +202,9 @@ class RenderWidgetHostViewWin virtual void SetScrollOffsetPinning( bool is_pinned_to_left, bool is_pinned_to_right) OVERRIDE; virtual gfx::PluginWindowHandle GetCompositingSurface() OVERRIDE; + virtual void AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) OVERRIDE; virtual void OnAccessibilityNotifications( const std::vector<ViewHostMsg_AccessibilityNotification_Params>& params ) OVERRIDE; @@ -343,6 +347,10 @@ class RenderWidgetHostViewWin // When we are doing accelerated compositing HWND compositor_host_window_; + // Presents a texture received from another process to the compositing + // window. + scoped_refptr<AcceleratedSurface> accelerated_surface_; + // true if the compositor host window must be hidden after the // software renderered view is updated. bool hide_compositor_window_at_next_paint_; diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index 5bbe3170..045f5b1 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -179,6 +179,11 @@ BackingStore* TestRenderWidgetHostView::AllocBackingStore( void TestRenderWidgetHostView::OnAcceleratedCompositingStateChange() { } +void TestRenderWidgetHostView::AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) { +} + #if defined(OS_MACOSX) gfx::Rect TestRenderWidgetHostView::GetViewCocoaBounds() const { @@ -226,14 +231,6 @@ void TestRenderWidgetHostView::AcceleratedSurfaceSetTransportDIB( TransportDIB::Handle transport_dib) { } -void TestRenderWidgetHostView::AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, - int gpu_host_id) { -} - #elif defined(OS_WIN) void TestRenderWidgetHostView::WillWmDestroy() { } diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h index 5a64703..36f0d6e 100644 --- a/content/browser/renderer_host/test_render_view_host.h +++ b/content/browser/renderer_host/test_render_view_host.h @@ -88,6 +88,9 @@ class TestRenderWidgetHostView : public RenderWidgetHostView { virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE {} virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE; virtual void OnAcceleratedCompositingStateChange() OVERRIDE; + virtual void AcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, + int gpu_host_id) OVERRIDE; #if defined(OS_MACOSX) virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE {} virtual gfx::Rect GetViewCocoaBounds() const OVERRIDE; @@ -112,12 +115,6 @@ class TestRenderWidgetHostView : public RenderWidgetHostView { int32 width, int32 height, TransportDIB::Handle transport_dib) OVERRIDE; - virtual void AcceleratedSurfaceBuffersSwapped( - gfx::PluginWindowHandle window, - uint64 surface_id, - int renderer_id, - int32 route_id, - int gpu_host_id) OVERRIDE; #elif defined(OS_WIN) virtual void WillWmDestroy() OVERRIDE; #endif |