Bug 1066280 - Fixes. - r=kamidphish,mattwoodrow
authorjdashg <jdashg+github@gmail.com>
Tue, 07 Oct 2014 21:11:54 -0700
changeset 209891 66f8715610050f9fc67c0190e7e7e3c8cd154ca8
parent 209890 a957533009dfbc03ede8e09f87de8007f410e871
child 209892 72ce4c2ccdcb6f0dd58f55422a52c5dce1caba71
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerskamidphish, mattwoodrow
bugs1066280
milestone35.0a1
Bug 1066280 - Fixes. - r=kamidphish,mattwoodrow From 4e9f52ab105333e8b1120342e9583b2d833a4465 Mon Sep 17 00:00:00 2001 --- dom/canvas/WebGLContext.cpp | 10 +++++-- gfx/gl/GLContext.cpp | 20 -------------- gfx/gl/GLContext.h | 3 -- gfx/gl/GLReadTexImageHelper.cpp | 5 +++- gfx/gl/GLScreenBuffer.cpp | 13 +++++++-- gfx/gl/GLUploadHelpers.cpp | 27 ++++++++++++++++++ gfx/gl/SharedSurfaceGralloc.cpp | 14 ++++------ gfx/gl/SharedSurfaceGralloc.h | 10 +++++-- gfx/gl/SurfaceTypes.cpp | 2 ++ gfx/gl/SurfaceTypes.h | 1 + gfx/layers/client/CanvasClient.cpp | 44 ++++++++++++++++++------------ gfx/layers/client/CanvasClient.h | 8 +++--- gfx/layers/client/ClientCanvasLayer.cpp | 6 ++++ gfx/layers/client/ClientCanvasLayer.h | 2 +- gfx/layers/client/TextureClient.cpp | 11 ++++---- gfx/layers/client/TextureClient.h | 6 ++-- gfx/layers/composite/TextureHost.cpp | 15 +++++----- gfx/layers/composite/TextureHost.h | 10 +++---- gfx/layers/d3d10/CanvasLayerD3D10.cpp | 9 ++++-- gfx/layers/d3d9/CanvasLayerD3D9.cpp | 8 ++++-- gfx/layers/ipc/LayersSurfaces.ipdlh | 4 +-- gfx/layers/moz.build | 4 ++- gfx/layers/opengl/GrallocTextureClient.cpp | 26 +++++++++++++++++- gfx/layers/opengl/GrallocTextureClient.h | 3 ++ 24 files changed, 171 insertions(+), 90 deletions(-)
dom/canvas/WebGLContext.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLReadTexImageHelper.cpp
gfx/gl/GLScreenBuffer.cpp
gfx/gl/GLUploadHelpers.cpp
gfx/gl/SharedSurfaceGralloc.cpp
gfx/gl/SharedSurfaceGralloc.h
gfx/gl/SurfaceTypes.cpp
gfx/gl/SurfaceTypes.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/client/ClientCanvasLayer.cpp
gfx/layers/client/ClientCanvasLayer.h
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClient.h
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/d3d10/CanvasLayerD3D10.cpp
gfx/layers/d3d9/CanvasLayerD3D9.cpp
gfx/layers/ipc/LayersSurfaces.ipdlh
gfx/layers/moz.build
gfx/layers/opengl/GrallocTextureClient.cpp
gfx/layers/opengl/GrallocTextureClient.h
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -656,16 +656,17 @@ CreateOffscreen(GLContext* gl,
                 layers::ISurfaceAllocator* surfAllocator)
 {
     SurfaceCaps baseCaps;
 
     baseCaps.color = true;
     baseCaps.alpha = options.alpha;
     baseCaps.antialias = options.antialias;
     baseCaps.depth = options.depth;
+    baseCaps.premultAlpha = options.premultipliedAlpha;
     baseCaps.preserve = options.preserveDrawingBuffer;
     baseCaps.stencil = options.stencil;
 
     // we should really have this behind a
     // |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
     // for now it's just behind a pref for testing/evaluation.
     baseCaps.bpp16 = Preferences::GetBool("webgl.prefer-16bpp", false);
 
@@ -1416,20 +1417,25 @@ WebGLContext::PresentScreenBuffer()
 {
     if (IsContextLost()) {
         return false;
     }
 
     if (!mShouldPresent) {
         return false;
     }
+    MOZ_ASSERT(!mBackbufferNeedsClear);
 
     gl->MakeCurrent();
-    MOZ_ASSERT(!mBackbufferNeedsClear);
-    if (!gl->PublishFrame()) {
+
+    auto screen = gl->Screen();
+    MOZ_ASSERT(screen);
+
+    auto size = screen->Size();
+    if (!screen->PublishFrame(size)) {
         ForceLoseContext();
         return false;
     }
 
     if (!mOptions.preserveDrawingBuffer) {
         mBackbufferNeedsClear = true;
     }
 
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1987,36 +1987,16 @@ GLContext::AssembleOffscreenFBs(const GL
     } else if (readFB) {
         NS_RUNTIMEABORT("readFB created when not requested!");
     }
 
     return isComplete;
 }
 
 
-
-bool
-GLContext::PublishFrame()
-{
-    MOZ_ASSERT(mScreen);
-
-    return mScreen->PublishFrame(OffscreenSize());
-}
-
-SharedSurface*
-GLContext::RequestFrame()
-{
-    MOZ_ASSERT(mScreen);
-    MOZ_CRASH("Not anymore!");
-
-    return nullptr;
-}
-
-
-
 void
 GLContext::ClearSafely()
 {
     // bug 659349 --- we must be very careful here: clearing a GL framebuffer is nontrivial, relies on a lot of state,
     // and in the case of the backbuffer of a WebGL context, state is exposed to scripts.
     //
     // The code here is taken from WebGLContext::ForceClearFramebufferWithDefaultValues, but I didn't find a good way of
     // sharing code with it. WebGL's code is somewhat performance-critical as it is typically called on every frame, so
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -3524,19 +3524,16 @@ public:
     bool IsOffscreen() const {
         return mScreen;
     }
 
     GLScreenBuffer* Screen() const {
         return mScreen.get();
     }
 
-    bool PublishFrame();
-    SharedSurface* RequestFrame();
-
     /* Clear to transparent black, with 0 depth and stencil,
      * while preserving current ClearColor etc. values.
      * Useful for resizing offscreen buffers.
      */
     void ClearSafely();
 
     bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
 
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -187,18 +187,21 @@ GetActualReadFormats(GLContext* gl,
     } else {
         switch (destFormat) {
             case LOCAL_GL_RGB: {
                 if (destType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV)
                     fallback = false;
                 break;
             }
             case LOCAL_GL_BGRA: {
-                if (destType == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV)
+                if (destType == LOCAL_GL_UNSIGNED_BYTE ||
+                    destType == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV)
+                {
                     fallback = false;
+                }
                 break;
             }
         }
     }
 
     if (fallback) {
         *out_readFormat = LOCAL_GL_RGBA;
         *out_readType = LOCAL_GL_UNSIGNED_BYTE;
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GLScreenBuffer.h"
 
 #include <cstring>
+#include "CompositorTypes.h"
 #include "GLContext.h"
 #include "GLBlitHelper.h"
 #include "GLReadTexImageHelper.h"
 #include "SharedSurfaceGL.h"
 #include "SurfaceStream.h"
 #ifdef MOZ_WIDGET_GONK
 #include "SharedSurfaceGralloc.h"
 #include "nsXULAppAPI.h"
@@ -38,21 +39,29 @@ GLScreenBuffer::Create(GLContext* gl,
     {
         return Move(ret);
     }
 
     UniquePtr<SurfaceFactory> factory;
 
 #ifdef MOZ_WIDGET_GONK
     /* On B2G, we want a Gralloc factory, and we want one right at the start */
+    auto allocator = caps.surfaceAllocator;
     if (!factory &&
-        caps.surfaceAllocator &&
+        allocator &&
         XRE_GetProcessType() != GeckoProcessType_Default)
     {
-        factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps);
+        layers::TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
+                                     TextureFlags::NEEDS_Y_FLIP;
+        if (!caps.premultAlpha) {
+            flags |= TextureFlags::NON_PREMULTIPLIED;
+        }
+
+        factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps, flags,
+                                                     allocator);
     }
 #endif
 #ifdef XP_MACOSX
     /* On OSX, we want an IOSurface factory, and we want one right at the start */
     if (!factory) {
         factory = SurfaceFactory_IOSurface::Create(gl, caps);
     }
 #endif
--- a/gfx/gl/GLUploadHelpers.cpp
+++ b/gfx/gl/GLUploadHelpers.cpp
@@ -425,16 +425,17 @@ UploadImageDataToTexture(GLContext* gl,
     GLenum format = 0;
     GLenum internalFormat = 0;
     GLenum type = 0;
     int32_t pixelSize = BytesPerPixel(aFormat);
     SurfaceFormat surfaceFormat = gfx::SurfaceFormat::UNKNOWN;
 
     MOZ_ASSERT(gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA ||
                gl->GetPreferredARGB32Format() == LOCAL_GL_RGBA);
+
     switch (aFormat) {
         case SurfaceFormat::B8G8R8A8:
             if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
               format = LOCAL_GL_BGRA;
               surfaceFormat = SurfaceFormat::R8G8B8A8;
               type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
             } else {
               format = LOCAL_GL_RGBA;
@@ -452,16 +453,42 @@ UploadImageDataToTexture(GLContext* gl,
               type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
             } else {
               format = LOCAL_GL_RGBA;
               surfaceFormat = SurfaceFormat::B8G8R8X8;
               type = LOCAL_GL_UNSIGNED_BYTE;
             }
             internalFormat = LOCAL_GL_RGBA;
             break;
+        case SurfaceFormat::R8G8B8A8:
+            if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+              format = LOCAL_GL_BGRA;
+              type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+              surfaceFormat = SurfaceFormat::B8G8R8A8;
+            } else {
+              format = LOCAL_GL_RGBA;
+              type = LOCAL_GL_UNSIGNED_BYTE;
+              surfaceFormat = SurfaceFormat::R8G8B8A8;
+            }
+            internalFormat = LOCAL_GL_RGBA;
+            break;
+        case SurfaceFormat::R8G8B8X8:
+            // Treat RGBX surfaces as RGBA except for the surface
+            // format used.
+            if (gl->GetPreferredARGB32Format() == LOCAL_GL_BGRA) {
+              format = LOCAL_GL_BGRA;
+              type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
+              surfaceFormat = SurfaceFormat::B8G8R8X8;
+            } else {
+              format = LOCAL_GL_RGBA;
+              type = LOCAL_GL_UNSIGNED_BYTE;
+              surfaceFormat = SurfaceFormat::R8G8B8X8;
+            }
+            internalFormat = LOCAL_GL_RGBA;
+            break;
         case SurfaceFormat::R5G6B5:
             internalFormat = format = LOCAL_GL_RGB;
             type = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
             surfaceFormat = SurfaceFormat::R5G6B5;
             break;
         case SurfaceFormat::A8:
             internalFormat = format = LOCAL_GL_LUMINANCE;
             type = LOCAL_GL_UNSIGNED_BYTE;
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -32,33 +32,31 @@
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::layers;
 using namespace android;
 
 SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL,
                                                const SurfaceCaps& caps,
+                                               layers::TextureFlags flags,
                                                layers::ISurfaceAllocator* allocator)
     : SurfaceFactory(prodGL, SharedSurfaceType::Gralloc, caps)
+    , mFlags(flags)
+    , mAllocator(allocator)
 {
-    if (caps.surfaceAllocator) {
-        allocator = caps.surfaceAllocator;
-    }
-
-    MOZ_ASSERT(allocator);
-
-    mAllocator = allocator;
+    MOZ_ASSERT(mAllocator);
 }
 
 /*static*/ UniquePtr<SharedSurface_Gralloc>
 SharedSurface_Gralloc::Create(GLContext* prodGL,
                               const GLFormats& formats,
                               const gfx::IntSize& size,
                               bool hasAlpha,
+                              layers::TextureFlags flags,
                               ISurfaceAllocator* allocator)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     MOZ_ASSERT(egl);
 
     UniquePtr<SharedSurface_Gralloc> ret;
 
     DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
@@ -72,17 +70,17 @@ SharedSurface_Gralloc::Create(GLContext*
     gfxImageFormat format
       = gfxPlatform::GetPlatform()->OptimalFormatForContent(type);
 
     RefPtr<GrallocTextureClientOGL> grallocTC =
       new GrallocTextureClientOGL(
           allocator,
           gfx::ImageFormatToSurfaceFormat(format),
           gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
-          layers::TextureFlags::DEFAULT);
+          flags);
 
     if (!grallocTC->AllocateForGLRendering(size)) {
       return Move(ret);
     }
 
     sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
 
     EGLDisplay display = egl->Display();
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -1,16 +1,17 @@
 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SHARED_SURFACE_GRALLOC_H_
 #define SHARED_SURFACE_GRALLOC_H_
 
+#include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersSurfaces.h"
 #include "SharedSurface.h"
 
 namespace mozilla {
 namespace layers {
 class ISurfaceAllocator;
 class GrallocTextureClientOGL;
 }
@@ -22,16 +23,17 @@ class GLLibraryEGL;
 class SharedSurface_Gralloc
     : public SharedSurface
 {
 public:
     static UniquePtr<SharedSurface_Gralloc> Create(GLContext* prodGL,
                                                    const GLFormats& formats,
                                                    const gfx::IntSize& size,
                                                    bool hasAlpha,
+                                                   layers::TextureFlags flags,
                                                    layers::ISurfaceAllocator* allocator);
 
     static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::Gralloc);
 
         return (SharedSurface_Gralloc*)surf;
     }
 
@@ -72,30 +74,32 @@ public:
         return mTextureClient;
     }
 };
 
 class SurfaceFactory_Gralloc
     : public SurfaceFactory
 {
 protected:
+    const layers::TextureFlags mFlags;
     RefPtr<layers::ISurfaceAllocator> mAllocator;
 
 public:
     SurfaceFactory_Gralloc(GLContext* prodGL,
                            const SurfaceCaps& caps,
-                           layers::ISurfaceAllocator* allocator = nullptr);
+                           layers::TextureFlags flags,
+                           layers::ISurfaceAllocator* allocator);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
         bool hasAlpha = mReadCaps.alpha;
 
         UniquePtr<SharedSurface> ret;
         if (mAllocator) {
-            ret = SharedSurface_Gralloc::Create(mGL, mFormats, size,
-                                                hasAlpha, mAllocator);
+            ret = SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha,
+                                                mFlags, mAllocator);
         }
         return Move(ret);
     }
 };
 
 } /* namespace gl */
 } /* namespace mozilla */
 
