Bug 640082 - Part 2 - Use texture_from_pixmap in CanvasLayerOGL. r=joe
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 09 Mar 2011 10:41:10 +1300
changeset 67634 bab34375319d680b726a6890116b6860479b364f
parent 67633 cd13b3b102e39766f1a6779e541971417f949361
child 67635 ea1b21a2bf821009cc2f2585a997586b85461cff
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs640082
milestone2.2a1pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 640082 - Part 2 - Use texture_from_pixmap in CanvasLayerOGL. r=joe
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -60,16 +60,22 @@ void
 CanvasLayerOGL::Destroy()
 {
   if (!mDestroyed) {
     if (mTexture) {
       GLContext *cx = mOGLManager->glForResources();
       cx->MakeCurrent();
       cx->fDeleteTextures(1, &mTexture);
     }
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+    if (mPixmap) {
+        sGLXLibrary.DestroyPixmap(mPixmap);
+        mPixmap = 0;
+    }
+#endif
 
     mDestroyed = PR_TRUE;
   }
 }
 
 void
 CanvasLayerOGL::Initialize(const Data& aData)
 {
@@ -77,19 +83,32 @@ CanvasLayerOGL::Initialize(const Data& a
 
   if (aData.mGLContext != nsnull &&
       aData.mSurface != nsnull)
   {
     NS_WARNING("CanvasLayerOGL can't have both surface and GLContext");
     return;
   }
 
+  mOGLManager->MakeCurrent();
+
   if (aData.mSurface) {
     mCanvasSurface = aData.mSurface;
     mNeedsYFlip = PR_FALSE;
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+    mPixmap = sGLXLibrary.CreatePixmap(aData.mSurface);
+    if (mPixmap) {
+        if (aData.mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
+            mLayerProgram = gl::RGBALayerProgramType;
+        } else {
+            mLayerProgram = gl::RGBXLayerProgramType;
+        }
+        MakeTexture();
+    }
+#endif
   } else if (aData.mGLContext) {
     if (!aData.mGLContext->IsOffscreen()) {
       NS_WARNING("CanvasLayerOGL with a non-offscreen GL context given");
       return;
     }
 
     mCanvasGLContext = aData.mGLContext;
     mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied;
@@ -138,16 +157,22 @@ CanvasLayerOGL::UpdateSurface()
   if (!mDirty)
     return;
   mDirty = PR_FALSE;
 
   if (mDestroyed || mDelayedUpdates) {
     return;
   }
 
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+  if (mPixmap) {
+    return;
+  }
+#endif
+
   mOGLManager->MakeCurrent();
 
   if (mCanvasGLContext &&
       mCanvasGLContext->GetContextType() == gl()->GetContextType())
   {
     if (gl()->BindOffscreenNeedsTexture(mCanvasGLContext) &&
         mTexture == 0)
     {
@@ -221,27 +246,39 @@ CanvasLayerOGL::RenderLayer(int aPreviou
                                    mTexture,
                                    true,
                                    drawRect.TopLeft());
   }
   if (!program) { 
     program = mOGLManager->GetColorTextureLayerProgram(mLayerProgram);
   }
 
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+  if (mPixmap && !mDelayedUpdates) {
+    sGLXLibrary.BindTexImage(mPixmap);
+  }
+#endif
+
   ApplyFilter(mFilter);
 
   program->Activate();
   program->SetLayerQuadRect(drawRect);
   program->SetLayerTransform(GetEffectiveTransform());
   program->SetLayerOpacity(GetEffectiveOpacity());
   program->SetRenderOffset(aOffset);
   program->SetTextureUnit(0);
 
   mOGLManager->BindAndDrawQuad(program, mNeedsYFlip ? true : false);
 
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+  if (mPixmap && !mDelayedUpdates) {
+    sGLXLibrary.ReleaseTexImage(mPixmap);
+  }
+#endif
+
   if (useGLContext) {
     gl()->UnbindTex2DOffscreen(mCanvasGLContext);
   }
 }
 
 
 ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
   : ShadowCanvasLayer(aManager, nsnull)
--- a/gfx/layers/opengl/CanvasLayerOGL.h
+++ b/gfx/layers/opengl/CanvasLayerOGL.h
@@ -38,30 +38,37 @@
 #ifndef GFX_CANVASLAYEROGL_H
 #define GFX_CANVASLAYEROGL_H
 
 #include "mozilla/layers/PLayers.h"
 #include "mozilla/layers/ShadowLayers.h"
 
 #include "LayerManagerOGL.h"
 #include "gfxASurface.h"
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+#include "GLXLibrary.h"
+#include "mozilla/X11Util.h"
+#endif
 
 namespace mozilla {
 namespace layers {
 
 class THEBES_API CanvasLayerOGL :
   public CanvasLayer,
   public LayerOGL
 {
 public:
   CanvasLayerOGL(LayerManagerOGL *aManager)
     : CanvasLayer(aManager, NULL),
       LayerOGL(aManager),
       mTexture(0),
       mDelayedUpdates(PR_FALSE)
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+      ,mPixmap(0)
+#endif
   { 
       mImplData = static_cast<LayerOGL*>(this);
   }
   ~CanvasLayerOGL() { Destroy(); }
 
   // CanvasLayer implementation
   virtual void Initialize(const Data& aData);
 
@@ -79,16 +86,19 @@ protected:
   gl::ShaderProgramType mLayerProgram;
 
   void MakeTexture();
   GLuint mTexture;
 
   PRPackedBool mDelayedUpdates;
   PRPackedBool mGLBufferIsPremultiplied;
   PRPackedBool mNeedsYFlip;
+#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+  GLXPixmap mPixmap;
+#endif
 };
 
 // NB: eventually we'll have separate shadow canvas2d and shadow
 // canvas3d layers, but currently they look the same from the
 // perspective of the compositor process
 class ShadowCanvasLayerOGL : public ShadowCanvasLayer,
                              public LayerOGL
 {