summaryrefslogtreecommitdiffstats
path: root/ui/gl/gl_image_glx.cc
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-18 05:15:50 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-18 05:15:50 +0000
commitf4ba36512524dc3150261942ec9a89b4dfb7364a (patch)
treee9f7e293728188a158b4156a03eb713f5eeebada /ui/gl/gl_image_glx.cc
parentfcb0f644c83064a695588aa74d755aff74a51286 (diff)
downloadchromium_src-f4ba36512524dc3150261942ec9a89b4dfb7364a.zip
chromium_src-f4ba36512524dc3150261942ec9a89b4dfb7364a.tar.gz
chromium_src-f4ba36512524dc3150261942ec9a89b4dfb7364a.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 Review URL: https://chromiumcodereview.appspot.com/10543125 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162654 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gl/gl_image_glx.cc')
-rw-r--r--ui/gl/gl_image_glx.cc175
1 files changed, 175 insertions, 0 deletions
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