Backed out changeset 5ff4c7dded93 (bug 1077301) for making bug 1084118 return with a near perma-fail vengeance.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 24 Oct 2014 14:25:25 -0400
changeset 212300 ca03ec2697992a17bc28354d4e0fba64a26553c1
parent 212299 7d515b995286c76af531e62ee20fae7274afa5a0
child 212301 37e6b0283f65dd04aa9de3bdd1cb15b51661ace1
push id27704
push userkwierso@gmail.com
push dateSat, 25 Oct 2014 01:25:30 +0000
treeherdermozilla-central@e37231060eb4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1077301, 1084118
milestone36.0a1
backs out5ff4c7dded937d7df22c3fa485e56e4805ef7c4a
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
Backed out changeset 5ff4c7dded93 (bug 1077301) for making bug 1084118 return with a near perma-fail vengeance.
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,16 +131,27 @@ 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
@@ -465,16 +476,20 @@ 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,16 +19,24 @@
 #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.
  */
@@ -74,16 +82,19 @@ 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);
@@ -105,61 +116,69 @@ 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)
 {
-  CompositableTextureSourceRef source;
+  RefPtr<TextureSource> 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;
   }
 
-  if (!host->BindTextureSource(source)) {
+  source = host->GetTextureSources();
+  MOZ_ASSERT(source);
+
+  if (!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;
 }
@@ -168,16 +187,19 @@ 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;
@@ -200,16 +222,22 @@ 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,16 +45,52 @@ 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.
@@ -71,16 +107,26 @@ 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,
@@ -201,16 +247,19 @@ 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) { }
@@ -260,16 +309,17 @@ 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,42 +30,38 @@ ContentHostBase::ContentHostBase(const T
   , mInitialised(false)
 {}
 
 ContentHostBase::~ContentHostBase()
 {
 }
 
 void
-ContentHostTexture::Composite(EffectChain& aEffectChain,
-                              float aOpacity,
-                              const gfx::Matrix4x4& aTransform,
-                              const Filter& aFilter,
-                              const Rect& aClipRect,
-                              const nsIntRegion* aVisibleRegion)
+ContentHostBase::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 (!mTextureHost->BindTextureSource(mTextureSource)) {
-    return;
-  }
-  MOZ_ASSERT(mTextureSource.get());
+  RefPtr<TextureSource> source = GetTextureSource();
+  RefPtr<TextureSource> sourceOnWhite = GetTextureSourceOnWhite();
 
-  if (mTextureHostOnWhite && !mTextureHostOnWhite->BindTextureSource(mTextureSourceOnWhite)) {
+  if (!source) {
     return;
   }
 
-  RefPtr<TexturedEffect> effect = CreateTexturedEffect(mTextureSource.get(),
-                                                       mTextureSourceOnWhite.get(),
-                                                       aFilter, true);
+  RefPtr<TexturedEffect> effect = GenEffect(aFilter);
   if (!effect) {
     return;
   }
 
   aEffectChain.mPrimaryEffect = effect;
 
   nsIntRegion tmpRegion;
   const nsIntRegion* renderRegion;
@@ -80,17 +76,17 @@ ContentHostTexture::Composite(EffectChai
   }
 
   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 = mTextureSource->GetSize();
+  gfx::IntSize texSize = source->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;
   }
@@ -104,24 +100,24 @@ ContentHostTexture::Composite(EffectChai
     nsIntRect regionRect = *iterRect;
     nsIntRect screenRect = regionRect;
     screenRect.MoveBy(origin);
 
     screenRects.Or(screenRects, screenRect);
     regionRects.Or(regionRects, regionRect);
   }
 
-  BigImageIterator* bigImgIter = mTextureSource->AsBigImageIterator();
+  BigImageIterator* bigImgIter = source->AsBigImageIterator();
   BigImageIterator* iterOnWhite = nullptr;
   if (bigImgIter) {
     bigImgIter->BeginBigImageIteration();
   }
 
-  if (mTextureSourceOnWhite) {
-    iterOnWhite = mTextureSourceOnWhite->AsBigImageIterator();
+  if (sourceOnWhite) {
+    iterOnWhite = sourceOnWhite->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);
@@ -204,49 +200,42 @@ ContentHostTexture::Composite(EffectChai
   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) {
-    mTextureHostOnWhite->PrepareTextureSource(mTextureSourceOnWhite);
-  }
 }
 
 void
 ContentHostTexture::SetCompositor(Compositor* aCompositor)
 {
   ContentHostBase::SetCompositor(aCompositor);
   if (mTextureHost) {
     mTextureHost->SetCompositor(aCompositor);
@@ -424,186 +413,16 @@ 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) {
@@ -615,16 +434,30 @@ 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);
@@ -845,42 +678,16 @@ 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,16 +91,28 @@ 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;
@@ -115,23 +127,16 @@ 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;
@@ -163,25 +168,33 @@ public:
     MOZ_ASSERT(mLocked);
     mTextureHost->Unlock();
     if (mTextureHostOnWhite) {
       mTextureHostOnWhite->Unlock();
     }
     mLocked = false;
   }
 
-  LayerRenderState GetRenderState();
+  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;
+  }
 
