Bug 1275725 - Add GLXTextureHostOGL for rendering GLXSurfaces on the GL compositor. r?nical draft
authorAndrew Comminos <andrew@comminos.com>
Wed, 25 May 2016 17:29:22 -0400
changeset 371067 398cad412c0ce8f1229c83d19ad4c32e3c182146
parent 371066 7e8db8d631eca2d7daa4fa653c78568251dfee64
child 371068 d3abfb9cbc246458128100a491231f90e7ea2968
push id19227
push userbmo:andrew@comminos.com
push dateWed, 25 May 2016 21:59:47 +0000
reviewersnical
bugs1275725
milestone49.0a1
Bug 1275725 - Add GLXTextureHostOGL for rendering GLXSurfaces on the GL compositor. r?nical MozReview-Commit-ID: CfCNN3NXFbu
gfx/layers/composite/TextureHost.cpp
gfx/layers/ipc/LayersSurfaces.ipdlh
gfx/layers/moz.build
gfx/layers/opengl/GLXTextureHostOGL.cpp
gfx/layers/opengl/GLXTextureHostOGL.h
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -36,16 +36,20 @@
 #include "../opengl/GrallocTextureClient.h"
 #include "../opengl/GrallocTextureHost.h"
 #endif
 
 #ifdef MOZ_X11
 #include "mozilla/layers/X11TextureHost.h"
 #endif
 
+#ifdef GL_PROVIDER_GLX
+#include "mozilla/layers/GLXTextureHostOGL.h"
+#endif
+
 #ifdef XP_MACOSX
 #include "../opengl/MacIOSurfaceTextureHostOGL.h"
 #endif
 
 #ifdef XP_WIN
 #include "mozilla/layers/TextureDIB.h"
 #endif
 
