Bug 973227 - Add a new X11TextureSourceOGL for upload x11 pixmaps to textures. r=nical
authorTom Schuster <evilpies@gmail.com>
Tue, 18 Feb 2014 01:30:05 +0100
changeset 169561 5eeffd689732242c358c621b950aec456b0d1bb2
parent 169560 cd950a00e2cbf4728043adfb0099ff4361dc70cf
child 169562 8da5f0f2f82c088be5a652162d9fe91263ef1d0f
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersnical
bugs973227
milestone30.0a1
Bug 973227 - Add a new X11TextureSourceOGL for upload x11 pixmaps to textures. r=nical
gfx/layers/client/CompositableClient.cpp
gfx/layers/composite/X11TextureHost.cpp
gfx/layers/moz.build
gfx/layers/opengl/X11TextureSourceOGL.cpp
gfx/layers/opengl/X11TextureSourceOGL.h
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -14,16 +14,19 @@
 #ifdef XP_WIN
 #include "mozilla/layers/TextureD3D9.h"
 #include "mozilla/layers/TextureD3D11.h"
 #include "gfxWindowsPlatform.h"
 #include "gfx2DGlue.h"
 #endif
 #ifdef MOZ_X11
 #include "mozilla/layers/TextureClientX11.h"
+#ifdef GL_PROVIDER_GLX
+#include "GLXLibrary.h"
+#endif
 #endif
 #ifdef MOZ_WIDGET_GONK
 #include <cutils/properties.h>
 #include "mozilla/layers/GrallocTextureClient.h"
 #endif
 
 using namespace mozilla::gfx;
 
@@ -249,22 +252,35 @@ CompositableClient::CreateTextureClientF
     } else {
       result = new CairoTextureClientD3D9(aFormat, aTextureFlags);
     }
   }
 #endif
 
 #ifdef MOZ_X11
   LayersBackend parentBackend = GetForwarder()->GetCompositorBackendType();
+  gfxSurfaceType type =
+    gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType();
+
   if (parentBackend == LayersBackend::LAYERS_BASIC &&
-      gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType() == gfxSurfaceType::Xlib &&
+      type == gfxSurfaceType::Xlib &&
       !(aTextureFlags & TEXTURE_ALLOC_FALLBACK))
   {
     result = new TextureClientX11(aFormat, aTextureFlags);
   }
+#ifdef GL_PROVIDER_GLX
+  if (parentBackend == LayersBackend::LAYERS_OPENGL &&
+      type == gfxSurfaceType::Xlib &&
+      !(aTextureFlags & TEXTURE_ALLOC_FALLBACK) &&
+      aFormat != SurfaceFormat::A8 &&
+      gl::sGLXLibrary.UseTextureFromPixmap())
+  {
+    result = new TextureClientX11(aFormat, aTextureFlags);
+  }
+#endif
 #endif
 
 #ifdef MOZ_WIDGET_GONK
   if (!DisableGralloc(aFormat)) {
     result = new GrallocTextureClientOGL(this, aFormat, aTextureFlags);
   }
 #endif
 
