Bug 1077301 - Simplify the gralloc texture code. r=sotaro
☠☠ backed out by fe2216810527 ☠ ☠
authorNicolas Silva <nsilva@mozilla.com>
Thu, 16 Oct 2014 19:08:32 +0200
changeset 210794 d16adf32157638597da7dc95fa22a44dc56eec9f
parent 210793 30b100f7edbed55cbbe02230134c3242ae2d4b9b
child 210795 8c7d2cd4fa067369938f25c582491cf546c6d198
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssotaro
bugs1077301
milestone36.0a1
Bug 1077301 - Simplify the gralloc texture code. r=sotaro
gfx/layers/Compositor.h
gfx/layers/composite/CompositableHost.cpp
gfx/layers/composite/CompositableHost.h
gfx/layers/composite/ContentHost.cpp
gfx/layers/composite/ContentHost.h
gfx/layers/composite/ImageHost.cpp
gfx/layers/composite/ImageHost.h
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/opengl/GrallocTextureHost.cpp
gfx/layers/opengl/GrallocTextureHost.h
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -131,27 +131,16 @@ class LayerManagerComposite;
 
 enum SurfaceInitMode
 {
   INIT_MODE_NONE,
   INIT_MODE_CLEAR
 };
 
 /**
- * A base class for a platform-dependent helper for use by TextureHost.
- */
-class CompositorBackendSpecificData
-{
-  NS_INLINE_DECL_REFCOUNTING(CompositorBackendSpecificData)
-
-protected:
-  virtual ~CompositorBackendSpecificData() {}
-};
-
-/**
  * Common interface for compositor backends.
  *
  * Compositor provides a cross-platform interface to a set of operations for
  * compositing quads. Compositor knows nothing about the layer tree. It must be
  * told everything about each composited quad - contents, location, transform,
  * opacity, etc.
  *
  * In theory it should be possible for different widgets to use the same
@@ -476,20 +465,16 @@ public:
       fillRatio = 100.0f * float(mPixelsFilled) / float(mPixelsPerFrame);
       if (fillRatio > 999.0f) {
         fillRatio = 999.0f;
       }
     }
     return fillRatio;
   }
 
-  virtual CompositorBackendSpecificData* GetCompositorBackendSpecificData() {
-    return nullptr;
-  }
-
   ScreenRotation GetScreenRotation() const {
     return mScreenRotation;
   }
 
   void SetScreenRotation(ScreenRotation aRotation) {
     mScreenRotation = aRotation;
   }
 
--- a/gfx/layers/composite/CompositableHost.cpp
+++ b/gfx/layers/composite/CompositableHost.cpp
@@ -19,24 +19,16 @@
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "mozilla/layers/PCompositableParent.h"
 
 namespace mozilla {
 namespace layers {
 
 class Compositor;
 
-CompositableBackendSpecificData::CompositableBackendSpecificData()
-  : mAllowSharingTextureHost(false)
-{
-  static uint64_t sNextID = 1;
-  ++sNextID;
-  mId = sNextID;
-}
-
 /**
  * IPDL actor used by CompositableHost to match with its corresponding
  * CompositableClient on the content side.
  *
  * CompositableParent is owned by the IPDL system. It's deletion is triggered
  * by either the CompositableChild's deletion, or by the IPDL communication
  * goind down.
  */