--- a/gfx/gl/SurfaceTypes.cpp
+++ b/gfx/gl/SurfaceTypes.cpp
@@ -25,32 +25,34 @@ SurfaceCaps::operator=(const SurfaceCaps
 {
     any = other.any;
     color = other.color;
     alpha = other.alpha;
     bpp16 = other.bpp16;
     depth = other.depth;
     stencil = other.stencil;
     antialias = other.antialias;
+    premultAlpha = other.premultAlpha;
     preserve = other.preserve;
     surfaceAllocator = other.surfaceAllocator;
 
     return *this;
 }
 
 void
 SurfaceCaps::Clear()
 {
     any = false;
     color = false;
     alpha = false;
     bpp16 = false;
     depth = false;
     stencil = false;
     antialias = false;
+    premultAlpha = false;
     preserve = false;
     surfaceAllocator = nullptr;
 }
 
 SurfaceCaps::~SurfaceCaps()
 {
 }
 
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -20,16 +20,17 @@ namespace gl {
 
 struct SurfaceCaps MOZ_FINAL
 {
     bool any;
     bool color, alpha;
     bool bpp16;
     bool depth, stencil;
     bool antialias;
+    bool premultAlpha;
     bool preserve;
 
     // The surface allocator that we want to create this
     // for.  May be null.
     RefPtr<layers::ISurfaceAllocator> surfaceAllocator;
 
     SurfaceCaps();
     SurfaceCaps(const SurfaceCaps& other);
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -43,17 +43,17 @@ CanvasClient::CreateCanvasClient(CanvasC
   if (XRE_GetProcessType() != GeckoProcessType_Default) {
     NS_WARNING("Most platforms still need an optimized way to share GL cross process.");
     return new CanvasClient2D(aForwarder, aFlags);
   }
 #endif
 
   switch (aType) {
   case CanvasClientTypeShSurf:
-    return new CanvasClientShSurf(aForwarder, aFlags);
+    return new CanvasClientSharedSurface(aForwarder, aFlags);
 
   case CanvasClientGLContext:
     aFlags |= TextureFlags::DEALLOCATE_CLIENT;
     return new CanvasClientSurfaceStream(aForwarder, aFlags);
 
   default:
     return new CanvasClient2D(aForwarder, aFlags);
   }
@@ -235,41 +235,39 @@ CanvasClientSurfaceStream::Update(gfx::I
   }
 #endif
 
   aLayer->Painted();
 }
 
 ////////////////////////////////////////////////////////////////////////
 
-CanvasClientShSurf::CanvasClientShSurf(CompositableForwarder* aLayerForwarder,
-                                       TextureFlags aFlags)
+CanvasClientSharedSurface::CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
+                                                     TextureFlags aFlags)
   : CanvasClient(aLayerForwarder, aFlags)
 {
 }
 
 ////////////////////////////////////////
 // Accelerated backends
 
 static TemporaryRef<TextureClient>
-TexClientFromShSurf(SharedSurface* surf, TextureFlags baseFlags)
+TexClientFromShSurf(SharedSurface* surf, TextureFlags flags)
 {
-  TextureFlags flags = baseFlags | TextureFlags::DEALLOCATE_CLIENT;
-
   switch (surf->mType) {
     case SharedSurfaceType::Basic:
       return nullptr;
 
 #ifdef MOZ_WIDGET_GONK
     case SharedSurfaceType::Gralloc:
       return GrallocTextureClientOGL::FromShSurf(surf, flags);
 #endif
 
     default:
-      return new ShSurfTexClient(flags, surf);
+      return new SharedSurfaceTextureClient(flags, surf);
   }
 }
 
 ////////////////////////////////////////
 // Readback
 
 // For formats compatible with R8G8B8A8.
 static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
@@ -279,26 +277,28 @@ static inline void SwapRB_R8G8B8A8(uint8
 
 class TexClientFactory
 {
   ISurfaceAllocator* const mAllocator;
   const bool mHasAlpha;
   const gfx::IntSize mSize;
   const gfx::BackendType mBackendType;
   const TextureFlags mBaseTexFlags;
+  const LayersBackend mLayersBackend;
 
 public:
   TexClientFactory(ISurfaceAllocator* allocator, bool hasAlpha,
                    const gfx::IntSize& size, gfx::BackendType backendType,
-                   TextureFlags baseTexFlags)
+                   TextureFlags baseTexFlags, LayersBackend layersBackend)
     : mAllocator(allocator)
     , mHasAlpha(hasAlpha)
     , mSize(size)
     , mBackendType(backendType)
     , mBaseTexFlags(baseTexFlags)
+    , mLayersBackend(layersBackend)
   {
   }
 
 protected:
   TemporaryRef<BufferTextureClient> Create(gfx::SurfaceFormat format) {
     return TextureClient::CreateForRawBufferAccess(mAllocator, format,
                                                    mSize, mBackendType,
                                                    mBaseTexFlags);
@@ -307,34 +307,43 @@ protected:
 public:
   TemporaryRef<BufferTextureClient> CreateB8G8R8AX8() {
     gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::B8G8R8A8
                                           : gfx::SurfaceFormat::B8G8R8X8;
     return Create(format);
   }
 
   TemporaryRef<BufferTextureClient> CreateR8G8B8AX8() {
-    // For now, assume that all RGBA formats are broken.
-    RefPtr<BufferTextureClient> ret = CreateB8G8R8AX8();
+    RefPtr<BufferTextureClient> ret;
 
-    if (ret) {
-      ret->AddFlags(TextureFlags::RB_SWAPPED);
+    bool areRGBAFormatsBroken = mLayersBackend == LayersBackend::LAYERS_BASIC;
+    if (!areRGBAFormatsBroken) {
+      gfx::SurfaceFormat format = mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
+                                            : gfx::SurfaceFormat::R8G8B8X8;
+      ret = Create(format);
+    }
+
+    if (!ret) {
+      ret = CreateB8G8R8AX8();
+      if (ret) {
+        ret->AddFlags(TextureFlags::RB_SWAPPED);
+      }
     }
 
     return ret.forget();
   }
 };
 
 static TemporaryRef<TextureClient>
 TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
                       TextureFlags baseFlags, LayersBackend layersBackend)
 {
   auto backendType = gfx::BackendType::CAIRO;
   TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
-                           baseFlags);
+                           baseFlags, layersBackend);
 
   RefPtr<BufferTextureClient> texClient;
 
   {
     gl::ScopedReadbackFB autoReadback(src);
 
     // We have a source FB, now we need a format.
     GLenum destFormat = LOCAL_GL_BGRA;
@@ -384,18 +393,20 @@ TexClientFromReadback(SharedSurface* src
     {
       ScopedPackAlignment autoAlign(gl, 4);
 
       gl->raw_fReadPixels(0, 0, width, height, readFormat, readType, lockedBytes);
     }
 
     // RB_SWAPPED doesn't work with D3D11. (bug 1051010)
     // RB_SWAPPED doesn't work with Basic. (bug ???????)
-    bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_D3D11 ||
-                                 layersBackend == LayersBackend::LAYERS_BASIC;
+    // RB_SWAPPED doesn't work with D3D9. (bug ???????)
+    bool layersNeedsManualSwap = layersBackend == LayersBackend::LAYERS_BASIC ||
+                                 layersBackend == LayersBackend::LAYERS_D3D9 ||
+                                 layersBackend == LayersBackend::LAYERS_D3D11;
     if (texClient->HasFlags(TextureFlags::RB_SWAPPED) &&
         layersNeedsManualSwap)
     {
       size_t pixels = width * height;
       uint8_t* itr = lockedBytes;
       for (size_t i = 0; i < pixels; i++) {
         SwapRB_R8G8B8A8(itr);
         itr += 4;
@@ -408,28 +419,27 @@ TexClientFromReadback(SharedSurface* src
   }
 
   return texClient.forget();
 }
 
 ////////////////////////////////////////
 
 void
-CanvasClientShSurf::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
+CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
   aLayer->mGLContext->MakeCurrent();
   GLScreenBuffer* screen = aLayer->mGLContext->Screen();
 
   if (mFront) {
     mPrevFront = mFront;
     mFront = nullptr;
   }
 
   mFront = screen->Front();
-
   if (!mFront)
     return;
 
   // Alright, now sort out the IPC goop.
   SharedSurface* surf = mFront->Surf();
   auto forwarder = GetForwarder();
   auto flags = GetTextureFlags() | TextureFlags::IMMUTABLE;
 
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -137,42 +137,42 @@ public:
   }
 
 private:
   RefPtr<TextureClient> mBuffer;
 };
 
 // Used for GL canvases where we don't need to do any readback, i.e., with a
 // GL backend.
-class CanvasClientShSurf : public CanvasClient
+class CanvasClientSharedSurface : public CanvasClient
 {
 private:
   RefPtr<gl::ShSurfHandle> mFront;
   RefPtr<gl::ShSurfHandle> mPrevFront;
 
   RefPtr<TextureClient> mFrontTex;
 
 public:
-  CanvasClientShSurf(CompositableForwarder* aLayerForwarder,
-                     TextureFlags aFlags);
+  CanvasClientSharedSurface(CompositableForwarder* aLayerForwarder,
+                            TextureFlags aFlags);
 
   virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE {
     return TextureInfo(CompositableType::IMAGE);
   }
 
   virtual void Clear() MOZ_OVERRIDE {
     mFront = nullptr;
     mPrevFront = nullptr;
     mFrontTex = nullptr;
   }
 
   virtual void Update(gfx::IntSize aSize,
                       ClientCanvasLayer* aLayer) MOZ_OVERRIDE;
 
   virtual void OnDetach() MOZ_OVERRIDE {
-    CanvasClientShSurf::Clear();
+    CanvasClientSharedSurface::Clear();
   }
 };
 
 }
 }
 
 #endif
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -72,18 +72,24 @@ ClientCanvasLayer::Initialize(const Data
 
     UniquePtr<SurfaceFactory> factory;
 
     if (!gfxPrefs::WebGLForceLayersReadback()) {
       switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
         case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
           if (mGLContext->GetContextType() == GLContextType::EGL) {
 #ifdef MOZ_WIDGET_GONK
+            TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
+                                 TextureFlags::NEEDS_Y_FLIP;
+            if (!aData.mIsGLAlphaPremult) {
+              flags |= TextureFlags::NON_PREMULTIPLIED;
+            }
             factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
                                                          caps,
+                                                         flags,
                                                          ClientManager()->AsShadowForwarder());
 #else
             bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
             if (!isCrossProcess) {
               // [Basic/OGL Layers, OMTC] WebGL layer init.
               factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
             } else {
               // we could do readback here maybe
--- a/gfx/layers/client/ClientCanvasLayer.h
+++ b/gfx/layers/client/ClientCanvasLayer.h
@@ -97,14 +97,14 @@ protected:
 
   UniquePtr<gl::SharedSurface> mTextureSurface;
   UniquePtr<gl::SurfaceFactory> mFactory;
 
   friend class DeprecatedCanvasClient2D;
   friend class CanvasClient2D;
   friend class DeprecatedCanvasClientSurfaceStream;
   friend class CanvasClientSurfaceStream;
-  friend class CanvasClientShSurf;
+  friend class CanvasClientSharedSurface;
 };
 }
 }
 
 #endif
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -856,33 +856,34 @@ StreamTextureClient::InitWith(gl::Surfac
 
 bool
 StreamTextureClient::IsAllocated() const
 {
   return mStream != 0;
 }
 
 ////////////////////////////////////////////////////////////////////////
-// ShSurfTexClient
+// SharedSurfaceTextureClient
 
-ShSurfTexClient::ShSurfTexClient(TextureFlags aFlags, gl::SharedSurface* surf)
+SharedSurfaceTextureClient::SharedSurfaceTextureClient(TextureFlags aFlags,
+                                                       gl::SharedSurface* surf)
   : TextureClient(aFlags)
   , mIsLocked(false)
   , mSurf(surf)
   , mGL(mSurf->mGL)
 {
   mSurf->Fence();
 }
 
-ShSurfTexClient::~ShSurfTexClient()
+SharedSurfaceTextureClient::~SharedSurfaceTextureClient()
 {
   // the data is owned externally.
 }
 
 bool
-ShSurfTexClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
+SharedSurfaceTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
 {
-  aOutDescriptor = ShSurfDescriptor((uintptr_t)mSurf);
+  aOutDescriptor = SharedSurfaceDescriptor((uintptr_t)mSurf);
   return true;
 }
 
 }
 }
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -677,23 +677,23 @@ protected:
   bool mIsLocked;
   RefPtr<gl::SurfaceStream> mStream;
   RefPtr<gl::GLContext> mGL; // Just for reference holding.
 };
 
 /**
  * A TextureClient implementation to share SharedSurfaces.
  */
