Bug 1197954 - Add support for GLX_SGI_video_sync to GLContextProviderGLX. r=jgilbert
authorAndrew Comminos <acomminos@mozilla.com>
Tue, 01 Mar 2016 19:01:00 -0800
changeset 336827 d6e83c1c3494e47e93f750e684e606e2e0f7c893
parent 336826 9f4d6b01a806df69498b0b1623cf4b9b0b135eeb
child 336828 a1e04f19b4a9c67044e4e42e3faa00d3b4bee539
push id12189
push usercku@mozilla.com
push dateFri, 04 Mar 2016 07:52:22 +0000
reviewersjgilbert
bugs1197954
milestone47.0a1
Bug 1197954 - Add support for GLX_SGI_video_sync to GLContextProviderGLX. r=jgilbert MozReview-Commit-ID: Fn9jwecuz5q
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLXLibrary.h
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -164,16 +164,22 @@ GLXLibrary::EnsureInitialized()
         { nullptr, { nullptr } }
     };
 
     GLLibraryLoader::SymLoadStruct symbols_createcontext[] = {
         { (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", nullptr } },
         { nullptr, { nullptr } }
     };
 
+    GLLibraryLoader::SymLoadStruct symbols_videosync[] = {
+      { (PRFuncPtr*) &xGetVideoSyncInternal, { "glXGetVideoSyncSGI", nullptr } },
+      { (PRFuncPtr*) &xWaitVideoSyncInternal, { "glXWaitVideoSyncSGI", nullptr } },
+      { nullptr, { nullptr } }
+    };
+
     if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return false;
     }
 
     Display *display = DefaultXDisplay();
     int screen = DefaultScreen(display);
 
@@ -241,16 +247,23 @@ GLXLibrary::EnsureInitialized()
         mHasCreateContextAttribs = true;
     }
 
     if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness"))
     {
         mHasRobustness = true;
     }
 
