diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 23:25:23 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 23:25:23 +0000 |
commit | 290fc49d46142b94f9c7754c8c3cf36408b9a269 (patch) | |
tree | d42113d9b5be8c7e8e7ef94dbdb6d949a5325d69 | |
parent | 5902f29b579cba7f1a11b2b6d02b5d3a1f4516cf (diff) | |
download | chromium_src-290fc49d46142b94f9c7754c8c3cf36408b9a269.zip chromium_src-290fc49d46142b94f9c7754c8c3cf36408b9a269.tar.gz chromium_src-290fc49d46142b94f9c7754c8c3cf36408b9a269.tar.bz2 |
Reland 110355 - Use shared D3D9 texture to transport the compositor's backing buffer to the browser process for presentation.
Implemented ImageTransportSurface for Linux (without texture sharing), XP, Vista and 7. XP. The non-texture sharing Linux and XP paths just present directly to the compositing child window owned by the browser process as before.
PassThroughImageTransportSurface still needs a proper name. I will move it into its own file once that is decided.
I moved AcceleratedSurfaceBuffersSwapped outside of the platform specific ifdefs and made the signature the same on all platforms for greater consistency.
I removed the code related to sharing surfaces between processes and synchronizing resize and swapping out of GpuCommandBufferStub. It is all now in ImageTransportSurface implementations.
Original Review URL: http://codereview.chromium.org/8060045
Review URL: http://codereview.chromium.org/8622004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111246 0039d316-1c4b-4281-b951-d872f2087c98
30 files changed, 555 insertions, 262 deletions
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc index 04c2f67..c565484 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.cc +++ b/content/browser/gpu/gpu_process_host_ui_shim.cc @@ -172,12 +172,12 @@ bool GpuProcessHostUIShim::OnControlMessageReceived( IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage, OnLogMessage) #if defined(TOOLKIT_USES_GTK) || defined(OS_WIN) + IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped, + OnAcceleratedSurfaceBuffersSwapped) IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView) #endif #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) - IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped, - OnAcceleratedSurfaceBuffersSwapped) IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceNew, OnAcceleratedSurfaceNew) #endif @@ -186,6 +186,7 @@ bool GpuProcessHostUIShim::OnControlMessageReceived( IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease, OnAcceleratedSurfaceRelease) #endif + IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() @@ -207,15 +208,14 @@ void GpuProcessHostUIShim::OnLogMessage( void GpuProcessHostUIShim::OnResizeView(int32 renderer_id, int32 render_view_id, - int32 command_buffer_route_id, + int32 route_id, gfx::Size size) { // Always respond even if the window no longer exists. The GPU process cannot // make progress on the resizing command buffer until it receives the // response. ScopedSendOnIOThread delayed_send( host_id_, - new GpuMsg_ResizeViewACK(renderer_id, - command_buffer_route_id)); + new AcceleratedSurfaceMsg_ResizeViewACK(route_id)); RenderViewHost* host = RenderViewHost::FromID(renderer_id, render_view_id); if (!host) @@ -312,6 +312,8 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew( params.route_id, surface_id, surface_handle)); } +#endif + void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped( const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { TRACE_EVENT0("renderer", @@ -332,24 +334,10 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped( delayed_send.Cancel(); -#if defined (OS_MACOSX) - view->AcceleratedSurfaceBuffersSwapped( - // Parameters needed to swap the IOSurface. - params.window, - params.surface_id, - // Parameters needed to formulate an acknowledgment. - params.renderer_id, - params.route_id, - host_id_); -#else // defined(UI_COMPOSITOR_IMAGE_TRANSPORT) - // view must send ACK message after next composite - view->AcceleratedSurfaceBuffersSwapped( - params.surface_id, params.route_id, host_id_); -#endif + // View must send ACK message after next composite. + view->AcceleratedSurfaceBuffersSwapped(params, host_id_); } -#endif - #if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease( diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h index ca54d2e..d4f566f 100644 --- a/content/browser/gpu/gpu_process_host_ui_shim.h +++ b/content/browser/gpu/gpu_process_host_ui_shim.h @@ -90,15 +90,16 @@ class GpuProcessHostUIShim #if defined(TOOLKIT_USES_GTK) || defined(OS_WIN) void OnResizeView(int32 renderer_id, int32 render_view_id, - int32 command_buffer_route_id, + int32 route_id, gfx::Size size); #endif + void OnAcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params); + #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) void OnAcceleratedSurfaceNew( const GpuHostMsg_AcceleratedSurfaceNew_Params& params); - void OnAcceleratedSurfaceBuffersSwapped( - const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params); #endif #if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 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 f44a076..44a8427 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 RenderWidgetHost; class WebCursor; @@ -187,6 +189,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| @@ -243,17 +253,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) @@ -262,10 +261,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 cae0359..62b1d27e 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -9,6 +9,7 @@ #include "content/browser/renderer_host/render_widget_host.h" #include "content/browser/renderer_host/web_input_event_aura.h" #include "content/public/browser/native_web_keyboard_event.h" +#include "content/common/gpu/gpu_messages.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" #include "ui/aura/client/aura_constants.h" @@ -275,46 +276,49 @@ 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. // Must still send the ACK. - host_->AcknowledgeSwapBuffers(route_id, gpu_host_id); + host_->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(&RenderWidgetHost::AcknowledgeSwapBuffers, - base::Unretained(host_), route_id, gpu_host_id)); + base::Unretained(host_), 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 cfe241f..3bef8a3 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -71,16 +71,15 @@ class CONTENT_EXPORT RenderWidgetHostViewAura 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 1994e1f..100c48a 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 1f799f3..5726aa7 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 4e3a192..3300a41 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -866,29 +866,27 @@ 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) { last_frame_was_accelerated_ = true; - 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 99cf505..d8c85df 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_impl.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" @@ -203,6 +207,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 +357,9 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { UnlockMouse(); ResetTooltip(); + + if (accelerated_surface_) + accelerated_surface_->Destroy(); } void RenderWidgetHostViewWin::CreateWnd(HWND parent) { @@ -1956,8 +1978,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 +2081,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 84611a0..0524288 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) && !defined(USE_AURA) 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 7b531af..8e1462b 100644 --- a/content/browser/renderer_host/test_render_view_host.h +++ b/content/browser/renderer_host/test_render_view_host.h @@ -89,6 +89,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; @@ -113,12 +116,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) && !defined(USE_AURA) virtual void WillWmDestroy() OVERRIDE; #endif diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index 2f14065..27eb490 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc @@ -209,14 +209,6 @@ void GpuChannel::CreateViewCommandBuffer( #endif // ENABLE_GPU } -void GpuChannel::ViewResized(int32 command_buffer_route_id) { - GpuCommandBufferStub* stub = stubs_.Lookup(command_buffer_route_id); - if (stub == NULL) - return; - - stub->ViewResized(); -} - GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32 route_id) { return stubs_.Lookup(route_id); } diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h index 782698f..bc642ac 100644 --- a/content/common/gpu/gpu_channel.h +++ b/content/common/gpu/gpu_channel.h @@ -88,8 +88,6 @@ class GpuChannel : public IPC::Channel::Listener, const GPUCreateCommandBufferConfig& init_params, int32* route_id); - void ViewResized(int32 command_buffer_route_id); - gfx::GLShareGroup* share_group() const { return share_group_.get(); } GpuCommandBufferStub* LookupCommandBuffer(int32 route_id); diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc index cd0b115..94838fb 100644 --- a/content/common/gpu/gpu_channel_manager.cc +++ b/content/common/gpu/gpu_channel_manager.cc @@ -62,9 +62,6 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer, OnCreateViewCommandBuffer) IPC_MESSAGE_HANDLER(GpuMsg_VisibilityChanged, OnVisibilityChanged) -#if defined(TOOLKIT_USES_GTK) || defined(OS_WIN) - IPC_MESSAGE_HANDLER(GpuMsg_ResizeViewACK, OnResizeViewACK); -#endif IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() return handled; @@ -127,6 +124,7 @@ void GpuChannelManager::OnCreateViewCommandBuffer( int32 render_view_id, int32 renderer_id, const GPUCreateCommandBufferConfig& init_params) { + DCHECK(render_view_id); int32 route_id = MSG_ROUTING_NONE; GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id); @@ -138,16 +136,6 @@ void GpuChannelManager::OnCreateViewCommandBuffer( Send(new GpuHostMsg_CommandBufferCreated(route_id)); } -void GpuChannelManager::OnResizeViewACK(int32 renderer_id, - int32 command_buffer_route_id) { - GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id); - if (iter == gpu_channels_.end()) - return; - scoped_refptr<GpuChannel> channel = iter->second; - - channel->ViewResized(command_buffer_route_id); -} - void GpuChannelManager::LoseAllContexts() { MessageLoop::current()->PostTask( FROM_HERE, diff --git a/content/common/gpu/gpu_channel_manager.h b/content/common/gpu/gpu_channel_manager.h index a6fff25..db0db36 100644 --- a/content/common/gpu/gpu_channel_manager.h +++ b/content/common/gpu/gpu_channel_manager.h @@ -77,7 +77,6 @@ class GpuChannelManager : public IPC::Channel::Listener, int32 render_view_id, int32 renderer_id, const GPUCreateCommandBufferConfig& init_params); - void OnResizeViewACK(int32 renderer_id, int32 command_buffer_route_id); void OnLoseAllContexts(); diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 5e741ee..195cf6e 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -15,13 +15,11 @@ #include "content/common/gpu/gpu_command_buffer_stub.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_watchdog.h" +#include "content/common/gpu/image_transport_surface.h" #include "gpu/command_buffer/common/constants.h" +#include "ui/gfx/gl/gl_bindings.h" #include "ui/gfx/gl/gl_switches.h" -#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) -#include "content/common/gpu/image_transport_surface.h" -#endif - GpuCommandBufferStub::GpuCommandBufferStub( GpuChannel* channel, GpuCommandBufferStub* share_group, @@ -125,6 +123,19 @@ bool GpuCommandBufferStub::IsScheduled() { return !scheduler_.get() || scheduler_->IsScheduled(); } +void GpuCommandBufferStub::SetSwapInterval() { +#if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) + // Set up swap interval for onscreen contexts. + if (!surface_->IsOffscreen()) { + decoder_->MakeCurrent(); + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) + context_->SetSwapInterval(0); + else + context_->SetSwapInterval(1); + } +#endif +} + void GpuCommandBufferStub::Destroy() { // The scheduler has raw references to the decoder and the command buffer so // destroy it before those. @@ -186,6 +197,7 @@ void GpuCommandBufferStub::OnInitialize( OnInitializeFailed(reply_message); return; } +#endif surface_ = ImageTransportSurface::CreateSurface( channel_->gpu_channel_manager(), @@ -193,9 +205,6 @@ void GpuCommandBufferStub::OnInitialize( renderer_id_, route_id_, handle_); -#elif defined(OS_WIN) || defined(OS_LINUX) || defined(OS_OPENBSD) - surface_ = gfx::GLSurface::CreateViewGLSurface(software_, handle_); -#endif } else { surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, gfx::Size(1, 1)); @@ -254,16 +263,6 @@ void GpuCommandBufferStub::OnInitialize( scheduler_->SetScheduledCallback( base::Bind(&GpuChannel::OnScheduled, base::Unretained(channel_))); - // On platforms that use an ImageTransportSurface, the surface - // handles co-ordinating the resize with the browser process. The - // surface sets it's own resize callback, so we shouldn't do it here. -#if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) - if (handle_ != gfx::kNullPluginWindow) { - decoder_->SetResizeCallback( - base::Bind(&GpuCommandBufferStub::OnResize, base::Unretained(this))); - } -#endif - if (watchdog_) { scheduler_->SetCommandProcessedCallback( base::Bind(&GpuCommandBufferStub::OnCommandProcessed, @@ -431,48 +430,6 @@ void GpuCommandBufferStub::OnCommandProcessed() { watchdog_->CheckArmed(); } -void GpuCommandBufferStub::OnResize(gfx::Size size) { - if (handle_ == gfx::kNullPluginWindow) - return; - -#if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \ - defined(OS_WIN) - GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); - - // On Windows, Linux, we need to coordinate resizing of onscreen - // contexts with the resizing of the actual OS-level window. We do this by - // sending a resize message to the browser process and descheduling the - // context until the ViewResized message comes back in reply. - // Send the resize message if needed - gpu_channel_manager->Send( - new GpuHostMsg_ResizeView(renderer_id_, - render_view_id_, - route_id_, - size)); - - scheduler_->SetScheduled(false); -#endif -} - -void GpuCommandBufferStub::ViewResized() { -#if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \ - defined(OS_WIN) - DCHECK(handle_ != gfx::kNullPluginWindow); - scheduler_->SetScheduled(true); -#endif - -#if defined(OS_WIN) - // Recreate the view surface to match the window size. Swap chains do not - // automatically resize with window size with D3D. - context_->ReleaseCurrent(surface_.get()); - if (surface_.get()) { - surface_->Destroy(); - surface_->Initialize(); - SetSwapInterval(); - } -#endif -} - void GpuCommandBufferStub::ReportState() { gpu::CommandBuffer::State state = command_buffer_->GetState(); if (state.error == gpu::error::kLostContext && @@ -485,19 +442,6 @@ void GpuCommandBufferStub::ReportState() { } } -void GpuCommandBufferStub::SetSwapInterval() { -#if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) - // Set up swap interval for onscreen contexts. - if (!surface_->IsOffscreen()) { - decoder_->MakeCurrent(); - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) - context_->SetSwapInterval(0); - else - context_->SetSwapInterval(1); - } -#endif -} - void GpuCommandBufferStub::OnCreateVideoDecoder( media::VideoDecodeAccelerator::Profile profile, IPC::Message* reply_message) { diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index 6ece34f..f581593 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -65,6 +65,9 @@ class GpuCommandBufferStub // Whether this command buffer can currently handle IPC messages. bool IsScheduled(); + // Set the swap interval according to the command line. + void SetSwapInterval(); + gpu::gles2::GLES2Decoder* decoder() const { return decoder_.get(); } gpu::GpuScheduler* scheduler() const { return scheduler_.get(); } @@ -78,8 +81,6 @@ class GpuCommandBufferStub // to the same renderer process. int32 route_id() const { return route_id_; } - void ViewResized(); - gfx::GpuPreference gpu_preference() { return gpu_preference_; } private: @@ -117,22 +118,11 @@ class GpuCommandBufferStub void OnSetSurfaceVisible(bool visible); -#if defined(OS_MACOSX) - void OnSwapBuffers(); - - // Returns the id of the current surface that is being rendered to - // (or 0 if no such surface has been created). - uint64 GetSurfaceId(); -#endif - void OnCommandProcessed(); void OnParseError(); - void OnResize(gfx::Size size); void ReportState(); - void SetSwapInterval(); - // The lifetime of objects of this class is managed by a GpuChannel. The // GpuChannels destroy all the GpuCommandBufferStubs that they own when they // are destroyed. So a raw pointer is safe. diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 906a195..8c99041 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -33,43 +33,17 @@ IPC_STRUCT_BEGIN(GPUCreateCommandBufferConfig) IPC_STRUCT_MEMBER(gfx::GpuPreference, gpu_preference) IPC_STRUCT_END() -#if defined(OS_MACOSX) IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceNew_Params) IPC_STRUCT_MEMBER(int32, renderer_id) IPC_STRUCT_MEMBER(int32, render_view_id) - IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window) IPC_STRUCT_MEMBER(int32, width) IPC_STRUCT_MEMBER(int32, height) IPC_STRUCT_MEMBER(uint64, surface_id) - IPC_STRUCT_MEMBER(bool, create_transport_dib) - IPC_STRUCT_MEMBER(int32, route_id) -IPC_STRUCT_END() - -IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params) - IPC_STRUCT_MEMBER(int32, renderer_id) - IPC_STRUCT_MEMBER(int32, render_view_id) - IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window) - IPC_STRUCT_MEMBER(uint64, surface_id) IPC_STRUCT_MEMBER(int32, route_id) -IPC_STRUCT_END() - -IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params) - IPC_STRUCT_MEMBER(int32, renderer_id) - IPC_STRUCT_MEMBER(int32, render_view_id) +#if defined(OS_MACOSX) IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window) - IPC_STRUCT_MEMBER(uint64, identifier) - IPC_STRUCT_MEMBER(int32, route_id) -IPC_STRUCT_END() + IPC_STRUCT_MEMBER(bool, create_transport_dib) #endif - -#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) -IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceNew_Params) - IPC_STRUCT_MEMBER(int32, renderer_id) - IPC_STRUCT_MEMBER(int32, render_view_id) - IPC_STRUCT_MEMBER(int32, width) - IPC_STRUCT_MEMBER(int32, height) - IPC_STRUCT_MEMBER(uint64, surface_id) - IPC_STRUCT_MEMBER(int32, route_id) IPC_STRUCT_END() IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params) @@ -77,6 +51,11 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params) IPC_STRUCT_MEMBER(int32, render_view_id) IPC_STRUCT_MEMBER(uint64, surface_id) IPC_STRUCT_MEMBER(int32, route_id) +#if defined(OS_WIN) + IPC_STRUCT_MEMBER(gfx::Size, size) +#elif defined(OS_MACOSX) + IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window) +#endif IPC_STRUCT_END() IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params) @@ -84,8 +63,10 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params) IPC_STRUCT_MEMBER(int32, render_view_id) IPC_STRUCT_MEMBER(uint64, identifier) IPC_STRUCT_MEMBER(int32, route_id) -IPC_STRUCT_END() +#if defined(OS_MACOSX) + IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window) #endif +IPC_STRUCT_END() IPC_STRUCT_TRAITS_BEGIN(content::DxDiagNode) IPC_STRUCT_TRAITS_MEMBER(values) @@ -160,16 +141,10 @@ IPC_MESSAGE_CONTROL4(GpuMsg_CreateViewCommandBuffer, // information. IPC_MESSAGE_CONTROL0(GpuMsg_CollectGraphicsInfo) -#if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \ - defined(OS_WIN) // Tells the GPU process that the browser process has finished resizing the // view. -IPC_MESSAGE_CONTROL2(GpuMsg_ResizeViewACK, - int32 /* renderer_id */, - int32 /* command_buffer_id */) -#endif +IPC_MESSAGE_ROUTED0(AcceleratedSurfaceMsg_ResizeViewACK) -#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) // Tells the GPU process that it's safe to start rendering to the surface. IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_NewACK, uint64 /* surface_id */, @@ -178,7 +153,6 @@ IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_NewACK, // Tells the GPU process that the browser process handled the swap // buffers request with the given number. IPC_MESSAGE_ROUTED0(AcceleratedSurfaceMsg_BuffersSwappedACK) -#endif // Tells the GPU process to remove all contexts. IPC_MESSAGE_CONTROL0(GpuMsg_Clean) @@ -234,18 +208,14 @@ IPC_MESSAGE_CONTROL3(GpuHostMsg_OnLogMessage, std::string /* header */, std::string /* message */) -#if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \ - defined(OS_WIN) // Resize the window that is being drawn into. It's important that this // resize be synchronized with the swapping of the front and back buffers. IPC_MESSAGE_CONTROL4(GpuHostMsg_ResizeView, int32 /* renderer_id */, int32 /* render_view_id */, - int32 /* command_buffer_route_id */, + int32 /* route_id */, gfx::Size /* size */) -#endif -#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) // This message is sent from the GPU process to the browser to notify about a // new or resized surface in the GPU. The browser allocates any resources // needed for it on its end and replies with an ACK containing any shared @@ -264,7 +234,6 @@ IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceBuffersSwapped, // is complete. IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceRelease, GpuHostMsg_AcceleratedSurfaceRelease_Params) -#endif //------------------------------------------------------------------------------ // GPU Channel Messages diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc index 5bb016e..d0dfee1 100644 --- a/content/common/gpu/image_transport_surface.cc +++ b/content/common/gpu/image_transport_surface.cc @@ -14,6 +14,12 @@ #include "content/common/gpu/gpu_messages.h" #include "gpu/command_buffer/service/gpu_scheduler.h" +ImageTransportSurface::ImageTransportSurface() { +} + +ImageTransportSurface::~ImageTransportSurface() { +} + ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface, GpuChannelManager* manager, int32 render_view_id, @@ -56,6 +62,7 @@ bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) { OnBuffersSwappedACK) IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_NewACK, OnNewSurfaceACK) + IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_ResizeViewACK, OnResizeViewACK); IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -91,6 +98,13 @@ void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped( manager_->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); } +void ImageTransportHelper::SendResizeView(const gfx::Size& size) { + manager_->Send(new GpuHostMsg_ResizeView(renderer_id_, + render_view_id_, + route_id_, + size)); +} + void ImageTransportHelper::SetScheduled(bool is_scheduled) { gpu::GpuScheduler* scheduler = Scheduler(); if (!scheduler) @@ -99,6 +113,13 @@ void ImageTransportHelper::SetScheduled(bool is_scheduled) { scheduler->SetScheduled(is_scheduled); } +void ImageTransportHelper::DeferToFence(base::Closure task) { + gpu::GpuScheduler* scheduler = Scheduler(); + DCHECK(scheduler); + + scheduler->DeferToFence(task); +} + void ImageTransportHelper::OnBuffersSwappedACK() { surface_->OnBuffersSwappedACK(); } @@ -109,8 +130,38 @@ void ImageTransportHelper::OnNewSurfaceACK( surface_->OnNewSurfaceACK(surface_id, shm_handle); } +void ImageTransportHelper::OnResizeViewACK() { + surface_->OnResizeViewACK(); +} + void ImageTransportHelper::Resize(gfx::Size size) { + // On windows, the surface is recreated and, in case the newly allocated + // surface happens to have the same address, it should be invalidated on the + // decoder so that future calls to MakeCurrent do not early out on the + // assumption that neither the context or surface have actually changed. +#if defined(OS_WIN) + Decoder()->ReleaseCurrent(); +#endif + surface_->OnResize(size); + +#if defined(OS_WIN) + Decoder()->MakeCurrent(); + SetSwapInterval(); +#endif +} + +void ImageTransportHelper::SetSwapInterval() { + GpuChannel* channel = manager_->LookupChannel(renderer_id_); + if (!channel) + return; + + GpuCommandBufferStub* stub = + channel->LookupCommandBuffer(command_buffer_id_); + if (!stub) + return; + + stub->SetSwapInterval(); } bool ImageTransportHelper::MakeCurrent() { @@ -146,4 +197,47 @@ gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() { return stub->decoder(); } +PassThroughImageTransportSurface::PassThroughImageTransportSurface( + GpuChannelManager* manager, + int32 render_view_id, + int32 renderer_id, + int32 command_buffer_id, + gfx::GLSurface* surface) : GLSurfaceAdapter(surface) { + helper_.reset(new ImageTransportHelper(this, + manager, + render_view_id, + renderer_id, + command_buffer_id, + gfx::kNullPluginWindow)); +} + +PassThroughImageTransportSurface::~PassThroughImageTransportSurface() { +} + +bool PassThroughImageTransportSurface::Initialize() { + // The surface is assumed to have already been initialized. + return helper_->Initialize(); +} + +void PassThroughImageTransportSurface::Destroy() { + helper_->Destroy(); + GLSurfaceAdapter::Destroy(); +} + +void PassThroughImageTransportSurface::OnNewSurfaceACK( + uint64 surface_id, TransportDIB::Handle surface_handle) { +} + +void PassThroughImageTransportSurface::OnBuffersSwappedACK() { +} + +void PassThroughImageTransportSurface::OnResizeViewACK() { + helper_->SetScheduled(true); +} + +void PassThroughImageTransportSurface::OnResize(gfx::Size size) { + helper_->SendResizeView(size); + helper_->SetScheduled(false); +} + #endif // defined(ENABLE_GPU) diff --git a/content/common/gpu/image_transport_surface.h b/content/common/gpu/image_transport_surface.h index 044d8c3..b791c6e 100644 --- a/content/common/gpu/image_transport_surface.h +++ b/content/common/gpu/image_transport_surface.h @@ -8,9 +8,12 @@ #if defined(ENABLE_GPU) +#include "base/callback.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" +#include "ui/gfx/gl/gl_surface.h" #include "ui/gfx/size.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/surface/transport_dib.h" @@ -48,9 +51,13 @@ class GLES2Decoder; class ImageTransportSurface { public: + ImageTransportSurface(); + virtual ~ImageTransportSurface(); + virtual void OnNewSurfaceACK( uint64 surface_id, TransportDIB::Handle surface_handle) = 0; virtual void OnBuffersSwappedACK() = 0; + virtual void OnResizeViewACK() = 0; virtual void OnResize(gfx::Size size) = 0; // Creates the appropriate surface depending on the GL implementation. @@ -60,6 +67,8 @@ class ImageTransportSurface { int32 renderer_id, int32 command_buffer_id, gfx::PluginWindowHandle handle); + private: + DISALLOW_COPY_AND_ASSIGN(ImageTransportSurface); }; class ImageTransportHelper : public IPC::Channel::Listener { @@ -87,10 +96,13 @@ class ImageTransportHelper : public IPC::Channel::Listener { GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params); void SendAcceleratedSurfaceRelease( GpuHostMsg_AcceleratedSurfaceRelease_Params params); + void SendResizeView(const gfx::Size& size); // Whether or not we should execute more commands. void SetScheduled(bool is_scheduled); + void DeferToFence(base::Closure task); + // Make the surface's context current. bool MakeCurrent(); @@ -101,10 +113,14 @@ class ImageTransportHelper : public IPC::Channel::Listener { // IPC::Message handlers. void OnNewSurfaceACK(uint64 surface_id, TransportDIB::Handle surface_handle); void OnBuffersSwappedACK(); + void OnResizeViewACK(); // Backbuffer resize callback. void Resize(gfx::Size size); + // Set the default swap interval on the surface. + void SetSwapInterval(); + // Weak pointers that point to objects that outlive this helper. ImageTransportSurface* surface_; GpuChannelManager* manager_; @@ -118,6 +134,36 @@ class ImageTransportHelper : public IPC::Channel::Listener { DISALLOW_COPY_AND_ASSIGN(ImageTransportHelper); }; +// An implementation of ImageTransportSurface that implements GLSurface through +// GLSurfaceAdapter, thereby forwarding GLSurface methods through to it. +class PassThroughImageTransportSurface + : public gfx::GLSurfaceAdapter, + public ImageTransportSurface { + public: + PassThroughImageTransportSurface(GpuChannelManager* manager, + int32 render_view_id, + int32 renderer_id, + int32 command_buffer_id, + gfx::GLSurface* surface); + virtual ~PassThroughImageTransportSurface(); + + // GLSurface implementation. + virtual bool Initialize(); + virtual void Destroy(); + + // ImageTransportSurface implementation. + virtual void OnNewSurfaceACK( + uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE; + virtual void OnBuffersSwappedACK() OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; + virtual void OnResize(gfx::Size size) OVERRIDE; + + private: + scoped_ptr<ImageTransportHelper> helper_; + + DISALLOW_COPY_AND_ASSIGN(PassThroughImageTransportSurface); +}; + #endif // defined(ENABLE_GPU) #endif // CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_H_ diff --git a/content/common/gpu/image_transport_surface_linux.cc b/content/common/gpu/image_transport_surface_linux.cc index 5cc75ba..bcb1284 100644 --- a/content/common/gpu/image_transport_surface_linux.cc +++ b/content/common/gpu/image_transport_surface_linux.cc @@ -77,6 +77,7 @@ class EGLImageTransportSurface : public ImageTransportSurface, virtual void OnNewSurfaceACK( uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE; virtual void OnBuffersSwappedACK() OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; virtual void OnResize(gfx::Size size) OVERRIDE; private: @@ -119,6 +120,7 @@ class GLXImageTransportSurface : public ImageTransportSurface, virtual void OnNewSurfaceACK( uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE; virtual void OnBuffersSwappedACK() OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; virtual void OnResize(gfx::Size size) OVERRIDE; private: @@ -167,6 +169,7 @@ class OSMesaImageTransportSurface : public ImageTransportSurface, virtual void OnNewSurfaceACK( uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE; virtual void OnBuffersSwappedACK() OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; virtual void OnResize(gfx::Size size) OVERRIDE; private: @@ -374,6 +377,11 @@ void EGLImageTransportSurface::OnBuffersSwappedACK() { helper_->SetScheduled(true); } + +void EGLImageTransportSurface::OnResizeViewACK() { + NOTREACHED(); +} + GLXImageTransportSurface::GLXImageTransportSurface( GpuChannelManager* manager, int32 render_view_id, @@ -539,6 +547,10 @@ void GLXImageTransportSurface::OnBuffersSwappedACK() { helper_->SetScheduled(true); } +void GLXImageTransportSurface::OnResizeViewACK() { + NOTREACHED(); +} + OSMesaImageTransportSurface::OSMesaImageTransportSurface( GpuChannelManager* manager, int32 render_view_id, @@ -617,6 +629,10 @@ void OSMesaImageTransportSurface::OnNewSurfaceACK( helper_->SetScheduled(true); } +void OSMesaImageTransportSurface::OnResizeViewACK() { + NOTREACHED(); +} + bool OSMesaImageTransportSurface::SwapBuffers() { DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL)); @@ -648,8 +664,9 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( int32 render_view_id, int32 renderer_id, int32 command_buffer_id, - gfx::PluginWindowHandle /* handle */) { + gfx::PluginWindowHandle handle) { scoped_refptr<gfx::GLSurface> surface; +#if defined(UI_COMPOSITOR_IMAGE_TRANSPORT) switch (gfx::GetGLImplementation()) { case gfx::kGLImplementationDesktopGL: surface = new GLXImageTransportSurface(manager, @@ -673,6 +690,17 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( NOTREACHED(); return NULL; } +#else + surface = gfx::GLSurface::CreateViewGLSurface(false, handle); + if (!surface.get()) + return NULL; + + surface = new PassThroughImageTransportSurface(manager, + render_view_id, + renderer_id, + command_buffer_id, + surface.get()); +#endif if (surface->Initialize()) return surface; else diff --git a/content/common/gpu/image_transport_surface_mac.cc b/content/common/gpu/image_transport_surface_mac.cc index 09d3521..8449f81 100644 --- a/content/common/gpu/image_transport_surface_mac.cc +++ b/content/common/gpu/image_transport_surface_mac.cc @@ -43,6 +43,7 @@ class IOSurfaceImageTransportSurface : public gfx::PbufferGLSurfaceCGL, virtual void OnNewSurfaceACK(uint64 surface_id, TransportDIB::Handle shm_handle) OVERRIDE; virtual void OnBuffersSwappedACK() OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; virtual void OnResize(gfx::Size size) OVERRIDE; private: @@ -94,6 +95,7 @@ class TransportDIBImageTransportSurface : public gfx::PbufferGLSurfaceCGL, virtual void OnBuffersSwappedACK() OVERRIDE; virtual void OnNewSurfaceACK(uint64 surface_id, TransportDIB::Handle shm_handle) OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; virtual void OnResize(gfx::Size size) OVERRIDE; private: @@ -239,6 +241,10 @@ void IOSurfaceImageTransportSurface::OnNewSurfaceACK( helper_->SetScheduled(true); } +void IOSurfaceImageTransportSurface::OnResizeViewACK() { + NOTREACHED(); +} + void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) { IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); @@ -443,6 +449,10 @@ void TransportDIBImageTransportSurface::OnNewSurfaceACK( DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL)); } +void TransportDIBImageTransportSurface::OnResizeViewACK() { + NOTREACHED(); +} + void TransportDIBImageTransportSurface::OnResize(gfx::Size size) { size_ = size; diff --git a/content/common/gpu/image_transport_surface_win.cc b/content/common/gpu/image_transport_surface_win.cc new file mode 100644 index 0000000..91040fe --- /dev/null +++ b/content/common/gpu/image_transport_surface_win.cc @@ -0,0 +1,176 @@ +// 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. + +#if defined(ENABLE_GPU) + +#include "content/common/gpu/image_transport_surface.h" + +#include "base/bind.h" +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/win/windows_version.h" +#include "content/common/gpu/gpu_messages.h" +#include "ui/gfx/gl/gl_bindings.h" +#include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_implementation.h" +#include "ui/gfx/gl/gl_surface_egl.h" +#include "ui/gfx/native_widget_types.h" + +namespace { + +// We are backed by an Pbuffer offscreen surface through which ANGLE provides +// a handle to the corresponding render target texture through an extension. +class PbufferImageTransportSurface + : public gfx::GLSurfaceAdapter, + public ImageTransportSurface, + public base::SupportsWeakPtr<PbufferImageTransportSurface> { + public: + PbufferImageTransportSurface(GpuChannelManager* manager, + int32 render_view_id, + int32 renderer_id, + int32 command_buffer_id); + + // GLSurface implementation + virtual bool Initialize(); + virtual void Destroy(); + virtual bool IsOffscreen(); + virtual bool SwapBuffers(); + + protected: + // ImageTransportSurface implementation + virtual void OnNewSurfaceACK(uint64 surface_id, + TransportDIB::Handle shm_handle) OVERRIDE; + virtual void OnBuffersSwappedACK() OVERRIDE; + virtual void OnResizeViewACK() OVERRIDE; + virtual void OnResize(gfx::Size size) OVERRIDE; + + private: + virtual ~PbufferImageTransportSurface(); + void SendBuffersSwapped(); + + scoped_ptr<ImageTransportHelper> helper_; + + DISALLOW_COPY_AND_ASSIGN(PbufferImageTransportSurface); +}; + +PbufferImageTransportSurface::PbufferImageTransportSurface( + GpuChannelManager* manager, + int32 render_view_id, + int32 renderer_id, + int32 command_buffer_id) + : GLSurfaceAdapter(new gfx::PbufferGLSurfaceEGL(false, + gfx::Size(1, 1))) { + helper_.reset(new ImageTransportHelper(this, + manager, + render_view_id, + renderer_id, + command_buffer_id, + gfx::kNullPluginWindow)); +} + +PbufferImageTransportSurface::~PbufferImageTransportSurface() { + Destroy(); +} + +bool PbufferImageTransportSurface::Initialize() { + // Only support this path if the GL implementation is ANGLE. + // IO surfaces will not work with, for example, OSMesa software renderer + // GL contexts. + if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) + return false; + + if (!helper_->Initialize()) + return false; + + return GLSurfaceAdapter::Initialize(); +} + +void PbufferImageTransportSurface::Destroy() { + helper_->Destroy(); + GLSurfaceAdapter::Destroy(); +} + +bool PbufferImageTransportSurface::IsOffscreen() { + return false; +} + +bool PbufferImageTransportSurface::SwapBuffers() { + HANDLE surface_handle = GetShareHandle(); + if (!surface_handle) + return false; + + helper_->DeferToFence(base::Bind( + &PbufferImageTransportSurface::SendBuffersSwapped, + AsWeakPtr())); + + return true; +} + +void PbufferImageTransportSurface::SendBuffersSwapped() { + GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; + params.surface_id = reinterpret_cast<int64>(GetShareHandle()); + params.size = GetSize(); + helper_->SendAcceleratedSurfaceBuffersSwapped(params); + + helper_->SetScheduled(false); +} + +void PbufferImageTransportSurface::OnBuffersSwappedACK() { + helper_->SetScheduled(true); +} + +void PbufferImageTransportSurface::OnNewSurfaceACK( + uint64 surface_id, + TransportDIB::Handle shm_handle) { + NOTIMPLEMENTED(); +} + +void PbufferImageTransportSurface::OnResizeViewACK() { + NOTIMPLEMENTED(); +} + +void PbufferImageTransportSurface::OnResize(gfx::Size size) { + Resize(size); +} + +} // namespace anonymous + +// static +scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface( + GpuChannelManager* manager, + int32 render_view_id, + int32 renderer_id, + int32 command_buffer_id, + gfx::PluginWindowHandle handle) { + scoped_refptr<gfx::GLSurface> surface; + + base::win::OSInfo* os_info = base::win::OSInfo::GetInstance(); + + // TODO(apatrick): Enable this once it has settled in the tree. + if (false && gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 && + os_info->version() >= base::win::VERSION_VISTA) { + surface = new PbufferImageTransportSurface(manager, + render_view_id, + renderer_id, + command_buffer_id); + } else { + surface = gfx::GLSurface::CreateViewGLSurface(false, handle); + if (!surface.get()) + return NULL; + + surface = new PassThroughImageTransportSurface(manager, + render_view_id, + renderer_id, + command_buffer_id, + surface.get()); + } + + if (surface->Initialize()) + return surface; + else + return NULL; +} + +#endif // ENABLE_GPU diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 9cb4b73..4bba9f3 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -15,6 +15,7 @@ '../third_party/speex/speex.gyp:libspeex', '../third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:webkit', '../third_party/zlib/zlib.gyp:zlib', + '../ui/gfx/surface/surface.gyp:surface', '../ui/ui.gyp:ui', '../ui/ui.gyp:ui_resources', '../webkit/support/webkit_support.gyp:webkit_resources', diff --git a/content/content_common.gypi b/content/content_common.gypi index c90697a..15c0201 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -145,6 +145,10 @@ 'common/gpu/gpu_process_launch_causes.h', 'common/gpu/gpu_watchdog.h', 'common/gpu/image_transport_surface.h', + 'common/gpu/image_transport_surface.cc', + 'common/gpu/image_transport_surface_linux.cc', + 'common/gpu/image_transport_surface_mac.cc', + 'common/gpu/image_transport_surface_win.cc', 'common/gpu/media/gpu_video_decode_accelerator.cc', 'common/gpu/media/gpu_video_decode_accelerator.h', 'common/gpu/transport_texture.cc', @@ -277,10 +281,6 @@ 'sources!': [ 'common/process_watcher_posix.cc', ], - 'sources': [ - 'common/gpu/image_transport_surface.cc', - 'common/gpu/image_transport_surface_mac.cc', - ], 'link_settings': { 'mac_bundle_resources': [ 'common/common.sb', @@ -303,11 +303,7 @@ 'common/gpu/x_util.h', ], }], - ['ui_compositor_image_transport==1', { - 'sources': [ - 'common/gpu/image_transport_surface.cc', - 'common/gpu/image_transport_surface_linux.cc', - ], + ['OS=="linux"', { 'include_dirs': [ '<(DEPTH)/third_party/angle/include', ], diff --git a/ui/gfx/surface/accelerated_surface_win.cc b/ui/gfx/surface/accelerated_surface_win.cc index efb5706..c3bc154 100644 --- a/ui/gfx/surface/accelerated_surface_win.cc +++ b/ui/gfx/surface/accelerated_surface_win.cc @@ -27,8 +27,14 @@ namespace { +typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version, + IDirect3D9Ex **d3d); + const int64 kPollQueryInterval = 1; +const wchar_t kD3D9ModuleName[] = L"d3d9.dll"; +const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex"; + class QuerySyncThread : public base::Thread, public base::RefCounted<QuerySyncThread> { @@ -330,8 +336,17 @@ void AcceleratedSurface::DoInitialize() { HRESULT hr; + HMODULE module = GetModuleHandle(kD3D9ModuleName); + if (!module) + return; + + Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>( + GetProcAddress(module, kCreate3D9DeviceExName)); + if (!create_func) + return; + base::win::ScopedComPtr<IDirect3D9Ex> d3d; - hr = Direct3DCreate9Ex(D3D_SDK_VERSION, d3d.Receive()); + hr = create_func(D3D_SDK_VERSION, d3d.Receive()); if (FAILED(hr)) return; |