-class ShSurfTexClient : public TextureClient
+class SharedSurfaceTextureClient : public TextureClient
 {
 public:
-  explicit ShSurfTexClient(TextureFlags aFlags, gl::SharedSurface* surf);
+  SharedSurfaceTextureClient(TextureFlags aFlags, gl::SharedSurface* surf);
 
 protected:
-  ~ShSurfTexClient();
+  ~SharedSurfaceTextureClient();
 
 public:
   // Boilerplate start
   virtual bool IsAllocated() const MOZ_OVERRIDE { return true; }
 
   virtual bool Lock(OpenMode) MOZ_OVERRIDE {
     MOZ_ASSERT(!mIsLocked);
     mIsLocked = true;
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -198,18 +198,18 @@ TextureHost::Create(const SurfaceDescrip
     case SurfaceDescriptor::TEGLImageDescriptor:
     case SurfaceDescriptor::TNewSurfaceDescriptorGralloc:
     case SurfaceDescriptor::TSurfaceTextureDescriptor:
       return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
 
     case SurfaceDescriptor::TSurfaceStreamDescriptor:
       return new StreamTextureHost(aFlags, aDesc.get_SurfaceStreamDescriptor());
 
-    case SurfaceDescriptor::TShSurfDescriptor:
-      return new ShSurfTexHost(aFlags, aDesc.get_ShSurfDescriptor());
+    case SurfaceDescriptor::TSharedSurfaceDescriptor:
+      return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor());
 
     case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
       if (Compositor::GetBackend() == LayersBackend::LAYERS_OPENGL) {
         return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
       } else {
         return CreateTextureHostBasic(aDesc, aDeallocator, aFlags);
       }
 
@@ -1084,43 +1084,44 @@ ShSurfToTexSource(gl::SharedSurface* abs
       break;
   }
 
   MOZ_ASSERT(texSource.get(), "TextureSource creation failed.");
   return texSource;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// ShSurfTexHost
+// SharedSurfaceTextureHost
 
-ShSurfTexHost::ShSurfTexHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc)
+SharedSurfaceTextureHost::SharedSurfaceTextureHost(TextureFlags aFlags,
+                                                   const SharedSurfaceDescriptor& aDesc)
   : TextureHost(aFlags)
   , mIsLocked(false)
   , mSurf((gl::SharedSurface*)aDesc.surf())
   , mCompositor(nullptr)
 {
   MOZ_ASSERT(mSurf);
 }
 
 gfx::SurfaceFormat
-ShSurfTexHost::GetFormat() const
+SharedSurfaceTextureHost::GetFormat() const
 {
   MOZ_ASSERT(mTexSource);
   return mTexSource->GetFormat();
 }
 
 gfx::IntSize
-ShSurfTexHost::GetSize() const
+SharedSurfaceTextureHost::GetSize() const
 {
   MOZ_ASSERT(mTexSource);
   return mTexSource->GetSize();
 }
 
 void
-ShSurfTexHost::EnsureTexSource()
+SharedSurfaceTextureHost::EnsureTexSource()
 {
   MOZ_ASSERT(mIsLocked);
 
   if (mTexSource)
     return;
 
   mSurf->WaitSync();
   mTexSource = ShSurfToTexSource(mSurf, mCompositor);
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -45,17 +45,17 @@ class Shmem;
 namespace layers {
 
 class Compositor;
 class CompositableHost;
 class CompositableBackendSpecificData;
 class CompositableParentManager;
 class SurfaceDescriptor;
 class SurfaceStreamDescriptor;
-class ShSurfDescriptor;
+class SharedSurfaceDescriptor;
 class ISurfaceAllocator;
 class TextureHostOGL;
 class TextureSourceOGL;
 class TextureSourceD3D9;
 class TextureSourceD3D11;
 class TextureSourceBasic;
 class DataTextureSource;
 class PTextureParent;
@@ -615,22 +615,22 @@ protected:
   gl::SurfaceStream* mStream;
   RefPtr<TextureSource> mTextureSource;
   RefPtr<DataTextureSource> mDataTextureSource;
 };
 
 /**
  * A TextureHost for SharedSurfaces
  */
-class ShSurfTexHost : public TextureHost
+class SharedSurfaceTextureHost : public TextureHost
 {
 public:
-  ShSurfTexHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc);
+  SharedSurfaceTextureHost(TextureFlags aFlags, const ShSurfDescriptor& aDesc);
 
-  virtual ~ShSurfTexHost() {};
+  virtual ~SharedSurfaceTextureHost() {};
 
   virtual void DeallocateDeviceData() MOZ_OVERRIDE {};
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE {
     return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
   }
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE {
@@ -662,17 +662,17 @@ public:
     return mTexSource;
   }
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
 #ifdef MOZ_LAYERS_HAVE_LOG
-  virtual const char* Name() { return "ShSurfTexHost"; }
+  virtual const char* Name() { return "SharedSurfaceTextureHost"; }
 #endif
 
 protected:
   void EnsureTexSource();
 
   bool mIsLocked;
   gl::SharedSurface* const mSurf;
   Compositor* mCompositor;
--- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp
+++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
@@ -113,20 +113,23 @@ CanvasLayerD3D10::UpdateSurface()
     return;
   }
 
   if (!mTexture) {
     return;
   }
 
   if (mGLContext) {
-    SharedSurface* surf = mGLContext->RequestFrame();
-    if (!surf) {
+    auto screen = mGLContext->Screen();
+    MOZ_ASSERT(screen);
+
+    SharedSurface* surf = screen->Front()->Surf();
+    if (!surf)
       return;
-    }
+    surf->WaitSync();
 
     switch (surf->mType) {
       case SharedSurfaceType::EGLSurfaceANGLE: {
         SharedSurface_ANGLEShareHandle* shareSurf = SharedSurface_ANGLEShareHandle::Cast(surf);
         HANDLE shareHandle = shareSurf->GetShareHandle();
 
         HRESULT hr = device()->OpenSharedResource(shareHandle,
                                                   __uuidof(ID3D10Texture2D),
--- a/gfx/layers/d3d9/CanvasLayerD3D9.cpp
+++ b/gfx/layers/d3d9/CanvasLayerD3D9.cpp
@@ -75,19 +75,23 @@ CanvasLayerD3D9::UpdateSurface()
       NS_WARNING("CanvasLayerD3D9::Updated called but no texture present and creation failed!");
       return;
     }
   }
 
   RefPtr<SourceSurface> surface;
 
   if (mGLContext) {
-    SharedSurface* surf = mGLContext->RequestFrame();
+    auto screen = mGLContext->Screen();
+    MOZ_ASSERT(screen);
+
+    SharedSurface* surf = screen->Front()->Surf();
     if (!surf)
-        return;
+      return;
+    surf->WaitSync();
 
     SharedSurface_Basic* shareSurf = SharedSurface_Basic::Cast(surf);
     surface = shareSurf->GetData();
   } else {
     surface = mDrawTarget->Snapshot();
   }
 
   // WebGL reads entire surface.
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -76,17 +76,17 @@ struct NewSurfaceDescriptorGralloc {
   IntSize size;
 };
 
 struct SurfaceStreamDescriptor {
   uintptr_t surfStream;
   bool yflip;
 };
 
-struct ShSurfDescriptor {
+struct SharedSurfaceDescriptor {
   uintptr_t surf;
 };
 
 /**
  * Used for shmem-backed YCbCr and (flavors of) RGBA textures
  */
 struct SurfaceDescriptorShmem {
   Shmem data;
@@ -108,14 +108,14 @@ union SurfaceDescriptor {
   SurfaceDescriptorDIB;
   SurfaceDescriptorD3D10;
   SurfaceDescriptorX11;
   SurfaceTextureDescriptor;
   EGLImageDescriptor;
   SurfaceStreamDescriptor;
   SurfaceDescriptorMacIOSurface;
   NewSurfaceDescriptorGralloc;
-  ShSurfDescriptor;
+  SharedSurfaceDescriptor;
   null_t;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -12,32 +12,34 @@ EXPORTS += [
     'basic/BasicPaintedLayer.h',
     'client/ClientCanvasLayer.h',
     'client/ClientContainerLayer.h',
     'client/ClientLayerManager.h',
     'client/ClientPaintedLayer.h',
     'client/ClientTiledPaintedLayer.h',
     'composite/CompositableHost.h',
     'composite/ImageHost.h',
+    'CompositorTypes.h',
     'CopyableCanvasLayer.h',
     'D3D9SurfaceImage.h',
     'FrameMetrics.h',
     'GLImages.h',
     'GrallocImages.h',
     'ImageContainer.h',
     'ImageLayers.h',
     'ImageTypes.h',
     'ipc/CompositorChild.h',
     'ipc/CompositorParent.h',
     'ipc/ShadowLayersManager.h',
     'ipc/ThreadSafeRefcountingWithMainThreadDestruction.h',
     'Layers.h',
     'LayerScope.h',
     'LayersLogging.h',
     'LayerSorter.h',
+    'LayersTypes.h',
     'LayerTreeInvalidation.h',
     'opengl/Composer2D.h',
     'opengl/OGLShaderProgram.h',
     'opengl/TexturePoolOGL.h',
     'protobuf/LayerScopePacket.pb.h',
     'ReadbackLayer.h',
     'TiledLayerBuffer.h',
 ]
@@ -93,17 +95,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
             'd3d10/PaintedLayerD3D10.cpp',
             'd3d10/ReadbackManagerD3D10.cpp',
             'd3d11/TextureD3D11.cpp',
             'ipc/ShadowLayerUtilsD3D10.cpp',
         ]
         SOURCES += [
             'd3d11/CompositorD3D11.cpp',
             'd3d11/ReadbackManagerD3D11.cpp',
-        ]         
+        ]
         if CONFIG['MOZ_ENABLE_DIRECT2D1_1']:
             DEFINES['USE_D2D1_1'] = True
 
 EXPORTS.gfxipc += [
     'ipc/ShadowLayerUtils.h',
 ]
 
 EXPORTS.mozilla.layers += [
--- a/gfx/layers/opengl/GrallocTextureClient.cpp
+++ b/gfx/layers/opengl/GrallocTextureClient.cpp
@@ -7,16 +7,17 @@
 
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/AsyncTransactionTracker.h" // for AsyncTransactionTracker
 #include "mozilla/layers/GrallocTextureClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/ISurfaceAllocator.h"
 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
 #include "gfx2DGlue.h"
+#include "SharedSurfaceGralloc.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace android;
 
 GrallocTextureClientOGL::GrallocTextureClientOGL(MaybeMagicGrallocBufferHandle buffer,
@@ -107,17 +108,17 @@ GrallocTextureClientOGL::WaitForBufferOw
   }
 
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
    if (mReleaseFenceHandle.IsValid()) {
      android::sp<Fence> fence = mReleaseFenceHandle.mFence;
 #if ANDROID_VERSION == 17
      fence->waitForever(1000, "GrallocTextureClientOGL::Lock");
      // 1000 is what Android uses. It is warning timeout ms.
-     // This timeous is removed since ANDROID_VERSION 18. 
+     // This timeous is removed since ANDROID_VERSION 18.
 #else
      fence->waitForever("GrallocTextureClientOGL::Lock");
 #endif
      mReleaseFenceHandle = FenceHandle();
    }
 #endif
 }
 
@@ -341,12 +342,35 @@ GrallocTextureClientOGL::Allocate(uint32
 size_t
 GrallocTextureClientOGL::GetBufferSize() const
 {
   // see Bug 908196
   MOZ_CRASH("This method should never be called.");
   return 0;
 }
 
+/*static*/ TemporaryRef<TextureClient>
+GrallocTextureClientOGL::FromShSurf(gl::SharedSurface* abstractSurf,
+                                    TextureFlags flags)
+{
+  auto surf = gl::SharedSurface_Gralloc::Cast(abstractSurf);
+
+  RefPtr<TextureClient> ret = surf->GetTextureClient();
+
+  TextureFlags mask = TextureFlags::NEEDS_Y_FLIP |
+                      TextureFlags::RB_SWAPPED |
+                      TextureFlags::NON_PREMULTIPLIED;
+  TextureFlags required = flags & mask;
+  TextureFlags present = ret->GetFlags() & mask;
+
+  if (present != required) {
+    printf_stderr("Present flags: 0x%x. Required: 0x%x.\n",
+                  (uint32_t)present,
+                  (uint32_t)required);
+    MOZ_CRASH("Flag requirement mismatch.");
+  }
+  return ret.forget();
+}
+
 } // namesapace layers
 } // namesapace mozilla
 
 #endif // MOZ_WIDGET_GONK
--- a/gfx/layers/opengl/GrallocTextureClient.h
+++ b/gfx/layers/opengl/GrallocTextureClient.h
@@ -113,16 +113,19 @@ public:
   {
     return mMediaBuffer;
   }
 
   virtual TemporaryRef<TextureClient>
   CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const MOZ_OVERRIDE;
 
+  static TemporaryRef<TextureClient> FromShSurf(gl::SharedSurface* surf,
+                                                TextureFlags flags);
+
 protected:
   /**
    * Unfortunately, until bug 879681 is fixed we need to use a GrallocBufferActor.
    */
   MaybeMagicGrallocBufferHandle mGrallocHandle;
 
   RefPtr<AsyncTransactionTracker> mRemoveFromCompositableTracker;