--- a/gfx/layers/composite/X11TextureHost.cpp
+++ b/gfx/layers/composite/X11TextureHost.cpp
@@ -1,16 +1,20 @@
 /* -*- 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 "X11TextureHost.h"
 #include "mozilla/layers/BasicCompositor.h"
 #include "mozilla/layers/X11TextureSourceBasic.h"
+#ifdef GL_PROVIDER_GLX
+#include "mozilla/layers/CompositorOGL.h"
+#include "mozilla/layers/X11TextureSourceOGL.h"
+#endif
 #include "gfxXlibSurface.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 X11TextureHost::X11TextureHost(TextureFlags aFlags,
@@ -34,16 +38,23 @@ X11TextureHost::Lock()
 
   if (!mTextureSource) {
     switch (mCompositor->GetBackendType()) {
       case LayersBackend::LAYERS_BASIC:
         mTextureSource =
           new X11TextureSourceBasic(static_cast<BasicCompositor*>(mCompositor),
                                     mSurface);
         break;
+#ifdef GL_PROVIDER_GLX
+      case LayersBackend::LAYERS_OPENGL:
+        mTextureSource =
+          new X11TextureSourceOGL(static_cast<CompositorOGL*>(mCompositor),
+                                  mSurface);
+        break;
+#endif
       default:
         return false;
     }
   }
 
   return true;
 }
 
@@ -54,16 +65,22 @@ X11TextureHost::SetCompositor(Compositor
   if (mTextureSource) {
     mTextureSource->SetCompositor(aCompositor);
   }
 }
 
 SurfaceFormat
 X11TextureHost::GetFormat() const
 {
-  return X11TextureSourceBasic::ContentTypeToSurfaceFormat(mSurface->GetContentType());
+  gfxContentType type = mSurface->GetContentType();
+#ifdef GL_PROVIDER_GLX
+  if (mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL) {
+    return X11TextureSourceOGL::ContentTypeToSurfaceFormat(type);
+  }
+#endif
+  return X11TextureSourceBasic::ContentTypeToSurfaceFormat(type);
 }
 
 IntSize
 X11TextureHost::GetSize() const
 {
   return ToIntSize(mSurface->GetSize());
 }
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -156,22 +156,24 @@ EXPORTS.mozilla.layers += [
 ]
 
 if CONFIG['MOZ_X11']:
     EXPORTS.mozilla.layers += [
         'basic/TextureClientX11.h',
         'basic/X11TextureSourceBasic.h',
         'composite/X11TextureHost.h',
         'ipc/ShadowLayerUtilsX11.h',
+        'opengl/X11TextureSourceOGL.h',
     ]
     SOURCES += [
         'basic/TextureClientX11.cpp',
         'basic/X11TextureSourceBasic.cpp',
         'composite/X11TextureHost.cpp',
         'ipc/ShadowLayerUtilsX11.cpp',
+        'opengl/X11TextureSourceOGL.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.layers += [
         'opengl/GLManager.h',
     ]
     EXPORTS += [
         'MacIOSurfaceImage.h',
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/X11TextureSourceOGL.cpp
@@ -0,0 +1,80 @@
+/* -*- 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 "X11TextureSourceOGL.h"
+#include "mozilla/layers/CompositorOGL.h"
+#include "gfxXlibSurface.h"
+#include "gfx2DGlue.h"
+
+using namespace mozilla;
+using namespace mozilla::layers;
+using namespace mozilla::gfx;
+
+X11TextureSourceOGL::X11TextureSourceOGL(CompositorOGL* aCompositor, gfxXlibSurface* aSurface)
+  : mCompositor(aCompositor),
+    mSurface(aSurface)
+{
+}
+
+void
+X11TextureSourceOGL::BindTexture(GLenum aTextureUnit)
+{
+  GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
+
+  gl()->fActiveTexture(aTextureUnit);
+  gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, tex);
+
+  gl::sGLXLibrary.xBindTexImage(mSurface->XDisplay(), mSurface->GetGLXPixmap(),
+                                LOCAL_GLX_FRONT_LEFT_EXT, NULL);
+
+  gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
+  gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
+
+  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
+}
+
+IntSize
+X11TextureSourceOGL::GetSize() const
+{
+  return ToIntSize(mSurface->GetSize());
+}
+
+SurfaceFormat
+X11TextureSourceOGL::GetFormat() const {
+  gfxContentType type = mSurface->GetContentType();
+  return X11TextureSourceOGL::ContentTypeToSurfaceFormat(type);
+}
+
+void
+X11TextureSourceOGL::SetCompositor(Compositor* aCompositor)
+{
+  MOZ_ASSERT(aCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
+  mCompositor = static_cast<CompositorOGL*>(aCompositor);
+}
+
+gl::GLContext*
+X11TextureSourceOGL::gl() const
+{
+  return mCompositor ? mCompositor->gl() : nullptr;
+}
+
+SurfaceFormat
+X11TextureSourceOGL::ContentTypeToSurfaceFormat(gfxContentType aType)
+{
+  // X11 uses a switched format and the OGL compositor
+  // doesn't support ALPHA / A8.
+  switch (aType) {
+    case gfxContentType::COLOR:
+      return SurfaceFormat::R8G8B8X8;
+    case gfxContentType::COLOR_ALPHA:
+      return SurfaceFormat::R8G8B8A8;
+    default:
+      return SurfaceFormat::UNKNOWN;
+  }
+}
+
+#endif
new file mode 100644
--- /dev/null
+++ b/gfx/layers/opengl/X11TextureSourceOGL.h
@@ -0,0 +1,56 @@
+/* -*- 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_X11TEXTURESOURCEOGL__H
+#define MOZILLA_GFX_X11TEXTURESOURCEOGL__H
+
+#ifdef GL_PROVIDER_GLX
+
+#include "mozilla/layers/TextureHostOGL.h"
+#include "mozilla/gfx/2D.h"
+
+namespace mozilla {
+namespace layers {
+
+// TextureSource for Xlib-backed surfaces.
+class X11TextureSourceOGL
+  : public TextureSourceOGL,
+    public NewTextureSource
+{
+public:
+  X11TextureSourceOGL(CompositorOGL* aCompositor, gfxXlibSurface* aSurface);
+
+  virtual X11TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
+
+  virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); } ;
+  virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
+  virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
+  virtual GLenum GetTextureTarget() const MOZ_OVERRIDE {
+    return LOCAL_GL_TEXTURE_2D;
+  }
+  virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
+  virtual GLenum GetWrapMode() const MOZ_OVERRIDE {
+     return LOCAL_GL_CLAMP_TO_EDGE;
+  }
+
+  virtual void DeallocateDeviceData() MOZ_OVERRIDE { }
+
+  virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
+
+  gl::GLContext* gl() const;
+  static gfx::SurfaceFormat ContentTypeToSurfaceFormat(gfxContentType aType);
+
+protected:
+  CompositorOGL* mCompositor;
+  RefPtr<gfxXlibSurface> mSurface;
+  RefPtr<gfx::SourceSurface> mSourceSurface;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif
+
+#endif // MOZILLA_GFX_X11TEXTURESOURCEOGL__H
\ No newline at end of file