-  virtual TemporaryRef<TexturedEffect> GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
+  LayerRenderState GetRenderState();
 
 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.
  */
@@ -259,39 +272,32 @@ 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 TemporaryRef<TexturedEffect>
-  GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE;
+  virtual TextureSource* GetTextureSource() MOZ_OVERRIDE;
+  virtual TextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE;
 
 private:
 
   void FlushUpdateQueue();
   void ProcessTextureUpdates();
 
   class Request
   {
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -32,40 +32,46 @@ ImageHost::ImageHost(const TextureInfo& 
   , mFrontBuffer(nullptr)
   , mHasPictureRect(false)
   , mLocked(false)
 {}
 
 ImageHost::~ImageHost()
 {
   if (mFrontBuffer) {
-    mFrontBuffer->UnbindTextureSource();
+    mFrontBuffer->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
+  }
+}
+
+void
+ImageHost::SetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
+{
+  CompositableHost::SetCompositableBackendSpecificData(aBackendData);
+  // ImageHost allows TextureHost sharing among ImageHosts.
+  if (aBackendData) {
+    aBackendData->SetAllowSharingTextureHost(true);
   }
 }
 
 void
 ImageHost::UseTextureHost(TextureHost* aTexture)
 {
-  if (mFrontBuffer && mFrontBuffer != aTexture) {
-    mFrontBuffer->UnbindTextureSource();
+  CompositableHost::UseTextureHost(aTexture);
+  if (mFrontBuffer) {
+    mFrontBuffer->UnsetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
   }
-  CompositableHost::UseTextureHost(aTexture);
   mFrontBuffer = aTexture;
-  if (mFrontBuffer) {
-    mFrontBuffer->PrepareTextureSource(mTextureSource);
-  }
 }
 
 void
 ImageHost::RemoveTextureHost(TextureHost* aTexture)
 {
   CompositableHost::RemoveTextureHost(aTexture);
   if (aTexture && mFrontBuffer == aTexture) {
-    mFrontBuffer->UnbindTextureSource();
-    mTextureSource = nullptr;
+    aTexture->SetCompositableBackendSpecificData(nullptr);
     mFrontBuffer = nullptr;
   }
 }
 
 TextureHost*
 ImageHost::GetAsTextureHost()
 {
   return mFrontBuffer;
@@ -86,68 +92,59 @@ 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;
   }
-
-  if (!mFrontBuffer->BindTextureSource(mTextureSource)) {
+  RefPtr<TextureSource> source = GetTextureSource();
+  if (!source) {
     return;
   }
 
-  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);
+  RefPtr<TexturedEffect> effect = GenEffect(aFilter);
   if (!effect) {
     return;
   }
 
   aEffectChain.mPrimaryEffect = effect;
-  IntSize textureSize = mTextureSource->GetSize();
+  IntSize textureSize = source->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 = mTextureSource->AsBigImageIterator();
+  BigImageIterator* it = source->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 || !mTextureSource->GetNextSibling(),
+    MOZ_ASSERT(it->GetTileCount() == 1 || !source->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);
@@ -168,17 +165,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 = mTextureSource->GetSize();
+    IntSize textureSize = source->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 {
@@ -271,28 +268,36 @@ 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)
 {
-  if (!mFrontBuffer->BindTextureSource(mTextureSource)) {
+  RefPtr<TextureSource> source = GetTextureSource();
+  if (!source) {
     return nullptr;
   }
   bool isAlphaPremultiplied = true;
   if (mFrontBuffer->GetFlags() & TextureFlags::NON_PREMULTIPLIED)
     isAlphaPremultiplied = false;
 
   return CreateTexturedEffect(mFrontBuffer->GetFormat(),
-                              mTextureSource,
+                              source,
                               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,16 +40,18 @@ 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;
@@ -77,22 +79,23 @@ 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,23 +139,16 @@ 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();
   }
@@ -279,16 +272,28 @@ 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()
 {
 }
@@ -312,21 +317,19 @@ 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)
@@ -836,36 +839,34 @@ 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, target,
-                                      surf->mSize, format,
-                                      true/*externally owned*/);
+      texSource = new GLTextureSource(compositorOGL, tex, format, target,
+                                      surf->mSize);
       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, target,
-                                      surf->mSize, format,
-                                      true/*externally owned*/);
+      texSource = new GLTextureSource(compositorOGL, tex, format, target,
+                                      surf->mSize);
       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,16 +41,17 @@ 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;
@@ -144,79 +145,20 @@ 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
@@ -356,35 +298,16 @@ 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.
    */
@@ -478,16 +401,20 @@ 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"; }
@@ -503,16 +430,17 @@ 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
@@ -131,28 +131,43 @@ 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;
   }
@@ -168,17 +183,17 @@ bool GrallocTextureSourceOGL::Lock()
   }
   gl()->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
   return true;
 }
 
 bool
 GrallocTextureSourceOGL::IsValid() const
 {
-  return !!gl() && !!mGraphicBuffer.get() && !!mCompositor;
+  return !!gl() && !!mGraphicBuffer.get() && (!!mCompositor || !!mTextureBackendSpecificData);
 }
 
 gl::GLContext*
 GrallocTextureSourceOGL::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
 
