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..d6ff1ca415de9774e9aa04b0b15d4475425971d5 100644 |
--- a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
+++ b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
@@ -22,8 +22,10 @@ namespace { |
class AcceleratedSurfaceContainerTouchEGL |
: public AcceleratedSurfaceContainerTouch { |
public: |
- AcceleratedSurfaceContainerTouchEGL(const gfx::Size& size, |
- uint64 surface_handle); |
+ explicit AcceleratedSurfaceContainerTouchEGL(const gfx::Size& size); |
+ |
+ virtual bool Initialize(uint64 *surface_id) OVERRIDE; |
+ |
// TextureGL implementation |
virtual void Draw(const ui::TextureDrawParams& params, |
const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
@@ -39,8 +41,10 @@ class AcceleratedSurfaceContainerTouchEGL |
class AcceleratedSurfaceContainerTouchGLX |
: public AcceleratedSurfaceContainerTouch { |
public: |
- AcceleratedSurfaceContainerTouchGLX(const gfx::Size& size, |
- uint64 surface_handle); |
+ explicit AcceleratedSurfaceContainerTouchGLX(const gfx::Size& size); |
+ |
+ virtual bool Initialize(uint64 *surface_id) OVERRIDE; |
+ |
// TextureGL implementation |
virtual void Draw(const ui::TextureDrawParams& params, |
const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
@@ -54,6 +58,29 @@ class AcceleratedSurfaceContainerTouchGLX |
DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX); |
}; |
+class AcceleratedSurfaceContainerTouchOSMesa |
+ : public AcceleratedSurfaceContainerTouch { |
+ public: |
+ explicit AcceleratedSurfaceContainerTouchOSMesa(const gfx::Size& size); |
+ |
+ virtual bool Initialize(uint64 *surface_id) OVERRIDE; |
+ |
+ // TextureGL implementation |
+ virtual void Draw(const ui::TextureDrawParams& params, |
+ const gfx::Rect& clip_bounds_in_texture) 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: |
+ ~AcceleratedSurfaceContainerTouchOSMesa(); |
+ |
+ scoped_ptr<TransportDIB> shared_mem_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchOSMesa); |
+}; |
+ |
class ScopedPtrXFree { |
public: |
void operator()(void* x) const { |
@@ -62,17 +89,19 @@ class ScopedPtrXFree { |
}; |
AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
- const gfx::Size& size, |
- uint64 surface_handle) |
+ const gfx::Size& size) |
: AcceleratedSurfaceContainerTouch(size), |
image_(NULL) { |
+} |
+ |
+bool AcceleratedSurfaceContainerTouchEGL::Initialize(uint64 *surface_id) { |
ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
DCHECK(instance); |
instance->MakeSharedContextCurrent(); |
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_); |
@@ -82,6 +111,8 @@ AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); |
glFlush(); |
+ |
+ return true; |
} |
AcceleratedSurfaceContainerTouchEGL::~AcceleratedSurfaceContainerTouchEGL() { |
@@ -115,16 +146,21 @@ void AcceleratedSurfaceContainerTouchEGL::Draw( |
} |
AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
- const gfx::Size& size, |
- uint64 surface_handle) |
+ const gfx::Size& size) |
: AcceleratedSurfaceContainerTouch(size), |
pixmap_(0), |
glx_pixmap_(0) { |
+} |
+ |
+bool AcceleratedSurfaceContainerTouchGLX::Initialize(uint64 *surface_id) { |
ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
DCHECK(instance); |
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. |
jonathan.backer
2011/09/21 20:27:36
Thanks.
|
Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
int event_base, error_base; |
if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { |
@@ -132,10 +168,10 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
XCompositeQueryVersion(dpy, &major, &minor); |
if (major == 0 && minor < 2) { |
LOG(ERROR) << "Pixmap from window not supported."; |
- return; |
+ return false; |
} |
} |
- pixmap_ = XCompositeNameWindowPixmap(dpy, surface_handle); |
+ pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_id); |
// Wrap the pixmap in a GLXPixmap |
int screen = DefaultScreen(dpy); |
@@ -182,7 +218,7 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
LOG(ERROR) |
<< "Could not find configuration suitable for binding a pixmap " |
<< "as a texture."; |
- return; |
+ return false; |
} |
const int pixmapAttribs[] = { |
@@ -201,6 +237,8 @@ AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
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); |
+ |
+ return true; |
} |
AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() { |
@@ -231,24 +269,94 @@ void AcceleratedSurfaceContainerTouchGLX::Draw( |
glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
} |
+AcceleratedSurfaceContainerTouchOSMesa::AcceleratedSurfaceContainerTouchOSMesa( |
+ const gfx::Size& size) |
+ : AcceleratedSurfaceContainerTouch(size), |
+ shared_mem_(0) { |
+} |
+ |
+bool AcceleratedSurfaceContainerTouchOSMesa::Initialize(uint64 *surface_id) { |
+ 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. |
+ *surface_id = next_id++; |
+ |
+ shared_mem_.reset( |
+ TransportDIB::Create(size_.GetArea() * 4, // GL_RGBA=4 B/px |
+ *surface_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); |
+ |
+ // we generate the ID to be used here. |
+ return true; |
+} |
+ |
+AcceleratedSurfaceContainerTouchOSMesa:: |
+ ~AcceleratedSurfaceContainerTouchOSMesa() { |
+} |
+ |
+TransportDIB::Handle AcceleratedSurfaceContainerTouchOSMesa::handle() const { |
+ if (shared_mem_.get()) |
+ return shared_mem_->handle(); |
+ else |
+ return TransportDIB::DefaultHandleValue(); |
+} |
+ |
+ |
+void AcceleratedSurfaceContainerTouchOSMesa::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()); |
+ |
+ DrawInternal(*instance->program_no_swizzle(), |
+ params, |
+ clip_bounds_in_texture); |
+ } |
+} |
+ |
} // namespace |
AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
const gfx::Size& size) : TextureGL(size) { |
} |
+TransportDIB::Handle AcceleratedSurfaceContainerTouch::handle() const { |
+ return TransportDIB::DefaultHandleValue(); |
+} |
+ |
// static |
AcceleratedSurfaceContainerTouch* |
AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( |
- const gfx::Size& size, |
- uint64 surface_handle) { |
+ const gfx::Size& size) { |
switch (gfx::GetGLImplementation()) { |
case gfx::kGLImplementationDesktopGL: |
- return new AcceleratedSurfaceContainerTouchGLX(size, |
- surface_handle); |
+ return new AcceleratedSurfaceContainerTouchGLX(size); |
case gfx::kGLImplementationEGLGLES2: |
- return new AcceleratedSurfaceContainerTouchEGL(size, |
- surface_handle); |
+ return new AcceleratedSurfaceContainerTouchEGL(size); |
+ case gfx::kGLImplementationOSMesaGL: |
+ return new AcceleratedSurfaceContainerTouchOSMesa(size); |
default: |
NOTREACHED(); |
return NULL; |