Bug 867656 - Part 1. Implement GetAsSurface for GL TextureHosts. r=bjacob
authorNicolas Silva <nical.bugzilla@gmail.com>
Sun, 26 May 2013 04:43:43 +0200
changeset 133458 3ded05a81797e93e0373b75ada927dbdd6f99d45
parent 133457 dcc5e600d4d3a35e3e42aa9e0e71f414e6b3eee5
child 133459 e6826a5768ef370c56d51eb40b247ab91f8061f3
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersbjacob
bugs867656
milestone24.0a1
Bug 867656 - Part 1. Implement GetAsSurface for GL TextureHosts. r=bjacob
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/composite/CanvasLayerComposite.cpp
gfx/layers/composite/CompositableHost.h
gfx/layers/composite/ContentHost.h
gfx/layers/composite/ImageHost.h
gfx/layers/composite/ImageLayerComposite.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/composite/ThebesLayerComposite.cpp
gfx/layers/d3d11/TextureD3D11.h
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -54,16 +54,24 @@ protected:
       mSurface = mCompositor->GetDrawTarget()->CreateSourceSurfaceFromData(mThebesImage->Data(),
                                                                            mSize,
                                                                            mThebesImage->Stride(),
                                                                            mFormat);
     }
     return true;
   }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE {
+    if (!mThebesImage) {
+      mThebesImage = mThebesSurface->GetAsImageSurface();
+    }
+    nsRefPtr<gfxImageSurface> result = mThebesImage;
+    return result.forget();
+  }
+
   BasicCompositor *mCompositor;
   RefPtr<SourceSurface> mSurface;
   nsRefPtr<gfxImageSurface> mThebesImage;
   nsRefPtr<gfxASurface> mThebesSurface;
   IntSize mSize;
 };
 
 TemporaryRef<TextureHost>
--- a/gfx/layers/composite/CanvasLayerComposite.cpp
+++ b/gfx/layers/composite/CanvasLayerComposite.cpp
@@ -6,16 +6,17 @@
 #include "ipc/AutoOpenSurface.h"
 #include "mozilla/layers/PLayerTransaction.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layers/CompositorTypes.h" // for TextureInfo
 #include "mozilla/layers/Effects.h"
 
 #include "CanvasLayerComposite.h"
 #include "ImageHost.h"
+#include "gfxUtils.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 
 CanvasLayerComposite::CanvasLayerComposite(LayerManagerComposite* aManager)
   : CanvasLayer(aManager, nullptr)
   , LayerComposite(aManager)
@@ -56,16 +57,23 @@ CanvasLayerComposite::RenderLayer(const 
                                   const nsIntRect& aClipRect)
 {
   if (!mImageHost) {
     return;
   }
 
   mCompositor->MakeCurrent();
 
+#ifdef MOZ_DUMP_PAINTING
+  if (gfxUtils::sDumpPainting) {
+    nsRefPtr<gfxImageSurface> surf = mImageHost->GetAsSurface();
+    WriteSnapshotToDumpFile(this, surf);
+  }
+#endif
+
   gfxPattern::GraphicsFilter filter = mFilter;
 #ifdef ANDROID
   // Bug 691354
   // Using the LINEAR filter we get unexplained artifacts.
   // Use NEAREST when no scaling is required.
   gfxMatrix matrix;
   bool is2D = GetEffectiveTransform().Is2D(&matrix);
   if (is2D && !matrix.HasNonTranslationOrFlip()) {
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -189,16 +189,20 @@ public:
     SetCompositor(aCompositor);
     SetLayer(aLayer);
   }
   void Detach() {
     SetLayer(nullptr);
     SetCompositor(nullptr);
   }
 
+#ifdef MOZ_DUMP_PAINTING
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() { return nullptr; }
+#endif
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix) { }
 #endif
 
 protected:
   TextureInfo mTextureInfo;
   Compositor* mCompositor;
   Layer* mLayer;
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -29,20 +29,16 @@ public:
   // tiling.
   virtual TiledLayerComposer* AsTiledLayerComposer() { return nullptr; }
 
   virtual void UpdateThebes(const ThebesBufferData& aData,
                             const nsIntRegion& aUpdated,
                             const nsIntRegion& aOldValidRegionBack,
                             nsIntRegion* aUpdatedRegionBack) = 0;
 
-#ifdef MOZ_DUMP_PAINTING
-  virtual already_AddRefed<gfxImageSurface> Dump() { return nullptr; }
-#endif
-  
   virtual void SetPaintWillResample(bool aResample) { }
 
 protected:
   ContentHost(const TextureInfo& aTextureInfo)
     : CompositableHost(aTextureInfo)
   {}
 };
 
