Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Unified Diff: content/browser/renderer_host/image_transport_client.cc

Issue 8307001: Enable accelerated compositing of web pages when using webkit compositor (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: rebase Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/image_transport_client.cc
diff --git a/content/browser/renderer_host/image_transport_client.cc b/content/browser/renderer_host/image_transport_client.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4d0c7fd3318b1a7613fecb0a2d087f1e0db125ec
--- /dev/null
+++ b/content/browser/renderer_host/image_transport_client.cc
@@ -0,0 +1,286 @@
+// Copyright (c) 2011 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 "content/browser/renderer_host/image_transport_client.h"
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xcomposite.h>
+
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "third_party/angle/include/EGL/egl.h"
+#include "third_party/angle/include/EGL/eglext.h"
+#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_implementation.h"
+#include "ui/gfx/gl/gl_surface_egl.h"
+#include "ui/gfx/gl/gl_surface_glx.h"
+#include "ui/gfx/size.h"
+
+namespace {
+
+class ScopedPtrXFree {
+ public:
+ void operator()(void* x) const {
+ ::XFree(x);
+ }
+};
+
+GLuint CreateTexture() {
+ GLuint texture;
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ 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);
+ return texture;
+}
+
+class ImageTransportClientEGL : public ImageTransportClient {
+ public:
+ explicit ImageTransportClientEGL(ui::SharedResources* resources)
+ : resources_(resources),
+ image_(NULL) {
+ }
+
+ virtual ~ImageTransportClientEGL() {
+ if (image_) {
+ resources_->MakeSharedContextCurrent();
+ eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_);
+ glFlush();
+ }
+ }
+
+ virtual unsigned int Initialize(uint64* surface_id) {
+ resources_->MakeSharedContextCurrent();
+ image_ = eglCreateImageKHR(
+ gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT,
+ EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_id), NULL);
+ if (!image_)
+ return 0;
+ GLuint texture = CreateTexture();
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_);
+ glFlush();
+ return texture;
+ }
+
+ virtual void Acquire() { }
+ virtual void Release() { }
+ virtual bool Flipped() { return true; }
+ virtual TransportDIB::Handle Handle() const {
+ return TransportDIB::DefaultHandleValue();
+ }
+
+ private:
+ ui::SharedResources* resources_;
+ EGLImageKHR image_;
+};
+
+class ImageTransportClientGLX : public ImageTransportClient {
+ public:
+ explicit ImageTransportClientGLX(ui::SharedResources* resources)
+ : resources_(resources),
+ pixmap_(0),
+ glx_pixmap_(0),
+ texture_(0) {
+ }
+
+ virtual ~ImageTransportClientGLX() {
+ Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
+ if (glx_pixmap_)
+ glXDestroyGLXPixmap(dpy, glx_pixmap_);
+ if (pixmap_)
+ XFreePixmap(dpy, pixmap_);
+ }
+
+ virtual unsigned int Initialize(uint64* surface_id) {
+ resources_->MakeSharedContextCurrent();
+ if (!InitializeOneOff())
+ return 0;
+
+ // 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();
+ pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_id);
+
+ const int pixmapAttribs[] = {
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
+ 0
+ };
+
+ glx_pixmap_ = glXCreatePixmap(dpy, fbconfig_.Get(), pixmap_, pixmapAttribs);
+
+ texture_ = CreateTexture();
+ return texture_;
+ }
+
+ virtual void Acquire() {
+ Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
+ }
+
+ virtual void Release() {
+ Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
+ glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT);
+ }
+
+ virtual bool Flipped() { return false; }
+ virtual TransportDIB::Handle Handle() const {
+ return TransportDIB::DefaultHandleValue();
+ }
+
+ private:
+ static bool InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ Display* dpy = gfx::GLSurfaceGLX::GetDisplay();
+
+ int event_base, error_base;
+ if (XCompositeQueryExtension(dpy, &event_base, &error_base)) {
+ int major = 0, minor = 2;
+ XCompositeQueryVersion(dpy, &major, &minor);
+ if (major == 0 && minor < 2) {
+ LOG(ERROR) << "Pixmap from window not supported.";
+ return false;
+ }
+ }
+ // Wrap the pixmap in a GLXPixmap
+ int screen = DefaultScreen(dpy);
+ XWindowAttributes gwa;
+ XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa);
+ unsigned int visualid = XVisualIDFromVisual(gwa.visual);
+
+ int nfbconfigs, config;
+ scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs(
+ glXGetFBConfigs(dpy, screen, &nfbconfigs));
+
+ for (config = 0; config < nfbconfigs; config++) {
+ XVisualInfo* visinfo = glXGetVisualFromFBConfig(
+ dpy, fbconfigs.get()[config]);
+ if (!visinfo || visinfo->visualid != visualid)
+ continue;
+
+ int value;
+ glXGetFBConfigAttrib(dpy,
+ fbconfigs.get()[config],
+ GLX_DRAWABLE_TYPE,
+ &value);
+ if (!(value & GLX_PIXMAP_BIT))
+ continue;
+
+ glXGetFBConfigAttrib(dpy,
+ fbconfigs.get()[config],
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT,
+ &value);
+ if (!(value & GLX_TEXTURE_2D_BIT_EXT))
+ continue;
+
+ glXGetFBConfigAttrib(dpy,
+ fbconfigs.get()[config],
+ GLX_BIND_TO_TEXTURE_RGB_EXT,
+ &value);
+ if (value == GL_FALSE)
+ continue;
+
+ break;
+ }
+
+ if (config == nfbconfigs) {
+ LOG(ERROR)
+ << "Could not find configuration suitable for binding a pixmap "
+ << "as a texture.";
+ return false;
+ }
+ fbconfig_.Get() = fbconfigs.get()[config];
+ initialized = true;
+ return initialized;
+ }
+
+ ui::SharedResources* resources_;
+ XID pixmap_;
+ XID glx_pixmap_;
+ GLuint texture_;
+ static base::LazyInstance<GLXFBConfig> fbconfig_;
+};
+
+base::LazyInstance<GLXFBConfig> ImageTransportClientGLX::fbconfig_(
+ base::LINKER_INITIALIZED);
+
+class ImageTransportClientOSMesa : public ImageTransportClient {
+ public:
+ ImageTransportClientOSMesa(ui::SharedResources* resources,
+ const gfx::Size& size)
+ : resources_(resources),
+ size_(size),
+ texture_(0) {
+ }
+
+ virtual ~ImageTransportClientOSMesa() {
+ }
+
+ virtual unsigned int Initialize(uint64* surface_id) {
+ // 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));
+ if (!shared_mem_.get())
+ return 0;
+
+ resources_->MakeSharedContextCurrent();
+ texture_ = CreateTexture();
+ return texture_;
+ }
+
+ virtual void Acquire() {
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ size_.width(), size_.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory());
+ }
+
+ virtual void Release() { }
+ virtual bool Flipped() { return false; }
+ virtual TransportDIB::Handle Handle() const { return shared_mem_->handle(); }
+
+ private:
+ ui::SharedResources* resources_;
+ gfx::Size size_;
+ scoped_ptr<TransportDIB> shared_mem_;
+ GLuint texture_;
+ static uint32 next_id_;
+};
+uint32 ImageTransportClientOSMesa::next_id_ = 0;
+
+} // anonymous namespace
+
+ImageTransportClient* ImageTransportClient::Create(
+ ui::SharedResources* resources,
+ const gfx::Size& size) {
+ switch (gfx::GetGLImplementation()) {
+ case gfx::kGLImplementationDesktopGL:
+ return new ImageTransportClientGLX(resources);
+ case gfx::kGLImplementationEGLGLES2:
+ return new ImageTransportClientEGL(resources);
+ case gfx::kGLImplementationOSMesaGL:
+ return new ImageTransportClientOSMesa(resources, size);
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
« no previous file with comments | « content/browser/renderer_host/image_transport_client.h ('k') | content/browser/renderer_host/render_widget_host_view_aura.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698