Commit 5b321238 authored by apatrick@chromium.org's avatar apatrick@chromium.org

Reland 110355 - Use shared D3D9 texture to transport the compositor's backing...

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.
Review URL: http://codereview.chromium.org/8060045
Review URL: http://codereview.chromium.org/8588045

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110626 0039d316-1c4b-4281-b951-d872f2087c98
parent a07ef3d0
......@@ -1144,19 +1144,20 @@ void RenderWidgetHostViewViews::AcceleratedSurfaceRelease(uint64 surface_id) {
}
void RenderWidgetHostViewViews::AcceleratedSurfaceBuffersSwapped(
uint64 surface_id,
int32 route_id,
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
SetExternalTexture(accelerated_surface_containers_[surface_id]->GetTexture());
SetExternalTexture(
accelerated_surface_containers_[params.surface_id]->GetTexture());
glFlush();
if (!GetWidget() || !GetWidget()->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 {
// 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 = GetWidget()->GetCompositor();
if (!compositor->HasObserver(this))
compositor->AddObserver(this);
......@@ -1173,4 +1174,12 @@ void RenderWidgetHostViewViews::OnCompositingEnded(ui::Compositor* compositor) {
compositor->RemoveObserver(this);
}
#else
void RenderWidgetHostViewViews::AcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
NOTREACHED();
}
#endif
......@@ -99,6 +99,9 @@ class RenderWidgetHostViewViews : 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;
#if defined(OS_POSIX) || defined(USE_AURA)
virtual void GetDefaultScreenInfo(WebKit::WebScreenInfo* results);
......@@ -187,10 +190,6 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView,
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;
// CompositorObserver implementation:
......
......@@ -173,13 +173,14 @@ bool GpuProcessHostUIShim::OnControlMessageReceived(
IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
OnLogMessage)
IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
OnAcceleratedSurfaceBuffersSwapped)
#if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN)
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
......@@ -188,6 +189,7 @@ bool GpuProcessHostUIShim::OnControlMessageReceived(
IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease,
OnAcceleratedSurfaceRelease)
#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
......@@ -209,15 +211,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)
......@@ -314,6 +315,8 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
params.route_id, surface_id, surface_handle));
}
#endif
void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
TRACE_EVENT0("renderer",
......@@ -334,24 +337,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(
......
......@@ -74,12 +74,7 @@ class GpuProcessHostUIShim
// actually received on the IO thread.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
// TODO(apatrick): Remove this when mac does not use AcceleratedSurfaces for
// when running the GPU thread in the browser process.
// This is now also used in TOUCH_UI builds.
static void SendToGpuHost(int host_id, IPC::Message* msg);
#endif
private:
explicit GpuProcessHostUIShim(int host_id);
......@@ -94,15 +89,16 @@ class GpuProcessHostUIShim
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)
......
......@@ -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);
}
}
......@@ -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
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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));
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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"
......@@ -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;
......
......@@ -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_;
......
......@@ -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() {
}
......
......@@ -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)
virtual void WillWmDestroy() OVERRIDE;
#endif
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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(TOUCH_UI) || 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,
......
......@@ -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();
......
......@@ -14,13 +14,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,
......@@ -124,6 +122,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.
......@@ -185,6 +196,7 @@ void GpuCommandBufferStub::OnInitialize(
OnInitializeFailed(reply_message);
return;
}
#endif
surface_ = ImageTransportSurface::CreateSurface(
channel_->gpu_channel_manager(),
......@@ -192,9 +204,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));
......@@ -253,16 +262,6 @@ void GpuCommandBufferStub::OnInitialize(
scheduler_->SetScheduledCallback(
NewCallback(channel_, &GpuChannel::OnScheduled));
// 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(
NewCallback(this, &GpuCommandBufferStub::OnResize));
}
#endif
if (watchdog_) {
scheduler_->SetCommandProcessedCallback(
NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed));
......@@ -429,48 +428,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 &&
......@@ -483,19 +440,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) {
......
......@@ -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.
......
......@@ -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
......
......@@ -13,6 +13,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,
......@@ -55,6 +61,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;
......@@ -90,6 +97,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)
......@@ -98,6 +112,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();
}
......@@ -108,8 +129,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() {
......@@ -145,4 +196,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)
......@@ -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_
......@@ -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
......
......@@ -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;
......
// 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
......@@ -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',
......
......@@ -141,6 +141,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',
......@@ -270,10 +274,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',
......@@ -296,11 +296,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',
],
......
......@@ -53,6 +53,15 @@
['exclude', 'accelerated_surface_win.h'],
],
}],
['OS=="win"', {
'msvs_settings': {
'VCLinkerTool': {
'DelayLoadDLLs': [
'd3d9.dll',
],
},
},
}],
],
},
],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment