Backed out 12 changesets (bug 1366502) for causing intermittent QuantumRender debug crashtest crashes on a CLOSED TREE.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 06 Jun 2017 18:06:42 -0400
changeset 410723 b6e861dcd4c25b9dd98bb820e7cad8a475f8e953
parent 410722 78aa5a83314a9d35fe03c8f7ab552ccfa81e1190
child 410724 5801aa478de12a62b2b2982659e787fcc4268d67
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1366502
milestone55.0a1
backs out42350bacb0bc3aa1f6c5daeb1377af74fb32001c
7f98b7f60e5885589af43fa130c90c1b9ffe65c5
265e39153027942550b4b2769b57d0bf04bfdcbf
cf598918bb1b06c2e7f2b7a268d31f3188a6174b
e2f21ee861e547bb6805f3ec51d24929913646f1
f7fcc15d8f90604bd930584faf8061792f3af3d7
22408b6a1ad10a761882ba353614c407c5b6d5c3
8846dac9ee352ed11e89fcb5a37ce1bb843a8a73
d5225d81b832f9f5e13aa6b4c194481a4569cad4
82f5a21b53a65e01781c20474a8c80ec013993c4
2b20aebef47d21ce00d9ca1e69ac5558cb1d78c3
95f4d82e3d79b83e8061399ef15e66f0515b07c7
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 12 changesets (bug 1366502) for causing intermittent QuantumRender debug crashtest crashes on a CLOSED TREE. Backed out changeset 42350bacb0bc (bug 1366502) Backed out changeset 7f98b7f60e58 (bug 1366502) Backed out changeset 265e39153027 (bug 1366502) Backed out changeset cf598918bb1b (bug 1366502) Backed out changeset e2f21ee861e5 (bug 1366502) Backed out changeset f7fcc15d8f90 (bug 1366502) Backed out changeset 22408b6a1ad1 (bug 1366502) Backed out changeset 8846dac9ee35 (bug 1366502) Backed out changeset d5225d81b832 (bug 1366502) Backed out changeset 82f5a21b53a6 (bug 1366502) Backed out changeset 2b20aebef47d (bug 1366502) Backed out changeset 95f4d82e3d79 (bug 1366502)
dom/media/test/reftest/reftest.list
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/d3d11/TextureD3D11.cpp
gfx/layers/d3d11/TextureD3D11.h
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
gfx/layers/wr/WebRenderCompositableHolder.cpp
gfx/layers/wr/WebRenderCompositableHolder.h
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderImageLayer.h
gfx/layers/wr/WebRenderTextureHost.cpp
gfx/layers/wr/WebRenderTextureHost.h
gfx/webrender_bindings/RenderBufferTextureHost.cpp
gfx/webrender_bindings/RenderBufferTextureHost.h
gfx/webrender_bindings/RenderTextureHost.cpp
gfx/webrender_bindings/RenderThread.cpp
gfx/webrender_bindings/RenderThread.h
gfx/webrender_bindings/src/bindings.rs
layout/reftests/webm-video/reftest.list
--- a/dom/media/test/reftest/reftest.list
+++ b/dom/media/test/reftest/reftest.list
@@ -1,2 +1,2 @@
-skip-if(Android) fuzzy-if(OSX,22,49977) skip-if(winWidget) fuzzy-if(webrender,70,600) HTTP(..) == short.mp4.firstframe.html short.mp4.firstframe-ref.html
-skip-if(Android) fuzzy-if(OSX,23,51392) fuzzy-if(winWidget,59,76797) fuzzy-if(webrender,60,1800) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html
+skip-if(Android) fuzzy-if(OSX,22,49977) skip-if(winWidget) HTTP(..) == short.mp4.firstframe.html short.mp4.firstframe-ref.html
+skip-if(Android) fuzzy-if(OSX,23,51392) fuzzy-if(winWidget,59,76797) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -552,90 +552,40 @@ BufferTextureHost::Lock()
 void
 BufferTextureHost::Unlock()
 {
   MOZ_ASSERT(mLocked);
   mLocked = false;
 }
 
 void
-BufferTextureHost::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                                  const std::function<wr::ImageKey()>& aImageKeyAllocator)
-{
-  MOZ_ASSERT(aImageKeys.IsEmpty());
-
-  if (GetFormat() != gfx::SurfaceFormat::YUV) {
-    // 1 image key
-    aImageKeys.AppendElement(aImageKeyAllocator());
-    MOZ_ASSERT(aImageKeys.Length() == 1);
-  } else {
-    // 3 image key
-    aImageKeys.AppendElement(aImageKeyAllocator());
-    aImageKeys.AppendElement(aImageKeyAllocator());
-    aImageKeys.AppendElement(aImageKeyAllocator());
-    MOZ_ASSERT(aImageKeys.Length() == 3);
-  }
-}
-
-void
 BufferTextureHost::AddWRImage(wr::WebRenderAPI* aAPI,
                               Range<const wr::ImageKey>& aImageKeys,
                               const wr::ExternalImageId& aExtID)
 {
-  if (GetFormat() != gfx::SurfaceFormat::YUV) {
-    MOZ_ASSERT(aImageKeys.length() == 1);
-
-    wr::ImageDescriptor descriptor(GetSize(),
-                                   ImageDataSerializer::ComputeRGBStride(GetFormat(), GetSize().width),
-                                   GetFormat());
-    aAPI->AddExternalImageBuffer(aImageKeys[0], descriptor, aExtID);
-  } else {
-    MOZ_ASSERT(aImageKeys.length() == 3);
+  MOZ_ASSERT(aImageKeys.length() == 1);
+  // XXX handling YUV
+  gfx::SurfaceFormat wrFormat =
+      (GetFormat() == gfx::SurfaceFormat::YUV) ? gfx::SurfaceFormat::B8G8R8A8
+                                               : GetFormat();
+  gfx::SurfaceFormat format = GetFormat();
+  uint32_t wrStride = 0;
 
-    const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
-    wr::ImageDescriptor yDescriptor(desc.ySize(), desc.ySize().width, gfx::SurfaceFormat::A8);
-    wr::ImageDescriptor cbcrDescriptor(desc.cbCrSize(), desc.cbCrSize().width, gfx::SurfaceFormat::A8);
-    aAPI->AddExternalImage(aImageKeys[0],
-                           yDescriptor,
-                           aExtID,
-                           WrExternalImageBufferType::ExternalBuffer,
-                           0);
-    aAPI->AddExternalImage(aImageKeys[1],
-                           cbcrDescriptor,
-                           aExtID,
-                           WrExternalImageBufferType::ExternalBuffer,
-                           1);
-    aAPI->AddExternalImage(aImageKeys[2],
-                           cbcrDescriptor,
-                           aExtID,
-                           WrExternalImageBufferType::ExternalBuffer,
-                           2);
+  if (format == gfx::SurfaceFormat::YUV) {
+    // XXX this stride is used until yuv image rendering by webrender is used.
+    // Software converted RGB buffers strides are aliened to 16
+    wrStride = gfx::GetAlignedStride<16>(GetSize().width, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8));
+  } else {
+    wrStride = ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
   }
-}
 