+    if (HasExtension(extensionsStr, "GLX_SGI_video_sync") &&
+        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_videosync,
+                                     (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
+    {
+        mHasVideoSync = true;
+    }
+
     mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
     mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation");
     mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa");
 
     mInitialized = true;
 
     return true;
 }
@@ -264,16 +277,26 @@ GLXLibrary::SupportsTextureFromPixmap(gf
 
     if (aSurface->GetType() != gfxSurfaceType::Xlib || !mUseTextureFromPixmap) {
         return false;
     }
 
     return true;
 }
 
+bool
+GLXLibrary::SupportsVideoSync()
+{
+    if (!EnsureInitialized()) {
+        return false;
+    }
+
+    return mHasVideoSync;
+}
+
 GLXPixmap
 GLXLibrary::CreatePixmap(gfxASurface* aSurface)
 {
     if (!SupportsTextureFromPixmap(aSurface)) {
         return None;
     }
 
     gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(aSurface);
@@ -732,16 +755,34 @@ GLXLibrary::xCreateContextAttribs(Displa
                                                       config,
                                                       share_list,
                                                       direct,
                                                       attrib_list);
     AFTER_GLX_CALL;
     return result;
 }
 
+int
+GLXLibrary::xGetVideoSync(unsigned int* count)
+{
+    BEFORE_GLX_CALL;
+    int result = xGetVideoSyncInternal(count);
+    AFTER_GLX_CALL;
+    return result;
+}
+
+int
+GLXLibrary::xWaitVideoSync(int divisor, int remainder, unsigned int* count)
+{
+    BEFORE_GLX_CALL;
+    int result = xWaitVideoSyncInternal(divisor, remainder, count);
+    AFTER_GLX_CALL;
+    return result;
+}
+
 already_AddRefed<GLContextGLX>
 GLContextGLX::CreateGLContext(
                   const SurfaceCaps& caps,
                   GLContextGLX* shareContext,
                   bool isOffscreen,
                   Display* display,
                   GLXDrawable drawable,
                   GLXFBConfig cfg,
--- a/gfx/gl/GLXLibrary.h
+++ b/gfx/gl/GLXLibrary.h
@@ -49,19 +49,22 @@ public:
     , xCreateGLXPixmapWithConfigInternal(nullptr)
     , xDestroyPixmapInternal(nullptr)
     , xQueryVersionInternal(nullptr)
     , xBindTexImageInternal(nullptr)
     , xReleaseTexImageInternal(nullptr)
     , xWaitGLInternal(nullptr)
     , xWaitXInternal(nullptr)
     , xCreateContextAttribsInternal(nullptr)
+    , xGetVideoSyncInternal(nullptr)
+    , xWaitVideoSyncInternal(nullptr)
     , mInitialized(false), mTriedInitializing(false)
     , mUseTextureFromPixmap(false), mDebug(false)
     , mHasRobustness(false), mHasCreateContextAttribs(false)
+    , mHasVideoSync(false)
     , mIsATI(false), mIsNVIDIA(false)
     , mClientIsMesa(false), mGLXMajorVersion(0)
     , mGLXMinorVersion(0)
     , mOGLLibrary(nullptr)
     {}
 
     void xDestroyContext(Display* display, GLXContext context);
     Bool xMakeCurrent(Display* display, 
@@ -115,28 +118,32 @@ public:
     void xWaitX();
 
     GLXContext xCreateContextAttribs(Display* display, 
                                      GLXFBConfig config, 
                                      GLXContext share_list, 
                                      Bool direct,
                                      const int* attrib_list);
 
+    int xGetVideoSync(unsigned int* count);
+    int xWaitVideoSync(int divisor, int remainder, unsigned int* count);
+
     bool EnsureInitialized();
 
     GLXPixmap CreatePixmap(gfxASurface* aSurface);
     void DestroyPixmap(Display* aDisplay, GLXPixmap aPixmap);
     void BindTexImage(Display* aDisplay, GLXPixmap aPixmap);
     void ReleaseTexImage(Display* aDisplay, GLXPixmap aPixmap);
     void UpdateTexImage(Display* aDisplay, GLXPixmap aPixmap);
 
     bool UseTextureFromPixmap() { return mUseTextureFromPixmap; }
     bool HasRobustness() { return mHasRobustness; }
     bool HasCreateContextAttribs() { return mHasCreateContextAttribs; }
     bool SupportsTextureFromPixmap(gfxASurface* aSurface);
+    bool SupportsVideoSync();
     bool IsATI() { return mIsATI; }
     bool GLXVersionCheck(int aMajor, int aMinor);
 
 private:
     
     typedef void (GLAPIENTRY * PFNGLXDESTROYCONTEXTPROC) (Display*,
                                                           GLXContext);
     PFNGLXDESTROYCONTEXTPROC xDestroyContextInternal;
@@ -220,27 +227,34 @@ private:
 
     typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXTATTRIBS) (Display *,
                                                                   GLXFBConfig,
                                                                   GLXContext,
                                                                   Bool,
                                                                   const int *);
     PFNGLXCREATECONTEXTATTRIBS xCreateContextAttribsInternal;
 
+    typedef int (GLAPIENTRY *PFNGLXGETVIDEOSYNCSGI) (unsigned int *count);
+    PFNGLXGETVIDEOSYNCSGI xGetVideoSyncInternal;
+
+    typedef int (GLAPIENTRY *PFNGLXWAITVIDEOSYNCSGI) (int divisor, int remainder, unsigned int *count);
+    PFNGLXWAITVIDEOSYNCSGI xWaitVideoSyncInternal;
+
 #ifdef DEBUG
     void BeforeGLXCall();
     void AfterGLXCall();
 #endif
 
     bool mInitialized;
     bool mTriedInitializing;
     bool mUseTextureFromPixmap;
     bool mDebug;
     bool mHasRobustness;
     bool mHasCreateContextAttribs;
+    bool mHasVideoSync;
     bool mIsATI;
     bool mIsNVIDIA;
     bool mClientIsMesa;
     int mGLXMajorVersion;
     int mGLXMinorVersion;
     PRLibrary *mOGLLibrary;
 };