Use glXCreateContextAttribsARB in viewer to make it easier to attach RenderDoc.
authorBrian Salomon <bsalomon@google.com>
Wed, 8 Mar 2017 15:50:21 +0000 (10:50 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 8 Mar 2017 16:25:50 +0000 (16:25 +0000)
Change-Id: I0cc82fe826b81a082b579f60af3d9ef35d5fe351
Reviewed-on: https://skia-review.googlesource.com/9407
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
tools/viewer/sk_app/unix/GLWindowContext_unix.cpp
tools/viewer/sk_app/unix/WindowContextFactory_unix.h
tools/viewer/sk_app/unix/Window_unix.cpp
tools/viewer/sk_app/unix/Window_unix.h

index a46bb62ff41368e05b14c1a9b09b452544eaee18..530a5b67dd7f75f3a24aa706f1653ae824a32b0f 100644 (file)
@@ -34,6 +34,7 @@ private:
 
     Display*     fDisplay;
     XWindow      fWindow;
+    GLXFBConfig* fFBConfig;
     XVisualInfo* fVisualInfo;
     GLXContext   fGLContext;
 };
@@ -42,6 +43,7 @@ GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const
         : GLWindowContext(params)
         , fDisplay(winInfo.fDisplay)
         , fWindow(winInfo.fWindow)
+        , fFBConfig(winInfo.fFBConfig)
         , fVisualInfo(winInfo.fVisualInfo)
         , fGLContext() {
     fWidth = winInfo.fWidth;
@@ -49,10 +51,38 @@ GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const
     this->initializeContext();
 }
 
+using CreateContextAttribsFn = GLXContext(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+
 void GLWindowContext_xlib::onInitializeContext() {
-    // any config code here (particularly for msaa)?
     SkASSERT(fDisplay);
-    fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE);
+    SkASSERT(!fGLContext);
+    // We attempt to use glXCreateContextAttribsARB as RenderDoc requires that the context be
+    // created with this rather than glXCreateContext.
+    CreateContextAttribsFn* createContextAttribs = (CreateContextAttribsFn*)glXGetProcAddressARB(
+            (const GLubyte*)"glXCreateContextAttribsARB");
+    if (createContextAttribs && fFBConfig) {
+        // Specifying 3.2 allows an arbitrarily high context version (so long as no 3.2 features
+        // have been removed).
+        for (int minor = 2; minor >= 0 && !fGLContext; --minor) {
+            // Ganesh prefers a compatibility profile for possible NVPR support. However, RenderDoc
+            // requires a core profile. Edit this code to use RenderDoc.
+            for (int profile : {GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+                                GLX_CONTEXT_CORE_PROFILE_BIT_ARB}) {
+                int attribs[] = {
+                        GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, minor,
+                        GLX_CONTEXT_PROFILE_MASK_ARB, profile,
+                        0
+                };
+                fGLContext = createContextAttribs(fDisplay, *fFBConfig, nullptr, True, attribs);
+                if (fGLContext) {
+                    break;
+                }
+            }
+        }
+    }
+    if (!fGLContext) {
+        fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE);
+    }
     if (!fGLContext) {
         return;
     }
