summaryrefslogtreecommitdiffstats
path: root/content/common
diff options
context:
space:
mode:
authorwjmaclean@google.com <wjmaclean@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-23 15:20:47 +0000
committerwjmaclean@google.com <wjmaclean@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-23 15:20:47 +0000
commitc457bf3e7f797d06aace7ffa1a0b2e1393ec4009 (patch)
treea3d0dc37e3dceeefdc4a68f71f192a5732bdd9cd /content/common
parentf96721bbd5f09d7e0ef305b42aa86a3b7ae0c298 (diff)
downloadchromium_src-c457bf3e7f797d06aace7ffa1a0b2e1393ec4009.zip
chromium_src-c457bf3e7f797d06aace7ffa1a0b2e1393ec4009.tar.gz
chromium_src-c457bf3e7f797d06aace7ffa1a0b2e1393ec4009.tar.bz2
Implements OSMesaImageTransportSurface in the GPU for sending GLSurface from the GPU to the browser.
Implements AcceleratedSurfaceContainerTouchOSMesa in the browser's renderer for receiving a GLSurface contents and building a GLTexture in the browser for compositing. BUG= TEST=./out/Debug/chrome --use-gl=osmesa --show-fps-counter Review URL: http://codereview.chromium.org/7980006 Patch from Dana Jansens <danakj@chromium.org>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@102500 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/common')
-rw-r--r--content/common/gpu/DEPS1
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc4
-rw-r--r--content/common/gpu/gpu_messages.h21
-rw-r--r--content/common/gpu/image_transport_surface_linux.cc214
-rw-r--r--content/common/gpu/image_transport_surface_linux.h21
5 files changed, 220 insertions, 41 deletions
diff --git a/content/common/gpu/DEPS b/content/common/gpu/DEPS
index 98cc1f3..428e3cd 100644
--- a/content/common/gpu/DEPS
+++ b/content/common/gpu/DEPS
@@ -7,4 +7,5 @@ include_rules = [
"+skia",
"+third_party/angle/include",
"+third_party/openmax",
+ "+third_party/mesa",
]
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index a53364a..d38d9c9 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -566,7 +566,7 @@ void GpuCommandBufferStub::OnResize(gfx::Size size) {
// asynchronously.
uint64 new_backing_store = accelerated_surface_->SetSurfaceSize(size);
if (new_backing_store) {
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
+ GpuHostMsg_AcceleratedSurfaceNew_Params params;
params.renderer_id = renderer_id_;
params.render_view_id = render_view_id_;
params.window = handle_;
@@ -574,7 +574,7 @@ void GpuCommandBufferStub::OnResize(gfx::Size size) {
params.height = size.height();
params.identifier = new_backing_store;
gpu_channel_manager->Send(
- new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params));
+ 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
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index f96a632..a6b96e4 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -31,7 +31,7 @@ IPC_STRUCT_BEGIN(GPUCreateCommandBufferConfig)
IPC_STRUCT_END()
#if defined(OS_MACOSX)
-IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params)
+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)
@@ -51,7 +51,7 @@ IPC_STRUCT_END()
#endif
#if defined(TOUCH_UI)
-IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params)
+IPC_STRUCT_BEGIN(GpuHostMsg_AcceleratedSurfaceNew_Params)
IPC_STRUCT_MEMBER(int32, renderer_id)
IPC_STRUCT_MEMBER(int32, render_view_id)
IPC_STRUCT_MEMBER(int32, width)
@@ -158,8 +158,9 @@ IPC_MESSAGE_CONTROL2(GpuMsg_ResizeViewACK,
#if defined(TOUCH_UI)
// Tells the GPU process that it's safe to start rendering to the surface.
-IPC_MESSAGE_ROUTED1(AcceleratedSurfaceMsg_SetSurfaceACK,
- uint64 /* surface_id */)
+IPC_MESSAGE_ROUTED2(AcceleratedSurfaceMsg_NewACK,
+ uint64 /* surface_id */,
+ TransportDIB::Handle /* shared memory buffer */)
// Tells the GPU process that the browser process handled the swap
// buffers request with the given number.
@@ -250,12 +251,12 @@ IPC_MESSAGE_CONTROL4(GpuHostMsg_ResizeView,
#endif
#if defined(OS_MACOSX) || defined(TOUCH_UI)
-// This message is sent from the GPU process to the browser to indicate that a
-// new backing store was allocated. The renderer ID and render view ID are
-// needed in order to uniquely identify the RenderWidgetHostView on the
-// browser side.
-IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceSetIOSurface,
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params)
+// 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
+// resources/identifiers to be used in the GPU.
+IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceNew,
+ GpuHostMsg_AcceleratedSurfaceNew_Params)
// This message notifies the browser process that the renderer
// swapped the buffers associated with the given "window", which
diff --git a/content/common/gpu/image_transport_surface_linux.cc b/content/common/gpu/image_transport_surface_linux.cc
index e0117e6..e7f304d 100644
--- a/content/common/gpu/image_transport_surface_linux.cc
+++ b/content/common/gpu/image_transport_surface_linux.cc
@@ -20,11 +20,13 @@
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "third_party/angle/include/EGL/egl.h"
#include "third_party/angle/include/EGL/eglext.h"
+#include "third_party/mesa/MesaLib/include/GL/osmesa.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_egl.h"
#include "ui/gfx/gl/gl_surface_glx.h"
+#include "ui/gfx/gl/gl_surface_osmesa.h"
#include "ui/gfx/surface/accelerated_surface_linux.h"
namespace {
@@ -50,7 +52,8 @@ class EGLImageTransportSurface : public ImageTransportSurface,
protected:
// ImageTransportSurface implementation
- virtual void OnSetSurfaceACK(uint64 surface_id) OVERRIDE;
+ virtual void OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE;
virtual void OnBuffersSwappedACK() OVERRIDE;
virtual void OnResize(gfx::Size size) OVERRIDE;
@@ -68,8 +71,8 @@ class EGLImageTransportSurface : public ImageTransportSurface,
DISALLOW_COPY_AND_ASSIGN(EGLImageTransportSurface);
};
-// We are backed by an Pbuffer offscreen surface for the purposes of creating a
-// context, but use FBOs to render to X Pixmap backed EGLImages.
+// We render to an off-screen (but mapped) window that the browser process will
+// read from via XComposite
class GLXImageTransportSurface : public ImageTransportSurface,
public gfx::NativeViewGLSurfaceGLX {
public:
@@ -87,9 +90,10 @@ class GLXImageTransportSurface : public ImageTransportSurface,
protected:
// ImageTransportSurface implementation:
- void OnSetSurfaceACK(uint64 surface_id) OVERRIDE;
- void OnBuffersSwappedACK() OVERRIDE;
- void OnResize(gfx::Size size) OVERRIDE;
+ virtual void OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE;
+ virtual void OnBuffersSwappedACK() OVERRIDE;
+ virtual void OnResize(gfx::Size size) OVERRIDE;
private:
virtual ~GLXImageTransportSurface();
@@ -111,6 +115,47 @@ class GLXImageTransportSurface : public ImageTransportSurface,
DISALLOW_COPY_AND_ASSIGN(GLXImageTransportSurface);
};
+// We render to a hunk of shared memory that we get from the browser.
+// Swapping buffers simply means telling the browser to read the contents
+// of the memory.
+class OSMesaImageTransportSurface : public ImageTransportSurface,
+ public gfx::GLSurfaceOSMesa {
+ public:
+ OSMesaImageTransportSurface(GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id);
+
+ // gfx::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* GetHandle() OVERRIDE;
+
+ protected:
+ // ImageTransportSurface implementation:
+ virtual void OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) OVERRIDE;
+ virtual void OnBuffersSwappedACK() OVERRIDE;
+ virtual void OnResize(gfx::Size size) OVERRIDE;
+
+ private:
+ virtual ~OSMesaImageTransportSurface();
+
+ // Tell the browser to release the surface.
+ void ReleaseSurface();
+
+ scoped_ptr<TransportDIB> shared_mem_;
+ uint32 shared_id_;
+ gfx::Size size_;
+
+ scoped_ptr<ImageTransportHelper> helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(OSMesaImageTransportSurface);
+};
+
EGLImageTransportSurface::EGLImageTransportSurface(
GpuChannelManager* manager,
int32 render_view_id,
@@ -145,6 +190,8 @@ void EGLImageTransportSurface::Destroy() {
PbufferGLSurfaceEGL::Destroy();
}
+// Make sure that buffer swaps occur for the surface, so we can send the data
+// to the actual onscreen surface in the browser
bool EGLImageTransportSurface::IsOffscreen() {
return false;
}
@@ -189,11 +236,11 @@ void EGLImageTransportSurface::OnResize(gfx::Size size) {
0);
glFlush();
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
+ GpuHostMsg_AcceleratedSurfaceNew_Params params;
params.width = size.width();
params.height = size.height();
params.identifier = back_surface_->pixmap();
- helper_->SendAcceleratedSurfaceSetIOSurface(params);
+ helper_->SendAcceleratedSurfaceNew(params);
helper_->SetScheduled(false);
}
@@ -225,8 +272,8 @@ gfx::Size EGLImageTransportSurface::GetSize() {
return back_surface_->size();
}
-void EGLImageTransportSurface::OnSetSurfaceACK(
- uint64 surface_id) {
+void EGLImageTransportSurface::OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle /*surface_handle*/) {
DCHECK_EQ(back_surface_->pixmap(), surface_id);
helper_->SetScheduled(true);
}
@@ -331,11 +378,11 @@ void GLXImageTransportSurface::OnResize(gfx::Size size) {
XResizeWindow(dpy, window_, size_.width(), size_.height());
XFlush(dpy);
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
+ GpuHostMsg_AcceleratedSurfaceNew_Params params;
params.width = size_.width();
params.height = size_.height();
params.identifier = window_;
- helper_->SendAcceleratedSurfaceSetIOSurface(params);
+ helper_->SendAcceleratedSurfaceNew(params);
helper_->SetScheduled(false);
}
@@ -363,8 +410,8 @@ void GLXImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
}
}
-void GLXImageTransportSurface::OnSetSurfaceACK(
- uint64 surface_id) {
+void GLXImageTransportSurface::OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle /*surface_handle*/) {
DCHECK(!bound_);
bound_ = true;
helper_->SetScheduled(true);
@@ -374,6 +421,117 @@ void GLXImageTransportSurface::OnBuffersSwappedACK() {
helper_->SetScheduled(true);
}
+OSMesaImageTransportSurface::OSMesaImageTransportSurface(
+ GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id)
+ : gfx::GLSurfaceOSMesa(OSMESA_RGBA, gfx::Size(1, 1)),
+ size_(gfx::Size(1, 1)) {
+ helper_.reset(new ImageTransportHelper(this,
+ manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id));
+}
+
+OSMesaImageTransportSurface::~OSMesaImageTransportSurface() {
+ Destroy();
+}
+
+bool OSMesaImageTransportSurface::Initialize() {
+ if (!helper_->Initialize())
+ return false;
+ return gfx::GLSurfaceOSMesa::Initialize();
+}
+
+void OSMesaImageTransportSurface::Destroy() {
+ if (shared_mem_.get())
+ ReleaseSurface();
+
+ helper_->Destroy();
+ gfx::GLSurfaceOSMesa::Destroy();
+}
+
+// Make sure that buffer swaps occur for the surface, so we can send the data
+// to the actual onscreen surface in the browser
+bool OSMesaImageTransportSurface::IsOffscreen() {
+ return false;
+}
+
+void OSMesaImageTransportSurface::ReleaseSurface() {
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params;
+ params.identifier = shared_id_;
+ helper_->SendAcceleratedSurfaceRelease(params);
+
+ shared_mem_.reset();
+ shared_id_ = 0;
+}
+
+void OSMesaImageTransportSurface::OnResize(gfx::Size size) {
+ if (shared_mem_.get())
+ ReleaseSurface();
+
+ // Now that the shared memory buffer is gone, we need to change OSMesa to
+ // point at something valid, so we'll let it point to the buffer in the super
+ // class. This would be really bad since that buffer has a different size,
+ // but we don't allow any drawing to take place until we reset the surface
+ // back to a new buffer of shared memory.
+ helper_->MakeCurrent();
+
+ 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
+ helper_->SendAcceleratedSurfaceNew(params);
+
+ helper_->SetScheduled(false);
+}
+
+void OSMesaImageTransportSurface::OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) {
+ shared_id_ = surface_id;
+ shared_mem_.reset(TransportDIB::Map(surface_handle));
+ DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL));
+
+ // When we get the shared memory buffer back we can use that for OSMesa to
+ // write in, so we give it to OSMesa.
+ helper_->MakeCurrent();
+
+ helper_->SetScheduled(true);
+}
+
+bool OSMesaImageTransportSurface::SwapBuffers() {
+ DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL));
+
+ // Copy the OSMesa buffer to the shared memory
+ memcpy(shared_mem_->memory(), GetHandle(), size_.GetArea() * 4);
+
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
+ params.surface_id = shared_id_;
+ helper_->SendAcceleratedSurfaceBuffersSwapped(params);
+
+ helper_->SetScheduled(false);
+ return true;
+}
+
+void OSMesaImageTransportSurface::OnBuffersSwappedACK() {
+ helper_->SetScheduled(true);
+}
+
+gfx::Size OSMesaImageTransportSurface::GetSize() {
+ return size_;
+}
+
+void* OSMesaImageTransportSurface::GetHandle() {
+ if (shared_mem_.get())
+ return shared_mem_->memory();
+ else
+ return GLSurfaceOSMesa::GetHandle();
+}
+
} // namespace
// static
@@ -396,6 +554,12 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
renderer_id,
command_buffer_id);
break;
+ case gfx::kGLImplementationOSMesaGL:
+ surface = new OSMesaImageTransportSurface(manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id);
+ break;
default:
NOTREACHED();
return NULL;
@@ -441,8 +605,8 @@ void ImageTransportHelper::Destroy() {
bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
- IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_SetSurfaceACK,
- OnSetSurfaceACK)
+ IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_NewACK,
+ OnNewSurfaceACK)
IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BuffersSwappedACK,
OnBuffersSwappedACK)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -458,12 +622,12 @@ void ImageTransportHelper::SendAcceleratedSurfaceRelease(
manager_->Send(new GpuHostMsg_AcceleratedSurfaceRelease(params));
}
-void ImageTransportHelper::SendAcceleratedSurfaceSetIOSurface(
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params 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_AcceleratedSurfaceSetIOSurface(params));
+ manager_->Send(new GpuHostMsg_AcceleratedSurfaceNew(params));
}
void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped(
@@ -482,8 +646,9 @@ void ImageTransportHelper::SetScheduled(bool is_scheduled) {
scheduler->SetScheduled(is_scheduled);
}
-void ImageTransportHelper::OnSetSurfaceACK(uint64 surface_id) {
- surface_->OnSetSurfaceACK(surface_id);
+void ImageTransportHelper::OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) {
+ surface_->OnNewSurfaceACK(surface_id, surface_handle);
}
void ImageTransportHelper::OnBuffersSwappedACK() {
@@ -494,6 +659,13 @@ 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)
diff --git a/content/common/gpu/image_transport_surface_linux.h b/content/common/gpu/image_transport_surface_linux.h
index 3dddd959..b146ab0 100644
--- a/content/common/gpu/image_transport_surface_linux.h
+++ b/content/common/gpu/image_transport_surface_linux.h
@@ -12,12 +12,13 @@
#include "ipc/ipc_channel.h"
#include "ipc/ipc_message.h"
#include "ui/gfx/size.h"
+#include "ui/gfx/surface/transport_dib.h"
class GpuChannelManager;
-struct GpuHostMsg_AcceleratedSurfaceRelease_Params;
-struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params;
+struct GpuHostMsg_AcceleratedSurfaceNew_Params;
struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
+struct GpuHostMsg_AcceleratedSurfaceRelease_Params;
namespace gfx {
class GLSurface;
@@ -33,7 +34,8 @@ class GLES2Decoder;
class ImageTransportSurface {
public:
- virtual void OnSetSurfaceACK(uint64 surface_id) = 0;
+ virtual void OnNewSurfaceACK(
+ uint64 surface_id, TransportDIB::Handle surface_handle) = 0;
virtual void OnBuffersSwappedACK() = 0;
virtual void OnResize(gfx::Size size) = 0;
@@ -63,22 +65,25 @@ class ImageTransportHelper : public IPC::Channel::Listener {
// Helper send functions. Caller fills in the surface specific params
// like size and surface id. The helper fills in the rest.
- void SendAcceleratedSurfaceRelease(
- GpuHostMsg_AcceleratedSurfaceRelease_Params params);
- void SendAcceleratedSurfaceSetIOSurface(
- GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params);
+ 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 OnSetSurfaceACK(uint64 surface_id);
+ void OnNewSurfaceACK(uint64 surface_id, TransportDIB::Handle surface_handle);
void OnBuffersSwappedACK();
// Backbuffer resize callback.