Bug 1014614 - Fix readback of SurfaceTextureImage r=jgilbert a=lsblakk
authorJames Willcox <snorp@snorp.net>
Wed, 05 Nov 2014 10:50:04 -0600
changeset 225867 dc39f1265c28
parent 225866 1ed1d7b0e4e3
child 225868 ce9444649361
push id7210
push userjwillcox@mozilla.com
push date2014-11-05 16:57 +0000
treeherdermozilla-aurora@ba9a79c05e9a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert, lsblakk
bugs1014614
milestone35.0a2
Bug 1014614 - Fix readback of SurfaceTextureImage r=jgilbert a=lsblakk
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,63 @@
+#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;
+
+namespace mozilla {
+namespace layers {
+
+static nsRefPtr<GLContext> sSnapshotContext;
+
+TemporaryRef<gfx::SourceSurface>
+SurfaceTextureImage::GetAsSourceSurface()
+{
+  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<gfx::DataSourceSurface> source =
+        gfx::Factory::CreateDataSourceSurface(mData.mSize, gfx::SurfaceFormat::B8G8R8A8);
+  if (NS_WARN_IF(!source)) {
+    return nullptr;
+  }
+
+  ReadPixelsIntoDataSurface(sSnapshotContext, source);
+  return source.forget();
+}
+
+} // layers
+} // mozilla
+
+#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
@@ -285,16 +285,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',