Bug 887791 - Add a TextureHost implementation for MacIOSurface. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 01 Nov 2013 14:54:14 +1300
changeset 153299 b1e603203bce97142266e3ca0bfcbe37074062ed
parent 153298 2d521539a285442263b8784f2db1130be18ae84c
child 153300 feb665b0ffb7a1a31c6c0d16478ffc9d682ff3b1
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersnical
bugs887791
milestone28.0a1
Bug 887791 - Add a TextureHost implementation for MacIOSurface. r=nical
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -99,16 +99,24 @@ CreateTextureHostOGL(uint64_t aID,
       const SharedTextureDescriptor& desc = aDesc.get_SharedTextureDescriptor();
       result = new SharedTextureHostOGL(aID, aFlags,
                                         desc.shareType(),
                                         desc.handle(),
                                         gfx::ToIntSize(desc.size()),
                                         desc.inverted());
       break;
     }
+#ifdef XP_MACOSX
+    case SurfaceDescriptor::TSurfaceDescriptorMacIOSurface: {
+      const SurfaceDescriptorMacIOSurface& desc =
+        aDesc.get_SurfaceDescriptorMacIOSurface();
+      result = new MacIOSurfaceTextureHostOGL(aID, aFlags, desc);
+      break;
+    }
+#endif
 #ifdef MOZ_WIDGET_GONK
     case SurfaceDescriptor::TNewSurfaceDescriptorGralloc: {
       const NewSurfaceDescriptorGralloc& desc =
         aDesc.get_NewSurfaceDescriptorGralloc();
       result = new GrallocTextureHostOGL(aID, aFlags, desc);
       break;
     }
 #endif
@@ -424,16 +432,73 @@ SharedTextureHostOGL::SetCompositor(Comp
 
 gfx::SurfaceFormat
 SharedTextureHostOGL::GetFormat() const
 {
   MOZ_ASSERT(mTextureSource);
   return mTextureSource->GetFormat();
 }
 
+#ifdef XP_MACOSX
+MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(uint64_t aID,
+                                                       TextureFlags aFlags,
+                                                       const SurfaceDescriptorMacIOSurface& aDescriptor)
+  : TextureHost(aID, aFlags)
+{
+  mSurface = MacIOSurface::LookupSurface(aDescriptor.surface(),
+                                         aDescriptor.scaleFactor(),
+                                         aDescriptor.hasAlpha());
+}
+
+bool
+MacIOSurfaceTextureHostOGL::Lock()
+{
+  if (!mCompositor) {
+    return false;
+  }
+
+  if (!mTextureSource) {
+    mTextureSource = new MacIOSurfaceTextureSourceOGL(mCompositor, mSurface);
+  }
+  return true;
+}
+
+void
+MacIOSurfaceTextureHostOGL::SetCompositor(Compositor* aCompositor)
+{
+  CompositorOGL* glCompositor = static_cast<CompositorOGL*>(aCompositor);
+  mCompositor = glCompositor;
+  if (mTextureSource) {
+    mTextureSource->SetCompositor(glCompositor);
+  }
+}
+
+void
+MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit)
+{
+  if (!gl()) {
+    NS_WARNING("Trying to bind a texture without a GLContext");
+    return;
+  }
+  GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
+
+  gl()->fActiveTexture(aTextureUnit);
+  gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex);
+  void *nativeGL = gl()->GetNativeData(gl::GLContext::NativeGLContext);
+  mSurface->CGLTexImageIOSurface2D(nativeGL);
+  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
+}
+
+gl::GLContext*
+MacIOSurfaceTextureSourceOGL::gl() const
+{
+  return mCompositor ? mCompositor->gl() : nullptr;
+}
+#endif
+
 TextureImageDeprecatedTextureHostOGL::~TextureImageDeprecatedTextureHostOGL()
 {
   MOZ_COUNT_DTOR(TextureImageDeprecatedTextureHostOGL);
   if (mTexture && mTexture->InUpdate()) {
     mTexture->EndUpdate();
   }
 }
 
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -29,16 +29,19 @@
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_WARNING
 #include "nsISupportsImpl.h"            // for TextureImage::Release, etc
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
 #include "LayerManagerOGLProgram.h"     // for ShaderProgramType, etc
 #ifdef MOZ_WIDGET_GONK
 #include <ui/GraphicBuffer.h>
 #endif