@@ -223,16 +227,24 @@ TextureHost::Create(const SurfaceDescrip
 
 #ifdef MOZ_X11
     case SurfaceDescriptor::TSurfaceDescriptorX11: {
       const SurfaceDescriptorX11& desc = aDesc.get_SurfaceDescriptorX11();
       return MakeAndAddRef<X11TextureHost>(aFlags, desc);
     }
 #endif
 
+#ifdef GL_PROVIDER_GLX
+    case SurfaceDescriptor::TSurfaceDescriptorGLX: {
+      if (aBackend == LayersBackend::LAYERS_OPENGL) {
+        return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
+      }
+    }
+#endif
+
 #ifdef XP_WIN
     case SurfaceDescriptor::TSurfaceDescriptorD3D9:
       return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
 
     case SurfaceDescriptor::TSurfaceDescriptorD3D10:
     case SurfaceDescriptor::TSurfaceDescriptorDXGIYCbCr:
       if (aBackend == LayersBackend::LAYERS_D3D9) {
         return CreateTextureHostD3D9(aDesc, aDeallocator, aFlags);
--- a/gfx/layers/ipc/LayersSurfaces.ipdlh
+++ b/gfx/layers/ipc/LayersSurfaces.ipdlh
@@ -123,26 +123,35 @@ union MemoryOrShmem {
   Shmem;
 };
 
 struct SurfaceDescriptorBuffer {
   BufferDescriptor desc;
   MemoryOrShmem data;
 };
 
+struct SurfaceDescriptorGLX {
+  int32_t glxPixmap; // GLXPixmap or None (on mesa)
+  int32_t xPixmap; // Pixmap
+  int32_t fbConfigId; // GLXFBConfigID
+  IntSize size;
+  bool hasAlpha;
+};
+
 union SurfaceDescriptor {
   SurfaceDescriptorBuffer;
   SurfaceDescriptorD3D9;
   SurfaceDescriptorDIB;
   SurfaceDescriptorD3D10;
   SurfaceDescriptorFileMapping;
   SurfaceDescriptorDXGIYCbCr;
   SurfaceDescriptorX11;
   SurfaceTextureDescriptor;
   EGLImageDescriptor;
   SurfaceDescriptorMacIOSurface;
   SurfaceDescriptorGralloc;
   SurfaceDescriptorSharedGLTexture;
+  SurfaceDescriptorGLX;
   null_t;
 };
 
 } // namespace
 } // namespace
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -194,24 +194,26 @@ EXPORTS.mozilla.layers += [
 ]
 
 if CONFIG['MOZ_X11']:
     EXPORTS.mozilla.layers += [
         'basic/TextureClientX11.h',
         'basic/X11TextureSourceBasic.h',
         'composite/X11TextureHost.h',
         'ipc/ShadowLayerUtilsX11.h',
+        'opengl/GLXTextureHostOGL.h',
         'opengl/X11TextureSourceOGL.h',
     ]
     SOURCES += [
         'basic/TextureClientX11.cpp',
         'basic/X11BasicCompositor.cpp',
         'basic/X11TextureSourceBasic.cpp',
         'composite/X11TextureHost.cpp',
         'ipc/ShadowLayerUtilsX11.cpp',
+        'opengl/GLXTextureHostOGL.cpp',
         'opengl/X11TextureSourceOGL.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.layers += [
         'opengl/GLManager.h',
     ]
     EXPORTS += [
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/GLXTextureHostOGL.cpp
@@ -0,0 +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/. */
+
+#ifdef GL_PROVIDER_GLX
+
+#include "GLXTextureHostOGL.h"
+
+namespace mozilla {
+namespace layers {
+
+GLXTextureHostOGL::GLXTextureHostOGL(TextureFlags aFlags,
+                                     const SurfaceDescriptorGLX& aDescriptor)
+  : GLTextureHost(aFlags,
+                  0,
+                  LOCAL_GL_TEXTURE_2D,
+                  0,
+                  aDescriptor.size(),
+                  aDescriptor.hasAlpha())
+{
+  bool ownsPixmap = !(aFlags & TextureFlags::DEALLOCATE_CLIENT);
+  mDisplay = DefaultXDisplay();
+
+  ScopedXFree<GLXFBConfig> fbConfig;
+  MOZ_RELEASE_ASSERT(gl::GLXSurface::GetFBConfigWithID(mDisplay,
+      (GLXFBConfigID) aDescriptor.fbConfigId(), &fbConfig));
+
+  if (aDescriptor.glxPixmap()) {
+    mGLXSurface = gl::GLXSurface::Wrap(mDisplay, aDescriptor.xPixmap(),
+                                       aDescriptor.glxPixmap(),
+                                       *fbConfig,
+                                       aDescriptor.size(),
+                                       ownsPixmap,
+                                       ownsPixmap);
+  } else {
+    mGLXSurface = gl::GLXSurface::Bind(mDisplay, aDescriptor.xPixmap(),
+                                       *fbConfig,
+                                       aDescriptor.size(),
+                                       ownsPixmap);
+  }
+}
+
+void
+GLXTextureHostOGL::DeallocateDeviceData()
+{
+  if (mTexture && gl() && gl()->MakeCurrent()) {
+    gl::sGLXLibrary.xReleaseTexImage(mDisplay, mGLXSurface->GetGLXPixmap(), LOCAL_GLX_FRONT_LEFT_EXT);
+    gl()->fDeleteTextures(1, &mTexture);
+    mTexture = 0;
+  }
+}
+
+bool
+GLXTextureHostOGL::Lock()
+{
+  if (!mTexture) {
+    gl()->fGenTextures(1, &mTexture);
+  }
+
+  gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
+  gl::sGLXLibrary.xBindTexImage(mDisplay, mGLXSurface->GetGLXPixmap(),
+                                LOCAL_GLX_FRONT_LEFT_EXT, nullptr);
+
+
+  // Texture source will be created in the first call to Lock().
+  return GLTextureHost::Lock();
+}
+
+void
+GLXTextureHostOGL::Unlock()
+{
+  gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
+  gl::sGLXLibrary.xReleaseTexImage(mDisplay, mGLXSurface->GetGLXPixmap(),
+                                   LOCAL_GLX_FRONT_LEFT_EXT);
+}
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // GL_PROVIDER_GLX
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/GLXTextureHostOGL.h
@@ -0,0 +1,47 @@
+/* -*- 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_GLXTEXTUREHOSTOGL_H
+#define MOZILLA_GFX_GLXTEXTUREHOSTOGL_H
+
+#ifdef GL_PROVIDER_GLX
+
+#include "mozilla/layers/TextureHostOGL.h"
+#include "mozilla/layers/LayersSurfaces.h"
+#include "mozilla/gfx/Types.h"
+#include "GLContextGLX.h"
+
+namespace mozilla {
+namespace layers {
+
+/**
+ * A TextureHost for GLXPixmap surfaces shared with a GLX context.
+ */
+class GLXTextureHostOGL : public GLTextureHost
+{
+public:
+  GLXTextureHostOGL(TextureFlags aFlags, const SurfaceDescriptorGLX& aDescriptor);
+
+  virtual void DeallocateDeviceData() override;
+
+  virtual bool Lock() override;
+
+  virtual void Unlock() override;
+
+#ifdef MOZ_LAYERS_HAVE_LOG
+  virtual const char* Name() override { return "GLXTextureHostOGL"; }
+#endif
+
+private:
+  Display* mDisplay;
+  RefPtr<gl::GLXSurface> mGLXSurface;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // GL_PROVIDER_GLX
+
+#endif // MOZILLA_GFX_GLXTEXTUREHOSTOGL_H
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -28,16 +28,17 @@
 #endif
 
 #ifdef XP_MACOSX
 #include "mozilla/layers/MacIOSurfaceTextureHostOGL.h"
 #endif
 
 #ifdef GL_PROVIDER_GLX
 #include "mozilla/layers/X11TextureHost.h"
+#include "mozilla/layers/GLXTextureHostOGL.h"
 #endif
 
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace layers {
 
@@ -95,16 +96,22 @@ CreateTextureHostOGL(const SurfaceDescri
 #endif
 
 #ifdef GL_PROVIDER_GLX
     case SurfaceDescriptor::TSurfaceDescriptorX11: {
       const auto& desc = aDesc.get_SurfaceDescriptorX11();
       result = new X11TextureHost(aFlags, desc);
       break;
     }
+
+    case SurfaceDescriptor::TSurfaceDescriptorGLX: {
+      const auto& desc = aDesc.get_SurfaceDescriptorGLX();
+      result = new GLXTextureHostOGL(aFlags, desc);
+      break;
+    }
 #endif
 
     case SurfaceDescriptor::TSurfaceDescriptorSharedGLTexture: {
       const auto& desc = aDesc.get_SurfaceDescriptorSharedGLTexture();
       result = new GLTextureHost(aFlags, desc.texture(),
                                  desc.target(),
                                  (GLsync)desc.fence(),
                                  desc.size(),
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -317,17 +317,17 @@ public:
 
   gl::GLContext* gl() const;
 
   virtual gfx::IntSize GetSize() const override { return mSize; }
 
   virtual const char* Name() override { return "GLTextureHost"; }
 
 protected:
-  const GLuint mTexture;
+  GLuint mTexture;
   const GLenum mTarget;
   GLsync mSync;
   const gfx::IntSize mSize;
   const bool mHasAlpha;
   RefPtr<CompositorOGL> mCompositor;
   RefPtr<GLTextureSource> mTextureSource;
 };