Bug 1014614 - Fix readback of SurfaceTextureImage r=jgilbert
authorJames Willcox <snorp@snorp.net>
Tue, 21 Oct 2014 08:53:02 -0500
changeset 211569 112be8f081b3
parent 211568 31cc8ab02681
child 211570 f33aefd6cea2
push id27680
push userryanvm@gmail.com
push date2014-10-21 19:21 +0000
treeherdermozilla-central@15099ba111e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1014614
milestone36.0a1
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 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,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
@@ -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',