Bug 1347062 - P4: create RenderBufferTextureHost and RenderMacIOSurfaceTextureHostOGL. r=nical,sotaro
authorJerryShih <hshih@mozilla.com>
Fri, 31 Mar 2017 22:29:14 +0800
changeset 351360 66e555be3167455e8f99ef8678b320d53d94c9d6
parent 351359 5aea276a528332383a3b51a48a46f48bc59a3663
child 351361 34976aba2753770c95f045a7bbd7b6b9389c6dbd
push id88854
push userkwierso@gmail.com
push dateWed, 05 Apr 2017 21:56:51 +0000
treeherdermozilla-inbound@3e654460c195 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical, sotaro
bugs1347062
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1347062 - P4: create RenderBufferTextureHost and RenderMacIOSurfaceTextureHostOGL. r=nical,sotaro 1) make RenderTextureHost into a abstract base class for all RenderXXXTextureHost. 2) create a base class RenderTextureHostOGL for all texture handle base texture. 3) create RenderBufferTextureHost for buffer texture at render thread. 4) create RenderMacIOSurfaceTextureHostOGL for MacIOSurface at render thread.
gfx/layers/composite/TextureHost.cpp
gfx/layers/composite/TextureHost.h
gfx/layers/moz.build
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
gfx/layers/wr/WebRenderTextureHost.cpp
gfx/layers/wr/WebRenderTextureHost.h
gfx/webrender_bindings/RenderBufferTextureHost.cpp
gfx/webrender_bindings/RenderBufferTextureHost.h
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
gfx/webrender_bindings/RenderTextureHost.cpp
gfx/webrender_bindings/RenderTextureHost.h
gfx/webrender_bindings/RenderTextureHostOGL.cpp
gfx/webrender_bindings/RenderTextureHostOGL.h
gfx/webrender_bindings/RenderThread.cpp
gfx/webrender_bindings/RendererOGL.cpp
gfx/webrender_bindings/moz.build
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -84,16 +84,28 @@ public:
   uint64_t GetSerial() const { return mSerial; }
 
   HostIPCAllocator* mSurfaceAllocator;
   RefPtr<TextureHost> mTextureHost;
   // mSerial is unique in TextureClient's process.
   const uint64_t mSerial;
 };
 