-void
-BufferTextureHost::PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                     const WrRect& aBounds,
-                                     const WrClipRegionToken aClip,
-                                     wr::ImageRendering aFilter,
-                                     Range<const wr::ImageKey>& aImageKeys)
-{
-  if (GetFormat() != gfx::SurfaceFormat::YUV) {
-    MOZ_ASSERT(aImageKeys.length() == 1);
-    aBuilder.PushImage(aBounds, aClip, aFilter, aImageKeys[0]);
-  } else {
-    MOZ_ASSERT(aImageKeys.length() == 3);
-    aBuilder.PushYCbCrPlanarImage(aBounds,
-                                  aClip,
-                                  aImageKeys[0],
-                                  aImageKeys[1],
-                                  aImageKeys[2],
-                                  WrYuvColorSpace::Rec601,
-                                  aFilter);
-  }
+  wr::ImageDescriptor descriptor(GetSize(), wrStride, wrFormat);
+  aAPI->AddExternalImageBuffer(aImageKeys[0],
+                               descriptor,
+                               aExtID);
 }
 
 void
 TextureHost::DeserializeReadLock(const ReadLockDescriptor& aDesc,
                                  ISurfaceAllocator* aAllocator)
 {
   RefPtr<TextureReadLock> lock = TextureReadLock::Deserialize(aDesc, aAllocator);
   if (!lock) {
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_TEXTUREHOST_H
 #define MOZILLA_GFX_TEXTUREHOST_H
 
-#include <functional>
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint64_t, uint32_t, uint8_t
 #include "gfxTypes.h"
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed, etc
 #include "mozilla/gfx/2D.h"             // for DataSourceSurface
 #include "mozilla/gfx/Point.h"          // for IntSize, IntPoint
@@ -34,17 +33,16 @@
 #include "mozilla/gfx/Rect.h"
 
 namespace mozilla {
 namespace ipc {
 class Shmem;
 } // namespace ipc
 
 namespace wr {
-class DisplayListBuilder;
 class WebRenderAPI;
 }
 
 namespace layers {
 
 class BufferDescriptor;
 class BufferTextureHost;
 class Compositor;
@@ -593,47 +591,25 @@ public:
   void SetReadLock(TextureReadLock* aReadLock);
 
   TextureReadLock* GetReadLock() { return mReadLock; }
 
   virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
   virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() { return nullptr; }
   virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
 
-  // Create all necessary image keys for this textureHost rendering.
-  // @param aImageKeys - [out] The set of ImageKeys used for this textureHost
-  // composing.
-  // @param aImageKeyAllocator - [in] The function which is used for creating
-  // the new ImageKey.
-  virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                              const std::function<wr::ImageKey()>& aImageKeyAllocator)
-  {
-    MOZ_ASSERT(aImageKeys.IsEmpty());
-    MOZ_ASSERT_UNREACHABLE("No GetWRImageKeys() implementation for this TextureHost type.");
-  }
-
   // Add all necessary textureHost informations to WebrenderAPI. Then, WR could
   // use these informations to compose this textureHost.
   virtual void AddWRImage(wr::WebRenderAPI* aAPI,
                           Range<const wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID)
   {
     MOZ_ASSERT_UNREACHABLE("No AddWRImage() implementation for this TextureHost type.");
   }
 
-  // Put all necessary WR commands into DisplayListBuilder for this textureHost rendering.
-  virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                 const WrRect& aBounds,
-                                 const WrClipRegionToken aClip,
-                                 wr::ImageRendering aFilter,
-                                 Range<const wr::ImageKey>& aKeys)
-  {
-    MOZ_ASSERT_UNREACHABLE("No PushExternalImage() implementation for this TextureHost type.");
-  }
-
 protected:
   void ReadUnlock();
 
   void RecycleTexture(TextureFlags aFlags);
 
   virtual void UpdatedInternal(const nsIntRegion *Region) {}
 
   /**
@@ -711,29 +687,20 @@ public:
   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
 
   virtual bool HasIntermediateBuffer() const override { return mHasIntermediateBuffer; }
 
   virtual BufferTextureHost* AsBufferTextureHost() override { return this; }
 
   const BufferDescriptor& GetBufferDescriptor() const { return mDescriptor; }
 
-  virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                              const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
-
   virtual void AddWRImage(wr::WebRenderAPI* aAPI,
                           Range<const wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID) override;
 
-  virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                 const WrRect& aBounds,
-                                 const WrClipRegionToken aClip,
-                                 wr::ImageRendering aFilter,
-                                 Range<const wr::ImageKey>& aImageKeys) override;
-
 protected:
   bool Upload(nsIntRegion *aRegion = nullptr);
   bool MaybeUpload(nsIntRegion *aRegion = nullptr);
   bool EnsureWrappingTextureSource();
 
   virtual void UpdatedInternal(const nsIntRegion* aRegion = nullptr) override;
 
   BufferDescriptor mDescriptor;
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -859,40 +859,23 @@ DXGITextureHostD3D11::BindTextureSource(
   MOZ_ASSERT(mIsLocked);
   // If Lock was successful we must have a valid TextureSource.
   MOZ_ASSERT(mTextureSource);
   aTexture = mTextureSource;
   return !!aTexture;
 }
 
 void
-DXGITextureHostD3D11::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                                     const std::function<wr::ImageKey()>& aImageKeyAllocator)
-{
-  MOZ_ASSERT_UNREACHABLE("No GetWRImageKeys() implementation for this DXGITextureHostD3D11 type.");
-}
-
-void
 DXGITextureHostD3D11::AddWRImage(wr::WebRenderAPI* aAPI,
                                  Range<const wr::ImageKey>& aImageKeys,
                                  const wr::ExternalImageId& aExtID)
 {
   MOZ_ASSERT_UNREACHABLE("No AddWRImage() implementation for this DXGITextureHostD3D11 type.");
 }
 
-void
-DXGITextureHostD3D11::PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                        const WrRect& aBounds,
-                                        const WrClipRegionToken aClip,
-                                        wr::ImageRendering aFilter,
-                                        Range<const wr::ImageKey>& aImageKeys)
-{
-  MOZ_ASSERT_UNREACHABLE("No PushExternalImage() implementation for this DXGITextureHostD3D11 type.");
-}
-
 DXGIYCbCrTextureHostD3D11::DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
   const SurfaceDescriptorDXGIYCbCr& aDescriptor)
   : TextureHost(aFlags)
   , mSize(aDescriptor.size())
   , mIsLocked(false)
 {
   mHandles[0] = aDescriptor.handleY();
   mHandles[1] = aDescriptor.handleCb();
@@ -1017,40 +1000,23 @@ DXGIYCbCrTextureHostD3D11::BindTextureSo
   MOZ_ASSERT(mIsLocked);
   // If Lock was successful we must have a valid TextureSource.
   MOZ_ASSERT(mTextureSources[0] && mTextureSources[1] && mTextureSources[2]);
   aTexture = mTextureSources[0].get();
   return !!aTexture;
 }
 
 void
-DXGIYCbCrTextureHostD3D11::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                                          const std::function<wr::ImageKey()>& aImageKeyAllocator)
-{
-  MOZ_ASSERT_UNREACHABLE("No GetWRImageKeys() implementation for this DXGIYCbCrTextureHostD3D11 type.");
-}
-
-void
 DXGIYCbCrTextureHostD3D11::AddWRImage(wr::WebRenderAPI* aAPI,
                                       Range<const wr::ImageKey>& aImageKeys,
                                       const wr::ExternalImageId& aExtID)
 {
   MOZ_ASSERT_UNREACHABLE("No AddWRImage() implementation for this DXGIYCbCrTextureHostD3D11 type.");
 }
 
-void
-DXGIYCbCrTextureHostD3D11::PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                             const WrRect& aBounds,
-                                             const WrClipRegionToken aClip,
-                                             wr::ImageRendering aFilter,
-                                             Range<const wr::ImageKey>& aImageKeys)
-{
-  MOZ_ASSERT_UNREACHABLE("No PushExternalImage() implementation for this DXGIYCbCrTextureHostD3D11 type.");
-}
-
 bool
 DataTextureSourceD3D11::Update(DataSourceSurface* aSurface,
                                nsIntRegion* aDestRegion,
                                IntPoint* aSrcOffset)
 {
   // Incremental update with a source offset is only used on Mac so it is not
   // clear that we ever will need to support it for D3D.
   MOZ_ASSERT(!aSrcOffset);
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -317,29 +317,20 @@ public:
 
   virtual gfx::IntSize GetSize() const override { return mSize; }
 
   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
   {
     return nullptr;
   }
 
-  virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                              const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
-
   virtual void AddWRImage(wr::WebRenderAPI* aAPI,
                           Range<const wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID) override;
 
-  virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                 const WrRect& aBounds,
-                                 const WrClipRegionToken aClip,
-                                 wr::ImageRendering aFilter,
-                                 Range<const wr::ImageKey>& aImageKeys) override;
-
 protected:
   bool LockInternal();
   void UnlockInternal();
 
   RefPtr<ID3D11Device> GetDevice();
 
   bool OpenSharedHandle();
 
@@ -375,29 +366,20 @@ public:
 
   virtual gfx::IntSize GetSize() const override { return mSize; }
 
   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
   {
     return nullptr;
   }
 
-  virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                              const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
-
   virtual void AddWRImage(wr::WebRenderAPI* aAPI,
                           Range<const wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID) override;
 
-  virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                 const WrRect& aBounds,
-                                 const WrClipRegionToken aClip,
-                                 wr::ImageRendering aFilter,
-                                 Range<const wr::ImageKey>& aImageKeys) override;
-
 protected:
   RefPtr<ID3D11Device> GetDevice();
 
   bool OpenSharedHandle();
 
   RefPtr<ID3D11Texture2D> mTextures[3];
   RefPtr<DataTextureSourceD3D11> mTextureSources[3];
 
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -110,62 +110,25 @@ MacIOSurfaceTextureHostOGL::GetSize() co
 
 gl::GLContext*
 MacIOSurfaceTextureHostOGL::gl() const
 {
   return mProvider ? mProvider->GetGLContext() : nullptr;
 }
 
 void
-MacIOSurfaceTextureHostOGL::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                                           const std::function<wr::ImageKey()>& aImageKeyAllocator)
-{
-  MOZ_ASSERT(aImageKeys.IsEmpty());
-
-  switch (GetFormat()) {
-    case gfx::SurfaceFormat::R8G8B8X8:
-    case gfx::SurfaceFormat::R8G8B8A8:
-    case gfx::SurfaceFormat::B8G8R8A8:
-    case gfx::SurfaceFormat::B8G8R8X8: {
-      // 1 image key
-      aImageKeys.AppendElement(aImageKeyAllocator());
-      MOZ_ASSERT(aImageKeys.Length() == 1);
-      break;
-    }
-    case gfx::SurfaceFormat::YUV422: {
-      // 1 image key
-      aImageKeys.AppendElement(aImageKeyAllocator());
-      MOZ_ASSERT(aImageKeys.Length() == 1);
-      break;
-    }
-    case gfx::SurfaceFormat::NV12: {
-      // 2 image key
-      aImageKeys.AppendElement(aImageKeyAllocator());
-      aImageKeys.AppendElement(aImageKeyAllocator());
-      MOZ_ASSERT(aImageKeys.Length() == 2);
-      break;
-    }
-    default: {
-      MOZ_ASSERT_UNREACHABLE("unexpected to be called");
-    }
-  }
-}
-
-void
 MacIOSurfaceTextureHostOGL::AddWRImage(wr::WebRenderAPI* aAPI,
                                        Range<const wr::ImageKey>& aImageKeys,
                                        const wr::ExternalImageId& aExtID)
 {
   MOZ_ASSERT(mSurface);
 
   switch (GetFormat()) {
     case gfx::SurfaceFormat::R8G8B8X8:
-    case gfx::SurfaceFormat::R8G8B8A8:
-    case gfx::SurfaceFormat::B8G8R8A8:
-    case gfx::SurfaceFormat::B8G8R8X8: {
+    case gfx::SurfaceFormat::R8G8B8A8: {
       MOZ_ASSERT(aImageKeys.length() == 1);
       MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
       wr::ImageDescriptor descriptor(GetSize(), GetFormat());
       aAPI->AddExternalImage(aImageKeys[0],
                              descriptor,
                              aExtID,
                              WrExternalImageBufferType::TextureRectHandle,
                              0);
@@ -206,54 +169,10 @@ MacIOSurfaceTextureHostOGL::AddWRImage(w
       break;
     }
     default: {
       MOZ_ASSERT_UNREACHABLE("unexpected to be called");
     }
   }
 }
 
-void
-MacIOSurfaceTextureHostOGL::PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                              const WrRect& aBounds,
-                                              const WrClipRegionToken aClip,
-                                              wr::ImageRendering aFilter,
-                                              Range<const wr::ImageKey>& aImageKeys)
-{
-  switch (GetFormat()) {
-    case gfx::SurfaceFormat::R8G8B8X8:
-    case gfx::SurfaceFormat::R8G8B8A8:
-    case gfx::SurfaceFormat::B8G8R8A8:
-    case gfx::SurfaceFormat::B8G8R8X8: {
-      MOZ_ASSERT(aImageKeys.length() == 1);
-      MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
-      aBuilder.PushImage(aBounds, aClip, aFilter, aImageKeys[0]);
-      break;
-    }
-    case gfx::SurfaceFormat::YUV422: {
-      MOZ_ASSERT(aImageKeys.length() == 1);
-      MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
-      aBuilder.PushYCbCrInterleavedImage(aBounds,
-                                         aClip,
-                                         aImageKeys[0],
-                                         WrYuvColorSpace::Rec601,
-                                         aFilter);
-      break;
-    }
-    case gfx::SurfaceFormat::NV12: {
-      MOZ_ASSERT(aImageKeys.length() == 2);
-      MOZ_ASSERT(mSurface->GetPlaneCount() == 2);
-      aBuilder.PushNV12Image(aBounds,
-                             aClip,
-                             aImageKeys[0],
-                             aImageKeys[1],
-                             WrYuvColorSpace::Rec601,
-                             aFilter);
-      break;
-    }
-    default: {
-      MOZ_ASSERT_UNREACHABLE("unexpected to be called");
-    }
-  }
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -57,29 +57,20 @@ public:
 
   virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() override { return this; }
 
   MacIOSurface* GetMacIOSurface()
   {
     return mSurface;
   }
 
-  virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                              const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
-
   virtual void AddWRImage(wr::WebRenderAPI* aAPI,
                           Range<const wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID) override;
 
-  virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                 const WrRect& aBounds,
-                                 const WrClipRegionToken aClip,
-                                 wr::ImageRendering aFilter,
-                                 Range<const wr::ImageKey>& aImageKeys) override;
-
 protected:
   GLTextureSource* CreateTextureSourceForPlane(size_t aPlane);
 
   RefPtr<GLTextureSource> mTextureSource;
   RefPtr<MacIOSurface> mSurface;
 };
 
 } // namespace layers
--- a/gfx/layers/wr/WebRenderCompositableHolder.cpp
+++ b/gfx/layers/wr/WebRenderCompositableHolder.cpp
@@ -7,16 +7,19 @@
 
 #include "CompositableHost.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/WebRenderImageHost.h"
 #include "mozilla/layers/WebRenderTextureHost.h"
 #include "mozilla/webrender/WebRenderAPI.h"
 
 namespace mozilla {
+
+using namespace gfx;
+
 namespace layers {
 
 WebRenderCompositableHolder::AsyncImagePipelineHolder::AsyncImagePipelineHolder()
  : mInitialised(false)
  , mIsChanged(false)
  , mUseExternalImage(false)
  , mFilter(WrImageRendering::Auto)
  , mMixBlendMode(WrMixBlendMode::Normal)
@@ -149,53 +152,127 @@ WebRenderCompositableHolder::UpdateAsync
   holder->mScTransform = aScTransform;
   holder->mScaleToSize = aScaleToSize;
   holder->mClipRect = aClipRect;
   holder->mMask = aMask;
   holder->mFilter = aFilter;
   holder->mMixBlendMode = aMixBlendMode;
 }
 
+void
+WebRenderCompositableHolder::GetImageKeys(nsTArray<wr::ImageKey>& aKeys, size_t aChannelNumber)
+{
+  MOZ_ASSERT(aChannelNumber > 0);
+  for (size_t i = 0; i < aChannelNumber; ++i) {
+    wr::ImageKey key = GetImageKey();
+    aKeys.AppendElement(key);
+  }
+}
+
+void
+WebRenderCompositableHolder::GetImageKeysForExternalImage(nsTArray<wr::ImageKey>& aKeys)
+{
+  MOZ_ASSERT(aKeys.IsEmpty());
+
+  // XXX (Jerry): Remove the hardcode image format setting.
+#if defined(XP_WIN)
+  // Use libyuv to convert the buffer to rgba format. So, use 1 image key here.
+  GetImageKeys(aKeys, 1);
+#elif defined(XP_MACOSX)
+  if (gfxVars::CanUseHardwareVideoDecoding()) {
+    // Use the hardware MacIOSurface with YCbCr interleaved format. It uses 1
+    // image key.
+    GetImageKeys(aKeys, 1);
+  } else {
+    // Use libyuv.
+    GetImageKeys(aKeys, 1);
+  }
+#elif defined(MOZ_WIDGET_GTK)
+  // Use libyuv.
+  GetImageKeys(aKeys, 1);
+#elif defined(ANDROID)
+  // Use libyuv.
+  GetImageKeys(aKeys, 1);
+#endif
+
+  MOZ_ASSERT(!aKeys.IsEmpty());
+}
+
 bool
 WebRenderCompositableHolder::GetImageKeyForTextureHost(wr::WebRenderAPI* aApi, TextureHost* aTexture, nsTArray<wr::ImageKey>& aKeys)
 {
   MOZ_ASSERT(aKeys.IsEmpty());
   MOZ_ASSERT(aTexture);
 
   WebRenderTextureHost* wrTexture = aTexture->AsWebRenderTextureHost();
 
   if (wrTexture) {
-    wrTexture->GetWRImageKeys(aKeys, std::bind(&WebRenderCompositableHolder::GetImageKey, this));
+    GetImageKeysForExternalImage(aKeys);
     MOZ_ASSERT(!aKeys.IsEmpty());
     Range<const wr::ImageKey> keys(&aKeys[0], aKeys.Length());
     wrTexture->AddWRImage(aApi, keys, wrTexture->GetExternalImageKey());
     return true;
   } else {
-    RefPtr<gfx::DataSourceSurface> dSurf = aTexture->GetAsSurface();
+    RefPtr<DataSourceSurface> dSurf = aTexture->GetAsSurface();
     if (!dSurf) {
       NS_ERROR("TextureHost does not return DataSourceSurface");
       return false;
     }
-    gfx::DataSourceSurface::MappedSurface map;
+    DataSourceSurface::MappedSurface map;
     if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
       NS_ERROR("DataSourceSurface failed to map");
       return false;
     }
-    gfx::IntSize size = dSurf->GetSize();
+    IntSize size = dSurf->GetSize();
     wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
     auto slice = Range<uint8_t>(map.mData, size.height * map.mStride);
 
     wr::ImageKey key = GetImageKey();
     aKeys.AppendElement(key);
     aApi->AddImage(key, descriptor, slice);
     dSurf->Unmap();
   }
   return false;
 }
 
+void
+WebRenderCompositableHolder::PushExternalImage(wr::DisplayListBuilder& aBuilder,
+                                               const WrRect& aBounds,
+                                               const WrClipRegionToken aClip,
+                                               wr::ImageRendering aFilter,
+                                               nsTArray<wr::ImageKey>& aKeys)
+{
+  // XXX (Jerry): Remove the hardcode image format setting. The format of
+  // textureClient could change from time to time. So, we just set the most
+  // usable format here.
+#if defined(XP_WIN)
+  // Use libyuv to convert the buffer to rgba format.
+  MOZ_ASSERT(aKeys.Length() == 1);
+  aBuilder.PushImage(aBounds, aClip, aFilter, aKeys[0]);
+#elif defined(XP_MACOSX)
+  if (gfx::gfxVars::CanUseHardwareVideoDecoding()) {
+    // Use the hardware MacIOSurface with YCbCr interleaved format.
+    MOZ_ASSERT(aKeys.Length() == 1);
+    aBuilder.PushYCbCrInterleavedImage(aBounds, aClip, aKeys[0], WrYuvColorSpace::Rec601, aFilter);
+  } else {
+    // Use libyuv to convert the buffer to rgba format.
+    MOZ_ASSERT(aKeys.Length() == 1);
+    aBuilder.PushImage(aBounds, aClip, aFilter, aKeys[0]);
+  }
+#elif defined(MOZ_WIDGET_GTK)
+  // Use libyuv to convert the buffer to rgba format.
+  MOZ_ASSERT(aKeys.Length() == 1);
+  aBuilder.PushImage(aBounds, aClip, aFilter, aKeys[0]);
+#elif defined(ANDROID)
+  // Use libyuv to convert the buffer to rgba format.
+  MOZ_ASSERT(aKeys.Length() == 1);
+  aBuilder.PushImage(aBounds, aClip, aFilter, aKeys[0]);
+#endif
+}
+
 bool
 WebRenderCompositableHolder::UpdateImageKeys(wr::WebRenderAPI* aApi,
                                              bool& aUseExternalImage,
                                              AsyncImagePipelineHolder* aHolder,
                                              nsTArray<wr::ImageKey>& aKeys,
                                              nsTArray<wr::ImageKey>& aKeysToDelete)
 {
   MOZ_ASSERT(aKeys.IsEmpty());
@@ -284,22 +361,21 @@ WebRenderCompositableHolder::ApplyAsyncI
       }
       LayerRect clipRect = holder->mClipRect.valueOr(rect);
       WrClipRegionToken clip = builder.PushClipRegion(
         wr::ToWrRect(clipRect),
         holder->mMask.ptrOr(nullptr));
 
       if (useExternalImage) {
         MOZ_ASSERT(holder->mCurrentTexture->AsWebRenderTextureHost());
-        Range<const wr::ImageKey> range_keys(&keys[0], keys.Length());
-        holder->mCurrentTexture->PushExternalImage(builder,
-                                                   wr::ToWrRect(rect),
-                                                   clip,
-                                                   holder->mFilter,
-                                                   range_keys);
+        PushExternalImage(builder,
+                          wr::ToWrRect(rect),
+                          clip,
+                          holder->mFilter,
+                          keys);
         HoldExternalImage(pipelineId, epoch, holder->mCurrentTexture->AsWebRenderTextureHost());
       } else {
         MOZ_ASSERT(keys.Length() == 1);
         builder.PushImage(wr::ToWrRect(rect),
                           clip,
                           holder->mFilter,
                           keys[0]);
       }
--- a/gfx/layers/wr/WebRenderCompositableHolder.h
+++ b/gfx/layers/wr/WebRenderCompositableHolder.h
@@ -88,17 +88,24 @@ private:
   uint32_t GetNamespace() { return mIdNamespace; }
   wr::ImageKey GetImageKey()
   {
     wr::ImageKey key;
     key.mNamespace = GetNamespace();
     key.mHandle = GetNextResourceId();
     return key;
   }
+  void GetImageKeys(nsTArray<wr::ImageKey>& aKeys, size_t aChannelNumber);
+  void GetImageKeysForExternalImage(nsTArray<wr::ImageKey>& aKeys);
   bool GetImageKeyForTextureHost(wr::WebRenderAPI* aApi, TextureHost* aTexture, nsTArray<wr::ImageKey>& aKeys);
+  void PushExternalImage(wr::DisplayListBuilder& aBuilder,
+                         const WrRect& aBounds,
+                         const WrClipRegionToken aClip,
+                         wr::ImageRendering aFilter,
+                         nsTArray<wr::ImageKey>& aKeys);
 
   struct ForwardingTextureHost {
     ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
       : mEpoch(aEpoch)
       , mTexture(aTexture)
     {}
     wr::Epoch mEpoch;
     CompositableTextureHostRef mTexture;
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -19,17 +19,17 @@
 
 namespace mozilla {
 namespace layers {
 
 using namespace gfx;
 
 WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
   : ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
-  , mImageClientContainerType(CompositableType::UNKNOWN)
+  , mImageClientTypeContainer(CompositableType::UNKNOWN)
 {
   MOZ_COUNT_CTOR(WebRenderImageLayer);
 }
 
 WebRenderImageLayer::~WebRenderImageLayer()
 {
   MOZ_COUNT_DTOR(WebRenderImageLayer);
 
@@ -43,30 +43,30 @@ WebRenderImageLayer::~WebRenderImageLaye
   if (mPipelineId.isSome()) {
     WrBridge()->RemovePipelineIdForAsyncCompositable(mPipelineId.ref());
   }
 }
 
 CompositableType
 WebRenderImageLayer::GetImageClientType()
 {
-  if (mImageClientContainerType != CompositableType::UNKNOWN) {
-    return mImageClientContainerType;
+  if (mImageClientTypeContainer != CompositableType::UNKNOWN) {
+    return mImageClientTypeContainer;
   }
 
   if (mContainer->IsAsync()) {
-    mImageClientContainerType = CompositableType::IMAGE_BRIDGE;
-    return mImageClientContainerType;
+    mImageClientTypeContainer = CompositableType::IMAGE_BRIDGE;
+    return mImageClientTypeContainer;
   }
 
   AutoLockImage autoLock(mContainer);
 
-  mImageClientContainerType = autoLock.HasImage()
+  mImageClientTypeContainer = autoLock.HasImage()
     ? CompositableType::IMAGE : CompositableType::UNKNOWN;
-  return mImageClientContainerType;
+  return mImageClientTypeContainer;
 }
 
 already_AddRefed<gfx::SourceSurface>
 WebRenderImageLayer::GetAsSourceSurface()
 {
   if (!mContainer) {
     return nullptr;
   }
--- a/gfx/layers/wr/WebRenderImageLayer.h
+++ b/gfx/layers/wr/WebRenderImageLayer.h
@@ -38,16 +38,16 @@ public:
 protected:
   CompositableType GetImageClientType();
 
   void AddWRVideoImage(size_t aChannelNumber);
 
   wr::MaybeExternalImageId mExternalImageId;
   Maybe<wr::ImageKey> mKey;
   RefPtr<ImageClient> mImageClient;
-  CompositableType mImageClientContainerType;
+  CompositableType mImageClientTypeContainer;
   Maybe<wr::PipelineId> mPipelineId;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERIMAGELAYER_H
--- a/gfx/layers/wr/WebRenderTextureHost.cpp
+++ b/gfx/layers/wr/WebRenderTextureHost.cpp
@@ -22,25 +22,16 @@ namespace layers {
 WebRenderTextureHost::WebRenderTextureHost(const SurfaceDescriptor& aDesc,
                                            TextureFlags aFlags,
                                            TextureHost* aTexture,
                                            wr::ExternalImageId& aExternalImageId)
   : TextureHost(aFlags)
   , mExternalImageId(aExternalImageId)
   , mIsWrappingNativeHandle(false)
 {
-  // The wrapped textureHost will be used in WebRender, and the WebRender could
-  // run at another thread. It's hard to control the life-time when gecko
-  // receives PTextureParent destroy message. It's possible that textureHost is
-  // still used by WebRender. So, we only accept the textureHost without
-  // DEALLOCATE_CLIENT flag here. If the buffer deallocation is controlled by
-  // parent, we could do something to make sure the wrapped textureHost is not
-  // used by WebRender and then release it.
-  MOZ_ASSERT(!(aFlags & TextureFlags::DEALLOCATE_CLIENT));
-
   MOZ_COUNT_CTOR(WebRenderTextureHost);
   mWrappedTextureHost = aTexture;
 
   CreateRenderTextureHost(aDesc, aTexture);
 }
 
 WebRenderTextureHost::~WebRenderTextureHost()
 {
@@ -71,17 +62,17 @@ WebRenderTextureHost::CreateRenderTextur
       mIsWrappingNativeHandle = true;
       break;
     }
 #endif
     default:
       gfxCriticalError() << "No WR implement for texture type:" << aDesc.type();
   }
 
-  wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(mExternalImageId), texture.forget());
+  wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(mExternalImageId), texture);
 }
 
 bool
 WebRenderTextureHost::Lock()
 {
   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
   return false;
 }
@@ -161,43 +152,20 @@ WebRenderTextureHost::GetRGBStride()
     // XXX this stride is used until yuv image rendering by webrender is used.
     // Software converted RGB buffers strides are aliened to 16
     return gfx::GetAlignedStride<16>(GetSize().width, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8));
   }
   return ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
 }
 
 void
-WebRenderTextureHost::GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                                     const std::function<wr::ImageKey()>& aImageKeyAllocator)
-{
-  MOZ_ASSERT(aImageKeys.IsEmpty());
-  mWrappedTextureHost->GetWRImageKeys(aImageKeys, aImageKeyAllocator);
-}
-
-void
 WebRenderTextureHost::AddWRImage(wr::WebRenderAPI* aAPI,
                                  Range<const wr::ImageKey>& aImageKeys,
                                  const wr::ExternalImageId& aExtID)
 {
   MOZ_ASSERT(mWrappedTextureHost);
   MOZ_ASSERT(mExternalImageId == aExtID);
 
   mWrappedTextureHost->AddWRImage(aAPI, aImageKeys, aExtID);
 }
 
-void
-WebRenderTextureHost::PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                        const WrRect& aBounds,
-                                        const WrClipRegionToken aClip,
-                                        wr::ImageRendering aFilter,
-                                        Range<const wr::ImageKey>& aImageKeys)
-{
-  MOZ_ASSERT(aImageKeys.length() > 0);
-  mWrappedTextureHost->PushExternalImage(aBuilder,
-                                         aBounds,
-                                         aClip,
-                                         aFilter,
-                                         aImageKeys);
-}
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderTextureHost.h
+++ b/gfx/layers/wr/WebRenderTextureHost.h
@@ -60,29 +60,20 @@ public:
   virtual WebRenderTextureHost* AsWebRenderTextureHost() override { return this; }
 
   wr::ExternalImageId GetExternalImageKey() { return mExternalImageId; }
 
   int32_t GetRGBStride();
 
   bool IsWrappingNativeHandle() { return mIsWrappingNativeHandle; }
 
-  virtual void GetWRImageKeys(nsTArray<wr::ImageKey>& aImageKeys,
-                              const std::function<wr::ImageKey()>& aImageKeyAllocator) override;
-
   virtual void AddWRImage(wr::WebRenderAPI* aAPI,
                           Range<const wr::ImageKey>& aImageKeys,
                           const wr::ExternalImageId& aExtID) override;
 
-  virtual void PushExternalImage(wr::DisplayListBuilder& aBuilder,
-                                 const WrRect& aBounds,
-                                 const WrClipRegionToken aClip,
-                                 wr::ImageRendering aFilter,
-                                 Range<const wr::ImageKey>& aImageKeys) override;
-
 protected:
   void CreateRenderTextureHost(const SurfaceDescriptor& aDesc, TextureHost* aTexture);
 
   RefPtr<TextureHost> mWrappedTextureHost;
   wr::ExternalImageId mExternalImageId;
 
   bool mIsWrappingNativeHandle;
 };
--- a/gfx/webrender_bindings/RenderBufferTextureHost.cpp
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.cpp
@@ -38,106 +38,73 @@ RenderBufferTextureHost::RenderBufferTex
   }
 }
 
 RenderBufferTextureHost::~RenderBufferTextureHost()
 {
   MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
 }
 
+already_AddRefed<gfx::DataSourceSurface>
+RenderBufferTextureHost::GetAsSurface()
+{
+  RefPtr<gfx::DataSourceSurface> result;
+  if (mFormat == gfx::SurfaceFormat::YUV) {
+    result = layers::ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(
+      GetBuffer(), mDescriptor.get_YCbCrDescriptor());
+    if (NS_WARN_IF(!result)) {
+      return nullptr;
+    }
+  } else {
+    result =
+      gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
+          layers::ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
+        mSize, mFormat);
+  }
+  return result.forget();
+}
+
 bool
 RenderBufferTextureHost::Lock()
 {
-  if (!mLocked) {
-    if (mFormat != gfx::SurfaceFormat::YUV) {
-      mSurface = gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
-                                                               layers::ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
-                                                               mSize,
-                                                               mFormat);
-      if (NS_WARN_IF(!mSurface)) {
-        return false;
-      }
-      if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
-        mSurface = nullptr;
-        return false;
-      }
-    } else {
-      const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
+  MOZ_ASSERT(!mLocked);
 
-      mYSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetYChannel(GetBuffer(), desc),
-                                                                desc.ySize().width,
-                                                                desc.ySize(),
-                                                                gfx::SurfaceFormat::A8);
-      mCbSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCbChannel(GetBuffer(), desc),
-                                                                 desc.cbCrSize().width,
-                                                                 desc.cbCrSize(),
-                                                                 gfx::SurfaceFormat::A8);
-      mCrSurface = gfx::Factory::CreateWrappingDataSourceSurface(layers::ImageDataSerializer::GetCrChannel(GetBuffer(), desc),
-                                                                 desc.cbCrSize().width,
-                                                                 desc.cbCrSize(),
-                                                                 gfx::SurfaceFormat::A8);
-      if (NS_WARN_IF(!mYSurface || !mCbSurface || !mCrSurface)) {
-        mYSurface = mCbSurface = mCrSurface = nullptr;
-        return false;
-      }
-      if (NS_WARN_IF(!mYSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mYMap) ||
-                     !mCbSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCbMap) ||
-                     !mCrSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mCrMap))) {
-        mYSurface = mCbSurface = mCrSurface = nullptr;
-        return false;
-      }
+  // XXX temporal workaround for YUV handling
+  if (!mSurface) {
+    mSurface = GetAsSurface();
+    if (!mSurface) {
+      return false;
     }
-    mLocked = true;
   }
 
+  if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
+    mSurface = nullptr;
+    return false;
+  }
+
+  mLocked = true;
   return true;
 }
 
 void
 RenderBufferTextureHost::Unlock()
 {
-  if (mLocked) {
-    if (mSurface) {
-      mSurface->Unmap();
-      mSurface = nullptr;
-    } else if (mYSurface) {
-      mYSurface->Unmap();
-      mCbSurface->Unmap();
-      mCrSurface->Unmap();
-      mYSurface = mCbSurface = mCrSurface = nullptr;
-    }
-    mLocked = false;
+  MOZ_ASSERT(mLocked);
+  mLocked = false;
+  if (mSurface) {
+    mSurface->Unmap();
   }
+  mSurface = nullptr;
 }
 
 RenderBufferTextureHost::RenderBufferData
 RenderBufferTextureHost::GetBufferDataForRender(uint8_t aChannelIndex)
 {
-  MOZ_ASSERT(mFormat != gfx::SurfaceFormat::YUV || aChannelIndex < 3);
-  MOZ_ASSERT(mFormat == gfx::SurfaceFormat::YUV || aChannelIndex < 1);
-  MOZ_ASSERT(mLocked);
-
-  if (mFormat != gfx::SurfaceFormat::YUV) {
-    MOZ_ASSERT(mSurface);
-
-    return RenderBufferData(mMap.mData, mMap.mStride * mSurface->GetSize().height);
-  } else {
-    MOZ_ASSERT(mYSurface && mCbSurface && mCrSurface);
+  // TODO: handle multiple channel bufferTextureHost(e.g. yuv textureHost)
+  MOZ_ASSERT(aChannelIndex < 1);
 
-    switch (aChannelIndex) {
-      case 0:
-        return RenderBufferData(mYMap.mData, mYMap.mStride * mYSurface->GetSize().height);
-        break;
-      case 1:
-        return RenderBufferData(mCbMap.mData, mCbMap.mStride * mCbSurface->GetSize().height);
-        break;
-      case 2:
-        return RenderBufferData(mCrMap.mData, mCrMap.mStride * mCrSurface->GetSize().height);
-        break;
-      default:
-        MOZ_ASSERT_UNREACHABLE("unexpected to be called");
-        return RenderBufferData(nullptr, 0);
-    }
-  }
+  MOZ_ASSERT(mLocked);
+  MOZ_ASSERT(mSurface);
+  return RenderBufferData(mMap.mData, mMap.mStride * mSurface->GetSize().height);
 }
 
 } // namespace wr
 } // namespace mozilla
--- a/gfx/webrender_bindings/RenderBufferTextureHost.h
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.h
@@ -37,35 +37,27 @@ public:
     size_t mBufferSize;
   };
 
   RenderBufferData GetBufferDataForRender(uint8_t aChannelIndex);
 
 private:
   virtual ~RenderBufferTextureHost();
 
+  already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
   uint8_t* GetBuffer() const
   {
     return mBuffer;
   }
 
   uint8_t* mBuffer;
   layers::BufferDescriptor mDescriptor;
   gfx::IntSize mSize;
   gfx::SurfaceFormat mFormat;
-
   RefPtr<gfx::DataSourceSurface> mSurface;
   gfx::DataSourceSurface::MappedSurface mMap;
-
-  RefPtr<gfx::DataSourceSurface> mYSurface;
-  RefPtr<gfx::DataSourceSurface> mCbSurface;
-  RefPtr<gfx::DataSourceSurface> mCrSurface;
-  gfx::DataSourceSurface::MappedSurface mYMap;
-  gfx::DataSourceSurface::MappedSurface mCbMap;
-  gfx::DataSourceSurface::MappedSurface mCrMap;
-
   bool mLocked;
 };
 
 } // namespace wr
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_RENDERBUFFERTEXTUREHOST_H
--- a/gfx/webrender_bindings/RenderTextureHost.cpp
+++ b/gfx/webrender_bindings/RenderTextureHost.cpp
@@ -1,24 +1,22 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RenderTextureHost.h"
-#include "RenderThread.h"
 
 namespace mozilla {
 namespace wr {
 
 RenderTextureHost::RenderTextureHost()
 {
   MOZ_COUNT_CTOR(RenderTextureHost);
 }
 
 RenderTextureHost::~RenderTextureHost()
 {
-  MOZ_ASSERT(RenderThread::IsInRenderThread());
   MOZ_COUNT_DTOR(RenderTextureHost);
 }
 
 } // namespace wr
 } // namespace mozilla
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -270,59 +270,34 @@ RenderThread::DecPendingFrameCount(wr::W
   if (oldCount <= 0) {
     return;
   }
   // Update pending frame count.
   mPendingFrameCounts.Put(AsUint64(aWindowId), oldCount - 1);
 }
 
 void
-RenderThread::RegisterExternalImage(uint64_t aExternalImageId, already_AddRefed<RenderTextureHost> aTexture)
+RenderThread::RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture)
 {
   MutexAutoLock lock(mRenderTextureMapLock);
-
-  MOZ_ASSERT(!mRenderTextures.Get(aExternalImageId).get());
-  RefPtr<RenderTextureHost> texture(aTexture);
-  mRenderTextures.Put(aExternalImageId, Move(texture));
+  MOZ_ASSERT(!mRenderTextures.Get(aExternalImageId));
+  mRenderTextures.Put(aExternalImageId, aTexture);
 }
 
 void
 RenderThread::UnregisterExternalImage(uint64_t aExternalImageId)
 {
   MutexAutoLock lock(mRenderTextureMapLock);
   MOZ_ASSERT(mRenderTextures.Get(aExternalImageId).get());
-  if (!IsInRenderThread()) {
-    // The RenderTextureHost should be released in render thread. So, post the
-    // deletion task here.
-    // The shmem and raw buffer are owned by compositor ipc channel. It's
-    // possible that RenderTextureHost is still exist after the shmem/raw buffer
-    // deletion. Then the buffer in RenderTextureHost becomes invalid. It's fine
-    // for this situation. Gecko will only release the buffer if WR doesn't need
-    // it. So, no one will access the invalid buffer in RenderTextureHost.
-    RefPtr<RenderTextureHost> texture = mRenderTextures.Get(aExternalImageId);
-    mRenderTextures.Remove(aExternalImageId);
-    Loop()->PostTask(NewRunnableMethod<RefPtr<RenderTextureHost>>(
-      this, &RenderThread::DeferredRenderTextureHostDestroy, Move(texture)
-    ));
-  } else {
-    mRenderTextures.Remove(aExternalImageId);
-  }
-}
-
-void
-RenderThread::DeferredRenderTextureHostDestroy(RefPtr<RenderTextureHost>)
-{
-  // Do nothing. Just decrease the ref-count of RenderTextureHost.
+  mRenderTextures.Remove(aExternalImageId);
 }
 
 RenderTextureHost*
 RenderThread::GetRenderTexture(WrExternalImageId aExternalImageId)
 {
-  MOZ_ASSERT(IsInRenderThread());
-
   MutexAutoLock lock(mRenderTextureMapLock);
   MOZ_ASSERT(mRenderTextures.Get(aExternalImageId.mHandle).get());
   return mRenderTextures.Get(aExternalImageId.mHandle).get();
 }
 
 } // namespace wr
 } // namespace mozilla
 
--- a/gfx/webrender_bindings/RenderThread.h
+++ b/gfx/webrender_bindings/RenderThread.h
@@ -100,37 +100,32 @@ public:
   void RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aCallBack);
 
   /// Can only be called from the render thread.
   void UpdateAndRender(wr::WindowId aWindowId);
 
   void Pause(wr::WindowId aWindowId);
   bool Resume(wr::WindowId aWindowId);
 
-  /// Can be called from any thread.
-  void RegisterExternalImage(uint64_t aExternalImageId, already_AddRefed<RenderTextureHost> aTexture);
+  void RegisterExternalImage(uint64_t aExternalImageId, RenderTextureHost* aTexture);
 
-  /// Can be called from any thread.
   void UnregisterExternalImage(uint64_t aExternalImageId);
 
-  /// Can only be called from the render thread.
   RenderTextureHost* GetRenderTexture(WrExternalImageId aExternalImageId);
 
   /// Can be called from any thread.
   uint32_t GetPendingFrameCount(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void IncPendingFrameCount(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void DecPendingFrameCount(wr::WindowId aWindowId);
 
 private:
   explicit RenderThread(base::Thread* aThread);
 
-  void DeferredRenderTextureHostDestroy(RefPtr<RenderTextureHost> aTexture);
-
   ~RenderThread();
 
   base::Thread* const mThread;
 
   std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
 
   Mutex mPendingFrameCountMapLock;
   nsDataHashtable<nsUint64HashKey, uint32_t> mPendingFrameCounts;
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1398,17 +1398,17 @@ pub extern "C" fn wr_dp_push_rect(state:
 #[no_mangle]
 pub extern "C" fn wr_dp_push_image(state: &mut WrState,
                                    bounds: WrRect,
                                    clip: WrClipRegionToken,
                                    stretch_size: WrSize,
                                    tile_spacing: WrSize,
                                    image_rendering: WrImageRendering,
                                    key: WrImageKey) {
-    assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
+    assert!(unsafe { !is_in_render_thread() });
 
     state.frame_builder
          .dl_builder
          .push_image(bounds.into(),
                      clip.into(),
                      stretch_size.into(),
                      tile_spacing.into(),
                      image_rendering,
@@ -1420,17 +1420,17 @@ pub extern "C" fn wr_dp_push_image(state
 pub extern "C" fn wr_dp_push_yuv_planar_image(state: &mut WrState,
                                               bounds: WrRect,
                                               clip: WrClipRegionToken,
                                               image_key_0: WrImageKey,
                                               image_key_1: WrImageKey,
                                               image_key_2: WrImageKey,
                                               color_space: WrYuvColorSpace,
                                               image_rendering: WrImageRendering) {
-    assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
+    assert!(unsafe { is_in_main_thread() });
 
     state.frame_builder
          .dl_builder
          .push_yuv_image(bounds.into(),
                          clip.into(),
                          YuvData::PlanarYCbCr(image_key_0, image_key_1, image_key_2),
                          color_space,
                          image_rendering);
@@ -1440,17 +1440,17 @@ pub extern "C" fn wr_dp_push_yuv_planar_
 #[no_mangle]
 pub extern "C" fn wr_dp_push_yuv_NV12_image(state: &mut WrState,
                                             bounds: WrRect,
                                             clip: WrClipRegionToken,
                                             image_key_0: WrImageKey,
                                             image_key_1: WrImageKey,
                                             color_space: WrYuvColorSpace,
                                             image_rendering: WrImageRendering) {
-    assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
+    assert!(unsafe { is_in_main_thread() });
 
     state.frame_builder
          .dl_builder
          .push_yuv_image(bounds.into(),
                          clip.into(),
                          YuvData::NV12(image_key_0, image_key_1),
                          color_space,
                          image_rendering);
@@ -1459,17 +1459,17 @@ pub extern "C" fn wr_dp_push_yuv_NV12_im
 /// Push a yuv interleaved image.
 #[no_mangle]
 pub extern "C" fn wr_dp_push_yuv_interleaved_image(state: &mut WrState,
                                                    bounds: WrRect,
                                                    clip: WrClipRegionToken,
                                                    image_key_0: WrImageKey,
                                                    color_space: WrYuvColorSpace,
                                                    image_rendering: WrImageRendering) {
-    assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
+    assert!(unsafe { is_in_main_thread() });
 
     state.frame_builder
          .dl_builder
          .push_yuv_image(bounds.into(),
                          clip.into(),
                          YuvData::InterleavedYCbCr(image_key_0),
                          color_space,
                          image_rendering);
--- a/layout/reftests/webm-video/reftest.list
+++ b/layout/reftests/webm-video/reftest.list
@@ -36,20 +36,20 @@ random-if(winWidget) random-if(cocoaWidg
 == webm-alpha.html webm-alpha-ref.html
 
 # Tests for <video src> with 'object-fit' & 'object-position':
 # These tests should be very similar to tests in our w3c-css/submitted/images3
 # reftest directory. They live here because they use WebM video (VP9), and it
 # wouldn't be fair of us to make a W3C testsuite implicitly depend on any
 # particular (non-spec-mandated) video codec.
 default-preferences test-pref(gfx.ycbcr.accurate-conversion,true)
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-contain-webm-001.html object-fit-contain-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-contain-webm-002.html object-fit-contain-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-cover-webm-001.html object-fit-cover-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-cover-webm-002.html object-fit-cover-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-fill-webm-001.html object-fit-fill-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-fill-webm-002.html object-fit-fill-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-none-webm-001.html object-fit-none-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-none-webm-002.html object-fit-none-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-scale-down-webm-001.html object-fit-scale-down-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
-fails-if(layersGPUAccelerated) skip-if(Android) fails-if(styloVsGecko) == object-fit-scale-down-webm-002.html object-fit-scale-down-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-contain-webm-001.html object-fit-contain-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-contain-webm-002.html object-fit-contain-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-cover-webm-001.html object-fit-cover-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-cover-webm-002.html object-fit-cover-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-fill-webm-001.html object-fit-fill-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-fill-webm-002.html object-fit-fill-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-none-webm-001.html object-fit-none-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-none-webm-002.html object-fit-none-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-scale-down-webm-001.html object-fit-scale-down-webm-001-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
+fails-if(layersGPUAccelerated&&!webrender) fails-if(webrender&&browserIsRemote) skip-if(Android) fails-if(styloVsGecko) == object-fit-scale-down-webm-002.html object-fit-scale-down-webm-002-ref.html # Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures
 fails-if(layersGPUAccelerated) skip-if(Android) fails fails-if(styloVsGecko) skip-if(webrender) == object-position-webm-001.html object-position-webm-001-ref.html # Bug 1098417 for across-the-board failure, Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures, Bug 1358055 for webrender failures
 fails-if(layersGPUAccelerated) skip-if(Android) fails fails-if(styloVsGecko) skip-if(webrender) == object-position-webm-002.html object-position-webm-002-ref.html # Bug 1098417 for across-the-board failure, Bug 1083516 for layersGPUAccelerated failures, Bug 1084564 for Android failures, Bug 1358055 for webrender failures