Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Unified Diff: content/common/gpu/image_transport_surface_linux.cc

Issue 7980006: Implement OSMesa image transport for TOUCH_UI builds (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Rebase onto newer trunk Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/image_transport_surface_linux.cc
diff --git a/content/common/gpu/image_transport_surface_linux.cc b/content/common/gpu/image_transport_surface_linux.cc
index e0117e69172b1d55133d9953c0a8961de8a6f097..cb3b8434f43877ef9f5291a75f658a401891c15b 100644
--- a/content/common/gpu/image_transport_surface_linux.cc
+++ b/content/common/gpu/image_transport_surface_linux.cc
@@ -50,7 +50,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 +69,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 +88,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 +113,52 @@ class GLXImageTransportSurface : public ImageTransportSurface,
DISALLOW_COPY_AND_ASSIGN(GLXImageTransportSurface);
};
+// We render to an off-screen (but mapped) window, then dump its contents
+// into a shared memory buffer to get the memory to the browser compositor.
+// This is to replicate the behaviour of OSMesa, without using OSMesa for now.
+class GLXShmImageTransportSurface : public ImageTransportSurface,
+ public gfx::PbufferGLSurfaceGLX {
+ public:
+ GLXShmImageTransportSurface(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 OnMakeCurrent(gfx::GLContext* context) OVERRIDE;
+ virtual unsigned int GetBackingFrameBufferObject() 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 ~GLXShmImageTransportSurface();
+
+ // Tell the browser to release the surface.
+ void ReleaseSurface();
+
+ uint32 fbo_id_;
+ uint32 texture_;
+
+ gfx::Size size_;
+
+ scoped_ptr<TransportDIB> shared_mem_;
+ uint32 shared_id_;
+
+ scoped_ptr<ImageTransportHelper> helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLXShmImageTransportSurface);
+};
+
EGLImageTransportSurface::EGLImageTransportSurface(
GpuChannelManager* manager,
int32 render_view_id,
@@ -145,6 +193,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 +239,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 +275,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 +381,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 +413,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 +424,162 @@ void GLXImageTransportSurface::OnBuffersSwappedACK() {
helper_->SetScheduled(true);
}
+GLXShmImageTransportSurface::GLXShmImageTransportSurface(
+ GpuChannelManager* manager,
+ int32 render_view_id,
+ int32 renderer_id,
+ int32 command_buffer_id)
+ : gfx::PbufferGLSurfaceGLX(gfx::Size(1,1)),
+ size_(0, 0) {
+ helper_.reset(new ImageTransportHelper(this,
+ manager,
+ render_view_id,
+ renderer_id,
+ command_buffer_id));
+}
+
+GLXShmImageTransportSurface::~GLXShmImageTransportSurface() {
+ Destroy();
+}
+
+bool GLXShmImageTransportSurface::Initialize() {
+ if (!helper_->Initialize())
+ return false;
+ return gfx::PbufferGLSurfaceGLX::Initialize();
+}
+
+void GLXShmImageTransportSurface::Destroy() {
+ if (shared_mem_.get())
+ ReleaseSurface();
+
+ helper_->Destroy();
+ gfx::PbufferGLSurfaceGLX::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 GLXShmImageTransportSurface::IsOffscreen() {
+ return false;
+}
+
+void GLXShmImageTransportSurface::ReleaseSurface() {
+ GpuHostMsg_AcceleratedSurfaceRelease_Params params;
+ params.identifier = shared_id_;
+ helper_->SendAcceleratedSurfaceRelease(params);
+
+ shared_mem_.reset();
+ shared_id_ = 0;
+}
+
+void GLXShmImageTransportSurface::OnResize(gfx::Size size) {
+ LOG(ERROR) << "OnResize *********** " << size;
+ size_ = size;
+
+ if (shared_mem_.get())
+ ReleaseSurface();
+
+ // resize the texture
+ LOG(ERROR) << std::hex << "4 GLError: " << glGetError();
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ LOG(ERROR) << std::hex << "5 GLError: " << glGetError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+ size_.width(), size_.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ LOG(ERROR) << std::hex << "6 GLError: " << glGetError();
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
+ LOG(ERROR) << std::hex << "6.1 GLError: " << glGetError();
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ texture_,
+ 0);
+ LOG(ERROR) << std::hex << "7 GLError: " << glGetError();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glFlush();
+ LOG(ERROR) << std::hex << "7.1 GLError: " << glGetError();
+
+ 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 GLXShmImageTransportSurface::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));
+
+ helper_->SetScheduled(true);
+}
+
+bool GLXShmImageTransportSurface::SwapBuffers() {
+ DCHECK_NE(shared_mem_.get(), static_cast<void*>(NULL));
+
+ // grab the pixel data from the texture into the shared memory, and send
+ // it over to the browser
+ LOG(ERROR) << std::hex << "1 GLError: " << glGetError();
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ LOG(ERROR) << std::hex << "2 GLError: " << glGetError();
+ LOG(ERROR) << "glReadPixels ***************";
+ glReadPixels(0, 0, size_.width(), size_.height(),
+ GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory());
+ LOG(ERROR) << std::hex << "3 GLError: " << glGetError();
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glFlush();
+ LOG(ERROR) << std::hex << "3.1 GLError: " << glGetError();
+
+ GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
+ params.surface_id = shared_id_;
+ helper_->SendAcceleratedSurfaceBuffersSwapped(params);
+
+ helper_->SetScheduled(false);
+ return true;
+}
+
+gfx::Size GLXShmImageTransportSurface::GetSize() {
+ return size_;
+}
+
+unsigned int GLXShmImageTransportSurface::GetBackingFrameBufferObject() {
+ return fbo_id_;
+}
+
+void GLXShmImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
+ if (fbo_id_)
+ return;
+
+ LOG(ERROR) << std::hex << "8 GLError: " << glGetError();
+ glGenTextures(1, &texture_);
+ glBindTexture(GL_TEXTURE_2D, texture_);
jonathan.backer 2011/09/20 15:16:29 I think you can get rid of a bit of code duplicati
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ LOG(ERROR) << std::hex << "9 GLError: " << glGetError();
+
+ glGenFramebuffersEXT(1, &fbo_id_);
+ LOG(ERROR) << std::hex << "10 GLError: " << glGetError();
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_);
+ LOG(ERROR) << std::hex << "11 GLError: " << glGetError();
+
+ GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOG(ERROR) << "Framebuffer incomplete";
+ }
+ LOG(ERROR) << std::hex << "12 GLError: " << glGetError();
+}
+
+void GLXShmImageTransportSurface::OnBuffersSwappedACK() {
+ helper_->SetScheduled(true);
+}
+
} // namespace
// static
@@ -385,7 +591,7 @@ scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
scoped_refptr<gfx::GLSurface> surface;
switch (gfx::GetGLImplementation()) {
case gfx::kGLImplementationDesktopGL:
- surface = new GLXImageTransportSurface(manager,
+ surface = new GLXShmImageTransportSurface(manager,
render_view_id,
renderer_id,
command_buffer_id);
@@ -441,8 +647,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 +664,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 +688,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() {

Powered by Google App Engine
This is Rietveld 408576698