@@ -210,16 +225,72 @@ 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());
@@ -228,100 +299,103 @@ 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) {
-    mFormat =
+    format =
       SurfaceFormatForAndroidPixelFormat(graphicBuffer->getPixelFormat(),
                                          aFlags & TextureFlags::RB_SWAPPED);
-    mSize = gfx::IntSize(graphicBuffer->getWidth(), graphicBuffer->getHeight());
+    mTextureSource = new GrallocTextureSourceOGL(nullptr,
+                                                 this,
+                                                 graphicBuffer,
+                                                 format);
   } else {
     printf_stderr("gralloc buffer is nullptr");
   }
 }
 
 GrallocTextureHostOGL::~GrallocTextureHostOGL()
-{}
+{
+  MOZ_ASSERT(!mTextureSource || (mFlags & TextureFlags::DEALLOCATE_CLIENT),
+             "Leaking our buffer");
+}
 
 void
 GrallocTextureHostOGL::SetCompositor(Compositor* aCompositor)
 {
-  mCompositor = static_cast<CompositorOGL*>(aCompositor);
-  if (mTilingTextureSource) {
-    mTilingTextureSource->SetCompositor(mCompositor);
-  }
-  if (mGLTextureSource) {
-    mGLTextureSource->SetCompositor(mCompositor);
-  }
-
-  if (mCompositor && aCompositor != mCompositor) {
-    DestroyEGLImage();
+  if (mTextureSource) {
+    mTextureSource->SetCompositor(static_cast<CompositorOGL*>(aCompositor));
   }
 }
 
 bool
 GrallocTextureHostOGL::Lock()
 {
-  return IsValid();
+  if (IsValid()) {
+    mTextureSource->Lock();
+    return true;
+  }
+  return false;
 }
 
 void
 GrallocTextureHostOGL::Unlock()
 {
   // Unlock is done internally by binding the texture to another gralloc buffer
 }
 
 bool
 GrallocTextureHostOGL::IsValid() const
 {
-  android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
-  return graphicBuffer != nullptr;
+  if (!mTextureSource) {
+    return false;
+  }
+  return mTextureSource->IsValid();
 }
 
 gfx::SurfaceFormat
 GrallocTextureHostOGL::GetFormat() const
 {
-  return mFormat;
+  if (!mTextureSource) {
+    return gfx::SurfaceFormat::UNKNOWN;
+  }
+  return mTextureSource->GetFormat();
 }
 
 void
 GrallocTextureHostOGL::DeallocateSharedData()
 {
-  if (mTilingTextureSource) {
-    mTilingTextureSource->ForgetBuffer();
-    mTilingTextureSource = nullptr;
+  if (mTextureSource) {
+    mTextureSource->ForgetBuffer();
+    mTextureSource = 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;
@@ -329,63 +403,54 @@ GrallocTextureHostOGL::DeallocateSharedD
 
     SharedBufferManagerParent::DropGrallocBuffer(owner, mGrallocHandle);
   }
 }
 
 void
 GrallocTextureHostOGL::ForgetSharedData()
 {
-  if (mTilingTextureSource) {
-    mTilingTextureSource->ForgetBuffer();
-    mTilingTextureSource = nullptr;
-  }
-  if (mGLTextureSource) {
-    mGLTextureSource = nullptr;
+  if (mTextureSource) {
+    mTextureSource->ForgetBuffer();
+    mTextureSource = nullptr;
   }
 }
 
 void
 GrallocTextureHostOGL::DeallocateDeviceData()
 {
-  if (mTilingTextureSource) {
-    mTilingTextureSource->DeallocateDeviceData();
+  if (mTextureSource) {
+    mTextureSource->DeallocateDeviceData();
   }
-  if (mGLTextureSource) {
-    mGLTextureSource = nullptr;
-  }
-  DestroyEGLImage();
 }
 
 LayerRenderState
 GrallocTextureHostOGL::GetRenderState()
 {
-  android::GraphicBuffer* graphicBuffer = GetGraphicBufferFromDesc(mGrallocHandle).get();
-
-  if (graphicBuffer) {
+  if (IsValid()) {
     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(graphicBuffer,
-                            gfx::ThebesIntSize(mDescriptorSize),
+    return LayerRenderState(mTextureSource->mGraphicBuffer.get(),
+                            gfx::ThebesIntSize(mSize),
                             flags,
                             this);
   }
 
   return LayerRenderState();
 }
 
 TemporaryRef<gfx::DataSourceSurface>
 GrallocTextureHostOGL::GetAsSurface() {
-  return mTilingTextureSource ? mTilingTextureSource->GetAsSurface()
-                              : nullptr;
+  return mTextureSource ? mTextureSource->GetAsSurface()
+                        : nullptr;
 }
 
 TemporaryRef<gfx::DataSourceSurface>
 GrallocTextureSourceOGL::GetAsSurface() {
   if (!IsValid() || !gl()->MakeCurrent()) {
     return nullptr;
   }
 
@@ -403,192 +468,109 @@ 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()
 {
-  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;
+  if (mTextureBackendSpecificData) {
+    mTextureBackendSpecificData->BindEGLImage(GetTextureTarget(), mEGLImage);
   } else {
-    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;
+    gl()->fEGLImageTargetTexture2D(GetTextureTarget(), mEGLImage);
   }
 }
 
 void
-GrallocTextureHostOGL::PrepareTextureSource(CompositableTextureSourceRef& aTextureSource)
+GrallocTextureHostOGL::SetCompositableBackendSpecificData(CompositableBackendSpecificData* 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;
+  if(!aBackendData) {
     return;
   }
 
-  if (mEGLImage == EGL_NO_IMAGE) {
-    // Should only happen the first time.
-    mEGLImage = EGLImageCreateFromNativeBuffer(gl, graphicBuffer->getNativeBuffer());
+  // 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();
   }
 
-  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;
+  // 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");
+    }
+  } else {
+    // Handle a case that CompositableHost has ownership of TextureSharedDataGonkOGL.
+    mCompositableBackendData = aBackendData;
+    CompositableDataGonkOGL* backend = static_cast<CompositableDataGonkOGL*>(mCompositableBackendData.get());
+    mTextureBackendSpecificData = backend->GetTextureBackendSpecificData();
+  }
 
-  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);
+  if (mTextureSource) {
+    mTextureSource->SetTextureBackendSpecificData(mTextureBackendSpecificData);
+  }
 
-    mGLTextureSource = new GLTextureSource(mCompositor, textureHandle, textureTarget,
-                                           mSize, mFormat);
-    aTextureSource = mGLTextureSource.get();
-  } else {
-    gl->fBindTexture(textureTarget, glSource->GetTextureHandle());
-
-    gl->fEGLImageTargetTexture2D(textureTarget, mEGLImage);
-    glSource->SetSize(mSize);
-    glSource->SetFormat(mFormat);
-    mGLTextureSource = glSource;
-  }
 }
 
-bool
-GrallocTextureHostOGL::BindTextureSource(CompositableTextureSourceRef& aTextureSource)
+void
+GrallocTextureHostOGL::UnsetCompositableBackendSpecificData(CompositableBackendSpecificData* aBackendData)
 {
-  // This happens at composition time.
-
-  // If mGLTextureSource is null it means PrepareTextureSource failed.
-  if (!mGLTextureSource) {
-    return false;
+  if(!aBackendData ||
+     !mTextureBackendSpecificData) {
+    return;
   }
 
-  // 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.get();
+  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 defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
-  // Wait until it's ready.
-  WaitAcquireFenceSyncComplete();
-#endif
-  return true;
+  if (mTextureSource) {
+    mTextureSource->SetTextureBackendSpecificData(mTextureBackendSpecificData);
+  }
 }
 
 } // namepsace layers
 } // namepsace mozilla
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -12,17 +12,16 @@
 #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,
@@ -43,16 +42,18 @@ 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()
   {
@@ -69,16 +70,17 @@ 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;
 };
@@ -106,57 +108,48 @@ 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 mDescriptorSize; }
+  virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   virtual LayerRenderState GetRenderState() MOZ_OVERRIDE;
 
-  virtual void PrepareTextureSource(CompositableTextureSourceRef& aTextureSource) MOZ_OVERRIDE;
-
-  virtual bool BindTextureSource(CompositableTextureSourceRef& aTextureSource) MOZ_OVERRIDE;
-
-  virtual void UnbindTextureSource() MOZ_OVERRIDE;
-
-  virtual TextureSource* GetTextureSources() MOZ_OVERRIDE;
+  virtual TextureSource* GetTextureSources() MOZ_OVERRIDE
+  {
+    return mTextureSource;
+  }
 
 #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<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;
+  RefPtr<GrallocTextureSourceOGL> mTextureSource;
+  gfx::IntSize mSize; // See comment in textureClientOGL.h
+
+  RefPtr<TextureSharedDataGonkOGL> mTextureBackendSpecificData;
+  UniquePtr<std::map<uint64_t, RefPtr<CompositableBackendSpecificData> > > mBackendDatas;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
 #endif
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -35,16 +35,26 @@
 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:
@@ -104,16 +114,184 @@ 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;
@@ -346,79 +524,50 @@ TextureImageTextureSourceOGL::BindTextur
   mTexImage->BindTexture(aTextureUnit);
   SetFilter(mGL, aFilter);
 }
 
 ////////////////////////////////////////////////////////////////////////
 // GLTextureSource
 
 GLTextureSource::GLTextureSource(CompositorOGL* aCompositor,
-                                 GLuint aTextureHandle,
-                                 GLenum aTarget,
-                                 gfx::IntSize aSize,
+                                 GLuint aTex,
                                  gfx::SurfaceFormat aFormat,
-                                 bool aExternallyOwned)
-  : mCompositor(aCompositor)
-  , mTextureHandle(aTextureHandle)
+                                 GLenum aTarget,
+                                 gfx::IntSize aSize)
+  : mSize(aSize)
+  , mCompositor(aCompositor)
+  , mTex(aTex)
+  , mFormat(aFormat)
   , mTextureTarget(aTarget)
