summaryrefslogtreecommitdiffstats
path: root/ui/gfx
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-22 23:04:37 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-22 23:04:37 +0000
commitad7bbbd6badf073dfd61bcc8d3ea9124d8b14ce7 (patch)
tree16d59f3a765faf69f39bf3dcff8d2fa4b6e15030 /ui/gfx
parent9cb2b3b8c8b21fb46d20ad4d6f14cdc7d6b3aeaf (diff)
downloadchromium_src-ad7bbbd6badf073dfd61bcc8d3ea9124d8b14ce7.zip
chromium_src-ad7bbbd6badf073dfd61bcc8d3ea9124d8b14ce7.tar.gz
chromium_src-ad7bbbd6badf073dfd61bcc8d3ea9124d8b14ce7.tar.bz2
Reland 81998.The bug in webkit\gpu\webgraphicscontext3d_in_process_impl.cc that assumed creating a new GLContext made it current is now fixed and this patch should now work.
Original message: Split OSMesa implementations of *GLContext into GLContextOSMesa and *GLSurfaceOSMesa. Surfaces are independent of contexts in GL. To facilitate sharing of surfaces between processes, I have separated them from the notion of contexts because contexts cannot be shared between processes. I started with EGL in r81512 and WGL in r81807. This is the same thing for OSMesa. GLContextOSMesa still has a pointer to a surface and still has some surface specific operations that just forward through to it. Once I have refactored all the GLContext implementations in this way, I will remove these pointers and the surface specific opertations. There will not be "view" and "offscreen" GL contexts. Rather there will be a single context type for each backend which can be made current with a surface that directs output either to a view or offscreen surface. Original review: http://codereview.chromium.org/6864031/ TEST=ran linux_layout and mac_layout try jobs (they were failing before) BUG=none Review URL: http://codereview.chromium.org/6881071 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82748 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r--ui/gfx/gl/gl.gyp2
-rw-r--r--ui/gfx/gl/gl_context_linux.cc107
-rw-r--r--ui/gfx/gl/gl_context_mac.cc6
-rw-r--r--ui/gfx/gl/gl_context_osmesa.cc102
-rw-r--r--ui/gfx/gl/gl_context_osmesa.h22
-rw-r--r--ui/gfx/gl/gl_context_win.cc101
-rw-r--r--ui/gfx/gl/gl_surface_egl.h6
-rw-r--r--ui/gfx/gl/gl_surface_osmesa.cc61
-rw-r--r--ui/gfx/gl/gl_surface_osmesa.h43
9 files changed, 240 insertions, 210 deletions
diff --git a/ui/gfx/gl/gl.gyp b/ui/gfx/gl/gl.gyp
index 507d9b4..83299b3a 100644
--- a/ui/gfx/gl/gl.gyp
+++ b/ui/gfx/gl/gl.gyp
@@ -76,6 +76,8 @@
'gl_interface.h',
'gl_surface.cc',
'gl_surface.h',
+ 'gl_surface_osmesa.cc',
+ 'gl_surface_osmesa.h',
'gl_switches.cc',
'gl_switches.h',
'<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc',
diff --git a/ui/gfx/gl/gl_context_linux.cc b/ui/gfx/gl/gl_context_linux.cc
index 6cd77dd..36f0e8a 100644
--- a/ui/gfx/gl/gl_context_linux.cc
+++ b/ui/gfx/gl/gl_context_linux.cc
@@ -22,6 +22,7 @@ extern "C" {
#include "ui/gfx/gl/gl_context_stub.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface_egl.h"
+#include "ui/gfx/gl/gl_surface_osmesa.h"
namespace {
@@ -77,29 +78,20 @@ class ViewGLContext : public BaseLinuxGLContext {
DISALLOW_COPY_AND_ASSIGN(ViewGLContext);
};
-// This class is a wrapper around a GL context that uses OSMesa to render
-// to an offscreen buffer and then blits it to a window.
-class OSMesaViewGLContext : public GLContext {
+// This OSMesa GL surface can use XLib to swap the contents of the buffer to a
+// view.
+class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
public:
- explicit OSMesaViewGLContext(gfx::PluginWindowHandle window)
- : window_graphics_context_(0),
- window_(window),
- pixmap_graphics_context_(0),
- pixmap_(0) {
- DCHECK(window);
- }
+ explicit NativeViewGLSurfaceOSMesa(gfx::PluginWindowHandle window);
+ virtual ~NativeViewGLSurfaceOSMesa();
// Initializes the GL context.
bool Initialize();
+ // Implement a subset of GLSurface.
virtual void Destroy();
- virtual bool MakeCurrent();
- virtual bool IsCurrent();
virtual bool IsOffscreen();
virtual bool SwapBuffers();
- virtual gfx::Size GetSize();
- virtual void* GetHandle();
- virtual void SetSwapInterval(int interval);
private:
bool UpdateSize();
@@ -108,9 +100,8 @@ class OSMesaViewGLContext : public GLContext {
gfx::PluginWindowHandle window_;
GC pixmap_graphics_context_;
Pixmap pixmap_;
- OSMesaGLContext osmesa_context_;
- DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext);
+ DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
};
// This class is a wrapper around a GL context used for offscreen rendering.
@@ -348,13 +339,20 @@ void ViewGLContext::SetSwapInterval(int interval) {
}
}
-bool OSMesaViewGLContext::Initialize() {
- if (!osmesa_context_.Initialize(OSMESA_BGRA, NULL)) {
- LOG(ERROR) << "OSMesaGLContext::Initialize failed.";
- Destroy();
- return false;
- }
+NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa(
+ gfx::PluginWindowHandle window)
+ : window_graphics_context_(0),
+ window_(window),
+ pixmap_graphics_context_(0),
+ pixmap_(0) {
+ DCHECK(window);
+}
+NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() {
+ Destroy();
+}
+
+bool NativeViewGLSurfaceOSMesa::Initialize() {
window_graphics_context_ = XCreateGC(GetXDisplayHelper(),
window_,
0,
@@ -370,9 +368,7 @@ bool OSMesaViewGLContext::Initialize() {
return true;
}
-void OSMesaViewGLContext::Destroy() {
- osmesa_context_.Destroy();
-
+void NativeViewGLSurfaceOSMesa::Destroy() {
Display* display = GetXDisplayHelper();
if (pixmap_graphics_context_) {
@@ -391,31 +387,19 @@ void OSMesaViewGLContext::Destroy() {
}
}
-bool OSMesaViewGLContext::MakeCurrent() {
- // TODO(apatrick): This is a bit of a hack. The window might have had zero
- // size when the context was initialized. Assume it has a valid size when
- // MakeCurrent is called and resize the back buffer if necessary.
- UpdateSize();
- return osmesa_context_.MakeCurrent();
-}
-
-bool OSMesaViewGLContext::IsCurrent() {
- return osmesa_context_.IsCurrent();
-}
-
-bool OSMesaViewGLContext::IsOffscreen() {
+bool NativeViewGLSurfaceOSMesa::IsOffscreen() {
return false;
}
-bool OSMesaViewGLContext::SwapBuffers() {
+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 OSMesaGLContext.";
+ LOG(ERROR) << "Failed to update size of GLContextOSMesa.";
return false;
}
- gfx::Size size = osmesa_context_.GetSize();
+ gfx::Size size = GetSize();
Display* display = GetXDisplayHelper();
@@ -427,7 +411,7 @@ bool OSMesaViewGLContext::SwapBuffers() {
attributes.depth,
pixmap_,
pixmap_graphics_context_,
- static_cast<const uint8*>(osmesa_context_.buffer()),
+ static_cast<const uint8*>(GetHandle()),
size.width(),
size.height());
@@ -443,21 +427,7 @@ bool OSMesaViewGLContext::SwapBuffers() {
return true;
}
-gfx::Size OSMesaViewGLContext::GetSize() {
- return osmesa_context_.GetSize();
-}
-
-void* OSMesaViewGLContext::GetHandle() {
- return osmesa_context_.GetHandle();
-}
-
-void OSMesaViewGLContext::SetSwapInterval(int interval) {
- DCHECK(IsCurrent());
- // Fail silently. It is legitimate to set the swap interval on a view context
- // but XLib does not have those semantics.
-}
-
-bool OSMesaViewGLContext::UpdateSize() {
+bool NativeViewGLSurfaceOSMesa::UpdateSize() {
// Get the window size.
XWindowAttributes attributes;
Display* display = GetXDisplayHelper();
@@ -466,12 +436,12 @@ bool OSMesaViewGLContext::UpdateSize() {
std::max(1, attributes.height));
// Early out if the size has not changed.
- gfx::Size osmesa_size = osmesa_context_.GetSize();
+ gfx::Size osmesa_size = GetSize();
if (pixmap_graphics_context_ && pixmap_ && window_size == osmesa_size)
return true;
// Change osmesa surface size to that of window.
- osmesa_context_.Resize(window_size);
+ Resize(window_size);
// Destroy the previous pixmap and graphics context.
if (pixmap_graphics_context_) {
@@ -529,9 +499,14 @@ GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
return context.release();
}
case kGLImplementationOSMesaGL: {
- scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window));
+ scoped_ptr<NativeViewGLSurfaceOSMesa> surface(
+ new NativeViewGLSurfaceOSMesa(window));
+ if (!surface->Initialize())
+ return NULL;
- if (!context->Initialize())
+ scoped_ptr<GLContextOSMesa> context(
+ new GLContextOSMesa(surface.release()));
+ if (!context->Initialize(OSMESA_BGRA, NULL))
return NULL;
return context.release();
@@ -823,8 +798,12 @@ GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
return context.release();
}
case kGLImplementationOSMesaGL: {
- scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
- if (!context->Initialize(OSMESA_RGBA, shared_context))
+ 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();
diff --git a/ui/gfx/gl/gl_context_mac.cc b/ui/gfx/gl/gl_context_mac.cc
index 10e8bf3..21b0403 100644
--- a/ui/gfx/gl/gl_context_mac.cc
+++ b/ui/gfx/gl/gl_context_mac.cc
@@ -192,7 +192,11 @@ GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
return context.release();
}
case kGLImplementationOSMesaGL: {
- scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa());
+ surface->Resize(gfx::Size(1, 1));
+
+ scoped_ptr<GLContextOSMesa> context(
+ new GLContextOSMesa(surface.release()));
if (!context->Initialize(OSMESA_RGBA, shared_context))
return NULL;
diff --git a/ui/gfx/gl/gl_context_osmesa.cc b/ui/gfx/gl/gl_context_osmesa.cc
index 9d1e802..6da01d1 100644
--- a/ui/gfx/gl/gl_context_osmesa.cc
+++ b/ui/gfx/gl/gl_context_osmesa.cc
@@ -12,19 +12,18 @@
namespace gfx {
-OSMesaGLContext::OSMesaGLContext() : context_(NULL)
+GLContextOSMesa::GLContextOSMesa(GLSurfaceOSMesa* surface)
+ : surface_(surface),
+ context_(NULL)
{
}
-OSMesaGLContext::~OSMesaGLContext() {
+GLContextOSMesa::~GLContextOSMesa() {
}
-bool OSMesaGLContext::Initialize(GLuint format, GLContext* shared_context) {
+bool GLContextOSMesa::Initialize(GLuint format, GLContext* shared_context) {
DCHECK(!context_);
- size_ = gfx::Size(1, 1);
- buffer_.reset(new int32[1]);
-
OSMesaContext shared_handle = NULL;
if (shared_context)
shared_handle = static_cast<OSMesaContext>(shared_context->GetHandle());
@@ -39,93 +38,64 @@ bool OSMesaGLContext::Initialize(GLuint format, GLContext* shared_context) {
return false;
}
- if (!MakeCurrent()) {
- LOG(ERROR) << "MakeCurrent failed.";
- Destroy();
- return false;
- }
-
- // Row 0 is at the top.
- OSMesaPixelStore(OSMESA_Y_UP, 0);
-
- if (!InitializeCommon()) {
- LOG(ERROR) << "GLContext::InitializeCommon failed.";
- Destroy();
- return false;
- }
-
return true;
}
-void OSMesaGLContext::Resize(const gfx::Size& new_size) {
- if (new_size == size_)
- return;
-
- // Allocate a new back buffer.
- scoped_array<int32> new_buffer(new int32[new_size.GetArea()]);
- memset(new_buffer.get(), 0, new_size.GetArea() * sizeof(new_buffer[0]));
-
- // Copy the current back buffer into the new buffer.
- int copy_width = std::min(size_.width(), new_size.width());
- int copy_height = std::min(size_.height(), new_size.height());
- for (int y = 0; y < copy_height; ++y) {
- for (int x = 0; x < copy_width; ++x) {
- new_buffer[y * new_size.width() + x] = buffer_[y * size_.width() + x];
- }
- }
-
- buffer_.reset(new_buffer.release());
- size_ = new_size;
-
- // If this context is current, need to call MakeCurrent again so OSMesa uses
- // the new buffer.
- if (IsCurrent())
- MakeCurrent();
-}
-
-void OSMesaGLContext::Destroy() {
+void GLContextOSMesa::Destroy() {
if (context_) {
OSMesaDestroyContext(static_cast<OSMesaContext>(context_));
context_ = NULL;
}
- buffer_.reset();
- size_ = gfx::Size();
+
+ surface_->Destroy();
+ surface_.reset();
}
-bool OSMesaGLContext::MakeCurrent() {
+bool GLContextOSMesa::MakeCurrent() {
DCHECK(context_);
- return OSMesaMakeCurrent(static_cast<OSMesaContext>(context_),
- buffer_.get(),
- GL_UNSIGNED_BYTE,
- size_.width(), size_.height()) == GL_TRUE;
+
+ gfx::Size size = surface_->GetSize();
+
+ if (!OSMesaMakeCurrent(static_cast<OSMesaContext>(context_),
+ surface_->GetHandle(),
+ GL_UNSIGNED_BYTE,
+ size.width(), size.height())) {
+ return false;
+ }
+
+ // Row 0 is at the top.
+ OSMesaPixelStore(OSMESA_Y_UP, 0);
+
return true;
}
-bool OSMesaGLContext::IsCurrent() {
+bool GLContextOSMesa::IsCurrent() {
DCHECK(context_);
return context_ == OSMesaGetCurrentContext();
}
-bool OSMesaGLContext::IsOffscreen() {
- return true;
+bool GLContextOSMesa::IsOffscreen() {
+ // TODO(apatrick): remove this from GLContext interface.
+ return surface_->IsOffscreen();
}
-bool OSMesaGLContext::SwapBuffers() {
- NOTREACHED() << "Should not call SwapBuffers on an OSMesaGLContext.";
- return false;
+bool GLContextOSMesa::SwapBuffers() {
+ // TODO(apatrick): remove this from GLContext interface.
+ return surface_->SwapBuffers();
}
-gfx::Size OSMesaGLContext::GetSize() {
- return size_;
+gfx::Size GLContextOSMesa::GetSize() {
+ // TODO(apatrick): remove this from GLContext interface.
+ return surface_->GetSize();
}
-void* OSMesaGLContext::GetHandle() {
+void* GLContextOSMesa::GetHandle() {
return context_;
}
-void OSMesaGLContext::SetSwapInterval(int interval) {
+void GLContextOSMesa::SetSwapInterval(int interval) {
DCHECK(IsCurrent());
- NOTREACHED() << "Attempt to call SetSwapInterval on an OSMesaGLContext.";
+ NOTREACHED() << "Attempt to call SetSwapInterval on an GLContextOSMesa.";
}
} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_osmesa.h b/ui/gfx/gl/gl_context_osmesa.h
index 77ca820..33aa21c 100644
--- a/ui/gfx/gl/gl_context_osmesa.h
+++ b/ui/gfx/gl/gl_context_osmesa.h
@@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h"
#include "ui/gfx/gl/gl_context.h"
+#include "ui/gfx/gl/gl_surface_osmesa.h"
#include "ui/gfx/size.h"
typedef struct osmesa_context *OSMesaContext;
@@ -15,22 +16,14 @@ typedef struct osmesa_context *OSMesaContext;
namespace gfx {
// Encapsulates an OSMesa OpenGL context that uses software rendering.
-class OSMesaGLContext : public GLContext {
+class GLContextOSMesa : public GLContext {
public:
- OSMesaGLContext();
- virtual ~OSMesaGLContext();
+ explicit GLContextOSMesa(GLSurfaceOSMesa* surface);
+ virtual ~GLContextOSMesa();
- // Initialize an OSMesa GL context with the default 1 x 1 initial size.
+ // Initialize an OSMesa GL context.
bool Initialize(GLuint format, GLContext* shared_context);
- // Resize the back buffer, preserving the old content. Does nothing if the
- // size is unchanged.
- void Resize(const gfx::Size& new_size);
-
- const void* buffer() const {
- return buffer_.get();
- }
-
// Implement GLContext.
virtual void Destroy();
virtual bool MakeCurrent();
@@ -42,11 +35,10 @@ class OSMesaGLContext : public GLContext {
virtual void SetSwapInterval(int interval);
private:
- gfx::Size size_;
- scoped_array<int32> buffer_;
+ scoped_ptr<GLSurfaceOSMesa> surface_;
OSMesaContext context_;
- DISALLOW_COPY_AND_ASSIGN(OSMesaGLContext);
+ DISALLOW_COPY_AND_ASSIGN(GLContextOSMesa);
};
} // namespace gfx
diff --git a/ui/gfx/gl/gl_context_win.cc b/ui/gfx/gl/gl_context_win.cc
index 87f3d98..3222b84 100644
--- a/ui/gfx/gl/gl_context_win.cc
+++ b/ui/gfx/gl/gl_context_win.cc
@@ -19,40 +19,33 @@
#include "ui/gfx/gl/gl_context_wgl.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface_egl.h"
+#include "ui/gfx/gl/gl_surface_osmesa.h"
#include "ui/gfx/gl/gl_surface_wgl.h"
namespace gfx {
-// This class is a wrapper around a GL context that uses OSMesa to render
-// to an offscreen buffer and then blits it to a window.
-class OSMesaViewGLContext : public GLContext {
+// This OSMesa GL surface can use GDI to swap the contents of the buffer to a
+// view.
+class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa {
public:
- explicit OSMesaViewGLContext(gfx::PluginWindowHandle window)
- : window_(window),
- device_context_(NULL) {
- DCHECK(window);
- }
+ explicit NativeViewGLSurfaceOSMesa(gfx::PluginWindowHandle window);
+ virtual ~NativeViewGLSurfaceOSMesa();
// Initializes the GL context.
bool Initialize();
+ // Implement subset of GLSurface.
virtual void Destroy();
- virtual bool MakeCurrent();
- virtual bool IsCurrent();
virtual bool IsOffscreen();
virtual bool SwapBuffers();
- virtual gfx::Size GetSize();
- virtual void* GetHandle();
- virtual void SetSwapInterval(int interval);
private:
void UpdateSize();
gfx::PluginWindowHandle window_;
HDC device_context_;
- OSMesaGLContext osmesa_context_;
- DISALLOW_COPY_AND_ASSIGN(OSMesaViewGLContext);
+ DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa);
};
// Helper routine that does one-off initialization like determining the
@@ -93,55 +86,45 @@ bool GLContext::InitializeOneOff() {
return true;
}
-bool OSMesaViewGLContext::Initialize() {
- // The GL context will render to this window.
- device_context_ = GetDC(window_);
+NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa(
+ gfx::PluginWindowHandle window)
+ : window_(window),
+ device_context_(NULL) {
+ DCHECK(window);
+}
- if (!osmesa_context_.Initialize(OSMESA_RGBA, NULL)) {
- LOG(ERROR) << "OSMesaGLContext::Initialize failed.";
- Destroy();
- return false;
- }
+NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() {
+ Destroy();
+}
+bool NativeViewGLSurfaceOSMesa::Initialize() {
+ device_context_ = GetDC(window_);
UpdateSize();
-
return true;
}
-void OSMesaViewGLContext::Destroy() {
- osmesa_context_.Destroy();
-
+void NativeViewGLSurfaceOSMesa::Destroy() {
if (window_ && device_context_)
ReleaseDC(window_, device_context_);
window_ = NULL;
device_context_ = NULL;
-}
-bool OSMesaViewGLContext::MakeCurrent() {
- // TODO(apatrick): This is a bit of a hack. The window might have had zero
- // size when the context was initialized. Assume it has a valid size when
- // MakeCurrent is called and resize the back buffer if necessary.
- UpdateSize();
- return osmesa_context_.MakeCurrent();
+ GLSurfaceOSMesa::Destroy();
}
-bool OSMesaViewGLContext::IsCurrent() {
- return osmesa_context_.IsCurrent();
-}
-
-bool OSMesaViewGLContext::IsOffscreen() {
+bool NativeViewGLSurfaceOSMesa::IsOffscreen() {
return false;
}
-bool OSMesaViewGLContext::SwapBuffers() {
+bool NativeViewGLSurfaceOSMesa::SwapBuffers() {
DCHECK(device_context_);
// Update the size before blitting so that the blit size is exactly the same
// as the window.
UpdateSize();
- gfx::Size size = osmesa_context_.GetSize();
+ gfx::Size size = GetSize();
// Note: negating the height below causes GDI to treat the bitmap data as row
// 0 being at the top.
@@ -166,7 +149,7 @@ bool OSMesaViewGLContext::SwapBuffers() {
StretchDIBits(device_context_,
0, 0, size.width(), size.height(),
0, 0, size.width(), size.height(),
- osmesa_context_.buffer(),
+ GetHandle(),
reinterpret_cast<BITMAPINFO*>(&info),
DIB_RGB_COLORS,
SRCCOPY);
@@ -174,21 +157,7 @@ bool OSMesaViewGLContext::SwapBuffers() {
return true;
}
-gfx::Size OSMesaViewGLContext::GetSize() {
- return osmesa_context_.GetSize();
-}
-
-void* OSMesaViewGLContext::GetHandle() {
- return osmesa_context_.GetHandle();
-}
-
-void OSMesaViewGLContext::SetSwapInterval(int interval) {
- DCHECK(IsCurrent());
- // Fail silently. It is legitimate to set the swap interval on a view context
- // but GDI does not have those semantics.
-}
-
-void OSMesaViewGLContext::UpdateSize() {
+void NativeViewGLSurfaceOSMesa::UpdateSize() {
// Change back buffer size to that of window. If window handle is invalid, do
// not change the back buffer size.
RECT rect;
@@ -198,15 +167,21 @@ void OSMesaViewGLContext::UpdateSize() {
gfx::Size window_size = gfx::Size(
std::max(1, static_cast<int>(rect.right - rect.left)),
std::max(1, static_cast<int>(rect.bottom - rect.top)));
- osmesa_context_.Resize(window_size);
+ Resize(window_size);
}
GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
bool multisampled) {
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL: {
- scoped_ptr<OSMesaViewGLContext> context(new OSMesaViewGLContext(window));
- if (!context->Initialize())
+ scoped_ptr<NativeViewGLSurfaceOSMesa> surface(
+ new NativeViewGLSurfaceOSMesa(window));
+ if (!surface->Initialize())
+ return NULL;
+
+ scoped_ptr<GLContextOSMesa> context(
+ new GLContextOSMesa(surface.release()));
+ if (!context->Initialize(OSMESA_RGBA, NULL))
return NULL;
return context.release();
@@ -248,7 +223,11 @@ GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window,
GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) {
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL: {
- scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext);
+ scoped_ptr<GLSurfaceOSMesa> surface(new GLSurfaceOSMesa());
+ surface->Resize(gfx::Size(1, 1));
+
+ scoped_ptr<GLContextOSMesa> context(
+ new GLContextOSMesa(surface.release()));
if (!context->Initialize(OSMESA_RGBA, shared_context))
return NULL;
diff --git a/ui/gfx/gl/gl_surface_egl.h b/ui/gfx/gl/gl_surface_egl.h
index 9ff1c2b..fe31494 100644
--- a/ui/gfx/gl/gl_surface_egl.h
+++ b/ui/gfx/gl/gl_surface_egl.h
@@ -15,7 +15,7 @@ typedef void* EGLSurface;
namespace gfx {
-// Interface for EGL contexts.
+// Interface for EGL surface.
class GLSurfaceEGL : public GLSurface {
public:
GLSurfaceEGL();
@@ -35,7 +35,7 @@ class NativeViewGLSurfaceEGL : public GLSurfaceEGL {
explicit NativeViewGLSurfaceEGL(void* window);
virtual ~NativeViewGLSurfaceEGL();
- // Initialize an EGL context.
+ // Initialize an EGL surface.
bool Initialize();
// Implement GLSurface.
@@ -58,7 +58,7 @@ class PbufferGLSurfaceEGL : public GLSurfaceEGL {
explicit PbufferGLSurfaceEGL(const gfx::Size& size);
virtual ~PbufferGLSurfaceEGL();
- // Initialize an EGL context that shares a namespace with another.
+ // Initialize an EGL surface.
bool Initialize();
// Implement GLSurface.
diff --git a/ui/gfx/gl/gl_surface_osmesa.cc b/ui/gfx/gl/gl_surface_osmesa.cc
new file mode 100644
index 0000000..8c4d11d
--- /dev/null
+++ b/ui/gfx/gl/gl_surface_osmesa.cc
@@ -0,0 +1,61 @@
+// 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 "ui/gfx/gl/gl_surface_osmesa.h"
+#include "base/logging.h"
+#include "ui/gfx/gl/gl_bindings.h"
+
+namespace gfx {
+
+GLSurfaceOSMesa::GLSurfaceOSMesa()
+{
+}
+
+GLSurfaceOSMesa::~GLSurfaceOSMesa() {
+}
+
+void GLSurfaceOSMesa::Resize(const gfx::Size& new_size) {
+ if (new_size == size_)
+ return;
+
+ // Allocate a new back buffer.
+ scoped_array<int32> new_buffer(new int32[new_size.GetArea()]);
+ memset(new_buffer.get(), 0, new_size.GetArea() * sizeof(new_buffer[0]));
+
+ // Copy the current back buffer into the new buffer.
+ int copy_width = std::min(size_.width(), new_size.width());
+ int copy_height = std::min(size_.height(), new_size.height());
+ for (int y = 0; y < copy_height; ++y) {
+ for (int x = 0; x < copy_width; ++x) {
+ new_buffer[y * new_size.width() + x] = buffer_[y * size_.width() + x];
+ }
+ }
+
+ buffer_.reset(new_buffer.release());
+ size_ = new_size;
+}
+
+void GLSurfaceOSMesa::Destroy() {
+ buffer_.reset();
+ size_ = gfx::Size();
+}
+
+bool GLSurfaceOSMesa::IsOffscreen() {
+ return true;
+}
+
+bool GLSurfaceOSMesa::SwapBuffers() {
+ NOTREACHED() << "Should not call SwapBuffers on an GLSurfaceOSMesa.";
+ return false;
+}
+
+gfx::Size GLSurfaceOSMesa::GetSize() {
+ return size_;
+}
+
+void* GLSurfaceOSMesa::GetHandle() {
+ return buffer_.get();
+}
+
+} // namespace gfx
diff --git a/ui/gfx/gl/gl_surface_osmesa.h b/ui/gfx/gl/gl_surface_osmesa.h
new file mode 100644
index 0000000..742d28a
--- /dev/null
+++ b/ui/gfx/gl/gl_surface_osmesa.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef UI_GFX_GL_GL_SURFACE_OSMESA_H_
+#define UI_GFX_GL_GL_SURFACE_OSMESA_H_
+#pragma once
+
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/gl/gl_surface.h"
+#include "ui/gfx/size.h"
+
+namespace gfx {
+
+// A surface that the Mesa software renderer draws to. This is actually just a
+// buffer in system memory. GetHandle returns a pointer to the buffer. These
+// surfaces can be resized and resizing preserves the contents.
+class GLSurfaceOSMesa : public GLSurface {
+ public:
+ GLSurfaceOSMesa();
+ virtual ~GLSurfaceOSMesa();
+
+ // Resize the back buffer, preserving the old content. Does nothing if the
+ // size is unchanged.
+ void Resize(const gfx::Size& new_size);
+
+ // Implement GLSurface.
+ virtual void Destroy();
+ virtual bool IsOffscreen();
+ virtual bool SwapBuffers();
+ virtual gfx::Size GetSize();
+ virtual void* GetHandle();
+
+ private:
+ gfx::Size size_;
+ scoped_array<int32> buffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(GLSurfaceOSMesa);
+};
+
+} // namespace gfx
+
+#endif // UI_GFX_GL_GL_SURFACE_OSMESA_H_