@@ -82,19 +74,16 @@ CompositableHost::CompositableHost(const
   , mKeepAttached(false)
 {
   MOZ_COUNT_CTOR(CompositableHost);
 }
 
 CompositableHost::~CompositableHost()
 {
   MOZ_COUNT_DTOR(CompositableHost);
-  if (mBackendData) {
-    mBackendData->ClearData();
-  }
 }
 
 PCompositableParent*
 CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr,
                                   const TextureInfo& aTextureInfo,
                                   uint64_t aID)
 {
   return new CompositableParent(aMgr, aTextureInfo, aID);
@@ -116,69 +105,61 @@ CompositableHost::FromIPDLActor(PComposi
 
 void
 CompositableHost::UseTextureHost(TextureHost* aTexture)
 {
   if (!aTexture) {
     return;
   }
   aTexture->SetCompositor(GetCompositor());
-  aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
 }
 
 void
 CompositableHost::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
                                             TextureHost* aTextureOnWhite)
 {
   MOZ_ASSERT(aTextureOnBlack && aTextureOnWhite);
   aTextureOnBlack->SetCompositor(GetCompositor());
-  aTextureOnBlack->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
   aTextureOnWhite->SetCompositor(GetCompositor());
-  aTextureOnWhite->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
 }
 
 void
 CompositableHost::RemoveTextureHost(TextureHost* aTexture)
-{
-  // Clear strong refrence to CompositableBackendSpecificData
-  aTexture->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
-}
+{}
 
 void
 CompositableHost::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = aCompositor;
 }
 
 bool
 CompositableHost::AddMaskEffect(EffectChain& aEffects,
                                 const gfx::Matrix4x4& aTransform,
                                 bool aIs3D)
 {
-  RefPtr<TextureSource> source;
+  CompositableTextureSourceRef source;
   RefPtr<TextureHost> host = GetAsTextureHost();
 
   if (!host) {
     NS_WARNING("Using compositable with no valid TextureHost as mask");
     return false;
   }
 
   if (!host->Lock()) {
     NS_WARNING("Failed to lock the mask texture");
     return false;
   }
 
-  source = host->GetTextureSources();
-  MOZ_ASSERT(source);
-
-  if (!source) {
+  if (!host->BindTextureSource(source)) {
     NS_WARNING("The TextureHost was successfully locked but can't provide a TextureSource");
     host->Unlock();
     return false;
   }
+  MOZ_ASSERT(source);
 
   RefPtr<EffectMask> effect = new EffectMask(source,
                                              source->GetSize(),
                                              aTransform);
   effect->mIs3D = aIs3D;
   aEffects.mSecondaryEffects[EffectTypes::MASK] = effect;
   return true;
 }
@@ -187,19 +168,16 @@ void
 CompositableHost::RemoveMaskEffect()
 {
   RefPtr<TextureHost> host = GetAsTextureHost();
   if (host) {
     host->Unlock();
   }
 }
 
-// implemented in TextureHostOGL.cpp
-TemporaryRef<CompositableBackendSpecificData> CreateCompositableBackendSpecificDataOGL();
-
 /* static */ TemporaryRef<CompositableHost>
 CompositableHost::Create(const TextureInfo& aTextureInfo)
 {
   RefPtr<CompositableHost> result;
   switch (aTextureInfo.mCompositableType) {
   case CompositableType::BUFFER_BRIDGE:
     NS_ERROR("Cannot create an image bridge compositable this way");
     break;
@@ -222,22 +200,16 @@ CompositableHost::Create(const TextureIn
     result = new ContentHostSingleBuffered(aTextureInfo);
     break;
   case CompositableType::CONTENT_DOUBLE:
     result = new ContentHostDoubleBuffered(aTextureInfo);
     break;
   default:
     NS_ERROR("Unknown CompositableType");
   }
-  // We know that Tiled buffers don't use the compositable backend-specific
-  // data, so don't bother creating it.
-  if (result && aTextureInfo.mCompositableType != CompositableType::BUFFER_TILED) {
-    RefPtr<CompositableBackendSpecificData> data = CreateCompositableBackendSpecificDataOGL();
-    result->SetCompositableBackendSpecificData(data);
-  }
   return result;
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 CompositableHost::DumpTextureHost(std::stringstream& aStream, TextureHost* aTexture)
 {
   if (!aTexture) {
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -45,52 +45,16 @@ class Compositor;
 class ISurfaceAllocator;
 class ThebesBufferData;
 class TiledLayerComposer;
 class CompositableParentManager;
 class PCompositableParent;
 struct EffectChain;
 
 /**
- * A base class for doing CompositableHost and platform dependent task on TextureHost.
- */
-class CompositableBackendSpecificData
-{
-protected:
-  virtual ~CompositableBackendSpecificData() {}
-
-public:
-  NS_INLINE_DECL_REFCOUNTING(CompositableBackendSpecificData)
-
-  CompositableBackendSpecificData();
-
-  virtual void ClearData() {}
-  virtual void SetCompositor(Compositor* aCompositor) {}
-
-  bool IsAllowingSharingTextureHost()
-  {
-    return mAllowSharingTextureHost;
-  }
-
-  void SetAllowSharingTextureHost(bool aAllow)
-  {
-    mAllowSharingTextureHost = aAllow;
-  }
-
-  uint64_t GetId()
-  {
-    return mId;
-  }
-
-public:
-  bool mAllowSharingTextureHost;
-  uint64_t mId;
-};
-
-/**
  * The compositor-side counterpart to CompositableClient. Responsible for
  * updating textures and data about textures from IPC and how textures are
  * composited (tiling, double buffering, etc.).
  *
  * Update (for images/canvases) and UpdateThebes (for Thebes) are called during
  * the layers transaction to update the Compositbale's textures from the
  * content side. The actual update (and any syncronous upload) is done by the
  * TextureHost, but it is coordinated by the CompositableHost.
@@ -107,26 +71,16 @@ protected:
 public:
   NS_INLINE_DECL_REFCOUNTING(CompositableHost)
   explicit CompositableHost(const TextureInfo& aTextureInfo);
 
   static TemporaryRef<CompositableHost> Create(const TextureInfo& aTextureInfo);
 
   virtual CompositableType GetType() = 0;
 
-  virtual CompositableBackendSpecificData* GetCompositableBackendSpecificData()
-  {
-    return mBackendData;
-  }
-
-  virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
-  {
-    mBackendData = aBackendData;
-  }
-
   // If base class overrides, it should still call the parent implementation
   virtual void SetCompositor(Compositor* aCompositor);
 
   // composite the contents of this buffer host to the compositor's surface
   virtual void Composite(EffectChain& aEffectChain,
                          float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Filter& aFilter,
@@ -247,19 +201,16 @@ public:
   virtual void Detach(Layer* aLayer = nullptr, AttachFlags aFlags = NO_FLAGS)
   {
     if (!mKeepAttached ||
         aLayer == mLayer ||
         aFlags & FORCE_DETACH) {
       SetLayer(nullptr);
       mAttached = false;
       mKeepAttached = false;
-      if (mBackendData) {
-        mBackendData->ClearData();
-      }
     }
   }
   bool IsAttached() { return mAttached; }
 
 #ifdef MOZ_DUMP_PAINTING
   virtual void Dump(std::stringstream& aStream,
                     const char* aPrefix="",
                     bool aDumpHtml=false) { }
@@ -309,17 +260,16 @@ public:
   }
 
 protected:
   TextureInfo mTextureInfo;
   uint64_t mAsyncID;
   uint64_t mCompositorID;
   RefPtr<Compositor> mCompositor;
   Layer* mLayer;
-  RefPtr<CompositableBackendSpecificData> mBackendData;
   uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
   bool mAttached;
   bool mKeepAttached;
 };
 
 class AutoLockCompositableHost MOZ_FINAL
 {
 public:
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -30,38 +30,42 @@ ContentHostBase::ContentHostBase(const T
   , mInitialised(false)
 {}
 
 ContentHostBase::~ContentHostBase()
 {
 }
 
 void
-ContentHostBase::Composite(EffectChain& aEffectChain,
-                           float aOpacity,
-                           const gfx::Matrix4x4& aTransform,
-                           const Filter& aFilter,
-                           const Rect& aClipRect,
-                           const nsIntRegion* aVisibleRegion)
+ContentHostTexture::Composite(EffectChain& aEffectChain,
+                              float aOpacity,
+                              const gfx::Matrix4x4& aTransform,
+                              const Filter& aFilter,
+                              const Rect& aClipRect,
+                              const nsIntRegion* aVisibleRegion)
 {
   NS_ASSERTION(aVisibleRegion, "Requires a visible region");
 
   AutoLockCompositableHost lock(this);
   if (lock.Failed()) {
     return;
   }
 
-  RefPtr<TextureSource> source = GetTextureSource();
-  RefPtr<TextureSource> sourceOnWhite = GetTextureSourceOnWhite();
+  if (!mTextureHost->BindTextureSource(mTextureSource)) {
+    return;
+  }
+  MOZ_ASSERT(mTextureSource.get());
 
-  if (!source) {
+  if (mTextureHostOnWhite && !mTextureHostOnWhite->BindTextureSource(mTextureSourceOnWhite)) {
     return;
   }
 
-  RefPtr<TexturedEffect> effect = GenEffect(aFilter);
+  RefPtr<TexturedEffect> effect = CreateTexturedEffect(mTextureSource.get(),
+                                                       mTextureSourceOnWhite.get(),
+                                                       aFilter, true);
   if (!effect) {
     return;
   }
 
   aEffectChain.mPrimaryEffect = effect;
 
   nsIntRegion tmpRegion;
   const nsIntRegion* renderRegion;
@@ -76,17 +80,17 @@ ContentHostBase::Composite(EffectChain& 
   }
 
   nsIntRegion region(*renderRegion);
   nsIntPoint origin = GetOriginOffset();
   // translate into TexImage space, buffer origin might not be at texture (0,0)
   region.MoveBy(-origin);
 
   // Figure out the intersecting draw region
-  gfx::IntSize texSize = source->GetSize();
+  gfx::IntSize texSize = mTextureSource->GetSize();
   nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
   textureRect.MoveBy(region.GetBounds().TopLeft());
   nsIntRegion subregion;
   subregion.And(region, textureRect);
   if (subregion.IsEmpty()) {
     // Region is empty, nothing to draw
     return;
   }
@@ -100,24 +104,24 @@ ContentHostBase::Composite(EffectChain& 
     nsIntRect regionRect = *iterRect;
     nsIntRect screenRect = regionRect;
     screenRect.MoveBy(origin);
 
     screenRects.Or(screenRects, screenRect);
     regionRects.Or(regionRects, regionRect);
   }
 
-  BigImageIterator* bigImgIter = source->AsBigImageIterator();
+  BigImageIterator* bigImgIter = mTextureSource->AsBigImageIterator();
   BigImageIterator* iterOnWhite = nullptr;
   if (bigImgIter) {
     bigImgIter->BeginBigImageIteration();
   }
 
-  if (sourceOnWhite) {
-    iterOnWhite = sourceOnWhite->AsBigImageIterator();
+  if (mTextureSourceOnWhite) {
+    iterOnWhite = mTextureSourceOnWhite->AsBigImageIterator();
     MOZ_ASSERT(!bigImgIter || bigImgIter->GetTileCount() == iterOnWhite->GetTileCount(),
                "Tile count mismatch on component alpha texture");
     if (iterOnWhite) {
       iterOnWhite->BeginBigImageIteration();
     }
   }
 
   bool usingTiles = (bigImgIter && bigImgIter->GetTileCount() > 1);
@@ -200,42 +204,49 @@ ContentHostBase::Composite(EffectChain& 
   DiagnosticFlags diagnostics = DiagnosticFlags::CONTENT;
   if (iterOnWhite) {
     diagnostics |= DiagnosticFlags::COMPONENT_ALPHA;
   }
   GetCompositor()->DrawDiagnostics(diagnostics, nsIntRegion(mBufferRect), aClipRect,
                                    aTransform, mFlashCounter);
 }
 
-TemporaryRef<TexturedEffect>
-ContentHostBase::GenEffect(const gfx::Filter& aFilter)
-{
-  RefPtr<TextureSource> source = GetTextureSource();
-  RefPtr<TextureSource> sourceOnWhite = GetTextureSourceOnWhite();
-  if (!source) {
-    return nullptr;
-  }
-  return CreateTexturedEffect(source, sourceOnWhite, aFilter, true);
-}
-
 void
 ContentHostTexture::UseTextureHost(TextureHost* aTexture)
 {
+  if (mTextureHost && mTextureHost != aTexture) {
+    mTextureHost->UnbindTextureSource();
+  }
   ContentHostBase::UseTextureHost(aTexture);
   mTextureHost = aTexture;
   mTextureHostOnWhite = nullptr;
+  if (mTextureHost) {
+    mTextureHost->PrepareTextureSource(mTextureSource);
+  }
 }
 
 void
 ContentHostTexture::UseComponentAlphaTextures(TextureHost* aTextureOnBlack,
                                               TextureHost* aTextureOnWhite)
 {
+  if (mTextureHost && mTextureHost != aTextureOnBlack) {
+    mTextureHost->UnbindTextureSource();
+  }
+  if (mTextureHostOnWhite && mTextureHostOnWhite != aTextureOnWhite) {
+    mTextureHostOnWhite->UnbindTextureSource();
+  }
   ContentHostBase::UseComponentAlphaTextures(aTextureOnBlack, aTextureOnWhite);
   mTextureHost = aTextureOnBlack;
   mTextureHostOnWhite = aTextureOnWhite;
+  if (mTextureHost) {
+    mTextureHost->PrepareTextureSource(mTextureSource);
+  }
+  if (mTextureHostOnWhite) {
+    mTextureHost->PrepareTextureSource(mTextureSourceOnWhite);
+  }
 }
 
 void
 ContentHostTexture::SetCompositor(Compositor* aCompositor)
 {
   ContentHostBase::SetCompositor(aCompositor);
   if (mTextureHost) {
     mTextureHost->SetCompositor(aCompositor);
@@ -413,16 +424,186 @@ ContentHostIncremental::UpdateIncrementa
                                                      aSurface,
                                                      aUpdated,
                                                      aBufferRect,
                                                      aBufferRotation));
   FlushUpdateQueue();
 }
 
 void
+ContentHostIncremental::Composite(EffectChain& aEffectChain,
+                                  float aOpacity,
+                                  const gfx::Matrix4x4& aTransform,
+                                  const Filter& aFilter,
+                                  const Rect& aClipRect,
+                                  const nsIntRegion* aVisibleRegion)
+{
+  NS_ASSERTION(aVisibleRegion, "Requires a visible region");
+
+  AutoLockCompositableHost lock(this);
+  if (lock.Failed()) {
+    return;
+  }
+
+  if (!mSource) {
+    return;
+  }
+
+  RefPtr<TexturedEffect> effect = CreateTexturedEffect(mSource.get(),
+                                                       mSourceOnWhite.get(),
+                                                       aFilter, true);
+  if (!effect) {
+    return;
+  }
+
+  aEffectChain.mPrimaryEffect = effect;
+
+  nsIntRegion tmpRegion;
+  const nsIntRegion* renderRegion;
+  if (PaintWillResample()) {
+    // If we're resampling, then the texture image will contain exactly the
+    // entire visible region's bounds, and we should draw it all in one quad
+    // to avoid unexpected aliasing.
+    tmpRegion = aVisibleRegion->GetBounds();
+    renderRegion = &tmpRegion;
+  } else {
+    renderRegion = aVisibleRegion;
+  }
+
+  nsIntRegion region(*renderRegion);
+  nsIntPoint origin = GetOriginOffset();
+  // translate into TexImage space, buffer origin might not be at texture (0,0)
+  region.MoveBy(-origin);
+
+  // Figure out the intersecting draw region
+  gfx::IntSize texSize = mSource->GetSize();
+  nsIntRect textureRect = nsIntRect(0, 0, texSize.width, texSize.height);
+  textureRect.MoveBy(region.GetBounds().TopLeft());
+  nsIntRegion subregion;
+  subregion.And(region, textureRect);
+  if (subregion.IsEmpty()) {
+    // Region is empty, nothing to draw
+    return;
+  }
+
+  nsIntRegion screenRects;
+  nsIntRegion regionRects;
+
+  // Collect texture/screen coordinates for drawing
+  nsIntRegionRectIterator iter(subregion);
+  while (const nsIntRect* iterRect = iter.Next()) {
+    nsIntRect regionRect = *iterRect;
+    nsIntRect screenRect = regionRect;
+    screenRect.MoveBy(origin);
+
+    screenRects.Or(screenRects, screenRect);
+    regionRects.Or(regionRects, regionRect);
+  }
+
+  BigImageIterator* bigImgIter = mSource->AsBigImageIterator();
+  BigImageIterator* iterOnWhite = nullptr;
+  if (bigImgIter) {
+    bigImgIter->BeginBigImageIteration();
+  }
+
+  if (mSourceOnWhite) {
+    iterOnWhite = mSourceOnWhite->AsBigImageIterator();
+    MOZ_ASSERT(!bigImgIter || bigImgIter->GetTileCount() == iterOnWhite->GetTileCount(),
+               "Tile count mismatch on component alpha texture");
+    if (iterOnWhite) {
+      iterOnWhite->BeginBigImageIteration();
+    }
+  }
+
+  bool usingTiles = (bigImgIter && bigImgIter->GetTileCount() > 1);
+  do {
+    if (iterOnWhite) {
+      MOZ_ASSERT(iterOnWhite->GetTileRect() == bigImgIter->GetTileRect(),
+                 "component alpha textures should be the same size.");
+    }
+
+    nsIntRect texRect = bigImgIter ? bigImgIter->GetTileRect()
+                                   : nsIntRect(0, 0,
+                                               texSize.width,
+                                               texSize.height);
+
+    // Draw texture. If we're using tiles, we do repeating manually, as texture
+    // repeat would cause each individual tile to repeat instead of the
+    // compound texture as a whole. This involves drawing at most 4 sections,
+    // 2 for each axis that has texture repeat.
+    for (int y = 0; y < (usingTiles ? 2 : 1); y++) {
+      for (int x = 0; x < (usingTiles ? 2 : 1); x++) {
+        nsIntRect currentTileRect(texRect);
+        currentTileRect.MoveBy(x * texSize.width, y * texSize.height);
+
+        nsIntRegionRectIterator screenIter(screenRects);
+        nsIntRegionRectIterator regionIter(regionRects);
+
+        const nsIntRect* screenRect;
+        const nsIntRect* regionRect;
+        while ((screenRect = screenIter.Next()) &&
+               (regionRect = regionIter.Next())) {
+          nsIntRect tileScreenRect(*screenRect);
+          nsIntRect tileRegionRect(*regionRect);
+
+          // When we're using tiles, find the intersection between the tile
+          // rect and this region rect. Tiling is then handled by the
+          // outer for-loops and modifying the tile rect.
+          if (usingTiles) {
+            tileScreenRect.MoveBy(-origin);
+            tileScreenRect = tileScreenRect.Intersect(currentTileRect);
+            tileScreenRect.MoveBy(origin);
+
+            if (tileScreenRect.IsEmpty())
+              continue;
+
+            tileRegionRect = regionRect->Intersect(currentTileRect);
+            tileRegionRect.MoveBy(-currentTileRect.TopLeft());
+          }
+          gfx::Rect rect(tileScreenRect.x, tileScreenRect.y,
+                         tileScreenRect.width, tileScreenRect.height);
+
+          effect->mTextureCoords = Rect(Float(tileRegionRect.x) / texRect.width,
+                                        Float(tileRegionRect.y) / texRect.height,
+                                        Float(tileRegionRect.width) / texRect.width,
+                                        Float(tileRegionRect.height) / texRect.height);
+          GetCompositor()->DrawQuad(rect, aClipRect, aEffectChain, aOpacity, aTransform);
+          if (usingTiles) {
+            DiagnosticFlags diagnostics = DiagnosticFlags::CONTENT | DiagnosticFlags::BIGIMAGE;
+            if (iterOnWhite) {
+              diagnostics |= DiagnosticFlags::COMPONENT_ALPHA;
+            }
+            GetCompositor()->DrawDiagnostics(diagnostics, rect, aClipRect,
+                                             aTransform, mFlashCounter);
+          }
+        }
+      }
+    }
+
+    if (iterOnWhite) {
+      iterOnWhite->NextTile();
+    }
+  } while (usingTiles && bigImgIter->NextTile());
+
+  if (bigImgIter) {
+    bigImgIter->EndBigImageIteration();
+  }
+  if (iterOnWhite) {
+    iterOnWhite->EndBigImageIteration();
+  }
+
+  DiagnosticFlags diagnostics = DiagnosticFlags::CONTENT;
+  if (iterOnWhite) {
+    diagnostics |= DiagnosticFlags::COMPONENT_ALPHA;
+  }
+  GetCompositor()->DrawDiagnostics(diagnostics, nsIntRegion(mBufferRect), aClipRect,
+                                   aTransform, mFlashCounter);
+}
+
+void
 ContentHostIncremental::FlushUpdateQueue()
 {
   // If we're not compositing for some reason (the window being minimized
   // is one example), then we never process these updates and it can consume
   // huge amounts of memory. Instead we forcibly process the updates (during the
   // transaction) if the list gets too long.
   static const uint32_t kMaxUpdateCount = 6;
   if (mUpdateList.Length() >= kMaxUpdateCount) {
@@ -434,30 +615,16 @@ void
 ContentHostIncremental::ProcessTextureUpdates()
 {
   for (uint32_t i = 0; i < mUpdateList.Length(); i++) {
     mUpdateList[i]->Execute(this);
   }
   mUpdateList.Clear();
 }
 
-TextureSource*
-ContentHostIncremental::GetTextureSource()
-{
-  MOZ_ASSERT(mLocked);
-  return mSource;
-}
-
-TextureSource*
-ContentHostIncremental::GetTextureSourceOnWhite()
-{
-  MOZ_ASSERT(mLocked);
-  return mSourceOnWhite;
-}
-
 void
 ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental* aHost)
 {
   Compositor* compositor = aHost->GetCompositor();
   MOZ_ASSERT(compositor);
 
   RefPtr<DataTextureSource> temp =
     compositor->CreateDataTextureSource(mTextureInfo.mTextureFlags);
@@ -678,16 +845,42 @@ ContentHostTexture::GetRenderState()
 
   if (mBufferRotation != nsIntPoint()) {
     result.mFlags |= LayerRenderStateFlags::BUFFER_ROTATION;
   }
   result.SetOffset(GetOriginOffset());
   return result;
 }
 
+TemporaryRef<TexturedEffect>
+ContentHostTexture::GenEffect(const gfx::Filter& aFilter)
+{
+  if (!mTextureHost) {
+    return nullptr;
+  }
+  if (!mTextureHost->BindTextureSource(mTextureSource)) {
+    return nullptr;
+  }
+  if (mTextureHostOnWhite && !mTextureHostOnWhite->BindTextureSource(mTextureSourceOnWhite)) {
+    return nullptr;
+  }
+  return CreateTexturedEffect(mTextureSource.get(),
+                              mTextureSourceOnWhite.get(),
+                              aFilter, true);
+}
+
+TemporaryRef<TexturedEffect>
+ContentHostIncremental::GenEffect(const gfx::Filter& aFilter)
+{
+  if (!mSource) {
+    return nullptr;
+  }
+  return CreateTexturedEffect(mSource, mSourceOnWhite, aFilter, true);
+}
+
 #ifdef MOZ_DUMP_PAINTING
 TemporaryRef<gfx::DataSourceSurface>
 ContentHostTexture::GetAsSurface()
 {
   if (!mTextureHost) {
     return nullptr;
   }
 
--- a/gfx/layers/composite/ContentHost.h
+++ b/gfx/layers/composite/ContentHost.h
@@ -91,28 +91,16 @@ class ContentHostBase : public ContentHo
 {
 public:
   typedef RotatedContentBuffer::ContentType ContentType;
   typedef RotatedContentBuffer::PaintState PaintState;
 
   explicit ContentHostBase(const TextureInfo& aTextureInfo);
   virtual ~ContentHostBase();
 
-  virtual void Composite(EffectChain& aEffectChain,
-                         float aOpacity,
-                         const gfx::Matrix4x4& aTransform,
-                         const gfx::Filter& aFilter,
-                         const gfx::Rect& aClipRect,
-                         const nsIntRegion* aVisibleRegion = nullptr);
-
-  virtual TextureSource* GetTextureSource() = 0;
-  virtual TextureSource* GetTextureSourceOnWhite() = 0;
-
-  virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
-
 protected:
   virtual nsIntPoint GetOriginOffset()
   {
     return mBufferRect.TopLeft() - mBufferRotation;
   }
 
 
   nsIntRect mBufferRect;
@@ -127,16 +115,23 @@ protected:
 class ContentHostTexture : public ContentHostBase
 {
 public:
   explicit ContentHostTexture(const TextureInfo& aTextureInfo)
     : ContentHostBase(aTextureInfo)
     , mLocked(false)
   { }
 
+  virtual void Composite(EffectChain& aEffectChain,
+                         float aOpacity,
+                         const gfx::Matrix4x4& aTransform,
+                         const gfx::Filter& aFilter,
+                         const gfx::Rect& aClipRect,
+                         const nsIntRegion* aVisibleRegion = nullptr);
+
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
 #ifdef MOZ_DUMP_PAINTING
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
   virtual void Dump(std::stringstream& aStream,
                     const char* aPrefix="",
                     bool aDumpHtml=false) MOZ_OVERRIDE;
@@ -168,33 +163,25 @@ public:
     MOZ_ASSERT(mLocked);
     mTextureHost->Unlock();
     if (mTextureHostOnWhite) {
       mTextureHostOnWhite->Unlock();
     }
     mLocked = false;
   }
 
-  virtual TextureSource* GetTextureSource() MOZ_OVERRIDE {
-    MOZ_ASSERT(mLocked);
-    return mTextureHost->GetTextureSources();
-  }
-  virtual TextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE {
-    MOZ_ASSERT(mLocked);
-    if (mTextureHostOnWhite) {
-      return mTextureHostOnWhite->GetTextureSources();
-    }
-    return nullptr;
-  }
+  LayerRenderState GetRenderState();
 
-  LayerRenderState GetRenderState();
+  virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
 
 protected:
   RefPtr<TextureHost> mTextureHost;
   RefPtr<TextureHost> mTextureHostOnWhite;
+  CompositableTextureSourceRef mTextureSource;
+  CompositableTextureSourceRef mTextureSourceOnWhite;
   bool mLocked;
 };
 
 /**
  * Double buffering is implemented by swapping the front and back TextureHosts.
  * We assume that whenever we use double buffering, then we have
  * render-to-texture and thus no texture upload to do.
  */
@@ -272,32 +259,39 @@ public:
                             const nsIntRegion& aUpdated,
                             const nsIntRegion& aOldValidRegionBack,
                             nsIntRegion* aUpdatedRegionBack)
   {
     NS_ERROR("Shouldn't call this");
     return false;
   }
 
+  virtual void Composite(EffectChain& aEffectChain,
+                         float aOpacity,
+                         const gfx::Matrix4x4& aTransform,
+                         const gfx::Filter& aFilter,
+                         const gfx::Rect& aClipRect,
+                         const nsIntRegion* aVisibleRegion = nullptr);
+
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) MOZ_OVERRIDE;
 
   virtual bool Lock() MOZ_OVERRIDE {
     MOZ_ASSERT(!mLocked);
     ProcessTextureUpdates();
     mLocked = true;
     return true;
   }
 
   virtual void Unlock() MOZ_OVERRIDE {
     MOZ_ASSERT(mLocked);
     mLocked = false;
   }
 
-  virtual TextureSource* GetTextureSource() MOZ_OVERRIDE;
-  virtual TextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE;
+  virtual TemporaryRef<TexturedEffect>
+  GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
 
 private:
 
   void FlushUpdateQueue();
   void ProcessTextureUpdates();
 
   class Request
   {
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -32,46 +32,40 @@ ImageHost::ImageHost(const TextureInfo& 
   , mFrontBuffer(nullptr)
   , mHasPictureRect(false)
   , mLocked(false)
 {}
 
 ImageHost::~ImageHost()
 {
   if (mFrontBuffer) {
-    mFrontBuffer->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
-  }
-}
-
-void
-ImageHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
-{
-  CompositableHost::SetCompositableBackendSpecificData(aBackendData);
-  // ImageHost allows TextureHost sharing among ImageHosts.
-  if (aBackendData) {
-    aBackendData->SetAllowSharingTextureHost(true);
+    mFrontBuffer->UnbindTextureSource();
   }
 }
 
 void
 ImageHost::UseTextureHost(TextureHost* aTexture)
 {
+  if (mFrontBuffer && mFrontBuffer != aTexture) {
+    mFrontBuffer->UnbindTextureSource();
+  }
   CompositableHost::UseTextureHost(aTexture);
+  mFrontBuffer = aTexture;
   if (mFrontBuffer) {
-    mFrontBuffer->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
+    mFrontBuffer->PrepareTextureSource(mTextureSource);
   }
-  mFrontBuffer = aTexture;
 }
 
 void
 ImageHost::RemoveTextureHost(TextureHost* aTexture)
 {
   CompositableHost::RemoveTextureHost(aTexture);
   if (aTexture && mFrontBuffer == aTexture) {
-    aTexture->SetCompositableBackendSpecificData(nullptr);
+    mFrontBuffer->UnbindTextureSource();
+    mTextureSource = nullptr;
     mFrontBuffer = nullptr;
   }
 }
 
 TextureHost*
 ImageHost::GetAsTextureHost()
 {
   return mFrontBuffer;
@@ -92,59 +86,68 @@ ImageHost::Composite(EffectChain& aEffec
     return;
   }
   if (!mFrontBuffer) {
     return;
   }
 
   // Make sure the front buffer has a compositor
   mFrontBuffer->SetCompositor(GetCompositor());
-  mFrontBuffer->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
 
   AutoLockCompositableHost autoLock(this);
   if (autoLock.Failed()) {
     NS_WARNING("failed to lock front buffer");
     return;
   }
-  RefPtr<TextureSource> source = GetTextureSource();
-  if (!source) {
+
+  if (!mFrontBuffer->BindTextureSource(mTextureSource)) {
     return;
   }
 
-  RefPtr<TexturedEffect> effect = GenEffect(aFilter);
+  if (!mTextureSource) {
+    // BindTextureSource above should have returned false!
+    MOZ_ASSERT(false);
+    return;
+  }
+
+  bool isAlphaPremultiplied = !(mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED);
+  RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
+                                                       mTextureSource.get(),
+                                                       aFilter,
+                                                       isAlphaPremultiplied);
   if (!effect) {
     return;
   }
 
   aEffectChain.mPrimaryEffect = effect;
-  IntSize textureSize = source->GetSize();
+  IntSize textureSize = mTextureSource->GetSize();
   gfx::Rect gfxPictureRect
     = mHasPictureRect ? gfx::Rect(0, 0, mPictureRect.width, mPictureRect.height)
                       : gfx::Rect(0, 0, textureSize.width, textureSize.height);
 
   gfx::Rect pictureRect(0, 0,
                         mPictureRect.width,
                         mPictureRect.height);
-  BigImageIterator* it = source->AsBigImageIterator();
+  BigImageIterator* it = mTextureSource->AsBigImageIterator();
   if (it) {
 
     // This iteration does not work if we have multiple texture sources here
     // (e.g. 3 YCbCr textures). There's nothing preventing the different
     // planes from having different resolutions or tile sizes. For example, a
     // YCbCr frame could have Cb and Cr planes that are half the resolution of
     // the Y plane, in such a way that the Y plane overflows the maximum
     // texture size and the Cb and Cr planes do not. Then the Y plane would be
     // split into multiple tiles and the Cb and Cr planes would just be one
     // tile each.
     // To handle the general case correctly, we'd have to create a grid of
     // intersected tiles over all planes, and then draw each grid tile using
     // the corresponding source tiles from all planes, with appropriate
     // per-plane per-tile texture coords.
     // DrawQuad currently assumes that all planes use the same texture coords.
-    MOZ_ASSERT(it->GetTileCount() == 1 || !source->GetNextSibling(),
+    MOZ_ASSERT(it->GetTileCount() == 1 || !mTextureSource->GetNextSibling(),
                "Can't handle multi-plane BigImages");
 
     it->BeginBigImageIteration();
     do {
       nsIntRect tileRect = it->GetTileRect();
       gfx::Rect rect(tileRect.x, tileRect.y, tileRect.width, tileRect.height);
       if (mHasPictureRect) {
         rect = rect.Intersect(pictureRect);
@@ -165,17 +168,17 @@ ImageHost::Composite(EffectChain& aEffec
                                        rect, aClipRect, aTransform, mFlashCounter);
     } while (it->NextTile());
     it->EndBigImageIteration();
     // layer border
     GetCompositor()->DrawDiagnostics(DiagnosticFlags::IMAGE,
                                      gfxPictureRect, aClipRect,
                                      aTransform, mFlashCounter);
   } else {
-    IntSize textureSize = source->GetSize();
+    IntSize textureSize = mTextureSource->GetSize();
     gfx::Rect rect;
     if (mHasPictureRect) {
       effect->mTextureCoords = Rect(Float(mPictureRect.x) / textureSize.width,
                                     Float(mPictureRect.y) / textureSize.height,
                                     Float(mPictureRect.width) / textureSize.width,
                                     Float(mPictureRect.height) / textureSize.height);
       rect = pictureRect;
     } else {
@@ -268,36 +271,28 @@ ImageHost::Lock()
 void
 ImageHost::Unlock()
 {
   MOZ_ASSERT(mLocked);
   mFrontBuffer->Unlock();
   mLocked = false;
 }
 
-TemporaryRef<TextureSource>
-ImageHost::GetTextureSource()
-{
-  MOZ_ASSERT(mLocked);
-  return mFrontBuffer->GetTextureSources();
-}
-
 TemporaryRef<TexturedEffect>
 ImageHost::GenEffect(const gfx::Filter& aFilter)
 {
-  RefPtr<TextureSource> source = GetTextureSource();
-  if (!source) {
+  if (!mFrontBuffer->BindTextureSource(mTextureSource)) {
     return nullptr;
   }
   bool isAlphaPremultiplied = true;
   if (mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED)
     isAlphaPremultiplied = false;
 
   return CreateTexturedEffect(mFrontBuffer->GetFormat(),
-                              source,
+                              mTextureSource,
                               aFilter,
                               isAlphaPremultiplied);
 }
 
 #ifdef MOZ_WIDGET_GONK
 ImageHostOverlay::ImageHostOverlay(const TextureInfo& aTextureInfo)
   : CompositableHost(aTextureInfo)
   , mHasPictureRect(false)
--- a/gfx/layers/composite/ImageHost.h
+++ b/gfx/layers/composite/ImageHost.h
@@ -40,18 +40,16 @@ struct EffectChain;
 class ImageHost : public CompositableHost
 {
 public:
   explicit ImageHost(const TextureInfo& aTextureInfo);
   ~ImageHost();
 
   virtual CompositableType GetType() { return mTextureInfo.mCompositableType; }
 
-  virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
-
   virtual void Composite(EffectChain& aEffectChain,
                          float aOpacity,
                          const gfx::Matrix4x4& aTransform,
                          const gfx::Filter& aFilter,
                          const gfx::Rect& aClipRect,
                          const nsIntRegion* aVisibleRegion = nullptr) MOZ_OVERRIDE;
 
   virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;
@@ -79,23 +77,22 @@ public:
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 #endif
 
   virtual bool Lock() MOZ_OVERRIDE;
 
   virtual void Unlock() MOZ_OVERRIDE;
 
-  virtual TemporaryRef<TextureSource> GetTextureSource();
-
   virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
 
 protected:
 
   RefPtr<TextureHost> mFrontBuffer;
+  CompositableTextureSourceRef mTextureSource;
   nsIntRect mPictureRect;
   bool mHasPictureRect;
   bool mLocked;
 };
 
 #ifdef MOZ_WIDGET_GONK
 
 /**
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -139,16 +139,23 @@ TextureHost::AsTextureHost(PTextureParen
 }
 
 PTextureParent*
 TextureHost::GetIPDLActor()
 {
   return mActor;
 }
 
+bool
+TextureHost::BindTextureSource(CompositableTextureSourceRef& texture)
+{
+  texture = GetTextureSources();
+  return !!texture;
+}
+
 FenceHandle
 TextureHost::GetAndResetReleaseFenceHandle()
 {
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   TextureHostOGL* hostOGL = this->AsHostOGL();
   if (!hostOGL) {
     return FenceHandle();
   }
@@ -272,28 +279,16 @@ void
 TextureHost::CompositorRecycle()
 {
   if (!mActor) {
     return;
   }
   static_cast<TextureParent*>(mActor)->CompositorRecycle();
 }
 
-void
-TextureHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
-{
-  mCompositableBackendData = aBackendData;
-}
-
-void
-TextureHost::UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
-{
-  mCompositableBackendData = nullptr;
-}
-
 TextureHost::TextureHost(TextureFlags aFlags)
     : mActor(nullptr)
     , mFlags(aFlags)
 {}
 
 TextureHost::~TextureHost()
 {
 }
@@ -317,19 +312,21 @@ TextureHost::PrintInfo(std::stringstream
     AppendToString(aStream, GetSize(), " [size=", "]");
     AppendToString(aStream, GetFormat(), " [format=", "]");
     Unlock();
   }
   AppendToString(aStream, mFlags, " [flags=", "]");
 }
 
 TextureSource::TextureSource()
+: mCompositableCount(0)
 {
     MOZ_COUNT_CTOR(TextureSource);
 }
+
 TextureSource::~TextureSource()
 {
     MOZ_COUNT_DTOR(TextureSource);
 }
 
 BufferTextureHost::BufferTextureHost(gfx::SurfaceFormat aFormat,
                                      TextureFlags aFlags)
 : TextureHost(aFlags)
@@ -838,34 +835,36 @@ SharedSurfaceToTexSource(gl::SharedSurfa
       auto surf = gl::SharedSurface_GLTexture::Cast(abstractSurf);
 
       MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
       CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
       gl::GLContext* gl = compositorOGL->gl();
 
       GLenum target = surf->ConsTextureTarget();
       GLuint tex = surf->ConsTexture(gl);
-      texSource = new GLTextureSource(compositorOGL, tex, format, target,
-                                      surf->mSize);
+      texSource = new GLTextureSource(compositorOGL, tex, target,
+                                      surf->mSize, format,
+                                      true/*externally owned*/);
       break;
     }
     case gl::SharedSurfaceType::EGLImageShare: {
       auto surf = gl::SharedSurface_EGLImage::Cast(abstractSurf);
 
       MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
       CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(compositor);
       gl::GLContext* gl = compositorOGL->gl();
       MOZ_ASSERT(gl->IsCurrent());
 
       GLenum target = 0;
       GLuint tex = 0;
       surf->AcquireConsumerTexture(gl, &tex, &target);
 
-      texSource = new GLTextureSource(compositorOGL, tex, format, target,
-                                      surf->mSize);
+      texSource = new GLTextureSource(compositorOGL, tex, target,
+                                      surf->mSize, format,
+                                      true/*externally owned*/);
       break;
     }
 #ifdef XP_MACOSX
     case gl::SharedSurfaceType::IOSurface: {
       auto surf = gl::SharedSurface_IOSurface::Cast(abstractSurf);
       MacIOSurface* ioSurf = surf->GetIOSurface();
 
       MOZ_ASSERT(compositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -41,17 +41,16 @@ class SharedSurface;
 namespace ipc {
 class Shmem;
 }
 
 namespace layers {
 
 class Compositor;
 class CompositableHost;
-class CompositableBackendSpecificData;
 class CompositableParentManager;
 class SurfaceDescriptor;
 class SharedSurfaceDescriptor;
 class ISurfaceAllocator;
 class TextureHostOGL;
 class TextureSourceOGL;
 class TextureSourceD3D9;
 class TextureSourceD3D11;
@@ -145,20 +144,79 @@ public:
     switch (index) {
       case 0: return this;
       case 1: return GetNextSibling();
       case 2: return GetNextSibling() ? GetNextSibling()->GetNextSibling() : nullptr;
     }
     return nullptr;
   }
 
+  void AddCompositableRef() { ++mCompositableCount; }
+
+  void ReleaseCompositableRef() {
+    --mCompositableCount;
+    MOZ_ASSERT(mCompositableCount >= 0);
+  }
+
+  int NumCompositableRefs() const { return mCompositableCount; }
+
 protected:
   virtual ~TextureSource();
 
   RefPtr<TextureSource> mNextSibling;
+  int mCompositableCount;
+};
+
+/**
+ * equivalent of a RefPtr<TextureSource>, that calls AddCompositableRef and
+ * ReleaseCompositableRef in addition to the usual AddRef and Release.
+ */
+class CompositableTextureSourceRef {
+public:
+  CompositableTextureSourceRef() {}
+
+  ~CompositableTextureSourceRef()
+  {
+    if (mRef) {
+      mRef->ReleaseCompositableRef();
+    }
+  }
+
+  CompositableTextureSourceRef& operator=(const TemporaryRef<TextureSource>& aOther)
+  {
+    RefPtr<TextureSource> temp = aOther;
+    if (temp) {
+      temp->AddCompositableRef();
+    }
+    if (mRef) {
+      mRef->ReleaseCompositableRef();
+    }
+    mRef = temp;
+    return *this;
+  }
+
+  CompositableTextureSourceRef& operator=(TextureSource* aOther)
+  {
+    if (aOther) {
+      aOther->AddCompositableRef();
+    }
+    if (mRef) {
+      mRef->ReleaseCompositableRef();
+    }
+    mRef = aOther;
+    return *this;
+  }
+
+  TextureSource* get() const { return mRef; }
+  operator TextureSource*() const { return mRef; }
+  TextureSource* operator->() const { return mRef; }
+  TextureSource& operator*() const { return *mRef; }
+
+private:
+  RefPtr<TextureSource> mRef;
 };
 
 /**
  * Interface for TextureSources that can be updated from a DataSourceSurface.
  *
  * All backend should implement at least one DataTextureSource.
  */
 class DataTextureSource : public TextureSource
@@ -298,16 +356,35 @@ public:
    *
    * This can trigger texture uploads, so do not call it inside transactions
    * so as to not upload textures while the main thread is blocked.
    * Must not be called while this TextureHost is not sucessfully Locked.
    */
   virtual TextureSource* GetTextureSources() = 0;
 
   /**
+   * Called during the transaction. The TextureSource may or may not be composited.
+   *
+   * Note that this is called outside of lock/unlock.
+   */
+  virtual void PrepareTextureSource(CompositableTextureSourceRef& aTexture) {}
+
+  /**
+   * Called at composition time, just before compositing the TextureSource composited.
+   *
+   * Note that this is called only withing lock/unlock.
+   */
+  virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture);
+
+  /**
+   * Called when another TextureHost will take over.
+   */
+  virtual void UnbindTextureSource() {}
+
+  /**
    * Is called before compositing if the shared data has changed since last
    * composition.
    * This method should be overload in cases like when we need to do a texture
    * upload for example.
    *
    * @param aRegion The region that has been changed, if nil, it means that the
    * entire surface should be updated.
    */
@@ -401,20 +478,16 @@ public:
    */
   virtual LayerRenderState GetRenderState()
   {
     // By default we return an empty render state, this should be overridden
     // by the TextureHost implementations that are used on B2G with Composer2D
     return LayerRenderState();
   }
 
-  virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
-
-  virtual void UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData);
-
   // If a texture host holds a reference to shmem, it should override this method
   // to forget about the shmem _without_ releasing it.
   virtual void OnShutdown() {}
 
   // Forget buffer actor. Used only for hacky fix for bug 966446.
   virtual void ForgetBufferActor() {}
 
   virtual const char *Name() { return "TextureHost"; }
@@ -430,17 +503,16 @@ public:
   /**
    * Cast to a TextureHost for each backend.
    */
   virtual TextureHostOGL* AsHostOGL() { return nullptr; }
 
 protected:
   PTextureParent* mActor;
   TextureFlags mFlags;
-  RefPtr<CompositableBackendSpecificData> mCompositableBackendData;
 
   friend class TextureParent;
 };
 
 /**
  * TextureHost that wraps a random access buffer such as a Shmem or some raw
  * memory.
  *
--- a/gfx/layers/opengl/GrallocTextureHost.cpp
+++ b/gfx/layers/opengl/GrallocTextureHost.cpp
@@ -125,43 +125,28 @@ GrallocTextureSourceOGL::BindTexture(GLe
   }
 
   GLuint tex = GetGLTexture();
   GLuint textureTarget = GetTextureTarget();
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(textureTarget, tex);
 
-  if (mTextureBackendSpecificData) {
-    // There are two paths for locking/unlocking - if mTextureBackendSpecificData is
-    // set, we use the texture on there, otherwise we use
-    // CompositorBackendSpecificData from the compositor and bind the EGLImage
-    // only in Lock().
-    if (!mEGLImage) {
-      mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
-    }
-    BindEGLImage();
-  }
-
   ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
 
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   if (mTextureHost) {
     // Wait until it's ready.
     mTextureHost->WaitAcquireFenceSyncComplete();
   }
 #endif
 }
 
 bool GrallocTextureSourceOGL::Lock()
 {
-  if (mTextureBackendSpecificData) {
-    return true;
-  }
-
   MOZ_ASSERT(IsValid());
   if (!IsValid()) {
     return false;
   }
   if (!gl()->MakeCurrent()) {
     NS_WARNING("Failed to make the gl context current");
     return false;
   }
@@ -177,17 +162,17 @@ bool GrallocTextureSourceOGL::Lock()
   }
   gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
   return true;
 }
 
 bool
 GrallocTextureSourceOGL::IsValid() const
 {
-  return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mTextureBackendSpecificData);
+  return !!gl() && !!mGraphicBuffer.get() && !!mCompositor;
 }
 
 gl::GLContext*
 GrallocTextureSourceOGL::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
 
@@ -219,72 +204,16 @@ GrallocTextureSourceOGL::GetTextureTarge
   if (gl()->Renderer() == gl::GLRenderer::SGX530 ||
       gl()->Renderer() == gl::GLRenderer::SGX540) {
     return LOCAL_GL_TEXTURE_EXTERNAL;
   }
 
   return TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
 }
 
-void
-GrallocTextureSourceOGL::SetTextureBackendSpecificData(TextureSharedDataGonkOGL* aBackendData)
-{
-  if (!aBackendData) {
-    DeallocateDeviceData();
-    // Update mTextureBackendSpecificData after calling DeallocateDeviceData().
-    mTextureBackendSpecificData = nullptr;
-    return;
-  }
-
-  if (mTextureBackendSpecificData != aBackendData) {
-    mNeedsReset = true;
-  }
-
-  if (!gl() || !gl()->MakeCurrent()) {
-    NS_WARNING("Failed to make the context current");
-    return;
-  }
-
-  if (!mNeedsReset) {
-    // Update binding to the EGLImage
-    GLuint tex = GetGLTexture();
-    GLuint textureTarget = GetTextureTarget();
-    gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-    gl()->fBindTexture(textureTarget, tex);
-    BindEGLImage();
-    return;
-  }
-
-  if (!mCompositor) {
-    mTextureBackendSpecificData = aBackendData;
-    return;
-  }
-
-  // delete old EGLImage
-  DeallocateDeviceData();
-
-  // Update mTextureBackendSpecificData after calling DeallocateDeviceData().
-  mTextureBackendSpecificData = aBackendData;
-
-  GLuint tex = GetGLTexture();
-  GLuint textureTarget = GetTextureTarget();
-
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
-  gl()->fBindTexture(textureTarget, tex);
-
-  // Setup texure parameters at the first binding.
-  gl()->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_T, GetWrapMode());
-  gl()->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_S, GetWrapMode());
-
-  // create new EGLImage
-  mEGLImage = EGLImageCreateFromNativeBuffer(gl(), mGraphicBuffer->getNativeBuffer());
-  BindEGLImage();
-  mNeedsReset = false;
-}
-
 gfx::IntSize
 GrallocTextureSourceOGL::GetSize() const
 {
   if (!IsValid()) {
     NS_WARNING("Trying to access the size of an invalid GrallocTextureSourceOGL");
     return gfx::IntSize(0, 0);
   }
   return gfx::IntSize(mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight());
@@ -293,103 +222,100 @@ GrallocTextureSourceOGL::GetSize() const
 void
 GrallocTextureSourceOGL::DeallocateDeviceData()
 {
   if (mEGLImage) {
     MOZ_ASSERT(mCompositor);
     if (!gl() || !gl()->MakeCurrent()) {
       return;
     }
-    if (mTextureBackendSpecificData) {
-      mTextureBackendSpecificData->ClearBoundEGLImage(mEGLImage);
-    }
     EGLImageDestroy(gl(), mEGLImage);
     mEGLImage = EGL_NO_IMAGE;
   }
 }
 
 GrallocTextureHostOGL::GrallocTextureHostOGL(TextureFlags aFlags,
                                              const NewSurfaceDescriptorGralloc& aDescriptor)
   : TextureHost(aFlags)
+  , mGrallocHandle(aDescriptor)
+  , mSize(0, 0)
+  , mDescriptorSize(aDescriptor.size())
+  , mFormat(gfx::SurfaceFormat::UNKNOWN)
+  , mEGLImage(EGL_NO_IMAGE)
 {
-  gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
-  mGrallocHandle = aDescriptor;
-
   android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
   MOZ_ASSERT(graphicBuffer);
 
-  mSize = aDescriptor.size();
   if (graphicBuffer) {
-    format =
+    mFormat =
       SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
                                          aFlags & TextureFlags::RB_SWAPPED);
-    mTextureSource = new GrallocTextureSourceOGL(nullptr,
-                                                 this,
-                                                 graphicBuffer,
-                                                 format);
+    mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight());
   } else {
     printf_stderr("gralloc buffer is nullptr");
   }
 }
 
 GrallocTextureHostOGL::~GrallocTextureHostOGL()
-{
-  MOZ_ASSERT(!mTextureSource || (mFlags & TextureFlags::DEALLOCATE_CLIENT),
-             "Leaking our buffer");
-}
+{}
 
 void
 GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
 {
-  if (mTextureSource) {
-    mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor));
+  mCompositor = static_cast<CompositorOGL*>(aCompositor);
+  if (mTilingTextureSource) {
+    mTilingTextureSource->SetCompositor(mCompositor);
+  }
+  if (mGLTextureSource) {
+    mGLTextureSource->SetCompositor(mCompositor);
+  }
+
+  if (mCompositor && aCompositor != mCompositor) {
+    DestroyEGLImage();
   }
 }
 
 bool
 GrallocTextureHostOGL::Lock()
 {
-  if (IsValid()) {
-    mTextureSource->Lock();
-    return true;
-  }
-  return false;
+  return IsValid();
 }
 
 void
 GrallocTextureHostOGL::Unlock()
 {
   // Unlock is done internally by binding the texture to another gralloc buffer
 }
 
 bool
 GrallocTextureHostOGL::IsValid() const
 {
-  if (!mTextureSource) {
-    return false;
-  }
-  return mTextureSource->IsValid();
+  android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
+  return graphicBuffer != nullptr;
 }
 
 gfx::SurfaceFormat
 GrallocTextureHostOGL::GetFormat() const
 {
-  if (!mTextureSource) {
-    return gfx::SurfaceFormat::UNKNOWN;
-  }
-  return mTextureSource->GetFormat();
+  return mFormat;
 }
 
 void
 GrallocTextureHostOGL::DeallocateSharedData()
 {
-  if (mTextureSource) {
-    mTextureSource->ForgetBuffer();
-    mTextureSource = nullptr;
+  if (mTilingTextureSource) {
+    mTilingTextureSource->ForgetBuffer();
+    mTilingTextureSource = nullptr;
   }
+  if (mGLTextureSource) {
+    mGLTextureSource = nullptr;
+  }
+
+  DestroyEGLImage();
+
   if (mGrallocHandle.buffer().type() != SurfaceDescriptor::Tnull_t) {
     MaybeMagicGrallocBufferHandle handle = mGrallocHandle.buffer();
     base::ProcessId owner;
     if (handle.type() == MaybeMagicGrallocBufferHandle::TGrallocBufferRef) {
       owner = handle.get_GrallocBufferRef().mOwner;
     }
     else {
       owner = handle.get_MagicGrallocBufferHandle().mRef.mOwner;
@@ -397,54 +323,63 @@ GrallocTextureHostOGL::DeallocateSharedD
 
     SharedBufferManagerParent::DropGrallocBuffer(owner, mGrallocHandle);
   }
 }
 
 void
 GrallocTextureHostOGL::ForgetSharedData()
 {
-  if (mTextureSource) {
-    mTextureSource->ForgetBuffer();
-    mTextureSource = nullptr;
+  if (mTilingTextureSource) {
+    mTilingTextureSource->ForgetBuffer();
+    mTilingTextureSource = nullptr;
+  }
+  if (mGLTextureSource) {
+    mGLTextureSource = nullptr;
   }
 }
 
 void
 GrallocTextureHostOGL::DeallocateDeviceData()
 {
-  if (mTextureSource) {
-    mTextureSource->DeallocateDeviceData();
+  if (mTilingTextureSource) {
+    mTilingTextureSource->DeallocateDeviceData();
   }
+  if (mGLTextureSource) {
+    mGLTextureSource = nullptr;
+  }
+  DestroyEGLImage();
 }
 
 LayerRenderState
 GrallocTextureHostOGL::GetRenderState()
 {
-  if (IsValid()) {
+  android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
+
+  if (graphicBuffer) {
     LayerRenderStateFlags flags = LayerRenderStateFlags::LAYER_RENDER_STATE_DEFAULT;
     if (mFlags & TextureFlags::NEEDS_Y_FLIP) {
       flags |= LayerRenderStateFlags::Y_FLIPPED;
     }
     if (mFlags & TextureFlags::RB_SWAPPED) {
       flags |= LayerRenderStateFlags::FORMAT_RB_SWAP;
     }
-    return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
-                            gfx::ThebesIntSize(mSize),
+    return LayerRenderState(graphicBuffer,
+                            gfx::ThebesIntSize(mDescriptorSize),
                             flags,
                             this);
   }
 
   return LayerRenderState();
 }
 
 TemporaryRef<gfx::DataSourceSurface>
 GrallocTextureHostOGL::GetAsSurface() {
-  return mTextureSource ? mTextureSource->GetAsSurface()
-                        : nullptr;
+  return mTilingTextureSource ? mTilingTextureSource->GetAsSurface()
+                              : nullptr;
 }
 
 TemporaryRef<gfx::DataSourceSurface>
 GrallocTextureSourceOGL::GetAsSurface() {
   if (!IsValid() || !gl()->MakeCurrent()) {
     return nullptr;
   }
 
@@ -462,109 +397,192 @@ GrallocTextureSourceOGL::GetAsSurface() 
 
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
   return surf.forget();
 }
 
 GLuint
 GrallocTextureSourceOGL::GetGLTexture()
 {
-  if (mTextureBackendSpecificData) {
-    mTextureBackendSpecificData->SetCompositor(mCompositor);
-    return mTextureBackendSpecificData->GetTexture();
-  }
-
   return mTexture;
 }
 
 void
 GrallocTextureSourceOGL::BindEGLImage()
 {
-  if (mTextureBackendSpecificData) {
-    mTextureBackendSpecificData->BindEGLImage(GetTextureTarget(), mEGLImage);
+  gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
+}
+
+TextureSource*
+GrallocTextureHostOGL::GetTextureSources()
+{
+  // This is now only used with tiled layers, and will eventually be removed.
+  // Other layer types use BindTextureSource instead.
+  MOZ_ASSERT(!mGLTextureSource);
+  if (!mTilingTextureSource) {
+    android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
+    MOZ_ASSERT(graphicBuffer);
+    if (!graphicBuffer) {
+      return nullptr;
+    }
+    mTilingTextureSource = new GrallocTextureSourceOGL(mCompositor, this,
+                                                 graphicBuffer, mFormat);
+  }
+  mTilingTextureSource->Lock();
+  return mTilingTextureSource;
+}
+
+void
+GrallocTextureHostOGL::UnbindTextureSource()
+{
+  // Clear the reference to the TextureSource (if any), because we know that
+  // another TextureHost is being bound to the TextureSource. This means that
+  // we will have to re-do gl->fEGLImageTargetTexture2D next time we go through
+  // BindTextureSource (otherwise we would have skipped it).
+  // Note that this doesn't "unlock" the gralloc buffer or force it to be
+  // detached, Although decreasing the refcount of the TextureSource may lead
+  // to the gl handle being destroyed, which would unlock the gralloc buffer.
+  // That said, this method is called before another TextureHost attaches to the
+  // TextureSource, which has the effect of unlocking the gralloc buffer. So when
+  // this is called we know we are going to be unlocked soon.
+  mGLTextureSource = nullptr;
+}
+
+GLenum GetTextureTarget(gl::GLContext* aGL, android::PixelFormat aFormat) {
+  MOZ_ASSERT(aGL);
+  if (aGL->Renderer() == gl::GLRenderer::SGX530 ||
+      aGL->Renderer() == gl::GLRenderer::SGX540) {
+    // SGX has a quirk that only TEXTURE_EXTERNAL works and any other value will
+    // result in black pixels when trying to draw from bound textures.
+    // Unfortunately, using TEXTURE_EXTERNAL on Adreno has a terrible effect on
+    // performance.
+    // See Bug 950050.
+    return LOCAL_GL_TEXTURE_EXTERNAL;
   } else {
-    gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
+    return TextureTargetForAndroidPixelFormat(aFormat);
+  }
+}
+
+void
+GrallocTextureHostOGL::DestroyEGLImage()
+{
+  // Only called when we want to get rid of the gralloc buffer, usually
+  // around the end of life of the TextureHost.
+  if (mEGLImage != EGL_NO_IMAGE && GetGLContext()) {
+    EGLImageDestroy(GetGLContext(), mEGLImage);
+    mEGLImage = EGL_NO_IMAGE;
   }
 }
 
 void
-GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
+GrallocTextureHostOGL::PrepareTextureSource(CompositableTextureSourceRef& aTextureSource)
 {
-  if(!aBackendData) {
+  // This happens during the layers transaction.
+  // All of the gralloc magic goes here. The only thing that happens externally
+  // and that is good to keep in mind is that when the TextureSource is deleted,
+  // it destroys its gl texture handle which is important for genlock.
+
+  // If this TextureHost's mGLTextureSource member is non-null, it means we are
+  // still bound to the TextureSource, in which case we can skip the driver
+  // overhead of binding the texture again (fEGLImageTargetTexture2D)
+  // As a result, if the TextureHost is used with several CompositableHosts,
+  // it will be bound to only one TextureSource, and we'll do the driver work
+  // only once, which is great. This means that all of the compositables that
+  // use this TextureHost will keep a reference to this TextureSource at least
+  // for the duration of this frame.
+
+  // If the compositable already has a TextureSource (the aTextureSource parameter),
+  // that is compatible and is not in use by several compositable, we try to
+  // attach to it. This has the effect of unlocking the previous TextureHost that
+  // we attached to the TextureSource (the previous frame)
+
+  // If the TextureSource used by the compositable is also used by other
+  // compositables (see NumCompositableRefs), we have to create a new TextureSource,
+  // because otherwise we would be modifying the content of every layer that uses
+  // the TextureSource in question, even thoug they don't use this TextureHost.
+
+  MOZ_ASSERT(!mTilingTextureSource);
+
+  android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
+
+  MOZ_ASSERT(graphicBuffer);
+  if (!graphicBuffer) {
+    mGLTextureSource = nullptr;
+    return;
+  }
+
+  if (mGLTextureSource && !mGLTextureSource->IsValid()) {
+    mGLTextureSource = nullptr;
+  }
+
+  if (mGLTextureSource) {
+    // We are already attached to a TextureSource, nothing to do except tell
+    // the compositable to use it.
+    aTextureSource = mGLTextureSource.get();
+    return;
+  }
+
+  gl::GLContext* gl = GetGLContext();
+  if (!gl || !gl->MakeCurrent()) {
+    mGLTextureSource = nullptr;
     return;
   }
 
-  // Update mTextureBackendSpecificData if it is not set yet.
-  if (!mTextureBackendSpecificData) {
-    MOZ_ASSERT(!mCompositableBackendData);
-    mCompositableBackendData = aBackendData;
-    CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
-    mTextureBackendSpecificData = backend->GetTextureBackendSpecificData();
-  }
-
-  // If TextureHost sharing by multiple CompositableHosts are detected,
-  // enable mBackendDatas usage.
-  if (!mBackendDatas &&
-      mCompositableBackendData &&
-      mCompositableBackendData != aBackendData &&
-      mTextureBackendSpecificData->IsAllowingSharingTextureHost())
-  {
-    mBackendDatas = MakeUnique<std::map<uint64_t, RefPtr<CompositableBackendSpecificData> > >();
-    (*mBackendDatas)[mCompositableBackendData->GetId()] = mCompositableBackendData;
-    mCompositableBackendData = nullptr;
-
-    // Get new mTextureBackendSpecificData
-    mTextureBackendSpecificData =
-      mTextureBackendSpecificData->GetNewTextureBackendSpecificData(mTextureSource->GetEGLImage());
-    mTextureBackendSpecificData->SetOwnedByTextureHost();
+  if (mEGLImage == EGL_NO_IMAGE) {
+    // Should only happen the first time.
+    mEGLImage = EGLImageCreateFromNativeBuffer(gl, graphicBuffer->getNativeBuffer());
   }
 
-  // Update mCompositableBackendData.
-  if (mBackendDatas)
-  {
-    // Handle a case that TextureHost has ownership of TextureSharedDataGonkOGL.
-    MOZ_ASSERT(aBackendData->IsAllowingSharingTextureHost());
-    (*mBackendDatas)[aBackendData->GetId()] = aBackendData;
-    if (mBackendDatas->size() > 200) {
-      NS_WARNING("Too many CompositableBackends");
-    }
+  GLenum textureTarget = GetTextureTarget(gl, graphicBuffer->getPixelFormat());
+
+  GLTextureSource* glSource = aTextureSource.get() ?
+    aTextureSource->AsSourceOGL()->AsGLTextureSource() : nullptr;
+
+  bool shouldCreateTextureSource = !glSource  || !glSource->IsValid()
+                                 || glSource->NumCompositableRefs() > 1
+                                 || glSource->GetTextureTarget() != textureTarget;
+
+  if (shouldCreateTextureSource) {
+    GLuint textureHandle;
+    gl->fGenTextures(1, &textureHandle);
+    gl->fBindTexture(textureTarget, textureHandle);
+    gl->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+    gl->fTexParameteri(textureTarget, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+    gl->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
+
+    mGLTextureSource = new GLTextureSource(mCompositor, textureHandle, textureTarget,
+                                           mSize, mFormat);
+    aTextureSource = mGLTextureSource.get();
   } else {
-    // Handle a case that CompositableHost has ownership of TextureSharedDataGonkOGL.
-    mCompositableBackendData = aBackendData;
-    CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
-    mTextureBackendSpecificData = backend->GetTextureBackendSpecificData();
+    gl->fBindTexture(textureTarget, glSource->GetTextureHandle());
+
+    gl->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
+    glSource->SetSize(mSize);
+    glSource->SetFormat(mFormat);
+    mGLTextureSource = glSource;
   }
-
-  if (mTextureSource) {
-    mTextureSource->SetTextureBackendSpecificData(mTextureBackendSpecificData);
-  }
-
 }
 
-void
-GrallocTextureHostOGL::UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
+bool
+GrallocTextureHostOGL::BindTextureSource(CompositableTextureSourceRef& aTextureSource)
 {
-  if(!aBackendData ||
-     !mTextureBackendSpecificData) {
-    return;
+  // This happens at composition time.
+
+  // If mGLTextureSource is null it means PrepareTextureSource failed.
+  if (!mGLTextureSource) {
+    return false;
   }
 
-  if (mBackendDatas)
-  {
-    // Handle a case that TextureHost has ownership of TextureSharedDataGonkOGL.
-    mBackendDatas->erase(aBackendData->GetId());
-    if (mBackendDatas->size() == 0) {
-      mCompositableBackendData = nullptr;
-      mTextureBackendSpecificData = nullptr;
-    }
-  } else {
-    // Handle a case that CompositableHost has ownership of TextureSharedDataGonkOGL.
-    mCompositableBackendData = nullptr;
-    mTextureBackendSpecificData = nullptr;
-  }
+  // If Prepare didn't fail, we expect our TextureSource to be the same as aTextureSource,
+  // otherwise it means something has fiddled with the TextureSource between Prepare and
+  // now.
+  MOZ_ASSERT(mGLTextureSource == aTextureSource);
+  aTextureSource = mGLTextureSource;
 
-  if (mTextureSource) {
-    mTextureSource->SetTextureBackendSpecificData(mTextureBackendSpecificData);
-  }
+#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
+  // Wait until it's ready.
+  WaitAcquireFenceSyncComplete();
+#endif
+  return true;
 }
 
 } // namepsace layers
 } // namepsace mozilla
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -12,16 +12,17 @@
 #include "mozilla/layers/ShadowLayerUtilsGralloc.h"
 #include <ui/GraphicBuffer.h>
 
 namespace mozilla {
 namespace layers {
 
 class GrallocTextureHostOGL;
 
+// Progressively getting replaced by GLTextureSource
 class GrallocTextureSourceOGL : public TextureSource
                               , public TextureSourceOGL
 {
 public:
   friend class GrallocTextureHostOGL;
 
   GrallocTextureSourceOGL(CompositorOGL* aCompositor,
                           GrallocTextureHostOGL* aTextureHost,
@@ -42,18 +43,16 @@ public:
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
 
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE
   {
     return LOCAL_GL_CLAMP_TO_EDGE;
   }
 
-  virtual void SetTextureBackendSpecificData(TextureSharedDataGonkOGL* aBackendData);
-
   void DeallocateDeviceData();
 
   gl::GLContext* gl() const;
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
   void ForgetBuffer()
   {
@@ -70,17 +69,16 @@ public:
   EGLImage GetEGLImage()
   {
     return mEGLImage;
   }
 
   bool Lock();
 
 protected:
-  RefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
   RefPtr<CompositorOGL> mCompositor;
   GrallocTextureHostOGL* mTextureHost;
   android::sp<android::GraphicBuffer> mGraphicBuffer;
   EGLImage mEGLImage;
   GLuint mTexture;
   gfx::SurfaceFormat mFormat;
   bool mNeedsReset;
 };
@@ -108,48 +106,57 @@ public:
   virtual void DeallocateSharedData() MOZ_OVERRIDE;
 
   virtual void ForgetSharedData() MOZ_OVERRIDE;
 
   virtual void DeallocateDeviceData() MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const;
 
-  virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
+  virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mDescriptorSize; }
 
   virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
 
-  virtual TextureSource* GetTextureSources() MOZ_OVERRIDE
-  {
-    return mTextureSource;
-  }
+  virtual void PrepareTextureSource(CompositableTextureSourceRef& aTextureSource) MOZ_OVERRIDE;
+
+  virtual bool BindTextureSource(CompositableTextureSourceRef& aTextureSource) MOZ_OVERRIDE;
+
+  virtual void UnbindTextureSource() MOZ_OVERRIDE;
+
+  virtual TextureSource* GetTextureSources() MOZ_OVERRIDE;
 
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
   virtual TextureHostOGL* AsHostOGL() MOZ_OVERRIDE
   {
     return this;
   }
 #endif
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
-  virtual void SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
-
-  virtual void UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData) MOZ_OVERRIDE;
-
   bool IsValid() const;
 
   virtual const char* Name() MOZ_OVERRIDE { return "GrallocTextureHostOGL"; }
 
+  gl::GLContext* GetGLContext() const { return mCompositor ? mCompositor->gl() : nullptr; }
+
 private:
+  void DestroyEGLImage();
+
   NewSurfaceDescriptorGralloc mGrallocHandle;
-  RefPtr<GrallocTextureSourceOGL> mTextureSource;
-  gfx::IntSize mSize; // See comment in textureClientOGL.h
-
-  RefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
-  UniquePtr<std::map<uint64_t, RefPtr<CompositableBackendSpecificData> > > mBackendDatas;
+  RefPtr<GLTextureSource> mGLTextureSource;
+  RefPtr<CompositorOGL> mCompositor;
+  // only used for tiling, will be removed.
+  RefPtr<GrallocTextureSourceOGL> mTilingTextureSource;
+  // Size reported by the GraphicBuffer
+  gfx::IntSize mSize;
+  // Size reported by TextureClient, can be different in some cases (video?),
+  // used by LayerRenderState.
+  gfx::IntSize mDescriptorSize;
+  gfx::SurfaceFormat mFormat;
+  EGLImage mEGLImage;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
 #endif
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -35,26 +35,16 @@
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
 class Compositor;
 
-TemporaryRef<CompositableBackendSpecificData>
-CreateCompositableBackendSpecificDataOGL()
-{
-#ifdef MOZ_WIDGET_GONK
-  return new CompositableDataGonkOGL();
-#else
-  return nullptr;
-#endif
-}
-
 TemporaryRef<TextureHost>
 CreateTextureHostOGL(const SurfaceDescriptor& aDesc,
                      ISurfaceAllocator* aDeallocator,
                      TextureFlags aFlags)
 {
   RefPtr<TextureHost> result;
   switch (aDesc.type()) {
     case SurfaceDescriptor::TSurfaceDescriptorShmem:
@@ -114,184 +104,16 @@ FlagsToGLFlags(TextureFlags aFlags)
   if (aFlags & TextureFlags::NEEDS_Y_FLIP)
     result |= TextureImage::NeedsYFlip;
   if (aFlags & TextureFlags::DISALLOW_BIGIMAGE)
     result |= TextureImage::DisallowBigImage;
 
   return static_cast<gl::TextureImage::Flags>(result);
 }
 
-CompositableDataGonkOGL::CompositableDataGonkOGL()
-{
-}
-
-CompositableDataGonkOGL::~CompositableDataGonkOGL()
-{
-   ClearData();
-}
-
-void
-CompositableDataGonkOGL::ClearData()
-{
-  CompositableBackendSpecificData::ClearData();
-  mTextureBackendSpecificData = nullptr;
-  mCompositor = nullptr;
-}
-
-void
-CompositableDataGonkOGL::SetCompositor(Compositor* aCompositor)
-{
-  mCompositor = static_cast<CompositorOGL*>(aCompositor);
-  if (mTextureBackendSpecificData) {
-    mTextureBackendSpecificData->SetCompositor(aCompositor);
-  }
-}
-
-TextureSharedDataGonkOGL*
-CompositableDataGonkOGL::GetTextureBackendSpecificData()
-{
-  if (!mTextureBackendSpecificData) {
-    mTextureBackendSpecificData = new TextureSharedDataGonkOGL();
-    mTextureBackendSpecificData->SetCompositor(mCompositor);
-    mTextureBackendSpecificData->SetAllowSharingTextureHost(IsAllowingSharingTextureHost());
-  }
-  return mTextureBackendSpecificData;
-}
-
-TextureSharedDataGonkOGL::TextureSharedDataGonkOGL()
- : mOwnedByCompositableHost(true)
- , mAllowSharingTextureHost(false)
- , mTexture(0)
- , mBoundEGLImage(EGL_NO_IMAGE)
-{
-}
-
-TextureSharedDataGonkOGL::TextureSharedDataGonkOGL(GLuint aTexture, EGLImage aImage, CompositorOGL* aCompositor)
- : mOwnedByCompositableHost(true)
- , mAllowSharingTextureHost(false)
- , mCompositor(aCompositor)
- , mTexture(aTexture)
- , mBoundEGLImage(aImage)
-{
-}
-
-TextureSharedDataGonkOGL::~TextureSharedDataGonkOGL()
-{
-  DeleteTextureIfPresent();
-}
-
-gl::GLContext*
-TextureSharedDataGonkOGL::gl() const
-{
-  return mCompositor ? mCompositor->gl() : nullptr;
-}
-
-void
-TextureSharedDataGonkOGL::SetCompositor(Compositor* aCompositor)
-{
-  if (gl() && mCompositor != aCompositor) {
-    DeleteTextureIfPresent();
-  }
-  mCompositor = static_cast<CompositorOGL*>(aCompositor);
-}
-
-void
-TextureSharedDataGonkOGL::ClearData()
-{
-  DeleteTextureIfPresent();
-}
-
-TemporaryRef<TextureSharedDataGonkOGL>
-TextureSharedDataGonkOGL::GetNewTextureBackendSpecificData(EGLImage aImage)
-{
-  MOZ_ASSERT(IsAllowingSharingTextureHost());
-
-  if (IsEGLImageBound(aImage))
-  {
-    // If EGLImage is already bound to OpenGL Texture,
-    // handover the OpenGL Texture to caller
-    GLuint textureId = GetAndResetGLTextureOwnership();
-    RefPtr<TextureSharedDataGonkOGL> data = new TextureSharedDataGonkOGL(textureId, aImage, mCompositor);
-    data->SetCompositor(mCompositor);
-    data->SetAllowSharingTextureHost(true);
-    return data;
-  }
-
-  // Create brand new TextureSharedDataGonkOGL
-  RefPtr<TextureSharedDataGonkOGL> data = new TextureSharedDataGonkOGL();
-  data->SetCompositor(mCompositor);
-  data->SetAllowSharingTextureHost(true);
-  return data;
-}
-
-GLuint
-TextureSharedDataGonkOGL::GetTexture()
-{
-  if (!mTexture) {
-    if (gl() && gl()->MakeCurrent()) {
-      gl()->fGenTextures(1, &mTexture);
-    }
-  }
-  return mTexture;
-}
-
-GLuint
-TextureSharedDataGonkOGL::GetAndResetGLTextureOwnership()
-{
-  GLuint texture = mTexture;
-  mTexture = 0;
-  mBoundEGLImage = EGL_NO_IMAGE;
-  return texture;
-}
-
-void
-TextureSharedDataGonkOGL::DeleteTextureIfPresent()
-{
-  if (mTexture) {
-    MOZ_ASSERT(mCompositor);
-    if (gl() && gl()->MakeCurrent()) {
-      gl()->fDeleteTextures(1, &mTexture);
-    }
-    mTexture = 0;
-    mBoundEGLImage = EGL_NO_IMAGE;
-  }
-}
-
-void
-TextureSharedDataGonkOGL::BindEGLImage(GLuint aTarget, EGLImage aImage)
-{
-  if (mBoundEGLImage != aImage) {
-    MOZ_ASSERT(gl());
-    if (gl()) {
-      gl()->fEGLImageTargetTexture2D(aTarget, aImage);
-    }
-    mBoundEGLImage = aImage;
-  }
-}
-
-void
-TextureSharedDataGonkOGL::ClearBoundEGLImage(EGLImage aImage)
-{
-  if (mBoundEGLImage == aImage) {
-    DeleteTextureIfPresent();
-    mBoundEGLImage = EGL_NO_IMAGE;
-  }
-}
-
-bool
-TextureSharedDataGonkOGL::IsEGLImageBound(EGLImage aImage)
-{
-  if (mTexture != 0 &&
-      aImage != EGL_NO_IMAGE &&
-      aImage == mBoundEGLImage) {
-    return true;
-  }
-  return false;
-}
-
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
 bool
 TextureHostOGL::SetReleaseFence(const android::sp<android::Fence>& aReleaseFence)
 {
   if (!aReleaseFence.get() || !aReleaseFence->isValid()) {
     // HWC might not provide Fence.
     // In this case, HWC implicitly handles buffer's fence.
     return false;
@@ -524,50 +346,79 @@ TextureImageTextureSourceOGL::BindTextur
   mTexImage->BindTexture(aTextureUnit);
   SetFilter(mGL, aFilter);
 }
 
 ////////////////////////////////////////////////////////////////////////
 // GLTextureSource
 
 GLTextureSource::GLTextureSource(CompositorOGL* aCompositor,
-                                 GLuint aTex,
-                                 gfx::SurfaceFormat aFormat,
+                                 GLuint aTextureHandle,
                                  GLenum aTarget,
-                                 gfx::IntSize aSize)
-  : mSize(aSize)
-  , mCompositor(aCompositor)
-  , mTex(aTex)
+                                 gfx::IntSize aSize,
+                                 gfx::SurfaceFormat aFormat,
+                                 bool aExternallyOwned)
+  : mCompositor(aCompositor)
+  , mTextureHandle(aTextureHandle)
+  , mTextureTarget(aTarget)
+  , mSize(aSize)
   , mFormat(aFormat)
-  , mTextureTarget(aTarget)
+  , mExternallyOwned(aExternallyOwned)
+{
+  MOZ_COUNT_CTOR(GLTextureSource);
+}
+
+GLTextureSource::~GLTextureSource()
 {
+  MOZ_COUNT_DTOR(GLTextureSource);
+  if (!mExternallyOwned) {
+    DeleteTextureHandle();
+  }
+}
+
+void
+GLTextureSource::DeallocateDeviceData()
+{
+  if (!mExternallyOwned) {
+    DeleteTextureHandle();
+  }
+}
+
+void
+GLTextureSource::DeleteTextureHandle()
+{
+  if (mTextureHandle != 0 && gl() && gl()->MakeCurrent()) {
+    gl()->fDeleteTextures(1, &mTextureHandle);
+  }
+  mTextureHandle = 0;
 }
 
 void
 GLTextureSource::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
+  MOZ_ASSERT(gl());
+  MOZ_ASSERT(mTextureHandle != 0);
   if (!gl()) {
-    NS_WARNING("Trying to bind a texture without a GLContext");
     return;
   }
   gl()->fActiveTexture(aTextureUnit);
-  gl()->fBindTexture(mTextureTarget, mTex);
+  gl()->fBindTexture(mTextureTarget, mTextureHandle);
   ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
 }
 
 void
 GLTextureSource::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = static_cast<CompositorOGL*>(aCompositor);
 }
 
 bool
 GLTextureSource::IsValid() const
 {
-  return !!gl();
+  return !!gl() && mTextureHandle != 0;
 }
 
 gl::GLContext*
 GLTextureSource::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
 
@@ -611,16 +462,20 @@ SurfaceTextureSource::BindTexture(GLenum
   mSurfTex->UpdateTexImage();
 
   ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
 }
 
 void
 SurfaceTextureSource::SetCompositor(Compositor* aCompositor)
 {
+  if (mCompositor != aCompositor) {
+    DeallocateDeviceData();
+  }
+
   mCompositor = static_cast<CompositorOGL*>(aCompositor);
 }
 
 bool
 SurfaceTextureSource::IsValid() const
 {
   return !!gl();
 }
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -50,109 +50,17 @@ class DataSourceSurface;
 }
 
 namespace layers {
 
 class Compositor;
 class CompositorOGL;
 class TextureImageTextureSourceOGL;
 class TextureSharedDataGonkOGL;
-
-/**
- * CompositableBackendSpecificData implementation for the Gonk OpenGL backend.
- * Share a same texture between TextureHosts in the same CompositableHost.
- * By shareing the texture among the TextureHosts, number of texture allocations
- * can be reduced than texture allocation in every TextureHosts.
- * From Bug 912134, use only one texture among all TextureHosts degrade
- * the rendering performance.
- * CompositableDataGonkOGL chooses in a middile of them.
- */
-class CompositableDataGonkOGL : public CompositableBackendSpecificData
-{
-protected:
-  virtual ~CompositableDataGonkOGL();
-
-public:
-  CompositableDataGonkOGL();
-  virtual void ClearData() MOZ_OVERRIDE;
-  virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
-
-  TextureSharedDataGonkOGL* GetTextureBackendSpecificData();
-protected:
-  nsRefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
-  RefPtr<CompositorOGL> mCompositor;
-};
-
-/**
- * Manage actual shared resources of CompositableDataGonkOGL.
- * The resources are split from CompositableDataGonkOGL to handle two use cases.
- * Normally TextureHost is used from one CompositableHost at the same time.
- * In this case, performance is good if the resources are owned by CompositableDataGonkOGL.
- * But TextureHost could be shared among multiple ImageHosts.
- * If it happens, performance is good if the resource is owned by TextureHost.
- * The resources ownership is carryed over from CompositableDataGonkOGL to TextureHost.
- * See Bug 1017351.
- */
-class TextureSharedDataGonkOGL
-{
-protected:
-  virtual ~TextureSharedDataGonkOGL();
-
-public:
-  NS_INLINE_DECL_REFCOUNTING(TextureSharedDataGonkOGL)
-
-  TextureSharedDataGonkOGL();
-  TextureSharedDataGonkOGL(GLuint aTexture, EGLImage aImage, CompositorOGL* aCompositor);
-
-  void SetCompositor(Compositor* aCompositor);
-  void ClearData();
-
-  // Mark TextureSharedDataGonkOGL as owned by TextureHost.
-  void SetOwnedByTextureHost()
-  {
-    mOwnedByCompositableHost = false;
-  }
-
-  // Check if this is owned by CompositableHost or TextureHost.
-  bool IsOwnedByCompositableHost()
-  {
-    return mOwnedByCompositableHost;
-  }
-
-  bool IsAllowingSharingTextureHost()
-  {
-    return mAllowSharingTextureHost;
-  }
-
-  void SetAllowSharingTextureHost(bool aAllow)
-  {
-    mAllowSharingTextureHost = aAllow;
-  }
-
-  // Create new TextureSharedDataGonkOGL.
-  // If aImage is already bound to OpenGL texture, the OpenGL textre is carried over
-  // to a new object. It could reduce calling fEGLImageTargetTexture2D()
-  // during resources ownership carry over from CompositableHost to TextureHost.
-  TemporaryRef<TextureSharedDataGonkOGL> GetNewTextureBackendSpecificData(EGLImage aImage);
-
-  GLuint GetTexture();
-  void DeleteTextureIfPresent();
-  gl::GLContext* gl() const;
-  void BindEGLImage(GLuint aTarget, EGLImage aImage);
-  void ClearBoundEGLImage(EGLImage aImage);
-  bool IsEGLImageBound(EGLImage aImage);
-protected:
-  GLuint GetAndResetGLTextureOwnership();
-
-  bool mOwnedByCompositableHost;
-  bool mAllowSharingTextureHost;
-  RefPtr<CompositorOGL> mCompositor;
-  GLuint mTexture;
-  EGLImage mBoundEGLImage;
-};
+class GLTextureSource;
 
 inline void ApplyFilterToBoundTexture(gl::GLContext* aGL,
                                       gfx::Filter aFilter,
                                       GLuint aTarget = LOCAL_GL_TEXTURE_2D)
 {
   GLenum filter =
     (aFilter == gfx::Filter::POINT ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR);
 
@@ -197,16 +105,18 @@ public:
   virtual gfx::SurfaceFormat GetFormat() const = 0;
 
   virtual GLenum GetWrapMode() const = 0;
 
   virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); }
 
   virtual TextureImageTextureSourceOGL* AsTextureImageTextureSource() { return nullptr; }
 
+  virtual GLTextureSource* AsGLTextureSource() { return nullptr; }
+
   void SetFilter(gl::GLContext* aGL, gfx::Filter aFilter)
   {
     if (mHasCachedFilter &&
         mCachedFilter == aFilter) {
       return;
     }
     mHasCachedFilter = true;
     mCachedFilter = aFilter;
@@ -365,47 +275,63 @@ protected:
  *
  * The shared texture handle is owned by the TextureHost.
  */
 class GLTextureSource : public TextureSource
                       , public TextureSourceOGL
 {
 public:
   GLTextureSource(CompositorOGL* aCompositor,
-                  GLuint aTex,
+                  GLuint aTextureHandle,
+                  GLenum aTarget,
+                  gfx::IntSize aSize,
                   gfx::SurfaceFormat aFormat,
-                  GLenum aTarget,
-                  gfx::IntSize aSize);
+                  bool aExternallyOwned = false);
+
+  ~GLTextureSource();
+
+  virtual GLTextureSource* AsGLTextureSource() MOZ_OVERRIDE { return this; }
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
 
   virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual bool IsValid() const MOZ_OVERRIDE;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
 
   virtual GLenum GetTextureTarget() const { return mTextureTarget; }
 
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
 
-  virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
+  virtual void DeallocateDeviceData() MOZ_OVERRIDE;
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
 
+  void SetSize(gfx::IntSize aSize) { mSize = aSize; }
+
+  void SetFormat(gfx::SurfaceFormat aFormat) { mFormat = aFormat; }
+
+  GLuint GetTextureHandle() const { return mTextureHandle; }
+
   gl::GLContext* gl() const;
 
 protected:
-  const gfx::IntSize mSize;
+  void DeleteTextureHandle();
+
   RefPtr<CompositorOGL> mCompositor;
-  const GLuint mTex;
-  const gfx::SurfaceFormat mFormat;
-  const GLenum mTextureTarget;
+  GLuint mTextureHandle;
+  GLenum mTextureTarget;
+  gfx::IntSize mSize;
+  gfx::SurfaceFormat mFormat;
+  // If the texture is externally owned, the gl handle will not be deleted
+  // in the destructor.
+  bool mExternallyOwned;
 };
 
 ////////////////////////////////////////////////////////////////////////
 // SurfaceTexture
 
 #ifdef MOZ_WIDGET_ANDROID
 
 class SurfaceTextureSource : public TextureSource