b=523959; [webgl] enable WebGL with EGL on Maemo and WinCE; r=stuart
authorVladimir Vukicevic <vladimir@pobox.com>
Sun, 06 Dec 2009 16:07:58 -0800
changeset 35488 7eb4406f8dedf452f87ab23eb89fb333abab683f
parent 35487 f73d36907682889e51bdf4aa219e6fcc073a77bd
child 35489 a86c5f1d3fefb52608f18e85f7ca4a0594e86f8a
push id10611
push uservladimir@mozilla.com
push dateMon, 07 Dec 2009 00:08:21 +0000
treeherdermozilla-central@7eb4406f8ded [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstuart
bugs523959
milestone1.9.3a1pre
b=523959; [webgl] enable WebGL with EGL on Maemo and WinCE; r=stuart
configure.in
content/canvas/src/Makefile.in
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/glwrap.cpp
content/canvas/src/glwrap.h
content/canvas/src/localgl.h
content/canvas/src/nsGLPbuffer.h
content/canvas/src/nsGLPbufferEGL.cpp
gfx/thebes/public/gfxXlibSurface.h
gfx/thebes/src/gfxXlibSurface.cpp
--- a/configure.in
+++ b/configure.in
@@ -4776,40 +4776,39 @@ dnl ====================================
 case "$MOZ_WIDGET_TOOLKIT" in
 photon)
 	MOZ_ENABLE_PHOTON=1
 	AC_DEFINE(MOZ_WIDGET_PHOTON)
     ;;
 
 cairo-windows)
     MOZ_WIDGET_TOOLKIT=windows
-    if test -z "$WINCE"; then
-        MOZ_WEBGL=1
-    fi
+    MOZ_WEBGL=1
     ;;
 
 cairo-gtk2|cairo-gtk2-x11)
     MOZ_WIDGET_TOOLKIT=gtk2
     MOZ_ENABLE_GTK2=1
     MOZ_ENABLE_XREMOTE=1
     MOZ_WEBGL=1
+    MOZ_WEBGL_GLX=1
 
     AC_DEFINE(MOZ_X11)
     MOZ_X11=1
     USE_FC_FREETYPE=1
 
     TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
     TK_LIBS='$(MOZ_GTK2_LIBS)'
     AC_DEFINE(MOZ_WIDGET_GTK2)
     ;;
 
 cairo-gtk2-dfb)
     MOZ_WIDGET_TOOLKIT=gtk2
     MOZ_ENABLE_GTK2=1
-    MOZ_WEBGL=1
+    MOZ_WEBGL=
 
     AC_DEFINE(MOZ_DFB)
     MOZ_DFB=1
 
     TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
     TK_LIBS='$(MOZ_GTK2_LIBS)'
     AC_DEFINE(MOZ_WIDGET_GTK2)
     if test "$no_x" != "yes"; then
@@ -6255,17 +6254,17 @@ PKG_CHECK_MODULES(LIBOSSO,libosso,
                   NS_OSSO=)
 
 if test $NS_OSSO; then
     if test -z "$MOZ_ENABLE_DBUS"; then
         AC_MSG_ERROR([DBus is required when building for OSSO])
     fi
     AC_DEFINE(NS_OSSO)
     MOZ_GFX_OPTIMIZE_MOBILE=1
-    MOZ_WEBGL=
+    MOZ_WEBGL_GLX=
 fi
 AC_SUBST(LIBOSSO_CFLAGS)
 AC_SUBST(LIBOSSO_LIBS)
 
 PKG_CHECK_MODULES(LIBHILDONFM,hildon-fm-2,
                   NS_HILDONFM=1,
                   NS_HILDONFM)
 AC_SUBST(LIBHILDONFM_CFLAGS)
@@ -8095,24 +8094,22 @@ if test "$MOZ_X11"; then
 
     if test ! -z "$MISSING_X"; then
         AC_MSG_ERROR([ Could not find the following X libraries: $MISSING_X ]);
     fi
 
 fi # MOZ_X11
 
 dnl Check for headers, etc. needed by WebGL.
