diff options
author | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 05:15:50 +0000 |
---|---|---|
committer | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 05:15:50 +0000 |
commit | f4ba36512524dc3150261942ec9a89b4dfb7364a (patch) | |
tree | e9f7e293728188a158b4156a03eb713f5eeebada /ui/gl/gl_image_glx.cc | |
parent | fcb0f644c83064a695588aa74d755aff74a51286 (diff) | |
download | chromium_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.cc | 175 |
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 |