Bug 1066280 - Fixes. - r=kamidphish,mattwoodrow
authorjdashg <jdashg+github@gmail.com>
Tue, 07 Oct 2014 21:11:54 -0700
changeset 233106 66f8715610050f9fc67c0190e7e7e3c8cd154ca8
parent 233105 a957533009dfbc03ede8e09f87de8007f410e871
child 233107 72ce4c2ccdcb6f0dd58f55422a52c5dce1caba71
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskamidphish, mattwoodrow
bugs1066280
milestone35.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 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;