-if test -n "$MOZ_WEBGL"; then
-    if test "$MOZ_WIDGET_TOOLKIT" = gtk2; then
-        AC_CHECK_HEADER(GL/glx.h)
-        if test "$ac_cv_header_GL_glx_h" != "yes"; then
-            AC_MSG_ERROR([Can't find header GL/glx.h for WebGL (install mesa-common-dev (Ubuntu), mesa-libGL-devel (Fedora), or Mesa (SuSE))])
-        fi
-    fi
-fi # MOZ_WEBGL
+if test -n "$MOZ_WEBGL_GLX"; then
+    AC_CHECK_HEADER(GL/glx.h)
+    if test "$ac_cv_header_GL_glx_h" != "yes"; then
+        AC_MSG_ERROR([Can't find header GL/glx.h for WebGL (install mesa-common-dev (Ubuntu), mesa-libGL-devel (Fedora), or Mesa (SuSE))])
+    fi
+fi # MOZ_WEBGL_GLX
 fi # COMPILE_ENVIRONMENT
 
 if test "$USE_FC_FREETYPE"; then
     if test "$COMPILE_ENVIRONMENT"; then
     	_SAVE_CPPFLAGS="$CPPFLAGS"
     	CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
         AC_CHECK_HEADERS(fontconfig/fcfreetype.h, , 
             [AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)])
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -52,49 +52,55 @@ CPPSRCS	= \
 	CanvasUtils.cpp \
 	nsCanvasRenderingContext2D.cpp \
 	$(NULL)
 
 # Canvas 3D Pieces
 
 ifdef MOZ_WEBGL
 
+ifeq (1_1,$(MOZ_X11)_$(NS_OSSO))
+WEBGL_PLATFORM = EGL
+DEFINES += -DUSE_GLES2
+endif
+
+ifeq (1_,$(MOZ_X11)_$(NS_OSSO))
+WEBGL_PLATFORM = GLX
+EXTRA_DSO_LIBS += X11
+endif
+
+
+ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
+ifdef WINCE
+WEBGL_PLATFORM = EGL
+DEFINES += -DUSE_GLES2
+else
+WEBGL_PLATFORM = WGL
+endif
+endif
+
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
+WEBGL_PLATFORM = CGL
+endif
+
 CPPSRCS += \
 	WebGLArrays.cpp \
 	WebGLContext.cpp \
 	WebGLContextGL.cpp \
 	WebGLContextUtils.cpp \
 	WebGLContextValidate.cpp \
 	NativeJSContext.cpp \
 	glwrap.cpp \
 	nsGLPbuffer.cpp \
 	nsGLPbufferOSMesa.cpp \
 	SimpleBuffer.cpp \
 	$(NULL)
 
-ifdef MOZ_X11
-EXTRA_DSO_LIBS += X11
-CPPSRCS += nsGLPbufferGLX.cpp
-DEFINES += -DUSE_GLX
-endif
-
-ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-ifdef WINCE
-CPPSRCS += nsGLPbufferEGL.cpp
-DEFINES += -DUSE_EGL
-else
-CPPSRCS += nsGLPbufferWGL.cpp
-DEFINES += -DUSE_WGL
-endif
-endif
-
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-CPPSRCS += nsGLPbufferCGL.cpp
-DEFINES += -DUSE_CGL
-endif
+CPPSRCS += nsGLPbuffer$(WEBGL_PLATFORM).cpp
+DEFINES += -DUSE_$(WEBGL_PLATFORM)
 
 else
 
 CPPSRCS += WebGLContextNotSupported.cpp
 
 endif
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -95,23 +95,23 @@ WebGLContext::SetCanvasElement(nsICanvas
         rv = prefBranch->GetBoolPref("software_render", &val);
         if (NS_SUCCEEDED(rv))
             forceSoftware = val;
     }
 
     LogMessage("Canvas 3D: creating PBuffer...");
 
     if (!forceSoftware) {
-#if defined(WINCE)
+#if defined(USE_EGL)
         mGLPbuffer = new nsGLPbufferEGL();
-#elif defined(XP_WIN)
+#elif defined(USE_WGL)
         mGLPbuffer = new nsGLPbufferWGL();
-#elif defined(XP_UNIX) && defined(MOZ_X11)
+#elif defined(USE_GLX)
         mGLPbuffer = new nsGLPbufferGLX();
-#elif defined(XP_MACOSX)
+#elif defined(USE_CGL)
         mGLPbuffer = new nsGLPbufferCGL();
 #else
         mGLPbuffer = nsnull;
 #endif
 
         if (mGLPbuffer && !mGLPbuffer->Init(this))
             mGLPbuffer = nsnull;
     }
@@ -248,24 +248,30 @@ WebGLContext::Render(gfxContext *ctx, gf
         mCanvasElement->GLWidgetSwapBuffers();
         mCanvasElement->GLWidgetEndDrawing();
     } else
 #endif
     {
         nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface();
         if (!surf)
             return NS_OK;
-
         // XXX we can optimize this on win32 at least, by creating an upside-down
         // DIB.
         nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
+
+#if defined(USE_EGL) && defined(MOZ_X11)
+        if (getenv("IMAGE")) {
+#endif
         gfxMatrix m;
         m.Translate(gfxPoint(0.0, mGLPbuffer->Height()));
         m.Scale(1.0, -1.0);
         pat->SetMatrix(m);
+#if defined(USE_EGL) && defined(MOZ_X11)
+        }
+#endif
 
         // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee
         // pixel alignment for this stuff!
         ctx->NewPath();
         ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
         ctx->Fill();
     }
 
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -377,26 +377,30 @@ WebGLContext::BindBuffer(GLenum target, 
 {
     WebGLBuffer *wbuf = static_cast<WebGLBuffer*>(buffer);
 
     if (wbuf && wbuf->Deleted())
         return ErrorMessage("glBindBuffer: buffer has already been deleted!");
 
     MakeContextCurrent();
 
+    //printf ("BindBuffer0: %04x\n", gl->fGetError());
+
     if (target == LOCAL_GL_ARRAY_BUFFER) {
         mBoundArrayBuffer = wbuf;
     } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
         mBoundElementArrayBuffer = wbuf;
     } else {
         return ErrorMessage("glBindBuffer: invalid target!");
     }
 
     gl->fBindBuffer(target, wbuf ? wbuf->GLName() : 0);
 
+    //printf ("BindBuffer: %04x\n", gl->fGetError());
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::BindFramebuffer(GLenum target, nsIWebGLFramebuffer *fb)
 {
     WebGLFramebuffer *wfb = static_cast<WebGLFramebuffer*>(fb);
 
@@ -976,18 +980,22 @@ WebGLContext::DrawArrays(GLenum mode, GL
         return ErrorMessage("drawArrays: overflow in offset+count");
     }
 
     if (!ValidateBuffers(offset+count))
         return NS_ERROR_INVALID_ARG;
 
     MakeContextCurrent();
 
+    //printf ("DrawArrays0: %04x\n", gl->fGetError());
+
     gl->fDrawArrays(mode, offset, count);
 
+    //printf ("DrawArrays: %04x\n", gl->fGetError());
+
     Invalidate();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebGLContext::DrawElements(GLenum mode, GLuint count, GLenum type, GLuint offset)
 {
@@ -2033,17 +2041,16 @@ WebGLContext::GetUniform(nsIWebGLProgram
     if (NS_FAILED(js.error))
         return js.error;
 
     MakeContextCurrent();
 
     GLint uArraySize = 0;
     GLenum uType = 0;
 
-    fprintf (stderr, "GetUniform: program: %d location: %d\n", program, location);
     gl->fGetActiveUniform(program, location, 0, NULL, &uArraySize, &uType, NULL);
     if (uArraySize == 0)
         return NS_ERROR_FAILURE;
 
     // glGetUniform needs to be called for each element of an array separately, so we don't
     // have to deal with uArraySize at all.
 
     GLenum baseType;
@@ -2897,26 +2904,40 @@ WebGLContext::VertexAttribPointer(GLuint
 }
 
 PRBool
 WebGLContext::ValidateGL()
 {
     // make sure that the opengl stuff that we need is supported
     GLint val = 0;
 
+    MakeContextCurrent();
+
     gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &val);
     mAttribBuffers.SetLength(val);
 
+    //fprintf(stderr, "GL_MAX_VERTEX_ATTRIBS: %d\n", val);
+
     gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_UNITS, &val);
     mBound2DTextures.SetLength(val);
     mBoundCubeMapTextures.SetLength(val);
 
+    //fprintf(stderr, "GL_MAX_TEXTURE_UNITS: %d\n", val);
+
     gl->fGetIntegerv(LOCAL_GL_MAX_COLOR_ATTACHMENTS, &val);
     mBoundColorFramebuffers.SetLength(val);
 
+#ifdef DEBUG_vladimir
+    gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT, &val);
+    fprintf(stderr, "GL_IMPLEMENTATION_COLOR_READ_FORMAT: 0x%04x\n", val);
+
+    gl->fGetIntegerv(LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE, &val);
+    fprintf(stderr, "GL_IMPLEMENTATION_COLOR_READ_TYPE: 0x%04x\n", val);
+#endif
+
 #ifndef USE_GLES2
     // gl_PointSize is always available in ES2 GLSL
     gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
 #endif
 
     return PR_TRUE;
 }
 
--- a/content/canvas/src/glwrap.cpp
+++ b/content/canvas/src/glwrap.cpp
@@ -45,21 +45,16 @@
 
 #include "prlink.h"
 
 #include "glwrap.h"
 
 #define MAX_SYMBOL_LENGTH 128
 #define MAX_SYMBOL_NAMES 5
 
-#ifdef MOZ_X11
-#define GLX_GLXEXT_LEGACY
-#include <GL/glx.h>
-#endif
-
 bool
 LibrarySymbolLoader::OpenLibrary(const char *library)
 {
     PRLibSpec lspec;
     lspec.type = PR_LibSpec_Pathname;
     lspec.value.pathname = library;
 
     mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
@@ -328,18 +323,20 @@ GLES20Wrap::InitWithPrefix(const char *p
         { (PRFuncPtr*) &fGenerateMipmap, { "GenerateMipmap", "GenerateMipmapEXT", NULL } },
         { (PRFuncPtr*) &fGenFramebuffers, { "GenFramebuffers", "GenFramebuffersEXT", NULL } },
         { (PRFuncPtr*) &fGenRenderbuffers, { "GenRenderbuffers", "GenRenderbuffersEXT", NULL } },
         { (PRFuncPtr*) &fGetFramebufferAttachmentParameteriv, { "GetFramebufferAttachmentParameteriv", "GetFramebufferAttachmentParameterivEXT", NULL } },
         { (PRFuncPtr*) &fGetRenderbufferParameteriv, { "GetRenderbufferParameteriv", "GetRenderbufferParameterivEXT", NULL } },
         { (PRFuncPtr*) &fIsFramebuffer, { "IsFramebuffer", "IsFramebufferEXT", NULL } },
         { (PRFuncPtr*) &fIsRenderbuffer, { "IsRenderbuffer", "IsRenderbufferEXT", NULL } },
         { (PRFuncPtr*) &fRenderbufferStorage, { "RenderbufferStorage", "RenderbufferStorageEXT", NULL } },
+#if 0
 	{ (PRFuncPtr*) &fMapBuffer, { "MapBuffer", NULL } },
 	{ (PRFuncPtr*) &fUnmapBuffer, { "UnmapBuffer", NULL } },
+#endif
 
         { NULL, { NULL } },
 
     };
 
     ok = LoadSymbols(&symbols[0], trygl, prefix);
 
     return ok;
--- a/content/canvas/src/glwrap.h
+++ b/content/canvas/src/glwrap.h
@@ -51,20 +51,16 @@
 #ifdef XP_WIN
 #define GLAPIENTRY __stdcall
 #else
 #define GLAPIENTRY
 #endif
 #define GLAPI
 #endif
 
-#ifdef WINCE
-#define USE_GLES2
-#endif
-
 typedef char realGLboolean;
 
 class LibrarySymbolLoader
 {
 public:
     bool OpenLibrary(const char *library);
 
     typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
@@ -296,20 +292,22 @@ public:
     typedef realGLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader);
     PFNGLISSHADERPROC fIsShader;
     typedef realGLboolean (GLAPIENTRY * PFNGLISTEXTUREPROC) (GLuint texture);
     PFNGLISTEXTUREPROC fIsTexture;
     typedef void (GLAPIENTRY * PFNGLLINEWIDTHPROC) (GLfloat width);
     PFNGLLINEWIDTHPROC fLineWidth;
     typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program);
     PFNGLLINKPROGRAMPROC fLinkProgram;
+#if 0
     typedef void * (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
     PFNGLMAPBUFFERPROC fMapBuffer;
     typedef realGLboolean (GLAPIENTRY * PFNGLUNAMPBUFFERPROC) (GLenum target);
     PFNGLUNAMPBUFFERPROC fUnmapBuffer;
+#endif
     typedef void (GLAPIENTRY * PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
     PFNGLPIXELSTOREIPROC fPixelStorei;
     typedef void (GLAPIENTRY * PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat bias);
     PFNGLPOLYGONOFFSETPROC fPolygonOffset;
     typedef void (GLAPIENTRY * PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
     PFNGLREADPIXELSPROC fReadPixels;
     typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, realGLboolean invert);
     PFNGLSAMPLECOVERAGEPROC fSampleCoverage;
--- a/content/canvas/src/localgl.h
+++ b/content/canvas/src/localgl.h
@@ -3020,16 +3020,19 @@ typedef PRInt32 GLintptr;
 #define LOCAL_GL_SUN_vertex 1
 #define LOCAL_GL_WIN_phong_shading 1
 #define LOCAL_GL_PHONG_WIN 0x80EA
 #define LOCAL_GL_PHONG_HINT_WIN 0x80EB
 #define LOCAL_GL_WIN_specular_fog 1
 #define LOCAL_GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
 #define LOCAL_GL_WIN_swap_hint 1
 
+#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE   0x8B9A
+#define LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+
 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
 #define WGL_ACCELERATION_ARB 0x2003
 #define WGL_NEED_PALETTE_ARB 0x2004
 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
 #define WGL_SWAP_METHOD_ARB 0x2007
@@ -3082,9 +3085,78 @@ typedef PRInt32 GLintptr;
 #define WGL_PBUFFER_LARGEST_ARB 0x2033
 #define WGL_PBUFFER_WIDTH_ARB 0x2034
 #define WGL_PBUFFER_HEIGHT_ARB 0x2035
 #define WGL_PBUFFER_LOST_ARB 0x2036
 
 #define WGL_SAMPLE_BUFFERS_ARB 0x2041
 #define WGL_SAMPLES_ARB 0x2042
 
+
+#define EGL_BUFFER_SIZE                 0x3020
+#define EGL_ALPHA_SIZE                  0x3021
+#define EGL_BLUE_SIZE                   0x3022
+#define EGL_GREEN_SIZE                  0x3023
+#define EGL_RED_SIZE                    0x3024
+#define EGL_DEPTH_SIZE                  0x3025
+#define EGL_STENCIL_SIZE                0x3026
+#define EGL_CONFIG_CAVEAT               0x3027
+#define EGL_CONFIG_ID                   0x3028
+#define EGL_LEVEL                       0x3029
+#define EGL_MAX_PBUFFER_HEIGHT          0x302A
+#define EGL_MAX_PBUFFER_PIXELS          0x302B
+#define EGL_MAX_PBUFFER_WIDTH           0x302C
+#define EGL_NATIVE_RENDERABLE           0x302D
+#define EGL_NATIVE_VISUAL_ID            0x302E
+#define EGL_NATIVE_VISUAL_TYPE          0x302F
+#define EGL_PRESERVED_RESOURCES         0x3030
+#define EGL_SAMPLES                     0x3031
+#define EGL_SAMPLE_BUFFERS              0x3032
+#define EGL_SURFACE_TYPE                0x3033
+#define EGL_TRANSPARENT_TYPE            0x3034
+#define EGL_TRANSPARENT_BLUE_VALUE      0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE     0x3036
+#define EGL_TRANSPARENT_RED_VALUE       0x3037
+#define EGL_NONE                        0x3038
+#define EGL_BIND_TO_TEXTURE_RGB         0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA        0x303A
+#define EGL_MIN_SWAP_INTERVAL           0x303B
+#define EGL_MAX_SWAP_INTERVAL           0x303C
+#define EGL_LUMINANCE_SIZE              0x303D
+#define EGL_ALPHA_MASK_SIZE             0x303E
+#define EGL_COLOR_BUFFER_TYPE           0x303F
+#define EGL_RENDERABLE_TYPE             0x3040
+#define EGL_MATCH_NATIVE_PIXMAP         0x3041
+#define EGL_CONFORMANT                  0x3042
+#define EGL_OPENGL_ES_BIT               0x0001
+#define EGL_OPENVG_BIT                  0x0002
+#define EGL_OPENGL_ES2_BIT              0x0004
+#define EGL_OPENGL_ES_API               0x30A0
+#define EGL_PBUFFER_BIT                 0x0001
+#define EGL_PIXMAP_BIT                  0x0002
+#define EGL_WINDOW_BIT                  0x0004
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
+#define EGL_VENDOR                      0x3053
+#define EGL_VERSION                     0x3054
+#define EGL_EXTENSIONS                  0x3055
+#define EGL_CLIENT_APIS                 0x308D
+#define EGL_HEIGHT                      0x3056
+#define EGL_WIDTH                       0x3057
+#define EGL_LARGEST_PBUFFER             0x3058
+#define EGL_TEXTURE_FORMAT              0x3080
+#define EGL_TEXTURE_TARGET              0x3081
+#define EGL_MIPMAP_TEXTURE              0x3082
+#define EGL_MIPMAP_LEVEL                0x3083
+#define EGL_RENDER_BUFFER               0x3086
+#define EGL_VG_COLORSPACE               0x3087
+#define EGL_VG_ALPHA_FORMAT             0x3088
+#define EGL_HORIZONTAL_RESOLUTION       0x3090
+#define EGL_VERTICAL_RESOLUTION         0x3091
+#define EGL_PIXEL_ASPECT_RATIO          0x3092
+#define EGL_SWAP_BEHAVIOR               0x3093
+#define EGL_MULTISAMPLE_RESOLVE         0x3099
+#define EGL_CONTEXT_CLIENT_TYPE         0x3097
+#define EGL_CONTEXT_CLIENT_VERSION      0x3098
+#define EGL_FALSE                       0
+#define EGL_TRUE                        1
+
 #endif
--- a/content/canvas/src/nsGLPbuffer.h
+++ b/content/canvas/src/nsGLPbuffer.h
@@ -43,31 +43,45 @@
 #include "c3d-standalone.h"
 #endif
 
 #include "nsStringGlue.h"
 
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 
-#if defined(WINCE)
-#include <egl/egl.h>
+#ifdef USE_EGL
+typedef int EGLint;
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+typedef void *EGLClientBuffer;
+#endif
+
+#ifdef XP_WIN
+#include "gfxWindowsSurface.h"
+#endif
+
+#ifdef MOZ_X11
+#include "gfxXlibSurface.h"
+#endif
+
+#if defined(WINCE) && defined(CAIRO_HAS_DDRAW_SURFACE)
 #include "gfxDDrawSurface.h"
 #endif
 
-#if defined(XP_WIN)
-#include "gfxWindowsSurface.h"
-#endif
-
-#if defined(XP_UNIX) && defined(MOZ_X11)
+#ifdef USE_GLX
 #define GLX_GLXEXT_LEGACY
 #include "GL/glx.h"
 #endif
 
-#ifdef XP_MACOSX
+#ifdef USE_CGL
 #include "gfxQuartzImageSurface.h"
 #include <OpenGL/CGLTypes.h>
 #endif
 
 #include "glwrap.h"
 
 namespace mozilla {
 class WebGLContext;
@@ -121,17 +135,17 @@ public:
 
     virtual gfxASurface* ThebesSurface();
 
 protected:
     nsRefPtr<gfxImageSurface> mThebesSurface;
     PrivateOSMesaContext mMesaContext;
 };
 
-#ifdef XP_MACOSX
+#ifdef USE_CGL
 class nsGLPbufferCGL :
     public nsGLPbuffer
 {
 public:
     nsGLPbufferCGL();
     virtual ~nsGLPbufferCGL();
 
     virtual PRBool Init(mozilla::WebGLContext *priv);
@@ -156,17 +170,17 @@ protected:
     nsRefPtr<gfxImageSurface> mThebesSurface;
     nsRefPtr<gfxQuartzImageSurface> mQuartzSurface;
 
     typedef void (GLAPIENTRY * PFNGLFLUSHPROC) (void);
     PFNGLFLUSHPROC fFlush;
 };
 #endif
 
-#if defined(XP_UNIX) && defined(MOZ_X11)
+#ifdef USE_GLX
 class nsGLPbufferGLX :
     public nsGLPbuffer
 {
 public:
     nsGLPbufferGLX();
     virtual ~nsGLPbufferGLX();
 
     virtual PRBool Init(mozilla::WebGLContext *priv);
@@ -183,17 +197,17 @@ protected:
 
     Display     *mDisplay;
     GLXFBConfig mFBConfig;
     GLXPbuffer mPbuffer;
     GLXContext mPbufferContext;
 };
 #endif
 
-#if defined(WINCE)
+#ifdef USE_EGL
 class nsGLPbufferEGL :
     public nsGLPbuffer
 {
 public:
     nsGLPbufferEGL();
     virtual ~nsGLPbufferEGL();
 
     virtual PRBool Init(mozilla::WebGLContext *priv);
@@ -206,22 +220,28 @@ public:
     virtual gfxASurface* ThebesSurface();
 
 protected:
     EGLDisplay mDisplay;
     EGLConfig mConfig;
     EGLSurface mSurface;
     EGLContext mContext;
 
+#if defined(XP_WIN)
     nsRefPtr<gfxImageSurface> mThebesSurface;
     nsRefPtr<gfxWindowsSurface> mWindowsSurface;
+#elif defined(MOZ_X11)
+    nsRefPtr<gfxImageSurface> mThebesSurface;
+    nsRefPtr<gfxXlibSurface> mXlibSurface;
+    Visual *mVisual;
+#endif
 };
 #endif
 
-#if defined(XP_WIN) && !defined(WINCE)
+#ifdef USE_WGL
 class nsGLPbufferWGL :
     public nsGLPbuffer
 {
 public:
     nsGLPbufferWGL();
     virtual ~nsGLPbufferWGL();
 
     virtual PRBool Init(mozilla::WebGLContext *priv);
--- a/content/canvas/src/nsGLPbufferEGL.cpp
+++ b/content/canvas/src/nsGLPbufferEGL.cpp
@@ -32,199 +32,456 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // this must be first, else windows.h breaks us
-#include "nsICanvasRenderingContextGL.h"
+#include "WebGLContext.h"
+#include "nsGLPbuffer.h"
 
 #include "nsDirectoryServiceUtils.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIPrefService.h"
 
-#include "nsGLPbuffer.h"
-#include "nsCanvasRenderingContextGL.h"
-
 #include "gfxContext.h"
 
 #include "glwrap.h"
 
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
+#ifdef MOZ_X11
+#include <gdk/gdkx.h>
+
+typedef Display* EGLNativeDisplayType;
+typedef Window EGLNativeWindowType;
+typedef Pixmap EGLNativePixmapType;
+#endif
+
+#ifdef WINCE
+typedef HDC EGLNativeDisplayType;
+typedef HWND EGLNativeWindowType;
+typedef HDC EGLNativePixmapType;
+#endif
+
+// some EGL defines
+#define EGL_DEFAULT_DISPLAY             ((EGLNativeDisplayType)0)
+#define EGL_NO_CONTEXT                  ((EGLContext)0)
+#define EGL_NO_DISPLAY                  ((EGLDisplay)0)
+#define EGL_NO_SURFACE                  ((EGLSurface)0)
+
+using namespace mozilla;
 
 static PRUint32 gActiveBuffers = 0;
 
+class EGLWrap
+    : public LibrarySymbolLoader
+{
+public:
+    EGLWrap() : fGetCurrentContext(0) { }
+
+    bool Init();
+
+public:
+    typedef EGLDisplay (*pfnGetDisplay)(void *display_id);
+    pfnGetDisplay fGetDisplay;
+    typedef EGLContext (*pfnGetCurrentContext)(void);
+    pfnGetCurrentContext fGetCurrentContext;
+    typedef EGLBoolean (*pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+    pfnMakeCurrent fMakeCurrent;
+    typedef EGLBoolean (*pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+    pfnDestroyContext fDestroyContext;
+    typedef EGLContext (*pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+    pfnCreateContext fCreateContext;
+    typedef EGLBoolean (*pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+    pfnDestroySurface fDestroySurface;
+    typedef EGLSurface (*pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+    pfnCreatePbufferSurface fCreatePbufferSurface;
+    typedef EGLSurface (*pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+    pfnCreatePixmapSurface fCreatePixmapSurface;
+    typedef EGLBoolean (*pfnBindAPI)(EGLenum api);
+    pfnBindAPI fBindAPI;
+    typedef EGLBoolean (*pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+    pfnInitialize fInitialize;
+    typedef EGLBoolean (*pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+    pfnChooseConfig fChooseConfig;
+    typedef EGLint (*pfnGetError)(void);
+    pfnGetError fGetError;
+    typedef EGLBoolean (*pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+    pfnGetConfigAttrib fGetConfigAttrib;
+    typedef EGLBoolean (*pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+    pfnGetConfigs fGetConfigs;
+    typedef EGLBoolean (*pfnWaitNative)(EGLint engine);
+    pfnWaitNative fWaitNative;
+};
+
+bool
+EGLWrap::Init()
+{
+    if (fGetDisplay)
+        return true;
+
+    SymLoadStruct symbols[] = {
+        { (PRFuncPtr*) &fGetDisplay, { "eglGetDisplay", NULL } },
+        { (PRFuncPtr*) &fGetCurrentContext, { "eglGetCurrentContext", NULL } },
+        { (PRFuncPtr*) &fMakeCurrent, { "eglMakeCurrent", NULL } },
+        { (PRFuncPtr*) &fDestroyContext, { "eglDestroyContext", NULL } },
+        { (PRFuncPtr*) &fCreateContext, { "eglCreateContext", NULL } },
+        { (PRFuncPtr*) &fDestroySurface, { "eglDestroySurface", NULL } },
+        { (PRFuncPtr*) &fCreatePbufferSurface, { "eglCreatePbufferSurface", NULL } },
+        { (PRFuncPtr*) &fCreatePixmapSurface, { "eglCreatePixmapSurface", NULL } },
+        { (PRFuncPtr*) &fBindAPI, { "eglBindAPI", NULL } },
+        { (PRFuncPtr*) &fInitialize, { "eglInitialize", NULL } },
+        { (PRFuncPtr*) &fChooseConfig, { "eglChooseConfig", NULL } },
+        { (PRFuncPtr*) &fGetError, { "eglGetError", NULL } },
+        { (PRFuncPtr*) &fGetConfigs, { "eglGetConfigs", NULL } },
+        { (PRFuncPtr*) &fGetConfigAttrib, { "eglGetConfigAttrib", NULL } },
+        { (PRFuncPtr*) &fWaitNative, { "eglWaitNative", NULL } },
+        { NULL, { NULL } }
+    };
+
+    return LoadSymbols(&symbols[0], true);
+}
+
+static EGLWrap gEGLWrap;
+
 nsGLPbufferEGL::nsGLPbufferEGL()
     : mDisplay(0), mConfig(0), mSurface(0)
 {
     gActiveBuffers++;
-    fprintf (stderr, "nsGLPbufferEGL: gActiveBuffers: %d\n", gActiveBuffers);
 }
 
+#ifdef WINCE
+// XXX wrong
+#define EGL_LIB "\\windows\\libEGL.dll"
+#define GLES2_LIB "\\windows\\libGLESv2.dll"
+#else
+#define EGL_LIB "/usr/lib/libEGL.so"
+#define GLES2_LIB "/usr/lib/libGLESv2.so"
+#endif
+
 PRBool
-nsGLPbufferEGL::Init(nsCanvasRenderingContextGLPrivate *priv)
+nsGLPbufferEGL::Init(mozilla::WebGLContext *priv)
 {
     mPriv = priv;
 
-    nsresult rv;
+#ifdef NS_OSSO
+    // Maemo has missing DSO dependencies on their OpenGL libraries;
+    // so ensure that the prerequisite libs are loaded in the process
+    // before loading GL.  An alternate approach is to use LD_PRELOAD.
+
+    // We'll just leak these libs; pvr_um.so seems to have been
+    // present on an older OS image, and now pvr2d.so is used.
+    PRLibSpec lspec;
+    lspec.type = PR_LibSpec_Pathname;
 
-    mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    lspec.value.pathname = "/usr/lib/libpvr_um.so";
+    PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_GLOBAL);
 
-    if (!eglInitialize(mDisplay, NULL, NULL)) {
-        LogMessage(NS_LITERAL_CSTRING("egl init failed"));
+    lspec.value.pathname = "/usr/lib/libpvr2d.so";
+    PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_GLOBAL);
+#endif
+
+    if (!gEGLWrap.OpenLibrary(EGL_LIB)) {
+        LogMessage("egl OpenLibrary failed");
         return PR_FALSE;
     }
 
-    eglBindAPI (EGL_OPENGL_ES_API);
+    if (!gEGLWrap.Init()) {
+        LogMessage("eglWrap init failed");
+        return PR_FALSE;
+    }
+
+    mDisplay = gEGLWrap.fGetDisplay(0);
 
+    if (!gEGLWrap.fInitialize(mDisplay, NULL, NULL)) {
+        LogMessage("egl init failed");
+        return PR_FALSE;
+    }
+
+    gEGLWrap.fBindAPI (EGL_OPENGL_ES_API);
+
+#if defined(MOZ_X11) && defined(NS_OSSO)
     EGLint attribs[] = {
         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
-#if 0
+        EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,
         EGL_RED_SIZE, 3,
         EGL_GREEN_SIZE, 3,
         EGL_BLUE_SIZE, 3,
-        /* EGL_ALPHA_SIZE, 3, */
+        EGL_ALPHA_SIZE, 3,
         EGL_DEPTH_SIZE, 1,
-#endif
         EGL_NONE
     };
 
     
+    EGLint ncfg = 0;
     EGLConfig cfg;
-    EGLint ncfg = 0;
+
+    if (!gEGLWrap.fChooseConfig(mDisplay, attribs, &cfg, 1, &ncfg) ||
+        ncfg < 1)
+    {
+        LogMessage("Canvas 3D: eglChooseConfig failed (ncfg: %d err: 0x%04x)", ncfg, gEGLWrap.fGetError());
+        return PR_FALSE;
+    }
+
+    EGLint visid;
 
-    if (!eglChooseConfig(mDisplay, attribs, &cfg, 1, &ncfg) ||
-        ncfg != 1)
-    {
-        LogMessage(NS_LITERAL_CSTRING("Canvas 3D: eglChooseConfig failed"));
+    gEGLWrap.fGetConfigAttrib(mDisplay, cfg, EGL_NATIVE_VISUAL_ID, &visid);
+
+    XVisualInfo vinfo;
+    vinfo.visualid = visid;
+    int pad;
+
+    LogMessage("Visual ID: %d\n", visid);
+
+    XVisualInfo *vf = XGetVisualInfo(gdk_x11_get_default_xdisplay(), VisualIDMask, &vinfo, &pad);
+
+    if (!vf) {
+        LogMessage("Null VisualInfo!");
         return PR_FALSE;
     }
 
+    LogMessage("Visual: 0x%08x\n", vf->visual);
+
+    mVisual = vf->visual;
     mConfig = cfg;
+#elif defined(WINCE)
+#define MAX_CONFIGS 32
+    EGLConfig configs[MAX_CONFIGS];
+    EGLint numConfigs;
 
+    gEGLWrap.fGetConfigs(mDisplay, configs, MAX_CONFIGS, &numConfigs);
+
+    mConfig = 0;
+
+    for (int i = 0; i < numConfigs; ++i) {
+        EGLint id;
+        EGLint surfaces, renderables;
+        EGLint rsize, gsize, bsize, asize, dsize;
+
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_CONFIG_ID, &id);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_SURFACE_TYPE, &surfaces);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_RENDERABLE_TYPE, &renderables);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_RED_SIZE, &rsize);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_GREEN_SIZE, &gsize);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_BLUE_SIZE, &bsize);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_ALPHA_SIZE, &asize);
+        gEGLWrap.fGetConfigAttrib(mDisplay, configs[i], EGL_DEPTH_SIZE, &dsize);
+
+#ifdef DEBUG_vladimir
+        fprintf(stderr, "config 0x%02x: s %x api %x rgba %d %d %d %d d %d\n", id, surfaces, renderables, rsize, gsize, bsize, asize, dsize);
+#endif
+
+        if ((surfaces & EGL_PBUFFER_BIT) &&
+            (renderables & EGL_OPENGL_ES2_BIT) &&
+            (rsize > 3) &&
+            (gsize > 3) &&
+            (bsize > 3) &&
+            (asize > 3) &&
+            (dsize > 1))
+        {
+            mConfig = configs[i];
+            break;
+        }
+    }
+
+    if (mConfig == 0) {
+        LogMessage("Failed to find config!");
+        return PR_FALSE;
+    }
+#else
+#error need some boilerplate code for EGL
+#endif
+
+    LogMessage("Resize 2,2");
     Resize(2, 2);
 
-    if (!mGLWrap.OpenLibrary("\\windows\\libglesv2.dll")) {
-        LogMessage(NS_LITERAL_CSTRING("Canvas 3D: Couldn't open opengl lib [1]"));
+    LogMessage("OpenLibrary");
+    if (!mGLWrap.OpenLibrary(GLES2_LIB)) {
+        LogMessage("Canvas 3D: Couldn't open EGL lib [1]");
         return PR_FALSE;
     }
 
+    LogMessage("GLWrap.Init");
     if (!mGLWrap.Init(GLES20Wrap::TRY_NATIVE_GL)) {
-        LogMessage(NS_LITERAL_CSTRING("Canvas 3D: GLWrap init failed"));
+        LogMessage("Canvas 3D: GLWrap init failed");
         return PR_FALSE;
     }
-
+    LogMessage("Init done");
     return PR_TRUE;
 }
 
 PRBool
 nsGLPbufferEGL::Resize(PRInt32 width, PRInt32 height)
 {
     if (mWidth == width &&
         mHeight == height)
     {
         return PR_TRUE;
     }
 
+    LogMessage("Resize %d %d start", width, height);
+
     Destroy();
 
+    LogMessage("Destroyed");
+
+#ifdef XP_WIN
     mWindowsSurface = new gfxWindowsSurface(gfxIntSize(width, height),
                                             gfxASurface::ImageFormatARGB32);
     if (mWindowsSurface->CairoStatus() != 0) {
+#ifdef DEBUG_vladimir
         fprintf (stderr, "image surface failed\n");
+#endif
         return PR_FALSE;
     }
 
     mThebesSurface = mWindowsSurface->GetImageSurface();
 
     EGLint attrs[] = {
         EGL_WIDTH, width,
         EGL_HEIGHT, height,
         EGL_NONE
     };
 
-    mSurface = eglCreatePbufferSurface(mDisplay, mConfig, attrs);
+    mSurface = gEGLWrap.fCreatePbufferSurface(mDisplay, mConfig, attrs);
     if (!mSurface) {
-        LogMessage(NS_LITERAL_CSTRING("Canvas 3D: eglCreatePbufferSurface failed"));
+        LogMessage("Canvas 3D: eglCreatePbufferSurface failed");
+        return PR_FALSE;
+    }
+#else
+
+    mXlibSurface = new gfxXlibSurface(gdk_x11_get_default_xdisplay(),
+                                        mVisual,
+                                        gfxIntSize(width, height),
+                                        32);
+    if (!mXlibSurface || mXlibSurface->CairoStatus() != 0) {
+#ifdef DEBUG_vladimir
+        fprintf (stderr, "Failed to create gfxXlibSurface");
+#endif
         return PR_FALSE;
     }
 
-    eglBindAPI(EGL_OPENGL_ES_API);
+    LogMessage("Created gfxXlibSurface, Drawable: 0x%08x", mXlibSurface->XDrawable());
+
+    // we need to XSync to ensure that the Pixmap is created on the server side,
+    // otherwise eglCreatePixmapSurface will fail (because it isn't part of the normal
+    // X protocol).
+    XSync(gdk_x11_get_default_xdisplay(), 0);
+
+    EGLint attrs[] = {
+        EGL_NONE
+    };
+
+    Pixmap px = (Pixmap) mXlibSurface->XDrawable();
+
+    mSurface = gEGLWrap.fCreatePixmapSurface(mDisplay, mConfig, (EGLNativePixmapType) px, attrs);
+    if (!mSurface) {
+#ifdef DEBUG_vladimir
+        fprintf (stderr, "Failed to create Pixmap EGLSurface\n");
+#endif
+        return PR_FALSE;
+    }
+
+    LogMessage("mSurface: %p", mSurface);
+#endif
+
+    gEGLWrap.fBindAPI(EGL_OPENGL_ES_API);
 
     EGLint cxattrs[] = {
         EGL_CONTEXT_CLIENT_VERSION, 2,
         EGL_NONE
     };
 
-    mContext = eglCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, cxattrs);
+    mContext = gEGLWrap.fCreateContext(mDisplay, mConfig, EGL_NO_CONTEXT, cxattrs);
     if (!mContext) {
         Destroy();
         return PR_FALSE;
     }
 
     mWidth = width;
     mHeight = height;
 
-    fprintf (stderr, "Resize: %d %d\n", width, height);
+#ifdef MOZ_X11
+    mThebesSurface = new gfxImageSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32);
+#endif
+
     return PR_TRUE;
 }
 
 void
 nsGLPbufferEGL::Destroy()
 {
     if (mContext) {
-        eglDestroyContext(mDisplay, mContext);
+        gEGLWrap.fDestroyContext(mDisplay, mContext);
         mContext = 0;
     }
 
     if (mSurface) {
-        eglDestroySurface(mDisplay, mSurface);
+        gEGLWrap.fDestroySurface(mDisplay, mSurface);
         mSurface = 0;
     }
 
     sCurrentContextToken = nsnull;
+
+    // leak this
+#ifdef MOZ_X11
+    NS_IF_ADDREF(mXlibSurface.get());
+    mXlibSurface = nsnull;
+#else
+    mWindowsSurface = nsnull;
+#endif
+
     mThebesSurface = nsnull;
+
 }
 
 nsGLPbufferEGL::~nsGLPbufferEGL()
 {
     Destroy();
 
     gActiveBuffers--;
-    fprintf (stderr, "nsGLPbufferEGL: gActiveBuffers: %d\n", gActiveBuffers);
     fflush (stderr);
 }
 
 void
 nsGLPbufferEGL::MakeContextCurrent()
 {
-    if (eglGetCurrentContext() == mContext)
+    if (gEGLWrap.fGetCurrentContext() == mContext)
         return;
 
-    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
+    gEGLWrap.fMakeCurrent(mDisplay, mSurface, mSurface, mContext);
 }
 
 void
 nsGLPbufferEGL::SwapBuffers()
 {
     //    eglCopyBuffers(mDisplay, mSurface, mWindowsSurface->GetDC());
     MakeContextCurrent();
-    mGLWrap.fReadPixels (0, 0, mWidth, mHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, mThebesSurface->Data());
+
+    //printf ("SwapBuffers0: %04x\n", mGLWrap.fGetError());
+
+    // this is wrong, we need to figure out a way to swap this, but we don't do anything here
+    mGLWrap.fFinish ();
+
+    mGLWrap.fReadPixels (0, 0, mWidth, mHeight, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, mThebesSurface->Data());
+
+    //printf ("SwapBuffers: %04x\n", mGLWrap.fGetError());
 
 #if 0
     // premultiply the image
     int len = mWidth*mHeight*4;
     unsigned char *src = mThebesSurface->Data();
     Premultiply(src, len);
 #endif
 }
 
 gfxASurface*
 nsGLPbufferEGL::ThebesSurface()
 {
+#if defined(MOZ_X11) && defined(NS_OSSO)
+    if (getenv("IMAGE"))
+        return mThebesSurface;
+    return mXlibSurface;
+#elif defined(WINCE)
     return mThebesSurface;
+#endif
 }
--- a/gfx/thebes/public/gfxXlibSurface.h
+++ b/gfx/thebes/public/gfxXlibSurface.h
@@ -49,20 +49,22 @@ public:
     // create a surface for the specified dpy/drawable/visual.
     // Will use XGetGeometry to query the window/pixmap size.
     gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual);
 
     // create a surface for the specified dpy/drawable/visual,
     // with explicitly provided width/height.
     gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size);
 
-    // create a new Pixmap on the display dpy, with
-    // the root window as the parent and the default depth
-    // for the default screen, and attach the given visual
-    gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size);
+    // create a new Pixmap on the display dpy, with the root window as
+    // the parent and the default depth for the default screen, and
+    // attach the given visual.  The depth argument is optional, and
+    // if not specified (or 0), the default depth of the default
+    // screen of dpy is used.
+    gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size, int depth = 0);
 
     gfxXlibSurface(Display* dpy, Drawable drawable, XRenderPictFormat *format,
                    const gfxIntSize& size);
 
     gfxXlibSurface(Display* dpy, XRenderPictFormat *format,
                    const gfxIntSize& size);
 
     gfxXlibSurface(cairo_surface_t *csurf);
--- a/gfx/thebes/src/gfxXlibSurface.cpp
+++ b/gfx/thebes/src/gfxXlibSurface.cpp
@@ -66,27 +66,27 @@ gfxXlibSurface::gfxXlibSurface(Display *
 {
     if (!CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT))
         return;
 
     cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, mSize.width, mSize.height);
     Init(surf);
 }
 
-gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size)
+gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size, int depth)
     : mPixmapTaken(PR_FALSE), mDisplay(dpy), mSize(size)
 
 {
     if (!CheckSurfaceSize(size, XLIB_IMAGE_SIDE_SIZE_LIMIT))
         return;
 
     mDrawable = (Drawable)XCreatePixmap(dpy,
                                         RootWindow(dpy, DefaultScreen(dpy)),
                                         mSize.width, mSize.height,
-                                        DefaultDepth(dpy, DefaultScreen(dpy)));
+                                        depth ? depth : DefaultDepth(dpy, DefaultScreen(dpy)));
 
     cairo_surface_t *surf = cairo_xlib_surface_create(dpy, mDrawable, visual, mSize.width, mSize.height);
 
     Init(surf);
     TakePixmap();
 }
 
 gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, XRenderPictFormat *format,