Bug 1014614 - Fix readback of SurfaceTextureImage r=jgilbert
💩💩 backed out by 53e24fd12cd1 💩 💩
authorJames Willcox <snorp@snorp.net>
Fri, 17 Oct 2014 10:35:13 -0500
changeset 210954 40f99ba7f616
parent 210953 8fbc3c85adfc
child 210955 cb31d5a52868
push id50598
push userjwillcox@mozilla.com
push date2014-10-17 15:36 +0000
treeherdermozilla-inbound@40f99ba7f616 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1014614
milestone36.0a1
Bug 1014614 - Fix readback of SurfaceTextureImage r=jgilbert
gfx/layers/GLImages.cpp
gfx/layers/GLImages.h
gfx/layers/moz.build
new file mode 100644
--- /dev/null
+++ b/gfx/layers/GLImages.cpp
@@ -0,0 +1,60 @@
+#ifdef MOZ_WIDGET_ANDROID
+
+#include "GLImages.h"
+#include "GLContext.h"
+#include "GLContextProvider.h"
+#include "ScopedGLHelpers.h"
+#include "GLImages.h"
+#include "GLBlitHelper.h"
+#include "GLReadTexImageHelper.h"
+#include "AndroidSurfaceTexture.h"
+
+using namespace mozilla;
+using namespace mozilla::gl;
+
+static Mutex sSnapshotMutex("SurfaceTextureImage::sSnapshotMutex");
+static nsRefPtr<GLContext> sSnapshotContext;
+
+TemporaryRef<gfx::SourceSurface>
+SurfaceTextureImage::GetAsSourceSurface()
+{
+  MutexAutoLock lock(sSnapshotMutex);
+
+  MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
+
+  if (!sSnapshotContext) {
+    SurfaceCaps caps = SurfaceCaps::ForRGBA();
+    sSnapshotContext = GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
+
+    if (!sSnapshotContext) {
+      return nullptr;
+    }
+  }
+
+  sSnapshotContext->MakeCurrent();
+  ScopedTexture scopedTex(sSnapshotContext);
+  ScopedBindTexture boundTex(sSnapshotContext, scopedTex.Texture());
+  sSnapshotContext->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA,
+                                mData.mSize.width, mData.mSize.height, 0,
+                                LOCAL_GL_RGBA,
+                                LOCAL_GL_UNSIGNED_BYTE,
+                                nullptr);
+
+  ScopedFramebufferForTexture fb(sSnapshotContext, scopedTex.Texture());
+
+  GLBlitHelper helper(sSnapshotContext);
+
+  helper.BlitImageToFramebuffer(this, mData.mSize, fb.FB(), false);
+  ScopedBindFramebuffer bind(sSnapshotContext, fb.FB());
+
+  RefPtr<DataSourceSurface> source =
+        Factory::CreateDataSourceSurface(mData.mSize, gfx::SurfaceFormat::B8G8R8A8);
+  if (NS_WARN_IF(!source)) {
+    return nullptr;
+  }
+
+  ReadPixelsIntoDataSurface(sSnapshotContext, source);
+  return source.forget();
+}
+
+#endif
--- a/gfx/layers/GLImages.h
+++ b/gfx/layers/GLImages.h
@@ -52,20 +52,17 @@ public:
     bool mInverted;
   };
 
   void SetData(const Data& aData) { mData = aData; }
   const Data* GetData() { return &mData; }
 
   gfx::IntSize GetSize() { return mData.mSize; }
 
-  virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE
-  {
-    return nullptr;
-  }
+  virtual TemporaryRef<gfx::SourceSurface> GetAsSourceSurface() MOZ_OVERRIDE;
 
   SurfaceTextureImage() : Image(nullptr, ImageFormat::SURFACE_TEXTURE) {}
 
 private:
   Data mData;
 };
 
 #endif // MOZ_WIDGET_ANDROID
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -283,16 +283,17 @@ UNIFIED_SOURCES += [
     'composite/LayerManagerComposite.cpp',
     'composite/PaintedLayerComposite.cpp',
     'composite/TextRenderer.cpp',
     'composite/TextureHost.cpp',
     'composite/TiledContentHost.cpp',
     'Compositor.cpp',
     'CopyableCanvasLayer.cpp',
     'Effects.cpp',
+    'GLImages.cpp',
     'ImageDataSerializer.cpp',
     'ImageLayers.cpp',
     'ipc/AsyncTransactionTracker.cpp',
     'ipc/CompositableTransactionParent.cpp',
     'ipc/CompositorBench.cpp',
     'ipc/CompositorChild.cpp',
     'ipc/CompositorParent.cpp',
     'ipc/ImageBridgeChild.cpp',