Index: chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
index ab0db73c1e1308ab1bb2de674dd91788db9090b3..ca8217c4ce049125cef17b4a1e2dcbe571388126 100644 |
--- a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
+++ b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
@@ -23,7 +23,7 @@ class AcceleratedSurfaceContainerTouchEGL |
: public AcceleratedSurfaceContainerTouch { |
public: |
AcceleratedSurfaceContainerTouchEGL(const gfx::Size& size, |
- uint64 surface_handle); |
+ uint64 surface_id); |
// TextureGL implementation |
virtual void Draw(const ui::TextureDrawParams& params, |
const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
@@ -40,7 +40,7 @@ class AcceleratedSurfaceContainerTouchGLX |
: public AcceleratedSurfaceContainerTouch { |
public: |
AcceleratedSurfaceContainerTouchGLX(const gfx::Size& size, |
- uint64 surface_handle); |
+ uint64 surface_id); |
// TextureGL implementation |
virtual void Draw(const ui::TextureDrawParams& params, |
const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
@@ -54,6 +54,30 @@ class AcceleratedSurfaceContainerTouchGLX |
DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX); |
}; |
+class AcceleratedSurfaceContainerTouchGLXShm |
+ : public AcceleratedSurfaceContainerTouch { |
+ public: |
+ AcceleratedSurfaceContainerTouchGLXShm(const gfx::Size& size, |
+ uint64 surface_handle); |
+ // TextureGL implementation |
+ virtual void Draw(const ui::TextureDrawParams& params, |
+ const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
+ |
+ virtual uint64 id() const OVERRIDE; |
+ |
+ // Some implementations of this class use shared memory, this the handle |
+ // to the shared buffer, which is part of the surface container. |
+ virtual TransportDIB::Handle handle() const OVERRIDE; |
+ |
+ private: |
+ ~AcceleratedSurfaceContainerTouchGLXShm(); |
+ |
+ uint64 id_; |
+ scoped_ptr<TransportDIB> shared_mem_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLXShm); |
+}; |
+ |
class ScopedPtrXFree { |
public: |
void operator()(void* x) const { |
@@ -63,8 +87,8 @@ class ScopedPtrXFree { |
AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
const gfx::Size& size, |
- uint64 surface_handle) |
- : AcceleratedSurfaceContainerTouch(size), |
+ uint64 surface_id) |
+ : AcceleratedSurfaceContainerTouch(size, surface_id), |
image_(NULL) { |
ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
DCHECK(instance); |
@@ -72,7 +96,7 @@ AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
image_ = eglCreateImageKHR( |
gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, |
- EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(surface_handle), NULL); |
+ EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(surface_id), NULL); |
glGenTextures(1, &texture_id_); |
glBindTexture(GL_TEXTURE_2D, texture_id_); |
@@ -116,8 +140,8 @@ void AcceleratedSurfaceContainerTouchEGL::Draw( |
AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
const gfx::Size& size, |
- uint64 surface_handle) |
- : AcceleratedSurfaceContainerTouch(size), |
+ uint64 surface_id) |
+ : AcceleratedSurfaceContainerTouch(size, surface_id), |
pixmap_(0), |
glx_pixmap_(0) { |
ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
@@ -125,6 +149,9 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
instance->MakeSharedContextCurrent(); |
// Create pixmap from window. |
+ // We receive a window here rather than a pixmap directly because drivers |
+ // require (or required) that the pixmap used to create the GL texture be |
+ // created in the same process as the texture. |
Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
int event_base, error_base; |
if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { |
@@ -135,7 +162,7 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
return; |
} |
} |
- pixmap_ = XCompositeNameWindowPixmap(dpy, surface_handle); |
+ pixmap_ = XCompositeNameWindowPixmap(dpy, surface_id); |
// Wrap the pixmap in a GLXPixmap |
int screen = DefaultScreen(dpy); |
@@ -231,24 +258,112 @@ void AcceleratedSurfaceContainerTouchGLX::Draw( |
glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
} |
+AcceleratedSurfaceContainerTouchGLXShm::AcceleratedSurfaceContainerTouchGLXShm( |
+ const gfx::Size& size, |
+ uint64 surface_id) |
+ : AcceleratedSurfaceContainerTouch(size, surface_id), |
+ id_(0), |
+ shared_mem_(0) { |
+ static uint32 next_id = 1; |
+ |
+ ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
+ DCHECK(instance); |
+ instance->MakeSharedContextCurrent(); |
+ |
+ // We expect to make the id here, so don't want the other end giving us one |
+ DCHECK_EQ(surface_id, static_cast<uint64>(0)); |
+ |
+ // It's possible that this ID gneration could clash with IDs from other |
+ // AcceleratedSurfaceContainerTouch* objects, however we should never have |
+ // ids active from more than one type at the same time, so we have free |
+ // reign of the id namespace. |
+ shared_mem_.reset( |
+ TransportDIB::Create(size.width() * size.height() * 4, // GL_RGBA=4 B/px |
+ next_id)); |
+ id_ = next_id++; |
+ |
+ // Create texture. |
+ glGenTextures(1, &texture_id_); |
+ glBindTexture(GL_TEXTURE_2D, texture_id_); |
+ 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); |
+} |
+ |
+AcceleratedSurfaceContainerTouchGLXShm:: |
+ ~AcceleratedSurfaceContainerTouchGLXShm() { |
+} |
+ |
+uint64 AcceleratedSurfaceContainerTouchGLXShm::id() const { |
+ return id_; |
+} |
+ |
+ |
+TransportDIB::Handle AcceleratedSurfaceContainerTouchGLXShm::handle() const { |
+ if (shared_mem_.get()) |
+ return shared_mem_->handle(); |
+ else |
+ return TransportDIB::DefaultHandleValue(); |
+} |
+ |
+ |
+void AcceleratedSurfaceContainerTouchGLXShm::Draw( |
+ const ui::TextureDrawParams& params, |
+ const gfx::Rect& clip_bounds_in_texture) { |
+ ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
+ DCHECK(instance); |
+ |
+ if (shared_mem_.get()) { |
+ glBindTexture(GL_TEXTURE_2D, texture_id_); |
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
+ size_.width(), size_.height(), 0, |
+ GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory()); |
+ |
+ ui::TextureDrawParams modified_params = params; |
+ |
+ // Texture from GPU is flipped vertically. |
+ ui::Transform flipped; |
+ flipped.SetScaleY(-1.0); |
+ flipped.SetTranslateY(size_.height()); |
+ flipped.ConcatTransform(params.transform); |
+ |
+ modified_params.transform = flipped; |
+ |
+ DrawInternal(*instance->program_no_swizzle(), |
+ modified_params, |
+ clip_bounds_in_texture); |
+ } |
+} |
+ |
} // namespace |
AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
- const gfx::Size& size) : TextureGL(size) { |
+ const gfx::Size& size, |
+ uint64 surface_id) : TextureGL(size) { |
+ id_ = surface_id; |
+} |
+ |
+uint64 AcceleratedSurfaceContainerTouch::id() const { |
+ return id_; |
+} |
+ |
+TransportDIB::Handle AcceleratedSurfaceContainerTouch::handle() const { |
+ return TransportDIB::DefaultHandleValue(); |
} |
// static |
AcceleratedSurfaceContainerTouch* |
AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( |
const gfx::Size& size, |
- uint64 surface_handle) { |
+ uint64 surface_id) { |
switch (gfx::GetGLImplementation()) { |
case gfx::kGLImplementationDesktopGL: |
- return new AcceleratedSurfaceContainerTouchGLX(size, |
- surface_handle); |
+ return new AcceleratedSurfaceContainerTouchGLXShm(size, |
+ surface_id); |
case gfx::kGLImplementationEGLGLES2: |
return new AcceleratedSurfaceContainerTouchEGL(size, |
- surface_handle); |
+ surface_id); |
default: |
NOTREACHED(); |
return NULL; |