@@ -88,19 +84,19 @@ public:
     result.mFlags = (mBufferRotation != nsIntPoint()) ?
                     LAYER_RENDER_STATE_BUFFER_ROTATION : 0;
     return result;
   }
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
 #ifdef MOZ_DUMP_PAINTING
-  virtual already_AddRefed<gfxImageSurface> Dump()
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface()
   {
-    return mTextureHost->Dump();
+    return mTextureHost->GetAsSurface();
   }
 #endif
 
   virtual TextureHost* GetTextureHost() MOZ_OVERRIDE;
 
   virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
   // The client has destroyed its texture clients and we should destroy our
   // texture hosts and SurfaceDescriptors. Note that we don't immediately
--- a/gfx/layers/composite/ImageHost.h
+++ b/gfx/layers/composite/ImageHost.h
@@ -82,16 +82,23 @@ public:
   }
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 #endif
 
+#ifdef MOZ_DUMP_PAINTING
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
+  {
+    return mTextureHost->GetAsSurface();
+  }
+#endif
+
 protected:
   virtual void MakeTextureHost(TextureIdentifier aTextureId,
                                const SurfaceDescriptor& aSurface,
                                ISurfaceAllocator* aAllocator,
                                const TextureInfo& aTextureInfo);
 
   RefPtr<TextureHost> mTextureHost;
   nsIntRect mPictureRect;
--- a/gfx/layers/composite/ImageLayerComposite.cpp
+++ b/gfx/layers/composite/ImageLayerComposite.cpp
@@ -5,16 +5,17 @@
 
 #include "gfxSharedImageSurface.h"
 
 #include "ipc/AutoOpenSurface.h"
 #include "ImageLayerComposite.h"
 #include "ImageHost.h"
 #include "gfxImageSurface.h"
 #include "gfx2DGlue.h"
+#include "gfxUtils.h"
 
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/CompositorTypes.h" // for TextureInfo
 #include "mozilla/layers/Effects.h"
 #include "CompositableHost.h"
 
 using namespace mozilla::gfx;
 
