Back out changeset 197317c196cf (bug 1077301) for apparently breaking component alpha on some Windows variants (perhaps those without accelerated layers backends).
authorL. David Baron <dbaron@dbaron.org>
Mon, 20 Oct 2014 00:23:46 -0400
changeset 211163 bcb2a8673c201b80735153b7216ae2a425f29838
parent 211162 983af7fa41f5293e39554d771e990e6aaa3ba463
child 211164 496e867cd2cd35bcac1adcae618273ddcf137c1d
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs1077301
milestone36.0a1
backs out197317c196cf68d98b83349027b20afbffe869a3
Back out changeset 197317c196cf (bug 1077301) for apparently breaking component alpha on some Windows variants (perhaps those without accelerated layers backends).
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) {
-    mTextureHost->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)
@@ -835,36 +838,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
@@ -125,28 +125,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;
   }
@@ -162,17 +177,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;
 }
 
@@ -204,16 +219,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());
@@ -222,100 +293,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;
@@ -323,63 +397,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;
   }
 
@@ -397,192 +462,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;
 }
 
@@ -462,20 +611,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
@@ -50,17 +50,109 @@ class DataSourceSurface;
 }
 
 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);
 
@@ -105,18 +197,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;
@@ -275,63 +365,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