-  , mSize(aSize)
-  , mFormat(aFormat)
-  , 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, mTextureHandle);
+  gl()->fBindTexture(mTextureTarget, mTex);
   ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
 }
 
 void
 GLTextureSource::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = static_cast<CompositorOGL*>(aCompositor);
 }
 
 bool
 GLTextureSource::IsValid() const
 {
-  return !!gl() && mTextureHandle != 0;
+  return !!gl();
 }
 
 gl::GLContext*
 GLTextureSource::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
 
@@ -460,20 +609,16 @@ 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
@@ -53,17 +53,109 @@ class AndroidSurfaceTexture;
 }
 
 namespace layers {
 
 class Compositor;
 class CompositorOGL;
 class TextureImageTextureSourceOGL;
 class TextureSharedDataGonkOGL;
-class GLTextureSource;
+
+/**
+ * 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;
+};
 
 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);
 
@@ -108,18 +200,16 @@ 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;
@@ -278,63 +368,47 @@ protected:
  *
  * The shared texture handle is owned by the TextureHost.
  */
 class GLTextureSource : public TextureSource
                       , public TextureSourceOGL
 {
 public:
   GLTextureSource(CompositorOGL* aCompositor,
-                  GLuint aTextureHandle,
-                  GLenum aTarget,
-                  gfx::IntSize aSize,
+                  GLuint aTex,
                   gfx::SurfaceFormat aFormat,
-                  bool aExternallyOwned = false);
-
-  ~GLTextureSource();
-
-  virtual GLTextureSource* AsGLTextureSource() MOZ_OVERRIDE { return this; }
+                  GLenum aTarget,
+                  gfx::IntSize aSize);
 
   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:
-  void DeleteTextureHandle();
-
+  const gfx::IntSize mSize;
   RefPtr<CompositorOGL> mCompositor;
-  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;
+  const GLuint mTex;
+  const gfx::SurfaceFormat mFormat;
+  const GLenum mTextureTarget;
 };
 
 ////////////////////////////////////////////////////////////////////////
 // SurfaceTexture
 
 #ifdef MOZ_WIDGET_ANDROID
 
 class SurfaceTextureSource : public TextureSource