@@ -68,16 +69,23 @@ ImageLayerComposite::GetLayer()
 void
 ImageLayerComposite::RenderLayer(const nsIntPoint& aOffset,
                                  const nsIntRect& aClipRect)
 {
   if (!mImageHost) {
     return;
   }
 
+#ifdef MOZ_DUMP_PAINTING
+  if (gfxUtils::sDumpPainting) {
+    nsRefPtr<gfxImageSurface> surf = mImageHost->GetAsSurface();
+    WriteSnapshotToDumpFile(this, surf);
+  }
+#endif
+
   mCompositor->MakeCurrent();
 
   EffectChain effectChain;
   LayerManagerComposite::AddMaskEffect(mMaskLayer, effectChain);
 
   gfx::Matrix4x4 transform;
   ToMatrix4x4(GetEffectiveTransform(), transform);
   gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -223,35 +223,33 @@ public:
    */
   virtual void SetCompositor(Compositor* aCompositor) {}
 
   ISurfaceAllocator* GetDeAllocator()
   {
     return mDeAllocator;
   }
 
-#ifdef MOZ_DUMP_PAINTING
-  virtual already_AddRefed<gfxImageSurface> Dump() { return nullptr; }
-#endif
-
   bool operator== (const TextureHost& o) const
   {
     return GetIdentifier() == o.GetIdentifier();
   }
   bool operator!= (const TextureHost& o) const
   {
     return GetIdentifier() != o.GetIdentifier();
   }
 
   LayerRenderState GetRenderState()
   {
     return LayerRenderState(mBuffer,
                             mFlags & NeedsYFlip ? LAYER_RENDER_STATE_Y_FLIPPED : 0);
   }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() = 0;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char *Name() = 0;
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 #endif
 
   /**
    * TEMPORARY.
    *
--- a/gfx/layers/composite/ThebesLayerComposite.cpp
+++ b/gfx/layers/composite/ThebesLayerComposite.cpp
@@ -96,17 +96,17 @@ ThebesLayerComposite::RenderLayer(const 
   }
 
   gfx::Matrix4x4 transform;
   ToMatrix4x4(GetEffectiveTransform(), transform);
   gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
 
 #ifdef MOZ_DUMP_PAINTING
   if (gfxUtils::sDumpPainting) {
-    nsRefPtr<gfxImageSurface> surf = mBuffer->Dump();
+    nsRefPtr<gfxImageSurface> surf = mBuffer->GetAsSurface();
     WriteSnapshotToDumpFile(this, surf);
   }
 #endif
 
   EffectChain effectChain;
   LayerManagerComposite::AddMaskEffect(mMaskLayer, effectChain);
 
   nsIntRegion visibleRegion = GetEffectiveVisibleRegion();
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -117,16 +117,21 @@ public:
   }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual LayerRenderState GetRenderState() { return LayerRenderState(); }
 
   virtual bool Lock() MOZ_OVERRIDE { return true; }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
+  {
+    return nullptr; // TODO: cf bug 872568
+  }
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "TextureHostShmemD3D11"; }
 #endif
 
   virtual void BeginTileIteration() MOZ_OVERRIDE {
     mIterating = true;
     mCurrentTile = 0;
   }
@@ -170,16 +175,21 @@ public:
 
   virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual bool Lock() MOZ_OVERRIDE;
   virtual void Unlock() MOZ_OVERRIDE;
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
+  {
+    return nullptr; // TODO: cf bug 872568
+  }
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "TextureHostDXGID3D11"; }
 #endif
 
 protected:
   virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
                           nsIntRegion* aRegion,
                           nsIntPoint* aOffset = nullptr) MOZ_OVERRIDE;
@@ -205,16 +215,21 @@ public:
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
   virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual bool IsYCbCrSource() const MOZ_OVERRIDE { return true; }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
+  {
+    return nullptr; // TODO: cf bug 872568
+  }
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() MOZ_OVERRIDE { return "TextureImageTextureHostD3D11"; }
 #endif
 
 protected:
   virtual void UpdateImpl(const SurfaceDescriptor& aSurface,
                           nsIntRegion* aRegion,
                           nsIntPoint* aOffset = nullptr) MOZ_OVERRIDE;
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -136,17 +136,16 @@ TextureImageTextureHostOGL::GetSize() co
       nsIntRect rect = mTexture->GetTileRect();
       return gfx::IntSize(rect.width, rect.height);
     }
     return gfx::IntSize(mTexture->GetSize().width, mTexture->GetSize().height);
   }
   return gfx::IntSize(0, 0);
 }
 
-
 void
 TextureImageTextureHostOGL::SetCompositor(Compositor* aCompositor)
 {
   CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
   GLContext* newGL = glCompositor ? glCompositor->gl() : nullptr;
   if (mGL != newGL) {
     mGL = newGL;
     mTexture = nullptr;
@@ -229,17 +228,17 @@ TextureImageTextureHostOGL::UpdateImpl(c
     mTexture->EndUpdate();
   }
 }
 
 bool
 TextureImageTextureHostOGL::Lock()
 {
   if (!mTexture) {
-    NS_WARNING("TextureImageAsTextureHost to be composited without texture");
+    NS_WARNING("TextureImageTextureHost to be composited without texture");
     return false;
   }
 
   NS_ASSERTION(mTexture->GetContentType() != gfxASurface::CONTENT_ALPHA,
                 "Image layer has alpha image");
 
   mFormat = FormatFromShaderType(mTexture->GetShaderProgramType());
 
@@ -872,10 +871,72 @@ GrallocTextureHostOGL::SetBuffer(Surface
 
   // only done for hacky fix in gecko 23 for bug 862324.
   // Doing this in SwapTextures is not enough, as the crash could occur right after SetBuffer.
   RegisterTextureHostAtGrallocBufferActor(this, *mBuffer);
 }
 
 #endif
 
+already_AddRefed<gfxImageSurface>
+TextureImageTextureHostOGL::GetAsSurface() {
+  nsRefPtr<gfxImageSurface> surf = IsValid() ?
+    mGL->GetTexImage(mTexture->GetTextureID(),
+                     false,
+                     mTexture->GetShaderProgramType())
+    : nullptr;
+  return surf.forget();
+}
+
+already_AddRefed<gfxImageSurface>
+YCbCrTextureHostOGL::GetAsSurface() {
+  nsRefPtr<gfxImageSurface> surf = IsValid() ?
+    mGL->GetTexImage(mYTexture->mTexImage->GetTextureID(),
+                     false,
+                     mYTexture->mTexImage->GetShaderProgramType())
+    : nullptr;
+  return surf.forget();
+}
+
+already_AddRefed<gfxImageSurface>
+SharedTextureHostOGL::GetAsSurface() {
+  nsRefPtr<gfxImageSurface> surf = IsValid() ?
+    mGL->GetTexImage(GetTextureHandle(),
+                     false,
+                     GetShaderProgram())
+    : nullptr;
+  return surf.forget();
+}
+
+already_AddRefed<gfxImageSurface>
+SurfaceStreamHostOGL::GetAsSurface() {
+  nsRefPtr<gfxImageSurface> surf = IsValid() ?
+    mGL->GetTexImage(mTextureHandle,
+                     false,
+                     GetShaderProgram())
+    : nullptr;
+  return surf.forget();
+}
+
+already_AddRefed<gfxImageSurface>
+TiledTextureHostOGL::GetAsSurface() {
+  nsRefPtr<gfxImageSurface> surf = IsValid() ?
+    mGL->GetTexImage(mTextureHandle,
+                     false,
+                     GetShaderProgram())
+    : nullptr;
+  return surf.forget();
+}
+
+#ifdef MOZ_WIDGET_GONK
+already_AddRefed<gfxImageSurface>
+GrallocTextureHostOGL::GetAsSurface() {
+  nsRefPtr<gfxImageSurface> surf = IsValid() && mGLTexture ?
+    mGL->GetTexImage(mGLTexture,
+                     false,
+                     GetShaderProgram())
+    : nullptr;
+  return surf.forget();
+}
+#endif
+
 } // namespace
 } // namespace
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -126,16 +126,18 @@ public:
 
   bool IsValid() const MOZ_OVERRIDE
   {
     return !!mTexture;
   }
 
   virtual bool Lock() MOZ_OVERRIDE;
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
+
   // textureSource
   void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE
   {
     mTexture->BindTexture(aTextureUnit);
   }
 
   gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
@@ -267,17 +269,16 @@ public:
     virtual gfx::IntSize GetSize() const MOZ_OVERRIDE
     {
       return gfx::IntSize(mTexImage->GetSize().width, mTexImage->GetSize().height);
     }
     virtual GLenum GetWrapMode() const MOZ_OVERRIDE
     {
       return mTexImage->GetWrapMode();
     }
-
   };
 
   // TextureSource implementation
 
   TextureSource* GetSubSource(int index) MOZ_OVERRIDE
   {
     switch (index) {
       case 0 : return mYTexture.get();
@@ -291,16 +292,18 @@ public:
   {
     if (!mYTexture->mTexImage) {
       NS_WARNING("YCbCrTextureHost::GetSize called but no data has been set yet");
       return gfx::IntSize(0,0);
     }
     return mYTexture->GetSize();
   }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "YCbCrTextureHostOGL"; }
 #endif
 
 private:
   RefPtr<Channel> mYTexture;
   RefPtr<Channel> mCbTexture;
   RefPtr<Channel> mCrTexture;
@@ -375,16 +378,18 @@ public:
   {
     return (mFormat == gfx::FORMAT_B8G8R8A8) ?
              gfxASurface::CONTENT_COLOR_ALPHA :
              gfxASurface::CONTENT_COLOR;
   }
 
   virtual gfx3DMatrix GetTextureTransform() MOZ_OVERRIDE;
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "SharedTextureHostOGL"; }
 #endif
 
 protected:
   void DeleteTextures();
 
   gfx::IntSize mSize;
@@ -458,16 +463,18 @@ public:
   }
   GLuint GetTextureID() { return mTextureHandle; }
   ContentType GetContentType() {
     return (mFormat == gfx::FORMAT_B8G8R8A8) ?
              gfxASurface::CONTENT_COLOR_ALPHA :
              gfxASurface::CONTENT_COLOR;
   }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "SurfaceStreamHostOGL"; }
 #endif
 
   SurfaceStreamHostOGL()
     : mGL(nullptr)
     , mTextureHandle(0)
     , mUploadTexture(0)
@@ -519,16 +526,18 @@ public:
   {
     return GetProgramTypeForTexture(this);
   }
 
   virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
                                 nsIntRegion* aRegion = nullptr)
   { MOZ_ASSERT(false, "Tiles should not use this path"); }
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "TiledTextureHostOGL"; }
 #endif
 
 protected:
   void DeleteTextures();
 
   virtual uint64_t GetIdentifier() const MOZ_OVERRIDE {
@@ -602,16 +611,18 @@ public:
 
   GLenum GetWrapMode() const MOZ_OVERRIDE
   {
     return LOCAL_GL_CLAMP_TO_EDGE;
   }
 
   bool IsValid() const MOZ_OVERRIDE;
 
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE;
+
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() { return "GrallocTextureHostOGL"; }
 #endif
 
   void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const;