index 1cc811d6225a3007c16b6c2387f0519bd48dd1f2..e6d033b4cd6d8060efd074611abdc716759d4ebc 100644 (file)
@@ -23,6 +23,7 @@ namespace window_context_factory {
 struct XlibWindowInfo {
     Display*     fDisplay;
     XWindow      fWindow;
+    GLXFBConfig* fFBConfig;
     XVisualInfo* fVisualInfo;
     int          fWidth;
     int          fHeight;
index de3cbd868e4ee8487232f073fae25497295a9991..ef0d85e0cea879608c3fd898c6b46d1a44ddb752 100644 (file)
@@ -55,28 +55,61 @@ bool Window_unix::initWindow(Display* display) {
     constexpr int initialHeight = 960;
 
     // Attempt to create a window that supports GL
-    GLint att[] = {
+
+    // We prefer the more recent glXChooseFBConfig but fall back to glXChooseVisual. They have
+    // slight differences in how attributes are specified.
+    static int constexpr kChooseFBConfigAtt[] = {
+        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_DOUBLEBUFFER, True,
+        GLX_STENCIL_SIZE, 8,
+        None
+    };
+    // For some reason glXChooseVisual takes a non-const pointer to the attributes.
+    int chooseVisualAtt[] = {
         GLX_RGBA,
-        GLX_DEPTH_SIZE, 24,
         GLX_DOUBLEBUFFER,
         GLX_STENCIL_SIZE, 8,
         None
     };
     SkASSERT(nullptr == fVisualInfo);
     if (fRequestedDisplayParams.fMSAASampleCount > 0) {
-        static const GLint kAttCount = SK_ARRAY_COUNT(att);
-        GLint msaaAtt[kAttCount + 4];
-        memcpy(msaaAtt, att, sizeof(att));
-        SkASSERT(None == msaaAtt[kAttCount - 1]);
-        msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
-        msaaAtt[kAttCount + 0] = 1;
-        msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
-        msaaAtt[kAttCount + 2] = fRequestedDisplayParams.fMSAASampleCount;
-        msaaAtt[kAttCount + 3] = None;
-        fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaAtt);
+        static const GLint kChooseFBConifgAttCnt = SK_ARRAY_COUNT(kChooseFBConfigAtt);
+        GLint msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 4];
+        memcpy(msaaChooseFBConfigAtt, kChooseFBConfigAtt, sizeof(kChooseFBConfigAtt));
+        SkASSERT(None == msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1]);
+        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
+        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 0] = 1;
+        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 1] = GLX_SAMPLES_ARB;
+        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 2] = fRequestedDisplayParams.fMSAASampleCount;
+        msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 3] = None;
+        int n;
+        fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), msaaChooseFBConfigAtt, &n);
+        if (n > 0) {
+            fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
+        } else {
+            static const GLint kChooseVisualAttCnt = SK_ARRAY_COUNT(chooseVisualAtt);
+            GLint msaaChooseVisualAtt[kChooseVisualAttCnt + 4];
+            memcpy(msaaChooseVisualAtt, chooseVisualAtt, sizeof(chooseVisualAtt));
+            SkASSERT(None == msaaChooseVisualAtt[kChooseVisualAttCnt - 1]);
+            msaaChooseFBConfigAtt[kChooseVisualAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
+            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 0] = 1;
+            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 1] = GLX_SAMPLES_ARB;
+            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 2] =
+                    fRequestedDisplayParams.fMSAASampleCount;
+            msaaChooseFBConfigAtt[kChooseVisualAttCnt + 3] = None;
+            fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaChooseVisualAtt);
+            fFBConfig = nullptr;
+        }
     }
     if (nullptr == fVisualInfo) {
-        fVisualInfo = glXChooseVisual(display, DefaultScreen(display), att);
+        int n;
+        fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), kChooseFBConfigAtt, &n);
+        if (n > 0) {
+            fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
+        } else {
+            fVisualInfo = glXChooseVisual(display, DefaultScreen(display), chooseVisualAtt);
+            fFBConfig = nullptr;
+        }
     }
 
     if (fVisualInfo) {
@@ -139,7 +172,14 @@ void Window_unix::closeWindow() {
         gWindowMap.remove(fWindow);
         XDestroyWindow(fDisplay, fWindow);
         fWindow = 0;
-        fVisualInfo = nullptr;
+        if (fFBConfig) {
+            XFree(fFBConfig);
+            fFBConfig = nullptr;
+        }
+        if (fVisualInfo) {
+            XFree(fVisualInfo);
+            fVisualInfo = nullptr;
+        }
         fDisplay = nullptr;
     }
 }
@@ -298,6 +338,7 @@ bool Window_unix::attach(BackendType attachType) {
     window_context_factory::XlibWindowInfo winInfo;
     winInfo.fDisplay = fDisplay;
     winInfo.fWindow = fWindow;
+    winInfo.fFBConfig = fFBConfig;
     winInfo.fVisualInfo = fVisualInfo;
 
     XWindowAttributes attrs;
index be202f74d2d45450b824432241b6bdf64f4b4de1..73f21af94aa3782e806858f3b53279ad75945268 100644 (file)
@@ -24,6 +24,7 @@ public:
                   , fDisplay(nullptr)
                   , fWindow(0)
                   , fGC(nullptr)
+                  , fFBConfig(nullptr)
                   , fVisualInfo(nullptr)
                   , fMSAASampleCount(0) {}
     ~Window_unix() override { this->closeWindow(); }
@@ -77,6 +78,7 @@ private:
     Display*     fDisplay;
     XWindow      fWindow;
     GC           fGC;
+    GLXFBConfig* fFBConfig;
     XVisualInfo* fVisualInfo;
     int          fMSAASampleCount;