summaryrefslogtreecommitdiffstats
path: root/ui/gfx/gl/gl_context_linux.cc
diff options
context:
space:
mode:
authorantonm@chromium.org <antonm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-12 13:37:32 +0000
committerantonm@chromium.org <antonm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-12 13:37:32 +0000
commit82642bb1c9402e67e46e0a48bdc075fd505fa36d (patch)
treecdbf1eea862acdbc63634ba23e3a8b921bbf72bf /ui/gfx/gl/gl_context_linux.cc
parentcc12116ee5640dcca9507900f259ed6d6ed4542b (diff)
downloadchromium_src-82642bb1c9402e67e46e0a48bdc075fd505fa36d.zip
chromium_src-82642bb1c9402e67e46e0a48bdc075fd505fa36d.tar.gz
chromium_src-82642bb1c9402e67e46e0a48bdc075fd505fa36d.tar.bz2
Revert "Reland 85013 - Split GLContext::Create*GLContext into GLSurface::Create*GLSurface plus a
surface type independent GLContext::CreateGLContext". git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85124 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx/gl/gl_context_linux.cc')
-rw-r--r--ui/gfx/gl/gl_context_linux.cc316
1 files changed, 297 insertions, 19 deletions
diff --git a/ui/gfx/gl/gl_context_linux.cc b/ui/gfx/gl/gl_context_linux.cc
index 3db60f3..deac474 100644
--- a/ui/gfx/gl/gl_context_linux.cc
+++ b/ui/gfx/gl/gl_context_linux.cc
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/gl/gl_context.h"
+#include <GL/osmesa.h>
+#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "third_party/mesa/MesaLib/include/GL/osmesa.h"
+#include "ui/base/x/x11_util.h"
#include "ui/gfx/gl/gl_bindings.h"
+#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_context_egl.h"
#include "ui/gfx/gl/gl_context_glx.h"
#include "ui/gfx/gl/gl_context_osmesa.h"
@@ -15,45 +16,322 @@
#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/gl/gl_surface_stub.h"
#include "ui/gfx/gl/gl_surface_osmesa.h"
namespace gfx {
-GLContext* GLContext::CreateGLContext(GLSurface* compatible_surface,
- GLContext* shared_context) {
- scoped_ptr<GLSurface> surface(compatible_surface);
+namespace {
+Display* g_osmesa_display;
+} // namespace anonymous
+
+// This OSMesa GL surface can use XLib to swap the contents of the buffer to a
+// view.
+class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
+ public:
+ explicit NativeViewGLSurfaceOSMesa(gfx::PluginWindowHandle window);
+ virtual ~NativeViewGLSurfaceOSMesa();
+
+ static bool InitializeOneOff();
+
+ // Initializes the GL context.
+ bool Initialize();
+
+ // Implement a subset of GLSurface.
+ virtual void Destroy();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+
+ private:
+ bool UpdateSize();
+
+ GC window_graphics_context_;
+ gfx::PluginWindowHandle window_;
+ GC pixmap_graphics_context_;
+ Pixmap pixmap_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
+};
+
+bool GLContext::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ static const GLImplementation kAllowedGLImplementations[] = {
+ kGLImplementationDesktopGL,
+ kGLImplementationEGLGLES2,
+ kGLImplementationOSMesaGL
+ };
+
+ if (!InitializeRequestedGLBindings(
+ kAllowedGLImplementations,
+ kAllowedGLImplementations + arraysize(kAllowedGLImplementations),
+ kGLImplementationDesktopGL)) {
+ LOG(ERROR) << "InitializeRequestedGLBindings failed.";
+ return false;
+ }
switch (GetGLImplementation()) {
- case kGLImplementationOSMesaGL: {
- scoped_ptr<GLContextOSMesa> context(
- new GLContextOSMesa(static_cast<GLSurfaceOSMesa*>(
- surface.release())));
- if (!context->Initialize(OSMESA_RGBA, shared_context))
+ case kGLImplementationDesktopGL:
+ if (!GLSurfaceGLX::InitializeOneOff()) {
+ LOG(ERROR) << "GLSurfaceGLX::InitializeOneOff failed.";
+ return false;
+ }
+ break;
+ case kGLImplementationEGLGLES2:
+ if (!GLSurfaceEGL::InitializeOneOff()) {
+ LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
+ return false;
+ }
+ break;
+ case kGLImplementationOSMesaGL:
+ if (!NativeViewGLSurfaceOSMesa::InitializeOneOff()) {
+ LOG(ERROR) << "NativeViewGLSurfaceOSMesa::InitializeOneOff failed.";
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ initialized = true;
+ return true;
+}
+
+NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa(
+ gfx::PluginWindowHandle window)
+ : window_graphics_context_(0),
+ window_(window),
+ pixmap_graphics_context_(0),
+ pixmap_(0) {
+ DCHECK(window);
+}
+
+NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() {
+ Destroy();
+}
+
+bool NativeViewGLSurfaceOSMesa::InitializeOneOff() {
+ static bool initialized = false;
+ if (initialized)
+ return true;
+
+ g_osmesa_display = XOpenDisplay(NULL);
+ if (!g_osmesa_display) {
+ LOG(ERROR) << "XOpenDisplay failed.";
+ return false;
+ }
+
+ initialized = true;
+ return true;
+}
+
+bool NativeViewGLSurfaceOSMesa::Initialize() {
+ window_graphics_context_ = XCreateGC(g_osmesa_display,
+ window_,
+ 0,
+ NULL);
+ if (!window_graphics_context_) {
+ LOG(ERROR) << "XCreateGC failed.";
+ Destroy();
+ return false;
+ }
+
+ UpdateSize();
+
+ return true;
+}
+
+void NativeViewGLSurfaceOSMesa::Destroy() {
+ if (pixmap_graphics_context_) {
+ XFreeGC(g_osmesa_display, pixmap_graphics_context_);
+ pixmap_graphics_context_ = NULL;
+ }
+
+ if (pixmap_) {
+ XFreePixmap(g_osmesa_display, pixmap_);
+ pixmap_ = 0;
+ }
+
+ if (window_graphics_context_) {
+ XFreeGC(g_osmesa_display, window_graphics_context_);
+ window_graphics_context_ = NULL;
+ }
+}
+
+bool NativeViewGLSurfaceOSMesa::IsOffscreen() {
+ return false;
+}
+
+bool NativeViewGLSurfaceOSMesa::SwapBuffers() {
+ // Update the size before blitting so that the blit size is exactly the same
+ // as the window.
+ if (!UpdateSize()) {
+ LOG(ERROR) << "Failed to update size of GLContextOSMesa.";
+ return false;
+ }
+
+ gfx::Size size = GetSize();
+
+ // Copy the frame into the pixmap.
+ XWindowAttributes attributes;
+ XGetWindowAttributes(g_osmesa_display, window_, &attributes);
+ ui::PutARGBImage(g_osmesa_display,
+ attributes.visual,
+ attributes.depth,
+ pixmap_,
+ pixmap_graphics_context_,
+ static_cast<const uint8*>(GetHandle()),
+ size.width(),
+ size.height());
+
+ // Copy the pixmap to the window.
+ XCopyArea(g_osmesa_display,
+ pixmap_,
+ window_,
+ window_graphics_context_,
+ 0, 0,
+ size.width(), size.height(),
+ 0, 0);
+
+ return true;
+}
+
+bool NativeViewGLSurfaceOSMesa::UpdateSize() {
+ // Get the window size.
+ XWindowAttributes attributes;
+ XGetWindowAttributes(g_osmesa_display, window_, &attributes);
+ gfx::Size window_size = gfx::Size(std::max(1, attributes.width),
+ std::max(1, attributes.height));
+
+ // Early out if the size has not changed.
+ gfx::Size osmesa_size = GetSize();
+ if (pixmap_graphics_context_ && pixmap_ && window_size == osmesa_size)
+ return true;
+
+ // Change osmesa surface size to that of window.
+ Resize(window_size);
+
+ // Destroy the previous pixmap and graphics context.
+ if (pixmap_graphics_context_) {
+ XFreeGC(g_osmesa_display, pixmap_graphics_context_);
+ pixmap_graphics_context_ = NULL;
+ }
+ if (pixmap_) {
+ XFreePixmap(g_osmesa_display, pixmap_);
+ pixmap_ = 0;
+ }
+
+ // Recreate a pixmap to hold the frame.
+ pixmap_ = XCreatePixmap(g_osmesa_display,
+ window_,
+ window_size.width(),
+ window_size.height(),
+ attributes.depth);
+ if (!pixmap_) {
+ LOG(ERROR) << "XCreatePixmap failed.";
+ return false;
+ }
+
+ // Recreate a graphics context for the pixmap.
+ pixmap_graphics_context_ = XCreateGC(g_osmesa_display, pixmap_, 0, NULL);
+ if (!pixmap_graphics_context_) {
+ LOG(ERROR) << "XCreateGC failed";
+ return false;
+ }
+
+ return true;
+}
+
+GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
+ bool multisampled) {
+ switch (GetGLImplementation()) {
+ case kGLImplementationDesktopGL: {
+ scoped_ptr<GLSurfaceGLX> surface(new NativeViewGLSurfaceGLX(window));
+ if (!surface->Initialize()) {
+ return NULL;
+ }
+
+ scoped_ptr<GLContextGLX> context(
+ new GLContextGLX(surface.release()));
+ if (!context->Initialize(NULL))
return NULL;
return context.release();
}
case kGLImplementationEGLGLES2: {
+ scoped_ptr<NativeViewGLSurfaceEGL> surface(new NativeViewGLSurfaceEGL(
+ window));
+ if (!surface->Initialize())
+ return NULL;
+
scoped_ptr<GLContextEGL> context(
- new GLContextEGL(
- static_cast<GLSurfaceEGL*>(surface.release())));
- if (!context->Initialize(shared_context))
+ new GLContextEGL(surface.release()));
+ if (!context->Initialize(NULL))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<NativeViewGLSurfaceOSMesa> surface(
+ new NativeViewGLSurfaceOSMesa(window));
+ if (!surface->Initialize())
+ return NULL;
+
+ scoped_ptr<GLContextOSMesa> context(
+ new GLContextOSMesa(surface.release()));
+ if (!context->Initialize(OSMESA_BGRA, NULL))
return NULL;
return context.release();
}
+ case kGLImplementationMockGL:
+ return new StubGLContext;
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
+ switch (GetGLImplementation()) {
case kGLImplementationDesktopGL: {
- scoped_ptr<GLContextGLX> context(
- new GLContextGLX(
- static_cast<GLSurfaceGLX*>(surface.release())));
+ scoped_ptr<PbufferGLSurfaceGLX> surface(new PbufferGLSurfaceGLX(
+ gfx::Size(1, 1)));
+ if (!surface->Initialize())
+ return NULL;
+
+ scoped_ptr<GLContextGLX> context(new GLContextGLX(surface.release()));
+ if (!context->Initialize(shared_context))
+ return NULL;
+
+ return context.release();
+ }
+ case kGLImplementationEGLGLES2: {
+ scoped_ptr<PbufferGLSurfaceEGL> surface(new PbufferGLSurfaceEGL(
+ gfx::Size(1, 1)));
+ if (!surface->Initialize())
+ return NULL;
+
+ scoped_ptr<GLContextEGL> context(new GLContextEGL(surface.release()));
if (!context->Initialize(shared_context))
return NULL;
return context.release();
}
+ case kGLImplementationOSMesaGL: {
+ scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa());
+ surface->Resize(gfx::Size(1, 1));
+
+ scoped_ptr<GLContextOSMesa> context(
+ new GLContextOSMesa(surface.release()));
+ if (!context->Initialize(OSMESA_BGRA, shared_context))
+ return NULL;
+
+ return context.release();
+ }
case kGLImplementationMockGL:
- return new GLContextStub;
+ return new StubGLContext;
default:
NOTREACHED();
return NULL;