+static bool
+WrapWithWebRenderTextureHost(LayersBackend aBackend,
+                             TextureFlags aFlags)
+{
+  if (!gfxVars::UseWebRender() ||
+      (aFlags & TextureFlags::SNAPSHOT) ||
+      (aBackend != LayersBackend::LAYERS_WR)) {
+    return false;
+  }
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 PTextureParent*
 TextureHost::CreateIPDLActor(HostIPCAllocator* aAllocator,
                              const SurfaceDescriptor& aSharedData,
                              LayersBackend aLayersBackend,
                              TextureFlags aFlags,
                              uint64_t aSerial)
 {
@@ -179,62 +191,65 @@ already_AddRefed<TextureHost> CreateText
                                                      TextureFlags aFlags);
 
 already_AddRefed<TextureHost>
 TextureHost::Create(const SurfaceDescriptor& aDesc,
                     ISurfaceAllocator* aDeallocator,
                     LayersBackend aBackend,
                     TextureFlags aFlags)
 {
+  RefPtr<TextureHost> result;
+
   switch (aDesc.type()) {
     case SurfaceDescriptor::TSurfaceDescriptorBuffer:
     case SurfaceDescriptor::TSurfaceDescriptorDIB:
     case SurfaceDescriptor::TSurfaceDescriptorFileMapping:
     case SurfaceDescriptor::TSurfaceDescriptorGPUVideo:
-      return CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
+      result = CreateBackendIndependentTextureHost(aDesc, aDeallocator, aBackend, aFlags);
+      break;
 
     case SurfaceDescriptor::TEGLImageDescriptor:
     case SurfaceDescriptor::TSurfaceTextureDescriptor:
     case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture:
-      return CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
+      result = CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
+      break;
 
     case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface:
       if (aBackend == LayersBackend::LAYERS_OPENGL ||
           aBackend == LayersBackend::LAYERS_WR) {
-        return CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
+        result = CreateTextureHostOGL(aDesc, aDeallocator, aBackend, aFlags);
+        break;
       } else {
-        return CreateTextureHostBasic(aDesc, aDeallocator, aBackend, aFlags);
+        result = CreateTextureHostBasic(aDesc, aDeallocator, aBackend, aFlags);
+        break;
       }
 
 #ifdef MOZ_X11
     case SurfaceDescriptor::TSurfaceDescriptorX11: {
       const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11();
-      return MakeAndAddRef<X11TextureHost>(aFlags, desc);
+      result = MakeAndAddRef<X11TextureHost>(aFlags, desc);
+      break;
     }
 #endif
 
 #ifdef XP_WIN
     case SurfaceDescriptor::TSurfaceDescriptorD3D10:
     case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr:
-      return CreateTextureHostD3D11(aDesc, aDeallocator, aBackend, aFlags);
+      result = CreateTextureHostD3D11(aDesc, aDeallocator, aBackend, aFlags);
+      break;
 #endif
     default:
       MOZ_CRASH("GFX: Unsupported Surface type host");
   }
-}
 
-bool WrapWithWebRenderTextureHost(LayersBackend aBackend,
-                                  TextureFlags aFlags)
-{
-  if (!gfxVars::UseWebRender() ||
-      (aFlags & TextureFlags::SNAPSHOT) ||
-      (aBackend != LayersBackend::LAYERS_WR)) {
-    return false;
+  if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
+    result = new WebRenderTextureHost(aDesc, aFlags, result);
   }
-  return true;
+
+  return result.forget();
 }
 
 already_AddRefed<TextureHost>
 CreateBackendIndependentTextureHost(const SurfaceDescriptor& aDesc,
                                     ISurfaceAllocator* aDeallocator,
                                     LayersBackend aBackend,
                                     TextureFlags aFlags)
 {
@@ -244,28 +259,22 @@ CreateBackendIndependentTextureHost(cons
       const SurfaceDescriptorBuffer& bufferDesc = aDesc.get_SurfaceDescriptorBuffer();
       const MemoryOrShmem& data = bufferDesc.data();
       switch (data.type()) {
         case MemoryOrShmem::TShmem: {
           result = new ShmemTextureHost(data.get_Shmem(),
                                         bufferDesc.desc(),
                                         aDeallocator,
                                         aFlags);
-          if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
-            result = new WebRenderTextureHost(aFlags, result);
-          }
           break;
         }
         case MemoryOrShmem::Tuintptr_t: {
           result = new MemoryTextureHost(reinterpret_cast<uint8_t*>(data.get_uintptr_t()),
                                          bufferDesc.desc(),
                                          aFlags);
-          if (WrapWithWebRenderTextureHost(aBackend, aFlags)) {
-            result = new WebRenderTextureHost(aFlags, result);
-          }
           break;
         }
         default:
           gfxCriticalError() << "Failed texture host for backend " << (int)data.type();
           MOZ_CRASH("GFX: No texture host for backend");
       }
       break;
     }
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -41,16 +41,17 @@ class BufferDescriptor;
 class BufferTextureHost;
 class Compositor;
 class CompositableParentManager;
 class ReadLockDescriptor;
 class CompositorBridgeParent;
 class SurfaceDescriptor;
 class HostIPCAllocator;
 class ISurfaceAllocator;
+class MacIOSurfaceTextureHostOGL;
 class TextureHostOGL;
 class TextureReadLock;
 class TextureSourceOGL;
 class TextureSourceD3D11;
 class TextureSourceBasic;
 class DataTextureSource;
 class PTextureParent;
 class TextureParent;
@@ -579,17 +580,17 @@ public:
 
   void DeserializeReadLock(const ReadLockDescriptor& aDesc,
                            ISurfaceAllocator* aAllocator);
   void SetReadLock(TextureReadLock* aReadLock);
 
   TextureReadLock* GetReadLock() { return mReadLock; }
 
   virtual BufferTextureHost* AsBufferTextureHost() { return nullptr; }
-
+  virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() { return nullptr; }
   virtual WebRenderTextureHost* AsWebRenderTextureHost() { return nullptr; }
 
 protected:
   void ReadUnlock();
 
   void RecycleTexture(TextureFlags aFlags);
 
   virtual void UpdatedInternal(const nsIntRegion *Region) {}
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -386,25 +386,27 @@ UNIFIED_SOURCES += [
     'wr/WebRenderContainerLayer.cpp',
     'wr/WebRenderDisplayItemLayer.cpp',
     'wr/WebRenderImageHost.cpp',
     'wr/WebRenderImageLayer.cpp',
     'wr/WebRenderLayerManager.cpp',
     'wr/WebRenderLayersLogging.cpp',
     'wr/WebRenderPaintedLayer.cpp',
     'wr/WebRenderTextLayer.cpp',
-    'wr/WebRenderTextureHost.cpp',
+    # XXX here are some unified build error.
+    #'wr/WebRenderTextureHost.cpp'
 ]
 
 SOURCES += [
     'basic/BasicImageLayer.cpp',
     'ImageContainer.cpp',
     'Layers.cpp',
     'LayerTreeInvalidation.cpp',
     'PersistentBufferProvider.cpp',
+    'wr/WebRenderTextureHost.cpp',
 ]
 
 # Disable RTTI in google protocol buffer
 DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = True
 
 # Workaround compiler bug (Bug 795594)
 if CONFIG['_MSC_VER'] and CONFIG['CPU_ARCH'] == 'x86_64':
     for src in [
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -93,16 +93,23 @@ public:
   gl::GLContext* gl() const;
 
   virtual gfx::IntSize GetSize() const override;
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() override { return "MacIOSurfaceTextureHostOGL"; }
 #endif
 
+  virtual MacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHost() override { return this; }
+
+  MacIOSurface* GetMacIOSurface()
+  {
+    return mSurface;
+  }
+
 protected:
   GLTextureSource* CreateTextureSourceForPlane(size_t aPlane);
 
   RefPtr<GLTextureSource> mTextureSource;
   RefPtr<MacIOSurface> mSurface;
 };
 
 } // namespace layers