+#ifdef XP_MACOSX
+#include "mozilla/gfx/MacIOSurface.h"
+#endif
 
 class gfxImageSurface;
 class gfxReusableSurfaceWrapper;
 class nsIntRegion;
 struct nsIntPoint;
 struct nsIntRect;
 struct nsIntSize;
 
@@ -343,16 +346,118 @@ protected:
   gfx::IntSize mSize;
   CompositorOGL* mCompositor;
   gl::SharedTextureHandle mSharedHandle;
   gl::SharedTextureShareType mShareType;
 
   RefPtr<SharedTextureSourceOGL> mTextureSource;
 };
 
+#ifdef XP_MACOSX
+/**
+ * A texture source meant for use with MacIOSurfaceTextureHostOGL.
+ *
+ * It does not own any GL texture, and attaches its shared handle to one of
+ * the compositor's temporary textures when binding.
+ */
+class MacIOSurfaceTextureSourceOGL : public NewTextureSource
+                                   , public TextureSourceOGL
+{
+public:
+  MacIOSurfaceTextureSourceOGL(CompositorOGL* aCompositor,
+                               MacIOSurface* aSurface)
+    : mCompositor(aCompositor)
+    , mSurface(aSurface)
+  {}
+
+  virtual TextureSourceOGL* AsSourceOGL() { return this; }
+
+  virtual void BindTexture(GLenum activetex) MOZ_OVERRIDE;
+
+  virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); }
+
+  virtual gfx::IntSize GetSize() const MOZ_OVERRIDE {
+    return gfx::IntSize(mSurface->GetDevicePixelWidth(),
+                        mSurface->GetDevicePixelHeight());
+  }
+
+  virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE {
+    return mSurface->HasAlpha() ? gfx::FORMAT_R8G8B8A8 : gfx::FORMAT_B8G8R8X8; }
+
+  virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_RECTANGLE_ARB; }
+
+  virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
+
+  virtual void UnbindTexture() MOZ_OVERRIDE {}
+
+  // MacIOSurfaceTextureSourceOGL doesn't own any gl texture
+  virtual void DeallocateDeviceData() {}
+
+  void SetCompositor(CompositorOGL* aCompositor) {
+    mCompositor = aCompositor;
+  }
+
+  gl::GLContext* gl() const;
+
+protected:
+  CompositorOGL* mCompositor;
+  RefPtr<MacIOSurface> mSurface;
+};
+
+/**
+ * A TextureHost for shared MacIOSurface
+ *
+ * Most of the logic actually happens in MacIOSurfaceTextureSourceOGL.
+ */
+class MacIOSurfaceTextureHostOGL : public TextureHost
+{
+public:
+  MacIOSurfaceTextureHostOGL(uint64_t aID,
+                             TextureFlags aFlags,
+                             const SurfaceDescriptorMacIOSurface& aDescriptor);
+
+  // SharedTextureHostOGL doesn't own any GL texture
+  virtual void DeallocateDeviceData() MOZ_OVERRIDE {}
+
+  virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
+
+  virtual bool Lock() MOZ_OVERRIDE;
+
+  virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE {
+    return mSurface->HasAlpha() ? gfx::FORMAT_R8G8B8A8 : gfx::FORMAT_B8G8R8X8;
+  }
+
+  virtual NewTextureSource* GetTextureSources() MOZ_OVERRIDE
+  {
+    return mTextureSource;
+  }
+
+  virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE
+  {
+    return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
+  }
+
+  gl::GLContext* gl() const;
+
+  virtual gfx::IntSize GetSize() const MOZ_OVERRIDE {
+    return gfx::IntSize(mSurface->GetDevicePixelWidth(),
+                        mSurface->GetDevicePixelHeight());
+  }
+
+#ifdef MOZ_LAYERS_HAVE_LOG
+  virtual const char* Name() { return "MacIOSurfaceTextureHostOGL"; }
+#endif
+
+protected:
+  CompositorOGL* mCompositor;
+  RefPtr<MacIOSurfaceTextureSourceOGL> mTextureSource;
+  RefPtr<MacIOSurface> mSurface;
+};
+#endif
+
 /**
  * DeprecatedTextureHost implementation using a TextureImage as the underlying texture.
  */
 class TextureImageDeprecatedTextureHostOGL : public DeprecatedTextureHost
                                            , public TextureSourceOGL
                                            , public TileIterator
 {
 public: