summaryrefslogtreecommitdiffstats
path: root/content/common/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'content/common/gpu')
-rw-r--r--content/common/gpu/gpu_channel.cc8
-rw-r--r--content/common/gpu/gpu_channel.h2
-rw-r--r--content/common/gpu/gpu_channel_manager.cc11
-rw-r--r--content/common/gpu/gpu_channel_manager.h2
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc159
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.h30
-rw-r--r--content/common/gpu/gpu_messages.h31
-rw-r--r--content/common/gpu/image_transport_surface.cc148
-rw-r--r--content/common/gpu/image_transport_surface.h123
-rw-r--r--content/common/gpu/image_transport_surface_linux.cc142
-rw-r--r--content/common/gpu/image_transport_surface_mac.cc476
11 files changed, 785 insertions, 347 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index 3434c74..89f775d 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -223,14 +223,6 @@ GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32 route_id) {
}
#if defined(OS_MACOSX)
-void GpuChannel::AcceleratedSurfaceBuffersSwapped(
- int32 route_id, uint64 swap_buffers_count) {
- GpuCommandBufferStub* stub = stubs_.Lookup(route_id);
- if (stub == NULL)
- return;
- stub->AcceleratedSurfaceBuffersSwapped(swap_buffers_count);
-}
-
void GpuChannel::DestroyCommandBufferByViewId(int32 render_view_id) {
// This responds to a message from the browser process to destroy the command
// buffer when the window with a GpuScheduler is closed (see
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index e02c2d8..242b746 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -99,8 +99,6 @@ class GpuChannel : public IPC::Channel::Listener,
GpuCommandBufferStub* LookupCommandBuffer(int32 route_id);
#if defined(OS_MACOSX)
- virtual void AcceleratedSurfaceBuffersSwapped(
- int32 route_id, uint64 swap_buffers_count);
void DestroyCommandBufferByViewId(int32 render_view_id);
#endif
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc
index 5d3aba8..491fdd6b 100644
--- a/content/common/gpu/gpu_channel_manager.cc
+++ b/content/common/gpu/gpu_channel_manager.cc
@@ -65,8 +65,6 @@ bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(GpuMsg_ResizeViewACK, OnResizeViewACK);
#endif
#if defined(OS_MACOSX)
- IPC_MESSAGE_HANDLER(GpuMsg_AcceleratedSurfaceBuffersSwappedACK,
- OnAcceleratedSurfaceBuffersSwappedACK)
IPC_MESSAGE_HANDLER(GpuMsg_DestroyCommandBuffer,
OnDestroyCommandBuffer)
#endif
@@ -154,15 +152,6 @@ void GpuChannelManager::OnResizeViewACK(int32 renderer_id,
}
#if defined(OS_MACOSX)
-void GpuChannelManager::OnAcceleratedSurfaceBuffersSwappedACK(
- int renderer_id, int32 route_id, uint64 swap_buffers_count) {
- GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
- if (iter == gpu_channels_.end())
- return;
- scoped_refptr<GpuChannel> channel = iter->second;
- channel->AcceleratedSurfaceBuffersSwapped(route_id, swap_buffers_count);
-}
-
void GpuChannelManager::OnDestroyCommandBuffer(
int renderer_id, int32 renderer_view_id) {
GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id);
diff --git a/content/common/gpu/gpu_channel_manager.h b/content/common/gpu/gpu_channel_manager.h
index e650a9c..517f02b 100644
--- a/content/common/gpu/gpu_channel_manager.h
+++ b/content/common/gpu/gpu_channel_manager.h
@@ -79,8 +79,6 @@ class GpuChannelManager : public IPC::Channel::Listener,
void OnResizeViewACK(int32 renderer_id, int32 command_buffer_route_id);
#if defined(OS_MACOSX)
- void OnAcceleratedSurfaceBuffersSwappedACK(
- int renderer_id, int32 route_id, uint64 swap_buffers_count);
void OnDestroyCommandBuffer(int renderer_id, int32 renderer_view_id);
#endif
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 57a076e..a15dd3a 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+ // 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.
@@ -17,8 +17,8 @@
#include "gpu/command_buffer/common/constants.h"
#include "ui/gfx/gl/gl_switches.h"
-#if defined(TOUCH_UI)
-#include "content/common/gpu/image_transport_surface_linux.h"
+#if defined(OS_MACOSX) || defined(TOUCH_UI)
+#include "content/common/gpu/image_transport_surface.h"
#endif
GpuCommandBufferStub::GpuCommandBufferStub(
@@ -48,10 +48,6 @@ GpuCommandBufferStub::GpuCommandBufferStub(
parent_stub_for_initialization_(),
parent_texture_for_initialization_(0),
watchdog_(watchdog),
-#if defined(OS_MACOSX)
- swap_buffers_count_(0),
- acknowledged_swap_buffers_count_(0),
-#endif
task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
if (share_group) {
context_group_ = share_group->context_group_;
@@ -124,21 +120,6 @@ bool GpuCommandBufferStub::IsScheduled() {
return !scheduler_.get() || scheduler_->IsScheduled();
}
-#if defined(OS_MACOSX)
-
-TransportDIB::Handle GpuCommandBufferStub::SetWindowSizeForTransportDIB(
- const gfx::Size& size) {
- return accelerated_surface_->SetTransportDIBSize(size);
-}
-
-void GpuCommandBufferStub::SetTransportDIBAllocAndFree(
- Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
- Callback1<TransportDIB::Id>::Type* deallocator) {
- accelerated_surface_->SetTransportDIBAllocAndFree(allocator, deallocator);
-}
-
-#endif // OS_MACOSX
-
void GpuCommandBufferStub::Destroy() {
// The scheduler has raw references to the decoder and the command buffer so
// destroy it before those.
@@ -153,10 +134,6 @@ void GpuCommandBufferStub::Destroy() {
context_ = NULL;
surface_ = NULL;
-
-#if defined(OS_MACOSX)
- accelerated_surface_.reset();
-#endif
}
void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
@@ -199,7 +176,7 @@ void GpuCommandBufferStub::OnInitialize(
decoder_->set_engine(scheduler_.get());
if (handle_) {
-#if defined(TOUCH_UI)
+#if defined(TOUCH_UI) || defined(OS_MACOSX)
if (software_) {
OnInitializeFailed(reply_message);
return;
@@ -209,12 +186,10 @@ void GpuCommandBufferStub::OnInitialize(
channel_->gpu_channel_manager(),
render_view_id_,
renderer_id_,
- route_id_);
+ route_id_,
+ handle_);
#elif defined(OS_WIN) || defined(OS_LINUX)
surface_ = gfx::GLSurface::CreateViewGLSurface(software_, handle_);
-#elif defined(OS_MACOSX)
- surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_,
- gfx::Size(1, 1));
#endif
} else {
surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_,
@@ -235,27 +210,6 @@ void GpuCommandBufferStub::OnInitialize(
return;
}
-#if defined(OS_MACOSX)
- // On Mac OS X since we can not render on-screen we don't even
- // attempt to create a view based GLContext. The only difference
- // between "on-screen" and "off-screen" rendering on this platform
- // is whether we allocate an AcceleratedSurface, which transmits the
- // rendering results back to the browser.
- if (handle_) {
- accelerated_surface_.reset(new AcceleratedSurface());
-
- // Note that although the GLContext is passed to Initialize and the
- // GLContext will later be owned by the decoder, AcceleratedSurface does
- // not hold on to the reference. It simply extracts the underlying GL
- // context in order to share the namespace with another context.
- if (!accelerated_surface_->Initialize(context_.get(), false)) {
- LOG(ERROR) << "Failed to initialize AcceleratedSurface.";
- OnInitializeFailed(reply_message);
- return;
- }
- }
-#endif
-
// Initialize the decoder with either the view or pbuffer GLContext.
if (!decoder_->Initialize(surface_.get(),
context_.get(),
@@ -281,15 +235,10 @@ void GpuCommandBufferStub::OnInitialize(
scheduler_->SetScheduledCallback(
NewCallback(channel_, &GpuChannel::OnScheduled));
-#if defined(OS_MACOSX)
- decoder_->SetSwapBuffersCallback(
- NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers));
-#endif
-
- // On TOUCH_UI, the ImageTransportSurface handles co-ordinating the
- // resize with the browser process. The ImageTransportSurface sets it's
- // own resize callback, so we shouldn't do it here.
-#if !defined(TOUCH_UI)
+ // 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(TOUCH_UI) && !defined(OS_MACOSX)
if (handle_ != gfx::kNullPluginWindow) {
decoder_->SetResizeCallback(
NewCallback(this, &GpuCommandBufferStub::OnResize));
@@ -490,100 +439,16 @@ void GpuCommandBufferStub::OnGetTransferBuffer(
Send(reply_message);
}
-#if defined(OS_MACOSX)
-void GpuCommandBufferStub::OnSwapBuffers() {
- TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSwapBuffers");
-
- DCHECK(decoder_.get());
- DCHECK(decoder_->GetGLContext());
- DCHECK(decoder_->GetGLContext()->IsCurrent(decoder_->GetGLSurface()));
-
- ++swap_buffers_count_;
-
- if (accelerated_surface_.get()) {
- accelerated_surface_->SwapBuffers();
- }
-
- if (handle_) {
- // To swap on OSX, we have to send a message to the browser to get the
- // context put onscreen.
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
- params.renderer_id = renderer_id_;
- params.render_view_id = render_view_id_;
- params.window = handle_;
- params.surface_id = GetSurfaceId();
- params.route_id = route_id();
- params.swap_buffers_count = swap_buffers_count_;
- gpu_channel_manager->Send(
- new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
- scheduler_->SetScheduled(false);
- }
-}
-
-uint64 GpuCommandBufferStub::GetSurfaceId() {
- if (!accelerated_surface_.get())
- return 0;
- return accelerated_surface_->GetSurfaceId();
-}
-#endif
-
void GpuCommandBufferStub::OnCommandProcessed() {
if (watchdog_)
watchdog_->CheckArmed();
}
-#if defined(OS_MACOSX)
-void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped(
- uint64 swap_buffers_count) {
- TRACE_EVENT1("gpu",
- "GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped",
- "frame", swap_buffers_count);
- DCHECK(handle_ != gfx::kNullPluginWindow);
-
- // Multiple swapbuffers may get consolidated together into a single
- // AcceleratedSurfaceBuffersSwapped call. Upstream code listening to the
- // GpuCommandBufferMsg_SwapBuffers expects to be called one time for every
- // swap. So, send one SwapBuffers message for every outstanding swap.
- uint64 delta = swap_buffers_count - acknowledged_swap_buffers_count_;
- acknowledged_swap_buffers_count_ = swap_buffers_count;
-
- for(uint64 i = 0; i < delta; i++) {
- // Wake up the GpuScheduler to start doing work again. When the scheduler
- // wakes up, it will send any deferred echo acknowledgements, triggering
- // associated swapbuffer callbacks.
- scheduler_->SetScheduled(true);
- }
-}
-#endif // defined(OS_MACOSX)
-
void GpuCommandBufferStub::OnResize(gfx::Size size) {
if (handle_ == gfx::kNullPluginWindow)
return;
-#if defined(OS_MACOSX)
- GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
-
- // On Mac, we need to tell the browser about the new IOSurface handle,
- // asynchronously.
- uint64 new_backing_store = accelerated_surface_->SetSurfaceSize(size);
- if (new_backing_store) {
- GpuHostMsg_AcceleratedSurfaceNew_Params params;
- params.renderer_id = renderer_id_;
- params.render_view_id = render_view_id_;
- params.window = handle_;
- params.width = size.width();
- params.height = size.height();
- params.identifier = new_backing_store;
- gpu_channel_manager->Send(
- new GpuHostMsg_AcceleratedSurfaceNew(params));
- } else {
- // TODO(kbr): figure out what to do here. It wouldn't be difficult
- // to support the compositor on 10.5, but the performance would be
- // questionable.
- NOTREACHED();
- }
-#elif defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN)
+#if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN)
GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
// On Windows, Linux, we need to coordinate resizing of onscreen
@@ -598,7 +463,7 @@ void GpuCommandBufferStub::OnResize(gfx::Size size) {
size));
scheduler_->SetScheduled(false);
-#endif // defined(OS_MACOSX)
+#endif // defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN)
}
void GpuCommandBufferStub::ViewResized() {
diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h
index 900e41f..d9d65a3 100644
--- a/content/common/gpu/gpu_command_buffer_stub.h
+++ b/content/common/gpu/gpu_command_buffer_stub.h
@@ -78,23 +78,6 @@ class GpuCommandBufferStub
void ViewResized();
-#if defined(OS_MACOSX)
- // Called only by the GpuChannel.
- void AcceleratedSurfaceBuffersSwapped(uint64 swap_buffers_count);
-
- // Needed only on Mac OS X, which does not render into an on-screen
- // window and therefore requires the backing store to be resized
- // manually. Returns an opaque identifier for the new backing store.
- // There are two versions of this method: one for use with the IOSurface
- // available in Mac OS X 10.6; and, one for use with the
- // TransportDIB-based version used on Mac OS X 10.5.
- virtual TransportDIB::Handle SetWindowSizeForTransportDIB(
- const gfx::Size& size);
- virtual void SetTransportDIBAllocAndFree(
- Callback2<size_t, TransportDIB::Handle*>::Type* allocator,
- Callback1<TransportDIB::Id>::Type* deallocator);
-#endif
-
private:
void Destroy();
@@ -184,19 +167,6 @@ class GpuCommandBufferStub
// decoder_route_id.
IDMap<GpuVideoDecodeAccelerator, IDMapOwnPointer> video_decoders_;
-#if defined(OS_MACOSX)
- // To prevent the GPU process from overloading the browser process,
- // we need to track the number of swap buffers calls issued and
- // acknowledged per on-screen context, and keep the GPU from getting
- // too far ahead of the browser. Note that this
- // is also predicated on a flow control mechanism between the
- // renderer and GPU processes.
- uint64 swap_buffers_count_;
- uint64 acknowledged_swap_buffers_count_;
- scoped_ptr<AcceleratedSurface> accelerated_surface_;
- scoped_ptr<Callback0::Type> wrapped_swap_buffers_callback_;
-#endif
-
ScopedRunnableMethodFactory<GpuCommandBufferStub> task_factory_;
DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub);
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index a6b96e4..f884f29 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -20,6 +20,7 @@
#include "media/video/video_decode_accelerator.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/size.h"
+#include "ui/gfx/surface/transport_dib.h"
#define IPC_MESSAGE_START GpuMsgStart
@@ -37,7 +38,9 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceNew_Params)
IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
IPC_STRUCT_MEMBER(int32, width)
IPC_STRUCT_MEMBER(int32, height)
- IPC_STRUCT_MEMBER(uint64, identifier)
+ 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)
@@ -46,7 +49,14 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)
IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
IPC_STRUCT_MEMBER(uint64, surface_id)
IPC_STRUCT_MEMBER(int32, route_id)
- IPC_STRUCT_MEMBER(uint64, swap_buffers_count)
+IPC_STRUCT_END()
+
+IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params)
+ IPC_STRUCT_MEMBER(int32, renderer_id)
+ IPC_STRUCT_MEMBER(int32, render_view_id)
+ IPC_STRUCT_MEMBER(gfx::PluginWindowHandle, window)
+ IPC_STRUCT_MEMBER(uint64, identifier)
+ IPC_STRUCT_MEMBER(int32, route_id)
IPC_STRUCT_END()
#endif
@@ -56,7 +66,7 @@ IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceNew_Params)
IPC_STRUCT_MEMBER(int32, render_view_id)
IPC_STRUCT_MEMBER(int32, width)
IPC_STRUCT_MEMBER(int32, height)
- IPC_STRUCT_MEMBER(uint64, identifier)
+ IPC_STRUCT_MEMBER(uint64, surface_id)
IPC_STRUCT_MEMBER(int32, route_id)
IPC_STRUCT_END()
@@ -65,7 +75,6 @@ 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)
- IPC_STRUCT_MEMBER(uint64, swap_buffers_count)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceRelease_Params)
@@ -156,7 +165,7 @@ IPC_MESSAGE_CONTROL2(GpuMsg_ResizeViewACK,
int32 /* command_buffer_id */)
#endif
-#if defined(TOUCH_UI)
+#if defined(OS_MACOSX) || defined(TOUCH_UI)
// Tells the GPU process that it's safe to start rendering to the surface.
IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_NewACK,
uint64 /* surface_id */,
@@ -168,16 +177,6 @@ IPC_MESSAGE_ROUTED0(AcceleratedSurfaceMsg_BuffersSwappedACK)
#endif
#if defined(OS_MACOSX)
-// Tells the GPU process that the browser process handled the swap
-// buffers request with the given number. Note that it is possible
-// for the browser process to coalesce frames; it is not guaranteed
-// that every GpuHostMsg_AcceleratedSurfaceBuffersSwapped message
-// will result in a buffer swap on the browser side.
-IPC_MESSAGE_CONTROL3(GpuMsg_AcceleratedSurfaceBuffersSwappedACK,
- int /* renderer_id */,
- int32 /* route_id */,
- uint64 /* swap_buffers_count */)
-
// Requests the GPU process to destroy the command buffer and remove the
// associated route. Further messages to this command buffer will result in a
// channel error.
@@ -263,9 +262,7 @@ IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceNew,
// should cause the browser to redraw the compositor's contents.
IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params)
-#endif
-#if defined(TOUCH_UI)
// Tells the browser to release whatever resources are associated with
// the given surface. The browser must send an ACK once this operation
// is complete.
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc
new file mode 100644
index 0000000..8d4c076
--- /dev/null
+++ b/content/common/gpu/image_transport_surface.cc
@@ -0,0 +1,148 @@
+// 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/callback.h"
+#include "content/common/gpu/gpu_channel.h"
+#include "content/common/gpu/gpu_channel_manager.h"
+#include "content/common/gpu/gpu_command_buffer_stub.h"
+#include "content/common/gpu/gpu_messages.h"
+#include "gpu/command_buffer/service/gpu_scheduler.h"
+
+ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface,
+ GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle)
+ : surface_(surface),
+ manager_(manager),
+ render_view_id_(render_view_id),
+ renderer_id_(renderer_id),
+ command_buffer_id_(command_buffer_id),
+ handle_(handle) {
+ route_id_ = manager_->GenerateRouteID();
+ manager_->AddRoute(route_id_, this);
+}
+
+ImageTransportHelper::~ImageTransportHelper() {
+ manager_->RemoveRoute(route_id_);
+}
+
+bool ImageTransportHelper::Initialize() {
+ gpu::gles2::GLES2Decoder* decoder = Decoder();
+
+ if (!decoder)
+ return false;
+
+ decoder->SetResizeCallback(
+ NewCallback(this, &ImageTransportHelper::Resize));
+
+ return true;
+}
+
+void ImageTransportHelper::Destroy() {
+}
+
+bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
+ IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BuffersSwappedACK,
+ OnBuffersSwappedACK)
+ IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_NewACK,
+ OnNewSurfaceACK)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void ImageTransportHelper::SendAcceleratedSurfaceRelease(
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params) {
+ params.renderer_id = renderer_id_;
+ params.render_view_id = render_view_id_;
+ params.route_id = route_id_;
+ manager_->Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
+}
+
+void ImageTransportHelper::SendAcceleratedSurfaceNew(
+ GpuHostMsg_AcceleratedSurfaceNew_Params params) {
+ params.renderer_id = renderer_id_;
+ params.render_view_id = render_view_id_;
+ params.route_id = route_id_;
+#if defined(OS_MACOSX)
+ params.window = handle_;
+#endif
+ manager_->Send(new GpuHostMsg_AcceleratedSurfaceNew(params));
+}
+
+void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped(
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params) {
+ params.renderer_id = renderer_id_;
+ params.render_view_id = render_view_id_;
+ params.route_id = route_id_;
+#if defined(OS_MACOSX)
+ params.window = handle_;
+#endif
+ manager_->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
+}
+
+void ImageTransportHelper::SetScheduled(bool is_scheduled) {
+ gpu::GpuScheduler* scheduler = Scheduler();
+ if (!scheduler)
+ return;
+
+ scheduler->SetScheduled(is_scheduled);
+}
+
+void ImageTransportHelper::OnBuffersSwappedACK() {
+ surface_->OnBuffersSwappedACK();
+}
+
+void ImageTransportHelper::OnNewSurfaceACK(
+ uint64 surface_id,
+ TransportDIB::Handle shm_handle) {
+ surface_->OnNewSurfaceACK(surface_id, shm_handle);
+}
+
+void ImageTransportHelper::Resize(gfx::Size size) {
+ surface_->OnResize(size);
+}
+
+bool ImageTransportHelper::MakeCurrent() {
+ gpu::gles2::GLES2Decoder* decoder = Decoder();
+ if (!decoder)
+ return false;
+ return decoder->MakeCurrent();
+}
+
+gpu::GpuScheduler* ImageTransportHelper::Scheduler() {
+ GpuChannel* channel = manager_->LookupChannel(renderer_id_);
+ if (!channel)
+ return NULL;
+
+ GpuCommandBufferStub* stub =
+ channel->LookupCommandBuffer(command_buffer_id_);
+ if (!stub)
+ return NULL;
+
+ return stub->scheduler();
+}
+
+gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
+ GpuChannel* channel = manager_->LookupChannel(renderer_id_);
+ if (!channel)
+ return NULL;
+
+ GpuCommandBufferStub* stub =
+ channel->LookupCommandBuffer(command_buffer_id_);
+ if (!stub)
+ return NULL;
+
+ return stub->decoder();
+}
+
+#endif // defined(ENABLE_GPU)
diff --git a/content/common/gpu/image_transport_surface.h b/content/common/gpu/image_transport_surface.h
new file mode 100644
index 0000000..044d8c3
--- /dev/null
+++ b/content/common/gpu/image_transport_surface.h
@@ -0,0 +1,123 @@
+// 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.
+
+#ifndef CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_H_
+#define CONTENT_COMMON_GPU_IMAGE_TRANSPORT_SURFACE_H_
+#pragma once
+
+#if defined(ENABLE_GPU)
+
+#include "base/memory/ref_counted.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
+#include "ui/gfx/size.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/surface/transport_dib.h"
+
+class GpuChannelManager;
+
+struct GpuHostMsg_AcceleratedSurfaceNew_Params;
+struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
+struct GpuHostMsg_AcceleratedSurfaceRelease_Params;
+
+namespace gfx {
+class GLSurface;
+}
+
+namespace gpu {
+class GpuScheduler;
+
+namespace gles2 {
+class GLES2Decoder;
+}
+}
+
+// The GPU process is agnostic as to how it displays results. On some platforms
+// it renders directly to window. On others it renders offscreen and transports
+// the results to the browser process to display. This file provides a simple
+// framework for making the offscreen path seem more like the onscreen path.
+//
+// The ImageTransportSurface class defines an simple interface for events that
+// should be responded to. The factory returns an offscreen surface that looks
+// a lot like an onscreen surface to the GPU process.
+//
+// The ImageTransportSurfaceHelper provides some glue to the outside world:
+// making sure outside events reach the ImageTransportSurface and
+// allowing the ImageTransportSurface to send events to the outside world.
+
+class ImageTransportSurface {
+ public:
+ virtual void OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) = 0;
+ virtual void OnBuffersSwappedACK() = 0;
+ virtual void OnResize(gfx::Size size) = 0;
+
+ // Creates the appropriate surface depending on the GL implementation.
+ static scoped_refptr<gfx::GLSurface>
+ CreateSurface(GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle);
+};
+
+class ImageTransportHelper : public IPC::Channel::Listener {
+ public:
+ // Takes weak pointers to objects that outlive the helper.
+ ImageTransportHelper(ImageTransportSurface* surface,
+ GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle);
+ virtual ~ImageTransportHelper();
+
+ bool Initialize();
+ void Destroy();
+
+ // IPC::Channel::Listener implementation:
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ // Helper send functions. Caller fills in the surface specific params
+ // like size and surface id. The helper fills in the rest.
+ void SendAcceleratedSurfaceNew(
+ GpuHostMsg_AcceleratedSurfaceNew_Params params);
+ void SendAcceleratedSurfaceBuffersSwapped(
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params);
+ void SendAcceleratedSurfaceRelease(
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params);
+
+ // Whether or not we should execute more commands.
+ void SetScheduled(bool is_scheduled);
+
+ // Make the surface's context current.
+ bool MakeCurrent();
+
+ private:
+ gpu::GpuScheduler* Scheduler();
+ gpu::gles2::GLES2Decoder* Decoder();
+
+ // IPC::Message handlers.
+ void OnNewSurfaceACK(uint64 surface_id, TransportDIB::Handle surface_handle);
+ void OnBuffersSwappedACK();
+
+ // Backbuffer resize callback.
+ void Resize(gfx::Size size);
+
+ // Weak pointers that point to objects that outlive this helper.
+ ImageTransportSurface* surface_;
+ GpuChannelManager* manager_;
+
+ int32 render_view_id_;
+ int32 renderer_id_;
+ int32 command_buffer_id_;
+ int32 route_id_;
+ gfx::PluginWindowHandle handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageTransportHelper);
+};
+
+#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 e7f304d..3389160 100644
--- a/content/common/gpu/image_transport_surface_linux.cc
+++ b/content/common/gpu/image_transport_surface_linux.cc
@@ -4,7 +4,7 @@
#if defined(ENABLE_GPU)
-#include "content/common/gpu/image_transport_surface_linux.h"
+#include "content/common/gpu/image_transport_surface.h"
// This conflicts with the defines in Xlib.h and must come first.
#include "content/common/gpu/gpu_messages.h"
@@ -167,7 +167,8 @@ EGLImageTransportSurface::EGLImageTransportSurface(
manager,
render_view_id,
renderer_id,
- command_buffer_id));
+ command_buffer_id,
+ gfx::kNullPluginWindow));
}
EGLImageTransportSurface::~EGLImageTransportSurface() {
@@ -239,7 +240,7 @@ void EGLImageTransportSurface::OnResize(gfx::Size size) {
GpuHostMsg_AcceleratedSurfaceNew_Params params;
params.width = size.width();
params.height = size.height();
- params.identifier = back_surface_->pixmap();
+ params.surface_id = back_surface_->pixmap();
helper_->SendAcceleratedSurfaceNew(params);
helper_->SetScheduled(false);
@@ -296,7 +297,8 @@ GLXImageTransportSurface::GLXImageTransportSurface(
manager,
render_view_id,
renderer_id,
- command_buffer_id));
+ command_buffer_id,
+ gfx::kNullPluginWindow));
}
GLXImageTransportSurface::~GLXImageTransportSurface() {
@@ -381,7 +383,7 @@ void GLXImageTransportSurface::OnResize(gfx::Size size) {
GpuHostMsg_AcceleratedSurfaceNew_Params params;
params.width = size_.width();
params.height = size_.height();
- params.identifier = window_;
+ params.surface_id = window_;
helper_->SendAcceleratedSurfaceNew(params);
helper_->SetScheduled(false);
@@ -432,7 +434,8 @@ OSMesaImageTransportSurface::OSMesaImageTransportSurface(
manager,
render_view_id,
renderer_id,
- command_buffer_id));
+ command_buffer_id,
+ gfx::kNullPluginWindow));
}
OSMesaImageTransportSurface::~OSMesaImageTransportSurface() {
@@ -484,7 +487,7 @@ void OSMesaImageTransportSurface::OnResize(gfx::Size size) {
GpuHostMsg_AcceleratedSurfaceNew_Params params;
params.width = size_.width();
params.height = size_.height();
- params.identifier = 0; // id comes from the browser with the shared mem
+ params.surface_id = 0; // id comes from the browser with the shared mem
helper_->SendAcceleratedSurfaceNew(params);
helper_->SetScheduled(false);
@@ -539,7 +542,8 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
GpuChannelManager* manager,
int32 render_view_id,
int32 renderer_id,
- int32 command_buffer_id) {
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle /* handle */) {
scoped_refptr<gfx::GLSurface> surface;
switch (gfx::GetGLImplementation()) {
case gfx::kGLImplementationDesktopGL:
@@ -570,126 +574,4 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
return NULL;
}
-ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface,
- GpuChannelManager* manager,
- int32 render_view_id,
- int32 renderer_id,
- int32 command_buffer_id)
- : surface_(surface),
- manager_(manager),
- render_view_id_(render_view_id),
- renderer_id_(renderer_id),
- command_buffer_id_(command_buffer_id) {
- route_id_ = manager_->GenerateRouteID();
- manager_->AddRoute(route_id_, this);
-}
-
-ImageTransportHelper::~ImageTransportHelper() {
- manager_->RemoveRoute(route_id_);
-}
-
-bool ImageTransportHelper::Initialize() {
- gpu::gles2::GLES2Decoder* decoder = Decoder();
- if (!decoder)
- return false;
-
- decoder->SetResizeCallback(
- NewCallback(this, &ImageTransportHelper::Resize));
-
- return true;
-}
-
-void ImageTransportHelper::Destroy() {
-}
-
-bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
- IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_NewACK,
- OnNewSurfaceACK)
- IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BuffersSwappedACK,
- OnBuffersSwappedACK)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void ImageTransportHelper::SendAcceleratedSurfaceRelease(
- GpuHostMsg_AcceleratedSurfaceRelease_Params params) {
- params.renderer_id = renderer_id_;
- params.render_view_id = render_view_id_;
- params.route_id = route_id_;
- manager_->Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
-}
-
-void ImageTransportHelper::SendAcceleratedSurfaceNew(
- GpuHostMsg_AcceleratedSurfaceNew_Params params) {
- params.renderer_id = renderer_id_;
- params.render_view_id = render_view_id_;
- params.route_id = route_id_;
- manager_->Send(new GpuHostMsg_AcceleratedSurfaceNew(params));
-}
-
-void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped(
- GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params) {
- params.renderer_id = renderer_id_;
- params.render_view_id = render_view_id_;
- params.route_id = route_id_;
- manager_->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
-}
-
-void ImageTransportHelper::SetScheduled(bool is_scheduled) {
- gpu::GpuScheduler* scheduler = Scheduler();
- if (!scheduler)
- return;
-
- scheduler->SetScheduled(is_scheduled);
-}
-
-void ImageTransportHelper::OnNewSurfaceACK(
- uint64 surface_id, TransportDIB::Handle surface_handle) {
- surface_->OnNewSurfaceACK(surface_id, surface_handle);
-}
-
-void ImageTransportHelper::OnBuffersSwappedACK() {
- surface_->OnBuffersSwappedACK();
-}
-
-void ImageTransportHelper::Resize(gfx::Size size) {
- surface_->OnResize(size);
-}
-
-bool ImageTransportHelper::MakeCurrent() {
- gpu::gles2::GLES2Decoder* decoder = Decoder();
- if (!decoder)
- return false;
- return decoder->MakeCurrent();
-}
-
-gpu::GpuScheduler* ImageTransportHelper::Scheduler() {
- GpuChannel* channel = manager_->LookupChannel(renderer_id_);
- if (!channel)
- return NULL;
-
- GpuCommandBufferStub* stub =
- channel->LookupCommandBuffer(command_buffer_id_);
- if (!stub)
- return NULL;
-
- return stub->scheduler();
-}
-
-gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
- GpuChannel* channel = manager_->LookupChannel(renderer_id_);
- if (!channel)
- return NULL;
-
- GpuCommandBufferStub* stub =
- channel->LookupCommandBuffer(command_buffer_id_);
- if (!stub)
- return NULL;
-
- return stub->decoder();
-}
-
#endif // defined(USE_GPU)
diff --git a/content/common/gpu/image_transport_surface_mac.cc b/content/common/gpu/image_transport_surface_mac.cc
new file mode 100644
index 0000000..44e72e0
--- /dev/null
+++ b/content/common/gpu/image_transport_surface_mac.cc
@@ -0,0 +1,476 @@
+// 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/mac/scoped_cftyperef.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/common/gpu/gpu_messages.h"
+#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+#include "ui/gfx/gl/gl_surface_cgl.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/surface/io_surface_support_mac.h"
+
+namespace {
+
+// We are backed by an Pbuffer offscreen surface for the purposes of creating a
+// context, but use FBOs to render to texture backed IOSurface
+class IOSurfaceImageTransportSurface : public gfx::PbufferGLSurfaceCGL,
+ public ImageTransportSurface {
+ public:
+ IOSurfaceImageTransportSurface(GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle);
+
+ // GLSurface implementation
+ virtual bool Initialize() OVERRIDE;
+ virtual void Destroy() OVERRIDE;
+ virtual bool IsOffscreen() OVERRIDE;
+ virtual bool SwapBuffers() OVERRIDE;
+ virtual gfx::Size GetSize() OVERRIDE;
+ virtual void OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
+ virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;
+
+ protected:
+ // ImageTransportSurface implementation
+ virtual void OnNewSurfaceACK(uint64 surface_id,
+ TransportDIB::Handle shm_handle) OVERRIDE;
+ virtual void OnBuffersSwappedACK() OVERRIDE;
+ virtual void OnResize(gfx::Size size) OVERRIDE;
+
+ private:
+ virtual ~IOSurfaceImageTransportSurface() OVERRIDE;
+
+ uint32 fbo_id_;
+ GLuint texture_id_;
+
+ base::mac::ScopedCFTypeRef<CFTypeRef> io_surface_;
+
+ // The id of |io_surface_| or 0 if that's NULL.
+ uint64 io_surface_id_;
+
+ // Weak pointer to the context that this was last made current to.
+ gfx::GLContext* context_;
+
+ gfx::Size size_;
+
+ scoped_ptr<ImageTransportHelper> helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(IOSurfaceImageTransportSurface);
+};
+
+// We are backed by an Pbuffer offscreen surface for the purposes of creating a
+// context, but use FBOs to render offscreen.
+class TransportDIBImageTransportSurface : public gfx::PbufferGLSurfaceCGL,
+ public ImageTransportSurface {
+ public:
+ TransportDIBImageTransportSurface(GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle);
+
+ // GLSurface implementation
+ virtual bool Initialize() OVERRIDE;
+ virtual void Destroy() OVERRIDE;
+ virtual bool IsOffscreen() OVERRIDE;
+ virtual bool SwapBuffers() OVERRIDE;
+ virtual gfx::Size GetSize() OVERRIDE;
+ virtual void OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
+ virtual unsigned int GetBackingFrameBufferObject() OVERRIDE;
+
+ protected:
+ // ImageTransportSurface implementation
+ virtual void OnBuffersSwappedACK() OVERRIDE;
+ virtual void OnNewSurfaceACK(uint64 surface_id,
+ TransportDIB::Handle shm_handle) OVERRIDE;
+ virtual void OnResize(gfx::Size size) OVERRIDE;
+
+ private:
+ virtual ~TransportDIBImageTransportSurface() OVERRIDE;
+
+ uint32 fbo_id_;
+ GLuint render_buffer_id_;
+
+ scoped_ptr<TransportDIB> shared_mem_;
+
+ gfx::Size size_;
+
+ static uint32 next_id_;
+
+ scoped_ptr<ImageTransportHelper> helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportDIBImageTransportSurface);
+};
+
+uint32 TransportDIBImageTransportSurface::next_id_ = 1;
+
+void AddBooleanValue(CFMutableDictionaryRef dictionary,
+ const CFStringRef key,
+ bool value) {
+ CFDictionaryAddValue(dictionary, key,
+ (value ? kCFBooleanTrue : kCFBooleanFalse));
+}
+
+void AddIntegerValue(CFMutableDictionaryRef dictionary,
+ const CFStringRef key,
+ int32 value) {
+ base::mac::ScopedCFTypeRef<CFNumberRef> number(
+ CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
+ CFDictionaryAddValue(dictionary, key, number.get());
+}
+
+IOSurfaceImageTransportSurface::IOSurfaceImageTransportSurface(
+ GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle)
+ : gfx::PbufferGLSurfaceCGL(gfx::Size(1, 1)),
+ fbo_id_(0),
+ texture_id_(0),
+ io_surface_id_(0),
+ context_(NULL) {
+ helper_.reset(new ImageTransportHelper(this,
+ manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id,
+ handle));
+
+}
+
+IOSurfaceImageTransportSurface::~IOSurfaceImageTransportSurface() {
+ Destroy();
+}
+
+bool IOSurfaceImageTransportSurface::Initialize() {
+ // Only support IOSurfaces if the GL implementation is the native desktop GL.
+ // IO surfaces will not work with, for example, OSMesa software renderer
+ // GL contexts.
+ if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL)
+ return false;
+
+ if (!helper_->Initialize())
+ return false;
+ return PbufferGLSurfaceCGL::Initialize();
+}
+
+void IOSurfaceImageTransportSurface::Destroy() {
+ if (fbo_id_) {
+ glDeleteFramebuffersEXT(1, &fbo_id_);
+ fbo_id_ = 0;
+ }
+
+ if (texture_id_) {
+ glDeleteTextures(1, &texture_id_);
+ texture_id_ = 0;
+ }
+
+ helper_->Destroy();
+ PbufferGLSurfaceCGL::Destroy();
+}
+
+bool IOSurfaceImageTransportSurface::IsOffscreen() {
+ return false;
+}
+
+void IOSurfaceImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
+ context_ = context;
+
+ if (fbo_id_)
+ return;
+
+ glGenFramebuffersEXT(1, &fbo_id_);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
+ OnResize(gfx::Size(1, 1));
+
+ GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOG(ERROR) << "Framebuffer incomplete.";
+ }
+}
+
+unsigned int IOSurfaceImageTransportSurface::GetBackingFrameBufferObject() {
+ return fbo_id_;
+}
+
+bool IOSurfaceImageTransportSurface::SwapBuffers() {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
+ glFlush();
+
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
+ params.surface_id = io_surface_id_;
+ helper_->SendAcceleratedSurfaceBuffersSwapped(params);
+
+ helper_->SetScheduled(false);
+ return true;
+}
+
+gfx::Size IOSurfaceImageTransportSurface::GetSize() {
+ return size_;
+}
+
+void IOSurfaceImageTransportSurface::OnBuffersSwappedACK() {
+ helper_->SetScheduled(true);
+}
+
+void IOSurfaceImageTransportSurface::OnNewSurfaceACK(
+ uint64 surface_id,
+ TransportDIB::Handle /* shm_handle */) {
+ DCHECK_EQ(io_surface_id_, surface_id);
+ helper_->SetScheduled(true);
+}
+
+void IOSurfaceImageTransportSurface::OnResize(gfx::Size size) {
+ IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
+
+ // Caching |context_| from OnMakeCurrent. It should still be current.
+ DCHECK(context_->IsCurrent(this));
+
+ size_ = size;
+
+ if (texture_id_)
+ glDeleteTextures(1, &texture_id_);
+
+ glGenTextures(1, &texture_id_);
+
+ // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
+ // Mac OS X and is required for IOSurface interoperability.
+ GLenum target = GL_TEXTURE_RECTANGLE_ARB;
+ glBindTexture(target, texture_id_);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target,
+ texture_id_,
+ 0);
+
+ // Allocate a new IOSurface, which is the GPU resource that can be
+ // shared across processes.
+ base::mac::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
+ properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks));
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfaceWidth(),
+ size_.width());
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfaceHeight(),
+ size_.height());
+ AddIntegerValue(properties,
+ io_surface_support->GetKIOSurfaceBytesPerElement(), 4);
+ AddBooleanValue(properties,
+ io_surface_support->GetKIOSurfaceIsGlobal(), true);
+ // I believe we should be able to unreference the IOSurfaces without
+ // synchronizing with the browser process because they are
+ // ultimately reference counted by the operating system.
+ io_surface_.reset(io_surface_support->IOSurfaceCreate(properties));
+
+ // Don't think we need to identify a plane.
+ GLuint plane = 0;
+ io_surface_support->CGLTexImageIOSurface2D(
+ static_cast<CGLContextObj>(context_->GetHandle()),
+ target,
+ GL_RGBA,
+ size_.width(),
+ size_.height(),
+ GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ io_surface_.get(),
+ plane);
+
+ io_surface_id_ = io_surface_support->IOSurfaceGetID(io_surface_);
+ glFlush();
+
+ GpuHostMsg_AcceleratedSurfaceNew_Params params;
+ params.width = size_.width();
+ params.height = size_.height();
+ params.surface_id = io_surface_id_;
+ params.create_transport_dib = false;
+ helper_->SendAcceleratedSurfaceNew(params);
+
+ helper_->SetScheduled(false);
+}
+
+TransportDIBImageTransportSurface::TransportDIBImageTransportSurface(
+ GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id,
+ gfx::PluginWindowHandle handle)
+ : gfx::PbufferGLSurfaceCGL(gfx::Size(1, 1)),
+ fbo_id_(0),
+ render_buffer_id_(0) {
+ helper_.reset(new ImageTransportHelper(this,
+ manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id,
+ handle));
+
+}
+
+TransportDIBImageTransportSurface::~TransportDIBImageTransportSurface() {
+ Destroy();
+}
+
+bool TransportDIBImageTransportSurface::Initialize() {
+ if (!helper_->Initialize())
+ return false;
+ return PbufferGLSurfaceCGL::Initialize();
+}
+
+void TransportDIBImageTransportSurface::Destroy() {
+ if (fbo_id_) {
+ glDeleteFramebuffersEXT(1, &fbo_id_);
+ fbo_id_ = 0;
+ }
+
+ if (render_buffer_id_) {
+ glDeleteRenderbuffersEXT(1, &render_buffer_id_);
+ render_buffer_id_ = 0;
+ }
+
+ helper_->Destroy();
+ PbufferGLSurfaceCGL::Destroy();
+}
+
+bool TransportDIBImageTransportSurface::IsOffscreen() {
+ return false;
+}
+
+void TransportDIBImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
+ if (fbo_id_)
+ return;
+
+ glGenFramebuffersEXT(1, &fbo_id_);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
+ OnResize(gfx::Size(1, 1));
+
+ GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOG(ERROR) << "Framebuffer incomplete.";
+ }
+}
+
+unsigned int TransportDIBImageTransportSurface::GetBackingFrameBufferObject() {
+ return fbo_id_;
+}
+
+bool TransportDIBImageTransportSurface::SwapBuffers() {
+ DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL));
+
+ GLint current_alignment;
+ glGetIntegerv(GL_PACK_ALIGNMENT, &current_alignment);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ glReadPixels(0, 0,
+ size_.width(), size_.height(),
+ GL_BGRA, // This pixel format should have no conversion.
+ GL_UNSIGNED_INT_8_8_8_8_REV,
+ shared_mem_->memory());
+ glPixelStorei(GL_PACK_ALIGNMENT, current_alignment);
+
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
+ params.surface_id = next_id_;
+ helper_->SendAcceleratedSurfaceBuffersSwapped(params);
+
+ helper_->SetScheduled(false);
+ return true;
+}
+
+gfx::Size TransportDIBImageTransportSurface::GetSize() {
+ return size_;
+}
+
+void TransportDIBImageTransportSurface::OnBuffersSwappedACK() {
+ helper_->SetScheduled(true);
+}
+
+void TransportDIBImageTransportSurface::OnNewSurfaceACK(
+ uint64 surface_id,
+ TransportDIB::Handle shm_handle) {
+ helper_->SetScheduled(true);
+
+ shared_mem_.reset(TransportDIB::Map(shm_handle));
+ DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL));
+}
+
+void TransportDIBImageTransportSurface::OnResize(gfx::Size size) {
+ size_ = size;
+
+ if (!render_buffer_id_)
+ glGenRenderbuffersEXT(1, &render_buffer_id_);
+
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffer_id_);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
+ GL_RGBA,
+ size_.width(), size_.height());
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT,
+ render_buffer_id_);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
+
+ GpuHostMsg_AcceleratedSurfaceNew_Params params;
+ params.width = size_.width();
+ params.height = size_.height();
+ params.surface_id = next_id_++;
+ params.create_transport_dib = true;
+ helper_->SendAcceleratedSurfaceNew(params);
+
+ helper_->SetScheduled(false);
+}
+
+} // namespace
+
+// 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;
+ IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
+
+ switch (gfx::GetGLImplementation()) {
+ case gfx::kGLImplementationDesktopGL:
+ if (!io_surface_support) {
+ surface = new TransportDIBImageTransportSurface(manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id,
+ handle);
+ } else {
+ surface = new IOSurfaceImageTransportSurface(manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id,
+ handle);
+ }
+ break;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+ if (surface->Initialize())
+ return surface;
+ else
+ return NULL;
+}
+
+#endif // defined(USE_GPU)