--- a/gfx/layers/wr/WebRenderTextureHost.cpp
+++ b/gfx/layers/wr/WebRenderTextureHost.cpp
@@ -1,47 +1,81 @@
 /* -*- 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 "WebRenderTextureHost.h"
 
 #include "mozilla/layers/ImageDataSerializer.h"
+#include "mozilla/layers/LayersSurfaces.h"
 #include "mozilla/webrender/RenderBufferTextureHost.h"
+#include "mozilla/webrender/RenderTextureHost.h"
 #include "mozilla/webrender/RenderThread.h"
 
+#ifdef XP_MACOSX
+#include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
+#include "mozilla/webrender/RenderMacIOSurfaceTextureHostOGL.h"
+#endif
+
 namespace mozilla {
 namespace layers {
 
 uint64_t WebRenderTextureHost::sSerialCounter(0);
 
-WebRenderTextureHost::WebRenderTextureHost(TextureFlags aFlags,
+WebRenderTextureHost::WebRenderTextureHost(const SurfaceDescriptor& aDesc,
+                                           TextureFlags aFlags,
                                            TextureHost* aTexture)
   : TextureHost(aFlags)
   , mExternalImageId(++sSerialCounter)
+  , mIsWrappingNativeHandle(false)
 {
   MOZ_COUNT_CTOR(WebRenderTextureHost);
   mWrappedTextureHost = aTexture;
 
-  // XXX support only BufferTextureHost for now.
-  BufferTextureHost* bufferTexture = aTexture->AsBufferTextureHost();
-  MOZ_ASSERT(bufferTexture);
-  RefPtr<wr::RenderTextureHost> texture =
-    new wr::RenderTextureHost(bufferTexture->GetBuffer(),
-                              bufferTexture->GetBufferDescriptor());
-  wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId, texture);
+  CreateRenderTextureHost(aDesc, aTexture);
 }
 
 WebRenderTextureHost::~WebRenderTextureHost()
 {
   MOZ_COUNT_DTOR(WebRenderTextureHost);
   wr::RenderThread::Get()->UnregisterExternalImage(mExternalImageId);
 }
 
+void
+WebRenderTextureHost::CreateRenderTextureHost(const layers::SurfaceDescriptor& aDesc,
+                                              TextureHost* aTexture)
+{
+  RefPtr<wr::RenderTextureHost> texture;
+
+  switch (aDesc.type()) {
+    case SurfaceDescriptor::TSurfaceDescriptorBuffer: {
+      BufferTextureHost* bufferTexture = aTexture->AsBufferTextureHost();
+      MOZ_ASSERT(bufferTexture);
+      texture = new wr::RenderBufferTextureHost(bufferTexture->GetBuffer(),
+                                                bufferTexture->GetBufferDescriptor());
+      mIsWrappingNativeHandle = false;
+      break;
+    }
+#ifdef XP_MACOSX
+    case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
+      MacIOSurfaceTextureHostOGL* macTexture = aTexture->AsMacIOSurfaceTextureHost();
+      MOZ_ASSERT(macTexture);
+      texture = new wr::RenderMacIOSurfaceTextureHostOGL(macTexture->GetMacIOSurface());
+      mIsWrappingNativeHandle = true;
+      break;
+    }
+#endif
+    default:
+      gfxCriticalError() << "No WR implement for texture type:" << aDesc.type();
+  }
+
+  wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId, texture);
+}
+
 bool
 WebRenderTextureHost::Lock()
 {
   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
   return false;
 }
 
 void
@@ -94,25 +128,34 @@ gfx::SurfaceFormat
 WebRenderTextureHost::GetFormat() const
 {
   if (!mWrappedTextureHost) {
     return gfx::SurfaceFormat::UNKNOWN;
   }
   return mWrappedTextureHost->GetFormat();
 }
 
+gfx::SurfaceFormat
+WebRenderTextureHost::GetReadFormat() const
+{
+  if (!mWrappedTextureHost) {
+    return gfx::SurfaceFormat::UNKNOWN;
+  }
+  return mWrappedTextureHost->GetReadFormat();
+}
+
 int32_t
 WebRenderTextureHost::GetRGBStride()
 {
   if (!mWrappedTextureHost) {
     return 0;
   }
   gfx::SurfaceFormat format = GetFormat();
-  if (GetFormat() == SurfaceFormat::YUV) {
+  if (GetFormat() == 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
-    return GetAlignedStride<16>(GetSize().width, BytesPerPixel(SurfaceFormat::B8G8R8A8));
+    return gfx::GetAlignedStride<16>(GetSize().width, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8));
   }
   return ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderTextureHost.h
+++ b/gfx/layers/wr/WebRenderTextureHost.h
@@ -6,33 +6,48 @@
 #ifndef MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
 #define MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
 
 #include "mozilla/layers/TextureHost.h"
 
 namespace mozilla {
 namespace layers {
 
+class SurfaceDescriptor;
+
+// This textureHost is specialized for WebRender usage. With WebRender, there is
+// no Compositor during composition. Instead, we use RendererOGL for composition.
+// So, there are some UNREACHABLE asserts for the original Compositor related
+// code path in this class. Furthermore, the RendererOGL runs at RenderThead
+// instead of Compositor thread. This class is also creating the corresponding
+// RenderXXXTextureHost used by RendererOGL at RenderThread.
 class WebRenderTextureHost : public TextureHost
 {
 public:
-  WebRenderTextureHost(TextureFlags aFlags,
+  WebRenderTextureHost(const SurfaceDescriptor& aDesc,
+                       TextureFlags aFlags,
                        TextureHost* aTexture);
   virtual ~WebRenderTextureHost();
 
   virtual void DeallocateDeviceData() override {}
 
   virtual void SetTextureSourceProvider(TextureSourceProvider* aProvider) override;
 
   virtual bool Lock() override;
 
   virtual void Unlock() override;
 
   virtual gfx::SurfaceFormat GetFormat() const override;
 
+  // Return the format used for reading the texture. Some hardware specific
+  // textureHosts use their special data representation internally, but we could
+  // treat these textureHost as the read-format when we read them.
+  // Please check TextureHost::GetReadFormat().
+  virtual gfx::SurfaceFormat GetReadFormat() const override;
+
   virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
 
   virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override;
 
   virtual YUVColorSpace GetYUVColorSpace() const override;
 
   virtual gfx::IntSize GetSize() const override;
 
@@ -40,19 +55,26 @@ public:
   virtual const char* Name() override { return "WebRenderTextureHost"; }
 #endif
 
   virtual WebRenderTextureHost* AsWebRenderTextureHost() override { return this; }
 
   uint64_t GetExternalImageKey() { return mExternalImageId; }
 
   int32_t GetRGBStride();
+
+  bool IsWrappingNativeHandle() { return mIsWrappingNativeHandle; }
+
 protected:
+  void CreateRenderTextureHost(const SurfaceDescriptor& aDesc, TextureHost* aTexture);
+
   RefPtr<TextureHost> mWrappedTextureHost;
   uint64_t mExternalImageId;
 
+  bool mIsWrappingNativeHandle;
+
   static uint64_t sSerialCounter;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
--- a/gfx/webrender_bindings/RenderBufferTextureHost.cpp
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.cpp
@@ -4,115 +4,112 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RenderBufferTextureHost.h"
 
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 
 namespace mozilla {
-
-using namespace gfx;
-using namespace layers;
-
 namespace wr {
 
-RenderTextureHost::RenderTextureHost(uint8_t* aBuffer, const BufferDescriptor& aDescriptor)
+RenderBufferTextureHost::RenderBufferTextureHost(uint8_t* aBuffer,
+                                                 const layers::BufferDescriptor& aDescriptor)
   : mBuffer(aBuffer)
   , mDescriptor(aDescriptor)
   , mLocked(false)
 {
-  MOZ_COUNT_CTOR(RenderTextureHost);
+  MOZ_COUNT_CTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
 
   switch (mDescriptor.type()) {
-    case BufferDescriptor::TYCbCrDescriptor: {
-      const YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
+    case layers::BufferDescriptor::TYCbCrDescriptor: {
+      const layers::YCbCrDescriptor& ycbcr = mDescriptor.get_YCbCrDescriptor();
       mSize = ycbcr.ySize();
       mFormat = gfx::SurfaceFormat::YUV;
       break;
     }
-    case BufferDescriptor::TRGBDescriptor: {
-      const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
+    case layers::BufferDescriptor::TRGBDescriptor: {
+      const layers::RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor();
       mSize = rgb.size();
       mFormat = rgb.format();
       break;
     }
     default:
       gfxCriticalError() << "Bad buffer host descriptor " << (int)mDescriptor.type();
       MOZ_CRASH("GFX: Bad descriptor");
   }
 }
 
-RenderTextureHost::~RenderTextureHost()
+RenderBufferTextureHost::~RenderBufferTextureHost()
 {
-  MOZ_COUNT_DTOR(RenderTextureHost);
+  MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHost, RenderTextureHost);
 }
 
 already_AddRefed<gfx::DataSourceSurface>
-RenderTextureHost::GetAsSurface()
+RenderBufferTextureHost::GetAsSurface()
 {
   RefPtr<gfx::DataSourceSurface> result;
   if (mFormat == gfx::SurfaceFormat::YUV) {
-    result = ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(
+    result = layers::ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(
       GetBuffer(), mDescriptor.get_YCbCrDescriptor());
     if (NS_WARN_IF(!result)) {
       return nullptr;
     }
   } else {
     result =
       gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(),
-        ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
+          layers::ImageDataSerializer::GetRGBStride(mDescriptor.get_RGBDescriptor()),
         mSize, mFormat);
   }
   return result.forget();
 }
 
 bool
-RenderTextureHost::Lock()
+RenderBufferTextureHost::Lock()
 {
   MOZ_ASSERT(!mLocked);
 
   // XXX temporal workaround for YUV handling
   if (!mSurface) {
     mSurface = GetAsSurface();
     if (!mSurface) {
       return false;
     }
   }
 
-  if (NS_WARN_IF(!mSurface->Map(DataSourceSurface::MapType::READ_WRITE, &mMap))) {
+  if (NS_WARN_IF(!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
     mSurface = nullptr;
     return false;
   }
 
   mLocked = true;
   return true;
 }
 
 void
-RenderTextureHost::Unlock()
+RenderBufferTextureHost::Unlock()
 {
   MOZ_ASSERT(mLocked);
   mLocked = false;
   if (mSurface) {
     mSurface->Unmap();
   }
   mSurface = nullptr;
 }
 
-uint8_t*
-RenderTextureHost::GetDataForRender() const
+const uint8_t*
+RenderBufferTextureHost::GetDataForRender() const
 {
   MOZ_ASSERT(mLocked);
   MOZ_ASSERT(mSurface);
   return mMap.mData;
 }
 
 size_t
-RenderTextureHost::GetBufferSizeForRender() const
+RenderBufferTextureHost::GetBufferSizeForRender() const
 {
   MOZ_ASSERT(mLocked);
   MOZ_ASSERT(mSurface);
   return mMap.mStride * mSurface->GetSize().height;
 }
 
 } // namespace wr
 } // namespace mozilla
--- a/gfx/webrender_bindings/RenderBufferTextureHost.h
+++ b/gfx/webrender_bindings/RenderBufferTextureHost.h
@@ -1,52 +1,61 @@
 /* -*- 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_RENDERTEXTUREHOST_H
-#define MOZILLA_GFX_RENDERTEXTUREHOST_H
+#ifndef MOZILLA_GFX_RENDERBUFFERTEXTUREHOST_H
+#define MOZILLA_GFX_RENDERBUFFERTEXTUREHOST_H
 
-#include "nsISupportsImpl.h"
-#include "mozilla/gfx/2D.h"
-#include "mozilla/layers/LayersSurfaces.h"
-#include "mozilla/RefPtr.h"
+#include "RenderTextureHost.h"
 
 namespace mozilla {
 namespace wr {
 
-class RenderTextureHost
+class RenderBufferTextureHost final : public RenderTextureHost
 {
 public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHost)
+  RenderBufferTextureHost(uint8_t* aBuffer,
+                          const layers::BufferDescriptor& aDescriptor);
 
-  RenderTextureHost(uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor);
-
-  bool Lock();
+  virtual bool Lock() override;
+  virtual void Unlock() override;
 
-  void Unlock();
-
-  gfx::IntSize GetSize() const { return mSize; }
+  virtual gfx::IntSize GetSize() const override
+  {
+    return mSize;
+  }
+  virtual gfx::SurfaceFormat GetFormat() const override
+  {
+    return mFormat;
+  }
 
-  gfx::SurfaceFormat GetFormat() const { return mFormat; }
+  virtual RenderBufferTextureHost* AsBufferTextureHost() override
+  {
+    return this;
+  }
 
-  uint8_t* GetDataForRender() const;
+  const uint8_t* GetDataForRender() const;
   size_t GetBufferSizeForRender() const;
 
-protected:
-  ~RenderTextureHost();
+private:
+  virtual ~RenderBufferTextureHost();
+
   already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
-  uint8_t* GetBuffer() const { return mBuffer; }
+  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;
   bool mLocked;
 };
 
 } // namespace wr
 } // namespace mozilla
 
-#endif // MOZILLA_GFX_RENDERTEXTUREHOST_H
+#endif // MOZILLA_GFX_RENDERBUFFERTEXTUREHOST_H
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.cpp
@@ -0,0 +1,103 @@
+/* -*- 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 "RenderMacIOSurfaceTextureHostOGL.h"
+
+#include "GLContextCGL.h"
+#include "mozilla/gfx/Logging.h"
+#include "ScopedGLHelpers.h"
+
+namespace mozilla {
+namespace wr {
+
+RenderMacIOSurfaceTextureHostOGL::RenderMacIOSurfaceTextureHostOGL(MacIOSurface* aSurface)
+  : mTextureHandle(0)
+{
+  MOZ_COUNT_CTOR_INHERITED(RenderMacIOSurfaceTextureHostOGL, RenderTextureHostOGL);
+
+  mSurface = aSurface;
+}
+
+RenderMacIOSurfaceTextureHostOGL::~RenderMacIOSurfaceTextureHostOGL()
+{
+  MOZ_COUNT_DTOR_INHERITED(RenderMacIOSurfaceTextureHostOGL, RenderTextureHostOGL);
+  DeleteTextureHandle();
+}
+
+bool
+RenderMacIOSurfaceTextureHostOGL::Lock()
+{
+  if (!mSurface || !mGL || !mGL->MakeCurrent()) {
+    return false;
+  }
+
+  if (!mTextureHandle) {
+    // xxx: should we need to handle the PlaneCount 3 iosurface?
+    MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
+    MOZ_ASSERT(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext());
+
+    mGL->fGenTextures(1, &mTextureHandle);
+    mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
+    gl::ScopedBindTexture texture(mGL, mTextureHandle, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+    mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+    mGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+    mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(mGL.get())->GetCGLContext(), 0);
+  }
+
+  return true;
+}
+
+void
+RenderMacIOSurfaceTextureHostOGL::Unlock()
+{
+
+}
+
+void
+RenderMacIOSurfaceTextureHostOGL::SetGLContext(gl::GLContext* aContext)
+{
+  if (mGL.get() != aContext) {
+    // release the texture handle in the previous gl context
+    DeleteTextureHandle();
+    mGL = aContext;
+  }
+}
+
+void
+RenderMacIOSurfaceTextureHostOGL::DeleteTextureHandle()
+{
+  if (mTextureHandle != 0 && mGL && mGL->MakeCurrent()) {
+    mGL->fDeleteTextures(1, &mTextureHandle);
+  }
+  mTextureHandle = 0;
+}
+
+GLuint
+RenderMacIOSurfaceTextureHostOGL::GetGLHandle()
+{
+  return mTextureHandle;
+}
+
+gfx::IntSize
+RenderMacIOSurfaceTextureHostOGL::GetSize() const
+{
+  if (!mSurface) {
+    return gfx::IntSize();
+  }
+  return gfx::IntSize(mSurface->GetDevicePixelWidth(),
+                      mSurface->GetDevicePixelHeight());
+}
+
+gfx::SurfaceFormat
+RenderMacIOSurfaceTextureHostOGL::GetFormat() const
+{
+  if (!mSurface) {
+    return gfx::SurfaceFormat::UNKNOWN;
+  }
+  return mSurface->GetReadFormat();
+}
+
+} // namespace wr
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderMacIOSurfaceTextureHostOGL.h
@@ -0,0 +1,53 @@
+/* -*- 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_RENDERMACIOSURFACETEXTUREHOSTOGL_H
+#define MOZILLA_GFX_RENDERMACIOSURFACETEXTUREHOSTOGL_H
+
+#include "mozilla/gfx/MacIOSurface.h"
+#include "mozilla/layers/TextureHostOGL.h"
+#include "RenderTextureHostOGL.h"
+
+namespace mozilla {
+
+namespace layers {
+class SurfaceDescriptorMacIOSurface;
+}
+
+namespace wr {
+
+class RenderMacIOSurfaceTextureHostOGL final : public RenderTextureHostOGL
+{
+public:
+  explicit RenderMacIOSurfaceTextureHostOGL(MacIOSurface* aSurface);
+
+  virtual bool Lock() override;
+  virtual void Unlock() override;
+
+  virtual gfx::IntSize GetSize() const override;
+  virtual gfx::SurfaceFormat GetFormat() const override;
+
+  virtual RenderMacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHostOGL() override
+  {
+    return this;
+  }
+
+  virtual void SetGLContext(gl::GLContext* aContext) override;
+
+  virtual GLuint GetGLHandle() override;
+
+private:
+  virtual ~RenderMacIOSurfaceTextureHostOGL();
+  void DeleteTextureHandle();
+
+  RefPtr<MacIOSurface> mSurface;
+  RefPtr<gl::GLContext> mGL;
+  GLuint mTextureHandle;
+};
+
+} // namespace wr
+} // namespace mozilla
+
+#endif // MOZILLA_GFX_RENDERMACIOSURFACETEXTUREHOSTOGL_H
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderTextureHost.cpp
@@ -0,0 +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"
+
+namespace mozilla {
+namespace wr {
+
+RenderTextureHost::RenderTextureHost()
+{
+  MOZ_COUNT_CTOR(RenderTextureHost);
+}
+
+RenderTextureHost::~RenderTextureHost()
+{
+  MOZ_COUNT_DTOR(RenderTextureHost);
+}
+
+} // namespace wr
+} // namespace mozilla
copy from gfx/webrender_bindings/RenderBufferTextureHost.h
copy to gfx/webrender_bindings/RenderTextureHost.h
--- a/gfx/webrender_bindings/RenderBufferTextureHost.h
+++ b/gfx/webrender_bindings/RenderTextureHost.h
@@ -9,44 +9,35 @@
 #include "nsISupportsImpl.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/layers/LayersSurfaces.h"
 #include "mozilla/RefPtr.h"
 
 namespace mozilla {
 namespace wr {
 
+class RenderBufferTextureHost;
+class RenderTextureHostOGL;
+
 class RenderTextureHost
 {
-public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RenderTextureHost)
 
-  RenderTextureHost(uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor);
+public:
+  RenderTextureHost();
 
-  bool Lock();
-
-  void Unlock();
+  virtual bool Lock() = 0;
+  virtual void Unlock() = 0;
 
-  gfx::IntSize GetSize() const { return mSize; }
+  virtual gfx::IntSize GetSize() const = 0;
+  virtual gfx::SurfaceFormat GetFormat() const = 0;
 
-  gfx::SurfaceFormat GetFormat() const { return mFormat; }
-
-  uint8_t* GetDataForRender() const;
-  size_t GetBufferSizeForRender() const;
+  virtual RenderBufferTextureHost* AsBufferTextureHost() { return nullptr; }
+  virtual RenderTextureHostOGL* AsTextureHostOGL() { return nullptr; }
 
 protected:
-  ~RenderTextureHost();
-  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;
-  bool mLocked;
+  virtual ~RenderTextureHost();
 };
 
 } // namespace wr
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_RENDERTEXTUREHOST_H
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderTextureHostOGL.cpp
@@ -0,0 +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 "RenderTextureHostOGL.h"
+
+namespace mozilla {
+namespace wr {
+
+RenderTextureHostOGL::RenderTextureHostOGL()
+{
+  MOZ_COUNT_CTOR_INHERITED(RenderTextureHostOGL, RenderTextureHost);
+}
+
+RenderTextureHostOGL::~RenderTextureHostOGL()
+{
+  MOZ_COUNT_DTOR_INHERITED(RenderTextureHostOGL, RenderTextureHost);
+}
+
+} // namespace wr
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderTextureHostOGL.h
@@ -0,0 +1,35 @@
+/* -*- 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_RENDERTEXTUREHOSTOGL_H
+#define MOZILLA_GFX_RENDERTEXTUREHOSTOGL_H
+
+#include "RenderTextureHost.h"
+
+namespace mozilla {
+namespace wr {
+
+class RenderMacIOSurfaceTextureHostOGL;
+
+class RenderTextureHostOGL : public RenderTextureHost
+{
+public:
+  RenderTextureHostOGL();
+
+  virtual void SetGLContext(gl::GLContext* aContext) = 0;
+
+  virtual GLuint GetGLHandle() = 0;
+
+  virtual RenderTextureHostOGL* AsTextureHostOGL() { return this; }
+  virtual RenderMacIOSurfaceTextureHostOGL* AsMacIOSurfaceTextureHostOGL() { return nullptr; }
+
+protected:
+  virtual ~RenderTextureHostOGL();
+};
+
+} // namespace wr
+} // namespace mozilla
+
+#endif // MOZILLA_GFX_RENDERTEXTUREHOSTOGL_H
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RenderThread.h"
 #include "nsThreadUtils.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/webrender/RendererOGL.h"
-#include "mozilla/webrender/RenderBufferTextureHost.h"
+#include "mozilla/webrender/RenderTextureHost.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "base/task.h"
 
 namespace mozilla {
 namespace wr {
 
 static StaticRefPtr<RenderThread> sRenderThread;
 
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RendererOGL.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
-#include "mozilla/webrender/RenderBufferTextureHost.h"
+#include "mozilla/webrender/RenderTextureHost.h"
 #include "mozilla/widget/CompositorWidget.h"
 
 namespace mozilla {
 namespace wr {
 
 WrExternalImage LockExternalImage(void* aObj, WrExternalImageId aId)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -5,25 +5,37 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'Graphics: WebRender')
 
 EXPORTS.mozilla.webrender += [
     'RenderBufferTextureHost.h',
     'RendererOGL.h',
+    'RenderTextureHost.h',
+    'RenderTextureHostOGL.h',
     'RenderThread.h',
     'webrender_ffi.h',
     'WebRenderAPI.h',
     'WebRenderTypes.h',
 ]
 
 UNIFIED_SOURCES += [
     'Moz2DImageRenderer.cpp',
     'RenderBufferTextureHost.cpp',
     'RendererOGL.cpp',
+    'RenderTextureHost.cpp',
+    'RenderTextureHostOGL.cpp',
     'RenderThread.cpp',
     'WebRenderAPI.cpp',
 ]
 
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+    EXPORTS.mozilla.webrender += [
+        'RenderMacIOSurfaceTextureHostOGL.h',
+    ]
+    UNIFIED_SOURCES += [
+        'RenderMacIOSurfaceTextureHostOGL.cpp',
+    ]
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'