diff options
author | reveman@google.com <reveman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 20:54:37 +0000 |
---|---|---|
committer | reveman@google.com <reveman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 20:54:37 +0000 |
commit | 09d50362dfdeff4d370c6897890186bd48c5c63d (patch) | |
tree | 2dd2456badedae14492f4965ca204ecab38873ef /ui/gl | |
parent | ee429b55e3bcc64b8bbf63c1c01bbfc4f1402da2 (diff) | |
download | chromium_src-09d50362dfdeff4d370c6897890186bd48c5c63d.zip chromium_src-09d50362dfdeff4d370c6897890186bd48c5c63d.tar.gz chromium_src-09d50362dfdeff4d370c6897890186bd48c5c63d.tar.bz2 |
gpu: Add support for GLX_EXT_texture_from_pixmap extension.
Implement CHROMIUM_texture_from_image. This extension behaves just like
EXT_texture_from_pixmap but uses chromium specific image identifiers rather
than platform specific pixmap IDs.
Add IPC message for creating an image identifier using a
gfx::PluginWindowHandle. Each GPU channel maintains a different set of
images and deleting an image will cause the internal image representation
to be freed once it's no longer bound to a texture.
BUG=132342
TEST=gpu_unittests --gtest_filter=TextureInfoTest.GetLevelImage:GLES2DecoderTest.BindTexImage2DCHROMIUM:GLES2DecoderTest.ReleaseTexImage2DCHROMIUM and manual
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=162654
Review URL: https://codereview.chromium.org/10543125
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162784 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gl')
-rw-r--r-- | ui/gl/gl.gyp | 16 | ||||
-rw-r--r-- | ui/gl/gl_image.cc | 24 | ||||
-rw-r--r-- | ui/gl/gl_image.h | 50 | ||||
-rw-r--r-- | ui/gl/gl_image_android.cc | 27 | ||||
-rw-r--r-- | ui/gl/gl_image_glx.cc | 175 | ||||
-rw-r--r-- | ui/gl/gl_image_glx.h | 42 | ||||
-rw-r--r-- | ui/gl/gl_image_linux.cc | 38 | ||||
-rw-r--r-- | ui/gl/gl_image_mac.cc | 29 | ||||
-rw-r--r-- | ui/gl/gl_image_stub.cc | 25 | ||||
-rw-r--r-- | ui/gl/gl_image_stub.h | 27 | ||||
-rw-r--r-- | ui/gl/gl_image_win.cc | 29 | ||||
-rw-r--r-- | ui/gl/gl_surface_glx.cc | 8 | ||||
-rw-r--r-- | ui/gl/gl_surface_glx.h | 1 |
13 files changed, 491 insertions, 0 deletions
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index 85e4303..32d5e69 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp @@ -53,6 +53,14 @@ 'gl_export.h', 'gl_fence.cc', 'gl_fence.h', + 'gl_image.cc', + 'gl_image.h', + 'gl_image_android.cc', + 'gl_image_linux.cc', + 'gl_image_mac.cc', + 'gl_image_stub.cc', + 'gl_image_stub.h', + 'gl_image_win.cc', 'gl_implementation.cc', 'gl_implementation.h', 'gl_implementation_android.cc', @@ -143,6 +151,8 @@ 'sources': [ 'gl_context_glx.cc', 'gl_context_glx.h', + 'gl_image_glx.cc', + 'gl_image_glx.h', 'gl_surface_glx.cc', 'gl_surface_glx.h', '<(gl_binding_output_dir)/gl_bindings_autogen_glx.cc', @@ -153,6 +163,12 @@ 'GL_GLEXT_PROTOTYPES', ], }, + 'link_settings': { + 'libraries': [ + '-lX11', + '-lXcomposite', + ], + }, }], ['OS=="win"', { 'sources': [ diff --git a/ui/gl/gl_image.cc b/ui/gl/gl_image.cc new file mode 100644 index 0000000..aaefb94 --- /dev/null +++ b/ui/gl/gl_image.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2012 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. + +#include "ui/gl/gl_image.h" + +#include "base/logging.h" + +namespace gfx { + +GLImage::GLImage() {} + +bool GLImage::BindTexImage() { + NOTIMPLEMENTED(); + return false; +} + +void GLImage::ReleaseTexImage() { + NOTIMPLEMENTED(); +} + +GLImage::~GLImage() {} + +} // namespace gfx diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h new file mode 100644 index 0000000..8df7c71 --- /dev/null +++ b/ui/gl/gl_image.h @@ -0,0 +1,50 @@ +// Copyright (c) 2012 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 UI_GL_GL_IMAGE_H_ +#define UI_GL_GL_IMAGE_H_ + +#include "base/memory/ref_counted.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/gfx/size.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_export.h" + +namespace gfx { + +class GLSurface; + +// Encapsulates an image that can be bound to a texture, hiding platform +// specific management. +class GL_EXPORT GLImage : public base::RefCounted<GLImage> { + public: + GLImage(); + + // Destroys the image. + virtual void Destroy() = 0; + + // Get the size of the image. + virtual gfx::Size GetSize() = 0; + + // Bind image to texture currently bound to GL_TEXTURE_2D target. + virtual bool BindTexImage(); + + // Release image from texture currently bound to GL_TEXTURE_2D target. + virtual void ReleaseTexImage(); + + // Create a GL image for a window. + static scoped_refptr<GLImage> CreateGLImage(gfx::PluginWindowHandle window); + + protected: + virtual ~GLImage(); + + private: + friend class base::RefCounted<GLImage>; + + DISALLOW_COPY_AND_ASSIGN(GLImage); +}; + +} // namespace gfx + +#endif // UI_GL_GL_IMAGE_H_ diff --git a/ui/gl/gl_image_android.cc b/ui/gl/gl_image_android.cc new file mode 100644 index 0000000..e55e3bb --- /dev/null +++ b/ui/gl/gl_image_android.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2012 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. + +#include "ui/gl/gl_image.h" + +#include "base/debug/trace_event.h" +#include "ui/gl/gl_image_stub.h" +#include "ui/gl/gl_implementation.h" + +namespace gfx { + +scoped_refptr<GLImage> GLImage::CreateGLImage(gfx::PluginWindowHandle window) { + TRACE_EVENT0("gpu", "GLImage::CreateGLImage"); + switch (GetGLImplementation()) { + case kGLImplementationEGLGLES2: { + return NULL; + } + case kGLImplementationMockGL: + return new GLImageStub; + default: + NOTREACHED(); + return NULL; + } +} + +} // namespace gfx diff --git a/ui/gl/gl_image_glx.cc b/ui/gl/gl_image_glx.cc new file mode 100644 index 0000000..5bb4077 --- /dev/null +++ b/ui/gl/gl_image_glx.cc @@ -0,0 +1,175 @@ +// Copyright (c) 2012 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. + +extern "C" { +#include <X11/extensions/Xcomposite.h> +} + +#include "ui/gl/gl_image_glx.h" + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" +#include "ui/gl/gl_surface_glx.h" + +namespace gfx { + +namespace { + +// scoped_ptr functor for XFree(). Use as follows: +// scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); +// where "XVisualInfo" is any X type that is freed with XFree. +class ScopedPtrXFree { + public: + void operator()(void* x) const { + ::XFree(x); + } +}; + +int BindToTextureFormat(int depth) { + if (depth == 32) + return GLX_BIND_TO_TEXTURE_RGBA_EXT; + + return GLX_BIND_TO_TEXTURE_RGB_EXT; +} + +int TextureFormat(int depth) { + if (depth == 32) + return GLX_TEXTURE_FORMAT_RGBA_EXT; + + return GLX_TEXTURE_FORMAT_RGB_EXT; +} + +} // namespace anonymous + +GLImageGLX::GLImageGLX(gfx::PluginWindowHandle window) + : display_(base::MessagePumpForUI::GetDefaultXDisplay()), + window_(window), + pixmap_(0), + glx_pixmap_(0) { +} + +bool GLImageGLX::Initialize() { + if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) { + LOG(ERROR) << "GLX_EXT_texture_from_pixmap not supported."; + return false; + } + + XWindowAttributes attributes; + if (!XGetWindowAttributes(display_, window_, &attributes)) { + LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; + return false; + } + + XVisualInfo templ; + templ.visualid = XVisualIDFromVisual(attributes.visual); + int num_visinfo = 0; + scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visinfo( + XGetVisualInfo(display_, + VisualIDMask, + &templ, + &num_visinfo)); + if (!visinfo.get()) { + LOG(ERROR) << "XGetVisualInfo failed for visual id " << + templ.visualid << "."; + return false; + } + if (!num_visinfo) { + LOG(ERROR) << "XGetVisualInfo returned 0 elements."; + return false; + } + + int config_attribs[] = { + GLX_VISUAL_ID, visinfo->visualid, + GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, + GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_EXT, + BindToTextureFormat(visinfo->depth), GL_TRUE, + 0 + }; + int num_elements = 0; + scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config( + glXChooseFBConfig(display_, + DefaultScreen(display_), + config_attribs, + &num_elements)); + if (!config.get()) { + LOG(ERROR) << "glXChooseFBConfig failed."; + return false; + } + if (!num_elements) { + LOG(ERROR) << "glXChooseFBConfig returned 0 elements."; + return false; + } + + // Create backing pixmap reference. + pixmap_ = XCompositeNameWindowPixmap(display_, window_); + + XID root = 0; + int x = 0; + int y = 0; + unsigned int width = 0; + unsigned int height = 0; + unsigned int bw = 0; + unsigned int depth = 0; + if (!XGetGeometry( + display_, pixmap_, &root, &x, &y, &width, &height, &bw, &depth)) { + LOG(ERROR) << "XGetGeometry failed for pixmap " << pixmap_ << "."; + return false; + } + + int pixmap_attribs[] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, TextureFormat(visinfo->depth), + 0 + }; + glx_pixmap_ = glXCreatePixmap( + display_, + *config.get(), + pixmap_, + pixmap_attribs); + if (!glx_pixmap_) { + LOG(ERROR) << "glXCreatePixmap failed."; + return false; + } + + size_ = gfx::Size(width, height); + return true; +} + +void GLImageGLX::Destroy() { + if (glx_pixmap_) { + glXDestroyGLXPixmap(display_, glx_pixmap_); + glx_pixmap_ = 0; + } + if (pixmap_) { + XFreePixmap(display_, pixmap_); + pixmap_ = 0; + } +} + +gfx::Size GLImageGLX::GetSize() { + return size_; +} + +bool GLImageGLX::BindTexImage() { + if (!glx_pixmap_) + return false; + + glXBindTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, 0); + return true; +} + +void GLImageGLX::ReleaseTexImage() { + if (!glx_pixmap_) + return; + + glXReleaseTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); +} + +GLImageGLX::~GLImageGLX() { + Destroy(); +} + +} // namespace gfx diff --git a/ui/gl/gl_image_glx.h b/ui/gl/gl_image_glx.h new file mode 100644 index 0000000..a3cec2d --- /dev/null +++ b/ui/gl/gl_image_glx.h @@ -0,0 +1,42 @@ +// Copyright (c) 2012 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 UI_GL_GL_IMAGE_GLX_H_ +#define UI_GL_GL_IMAGE_GLX_H_ + +#include "ui/base/x/x11_util.h" +#include "ui/gfx/size.h" +#include "ui/gl/gl_export.h" +#include "ui/gl/gl_image.h" + +namespace gfx { + +class GL_EXPORT GLImageGLX : public GLImage { + public: + explicit GLImageGLX(gfx::PluginWindowHandle window); + + virtual bool Initialize(); + + // Implement GLImage. + virtual void Destroy() OVERRIDE; + virtual gfx::Size GetSize() OVERRIDE; + virtual bool BindTexImage() OVERRIDE; + virtual void ReleaseTexImage() OVERRIDE; + + protected: + virtual ~GLImageGLX(); + + private: + Display* display_; + gfx::PluginWindowHandle window_; + XID pixmap_; + XID glx_pixmap_; + gfx::Size size_; + + DISALLOW_COPY_AND_ASSIGN(GLImageGLX); +}; + +} // namespace gfx + +#endif // UI_GL_GL_IMAGE_GLX_H_ diff --git a/ui/gl/gl_image_linux.cc b/ui/gl/gl_image_linux.cc new file mode 100644 index 0000000..75efd2a --- /dev/null +++ b/ui/gl/gl_image_linux.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2012 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. + +#include "ui/gl/gl_image.h" + +#include "base/debug/trace_event.h" +#include "ui/gl/gl_image_glx.h" +#include "ui/gl/gl_image_stub.h" +#include "ui/gl/gl_implementation.h" + +namespace gfx { + +scoped_refptr<GLImage> GLImage::CreateGLImage(gfx::PluginWindowHandle window) { + TRACE_EVENT0("gpu", "GLImage::CreateGLImage"); + switch (GetGLImplementation()) { + case kGLImplementationOSMesaGL: { + return NULL; + } + case kGLImplementationDesktopGL: { + scoped_refptr<GLImageGLX> image(new GLImageGLX(window)); + if (!image->Initialize()) + return NULL; + + return image; + } + case kGLImplementationEGLGLES2: { + return NULL; + } + case kGLImplementationMockGL: + return new GLImageStub; + default: + NOTREACHED(); + return NULL; + } +} + +} // namespace gfx diff --git a/ui/gl/gl_image_mac.cc b/ui/gl/gl_image_mac.cc new file mode 100644 index 0000000..a4b522a --- /dev/null +++ b/ui/gl/gl_image_mac.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2012 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. + +#include "ui/gl/gl_image.h" + +#include "base/debug/trace_event.h" +#include "ui/gl/gl_image_stub.h" +#include "ui/gl/gl_implementation.h" + +namespace gfx { + +scoped_refptr<GLImage> GLImage::CreateGLImage(gfx::PluginWindowHandle window) { + TRACE_EVENT0("gpu", "GLImage::CreateGLImage"); + switch (GetGLImplementation()) { + case kGLImplementationOSMesaGL: + case kGLImplementationDesktopGL: + case kGLImplementationAppleGL: { + return NULL; + } + case kGLImplementationMockGL: + return new GLImageStub; + default: + NOTREACHED(); + return NULL; + } +} + +} // namespace gfx diff --git a/ui/gl/gl_image_stub.cc b/ui/gl/gl_image_stub.cc new file mode 100644 index 0000000..86efe6e --- /dev/null +++ b/ui/gl/gl_image_stub.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2012 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. + +#include "ui/gl/gl_image_stub.h" + +namespace gfx { + +void GLImageStub::Destroy() { +} + +gfx::Size GLImageStub::GetSize() { + return gfx::Size(1, 1); +} + +bool GLImageStub::BindTexImage() { + return true; +} + +void GLImageStub::ReleaseTexImage() { +} + +GLImageStub::~GLImageStub() {} + +} // namespace gfx diff --git a/ui/gl/gl_image_stub.h b/ui/gl/gl_image_stub.h new file mode 100644 index 0000000..8b47358 --- /dev/null +++ b/ui/gl/gl_image_stub.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 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 UI_GL_GL_IMAGE_STUB_H_ +#define UI_GL_GL_IMAGE_STUB_H_ + +#include "ui/gl/gl_image.h" + +namespace gfx { + +// A GLImage that does nothing for unit tests. +class GL_EXPORT GLImageStub : public GLImage { + public: + // Implement GLImage. + virtual void Destroy() OVERRIDE; + virtual gfx::Size GetSize() OVERRIDE; + virtual bool BindTexImage() OVERRIDE; + virtual void ReleaseTexImage() OVERRIDE; + + protected: + virtual ~GLImageStub(); +}; + +} // namespace gfx + +#endif // UI_GL_GL_IMAGE_STUB_H_ diff --git a/ui/gl/gl_image_win.cc b/ui/gl/gl_image_win.cc new file mode 100644 index 0000000..8c54bf4 --- /dev/null +++ b/ui/gl/gl_image_win.cc @@ -0,0 +1,29 @@ +// Copyright (c) 2012 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. + +#include "ui/gl/gl_image.h" + +#include "base/debug/trace_event.h" +#include "ui/gl/gl_image_stub.h" +#include "ui/gl/gl_implementation.h" + +namespace gfx { + +scoped_refptr<GLImage> GLImage::CreateGLImage(gfx::PluginWindowHandle window) { + TRACE_EVENT0("gpu", "GLImage::CreateGLImage"); + switch (GetGLImplementation()) { + case kGLImplementationOSMesaGL: + case kGLImplementationDesktopGL: + case kGLImplementationEGLGLES2: { + return NULL; + } + case kGLImplementationMockGL: + return new GLImageStub; + default: + NOTREACHED(); + return NULL; + } +} + +} // namespace gfx diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc index 8428cfc..6e16754 100644 --- a/ui/gl/gl_surface_glx.cc +++ b/ui/gl/gl_surface_glx.cc @@ -36,6 +36,7 @@ class ScopedPtrXFree { Display* g_display; const char* g_glx_extensions = NULL; bool g_glx_create_context_robustness_supported = false; +bool g_glx_texture_from_pixmap_supported = false; } // namespace @@ -66,6 +67,8 @@ bool GLSurfaceGLX::InitializeOneOff() { g_glx_extensions = glXQueryExtensionsString(g_display, 0); g_glx_create_context_robustness_supported = HasGLXExtension("GLX_ARB_create_context_robustness"); + g_glx_texture_from_pixmap_supported = + HasGLXExtension("GLX_EXT_texture_from_pixmap"); initialized = true; return true; @@ -86,6 +89,11 @@ bool GLSurfaceGLX::IsCreateContextRobustnessSupported() { return g_glx_create_context_robustness_supported; } +// static +bool GLSurfaceGLX::IsTextureFromPixmapSupported() { + return g_glx_texture_from_pixmap_supported; +} + void* GLSurfaceGLX::GetDisplay() { return g_display; } diff --git a/ui/gl/gl_surface_glx.h b/ui/gl/gl_surface_glx.h index 644b51b..0dc235c 100644 --- a/ui/gl/gl_surface_glx.h +++ b/ui/gl/gl_surface_glx.h @@ -27,6 +27,7 @@ class GL_EXPORT GLSurfaceGLX : public GLSurface { static const char* GetGLXExtensions(); static bool HasGLXExtension(const char* name); static bool IsCreateContextRobustnessSupported(); + static bool IsTextureFromPixmapSupported(); virtual void* GetDisplay() OVERRIDE; |