summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/accelerated_surface_container_touch.cc396
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.cc19
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.h7
3 files changed, 413 insertions, 9 deletions
diff --git a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc
new file mode 100644
index 0000000..d7bb95a
--- /dev/null
+++ b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc
@@ -0,0 +1,396 @@
+// 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 "chrome/browser/renderer_host/accelerated_surface_container_touch.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/rect.h"
+#include "ui/gfx/transform.h"
+
+namespace {
+
+class AcceleratedSurfaceContainerTouchEGL
+ : public AcceleratedSurfaceContainerTouch {
+ public:
+ 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;
+
+ private:
+ virtual ~AcceleratedSurfaceContainerTouchEGL();
+
+ void* image_;
+
+ DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchEGL);
+};
+
+class AcceleratedSurfaceContainerTouchGLX
+ : public AcceleratedSurfaceContainerTouch {
+ public:
+ 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;
+
+ protected:
+ static bool InitializeOneOff();
+
+ static base::LazyInstance<GLXFBConfig> fbconfig_;
+
+ private:
+ virtual ~AcceleratedSurfaceContainerTouchGLX();
+
+ XID pixmap_;
+ XID glx_pixmap_;
+
+ 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 gives the handle
+ // to the shared buffer, which is part of the surface container.
+ // When shared memory is not used, this will return
+ // TransportDIB::DefaultHandleValue().
+ virtual TransportDIB::Handle Handle() const OVERRIDE;
+
+ private:
+ virtual ~AcceleratedSurfaceContainerTouchOSMesa();
+
+ scoped_ptr<TransportDIB> shared_mem_;
+
+ DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchOSMesa);
+};
+
+class ScopedPtrXFree {
+ public:
+ void operator()(void* x) const {
+ ::XFree(x);
+ }
+};
+
+// static
+base::LazyInstance<GLXFBConfig> AcceleratedSurfaceContainerTouchGLX::fbconfig_(
+ base::LINKER_INITIALIZED);
+
+AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL(
+ 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_id), NULL);
+
+ 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);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_);
+ glFlush();
+
+ return true;
+}
+
+AcceleratedSurfaceContainerTouchEGL::~AcceleratedSurfaceContainerTouchEGL() {
+ ui::SharedResources* instance = ui::SharedResources::GetInstance();
+ DCHECK(instance);
+ instance->MakeSharedContextCurrent();
+
+ eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_);
+ glFlush();
+}
+
+void AcceleratedSurfaceContainerTouchEGL::Draw(
+ const ui::TextureDrawParams& params,
+ const gfx::Rect& clip_bounds_in_texture) {
+ ui::SharedResources* instance = ui::SharedResources::GetInstance();
+ DCHECK(instance);
+
+ ui::TextureDrawParams modified_params = params;
+ modified_params.vertically_flipped = true;
+
+ DrawInternal(*instance->program_no_swizzle(),
+ modified_params,
+ clip_bounds_in_texture);
+}
+
+AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX(
+ 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();
+
+ if (!AcceleratedSurfaceContainerTouchGLX::InitializeOneOff())
+ return false;
+
+ // 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 = static_cast<Display*>(instance->GetDisplay());
+ pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_id);
+
+ // Wrap the pixmap in a GLXPixmap
+ 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);
+
+ // 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);
+
+ return true;
+}
+
+AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() {
+ ui::SharedResources* instance = ui::SharedResources::GetInstance();
+ DCHECK(instance);
+ instance->MakeSharedContextCurrent();
+
+ Display* dpy = static_cast<Display*>(instance->GetDisplay());
+ if (glx_pixmap_)
+ glXDestroyGLXPixmap(dpy, glx_pixmap_);
+ if (pixmap_)
+ XFreePixmap(dpy, pixmap_);
+}
+
+void AcceleratedSurfaceContainerTouchGLX::Draw(
+ const ui::TextureDrawParams& params,
+ const gfx::Rect& clip_bounds_in_texture) {
+ ui::SharedResources* instance = ui::SharedResources::GetInstance();
+ DCHECK(instance);
+
+ Display* dpy = static_cast<Display*>(instance->GetDisplay());
+
+ glBindTexture(GL_TEXTURE_2D, texture_id_);
+ glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL);
+ DrawInternal(*instance->program_no_swizzle(),
+ params,
+ clip_bounds_in_texture);
+ glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT);
+}
+
+// static
+bool AcceleratedSurfaceContainerTouchGLX::InitializeOneOff()
+{
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ ui::SharedResources* instance = ui::SharedResources::GetInstance();
+ DCHECK(instance);
+
+ Display* dpy = static_cast<Display*>(instance->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;
+}
+
+AcceleratedSurfaceContainerTouchOSMesa::AcceleratedSurfaceContainerTouchOSMesa(
+ const gfx::Size& size)
+ : AcceleratedSurfaceContainerTouch(size) {
+}
+
+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;
+}
+
+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);
+ }
+}
+
+TransportDIB::Handle AcceleratedSurfaceContainerTouchOSMesa::Handle() const {
+ if (shared_mem_.get())
+ return shared_mem_->handle();
+ else
+ return TransportDIB::DefaultHandleValue();
+}
+
+AcceleratedSurfaceContainerTouchOSMesa::
+ ~AcceleratedSurfaceContainerTouchOSMesa() {
+}
+
+} // 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) {
+ switch (gfx::GetGLImplementation()) {
+ case gfx::kGLImplementationDesktopGL:
+ return new AcceleratedSurfaceContainerTouchGLX(size);
+ case gfx::kGLImplementationEGLGLES2:
+ return new AcceleratedSurfaceContainerTouchEGL(size);
+ case gfx::kGLImplementationOSMesaGL:
+ return new AcceleratedSurfaceContainerTouchOSMesa(size);
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+void AcceleratedSurfaceContainerTouch::SetCanvas(
+ const SkCanvas& canvas,
+ const gfx::Point& origin,
+ const gfx::Size& overall_size) {
+ NOTREACHED();
+}
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.cc b/chrome/browser/renderer_host/render_widget_host_view_views.cc
index 98bf72a..69e9be4 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_views.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc
@@ -1144,19 +1144,20 @@ void RenderWidgetHostViewViews::AcceleratedSurfaceRelease(uint64 surface_id) {
}
void RenderWidgetHostViewViews::AcceleratedSurfaceBuffersSwapped(
- uint64 surface_id,
- int32 route_id,
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
int gpu_host_id) {
- SetExternalTexture(accelerated_surface_containers_[surface_id]->GetTexture());
+ SetExternalTexture(
+ accelerated_surface_containers_[params.surface_id]->GetTexture());
glFlush();
if (!GetWidget() || !GetWidget()->GetCompositor()) {
// We have no compositor, so we have no way to display the surface
- AcknowledgeSwapBuffers(route_id, gpu_host_id); // Must still send the ACK
+ // Must still send the ACK
+ AcknowledgeSwapBuffers(params.route_id, gpu_host_id);
} else {
// Add sending an ACK to the list of things to do OnCompositingEnded
on_compositing_ended_callbacks_.push_back(
- base::Bind(AcknowledgeSwapBuffers, route_id, gpu_host_id));
+ base::Bind(AcknowledgeSwapBuffers, params.route_id, gpu_host_id));
ui::Compositor *compositor = GetWidget()->GetCompositor();
if (!compositor->HasObserver(this))
compositor->AddObserver(this);
@@ -1173,4 +1174,12 @@ void RenderWidgetHostViewViews::OnCompositingEnded(ui::Compositor* compositor) {
compositor->RemoveObserver(this);
}
+#else
+
+void RenderWidgetHostViewViews::AcceleratedSurfaceBuffersSwapped(
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
+ int gpu_host_id) {
+ NOTREACHED();
+}
+
#endif
diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.h b/chrome/browser/renderer_host/render_widget_host_view_views.h
index 083e2ae..ae0ef11 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_views.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_views.h
@@ -99,6 +99,9 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView,
virtual void ShowingContextMenu(bool showing) OVERRIDE;
virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE;
virtual void OnAcceleratedCompositingStateChange() OVERRIDE;
+ virtual void AcceleratedSurfaceBuffersSwapped(
+ const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
+ int gpu_host_id) OVERRIDE;
virtual void SetBackground(const SkBitmap& background) OVERRIDE;
#if defined(OS_POSIX) || defined(USE_AURA)
virtual void GetDefaultScreenInfo(WebKit::WebScreenInfo* results);
@@ -187,10 +190,6 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView,
int32 height,
uint64* surface_id,
TransportDIB::Handle* surface_handle) OVERRIDE;
- virtual void AcceleratedSurfaceBuffersSwapped(
- uint64 surface_id,
- int32 route_id,
- int gpu_host_id) OVERRIDE;
virtual void AcceleratedSurfaceRelease(uint64 surface_id) OVERRIDE;
// CompositorObserver implementation: