1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon 8273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon#include "gl/GLTestContext.h" 9300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon#include "SkOnce.h" 1016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 119e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen#include <X11/Xlib.h> 129e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen#include <GL/glx.h> 1316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com#include <GL/glu.h> 1416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 15fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova#include <vector> 16fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova#include <utility> 17fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova 189e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunennamespace { 1910805961ce424868e8315e00f6dbeeaa62d466acbsalomon 209e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen/* Note: Skia requires glx 1.3 or newer */ 2110805961ce424868e8315e00f6dbeeaa62d466acbsalomon 229e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen/* This struct is taken from a mesa demo. Please update as required */ 23fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarovastatic const std::vector<std::pair<int, int>> gl_versions = { 249e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {1, 0}, 259e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {1, 1}, 269e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {1, 2}, 279e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {1, 3}, 289e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {1, 4}, 299e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {1, 5}, 309e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {2, 0}, 319e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {2, 1}, 329e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {3, 0}, 339e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {3, 1}, 349e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {3, 2}, 359e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {3, 3}, 369e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {4, 0}, 379e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {4, 1}, 389e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {4, 2}, 399e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {4, 3}, 409e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen {4, 4}, 419e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen}; 42fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova 43fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarovastatic const std::vector<std::pair<int, int>> gles_versions = { 44fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova {2, 0}, 45fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova {3, 0}, 46fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova}; 4716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 4816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.comstatic bool ctxErrorOccurred = false; 4916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.comstatic int ctxErrorHandler(Display *dpy, XErrorEvent *ev) { 5016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com ctxErrorOccurred = true; 5116bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com return 0; 5216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com} 5316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 54273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonclass GLXGLTestContext : public sk_gpu_test::GLTestContext { 559e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunenpublic: 56273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon GLXGLTestContext(GrGLStandard forcedGpuAPI, GLXGLTestContext* shareList); 57273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon ~GLXGLTestContext() override; 589e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen 599e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunenprivate: 6030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen void destroyGLContext(); 61fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova static GLXContext CreateBestContext(bool isES, Display* display, GLXFBConfig bestFbc, 62fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova GLXContext glxSharedContext); 6330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 64d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton void onPlatformMakeCurrent() const override; 65d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton void onPlatformSwapBuffers() const override; 66d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton GrGLFuncPtr onPlatformGetProcAddress(const char*) const override; 67d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton 689e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen GLXContext fContext; 699e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen Display* fDisplay; 709e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen Pixmap fPixmap; 719e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen GLXPixmap fGlxPixmap; 729e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen}; 739e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen 74300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomonstatic Display* get_display() { 75300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon class AutoDisplay { 76300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon public: 77fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein AutoDisplay() { fDisplay = XOpenDisplay(nullptr); } 78300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon ~AutoDisplay() { 79300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon if (fDisplay) { 80300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon XCloseDisplay(fDisplay); 81300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon } 82300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon } 83300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon Display* display() const { return fDisplay; } 84300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon private: 85300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon Display* fDisplay; 86300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon }; 87300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon static std::unique_ptr<AutoDisplay> ad; 88300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon static SkOnce once; 89300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon once([] { ad.reset(new AutoDisplay{}); }); 90300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon return ad->display(); 91300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon} 92300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon 93273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGLXGLTestContext::GLXGLTestContext(GrGLStandard forcedGpuAPI, GLXGLTestContext* shareContext) 9496fcdcc219d2a0d3579719b84b28bede76efba64halcanary : fContext(nullptr) 9596fcdcc219d2a0d3579719b84b28bede76efba64halcanary , fDisplay(nullptr) 96373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com , fPixmap(0) 97373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com , fGlxPixmap(0) { 98300178b1c83e7a9b8d3bee7aeb09e0d4fb096d6bbsalomon fDisplay = get_display(); 9916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 100b59d1bc7a8596f346d57a9cfcd461dddc6d75edbjoshualitt GLXContext glxShareContext = shareContext ? shareContext->fContext : nullptr; 101b59d1bc7a8596f346d57a9cfcd461dddc6d75edbjoshualitt 102373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com if (!fDisplay) { 10316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com SkDebugf("Failed to open X display.\n"); 104373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com this->destroyGLContext(); 10530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 10616bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 10716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 10816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Get a matching FB config 10916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com static int visual_attribs[] = { 11016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com GLX_X_RENDERABLE , True, 11116bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, 11216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com None 11316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com }; 11416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 115c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt int glx_major, glx_minor; 116c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt 117c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt // FBConfigs were added in GLX version 1.3. 118c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || 119c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { 120c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt SkDebugf("GLX version 1.3 or higher required.\n"); 121c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt this->destroyGLContext(); 12230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 123c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt } 124c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt 12516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Getting matching framebuffer configs.\n"); 12616bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com int fbcount; 127373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), 12816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com visual_attribs, &fbcount); 12916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com if (!fbc) { 13016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com SkDebugf("Failed to retrieve a framebuffer config.\n"); 131373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com this->destroyGLContext(); 13230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 13316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 13416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Found %d matching FB configs.\n", fbcount); 13516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 13616bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Pick the FB config/visual with the most samples per pixel 13716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Getting XVisualInfos.\n"); 138bb89cda7e799bdec58c026a447363024a4bc1a5arobertphillips@google.com int best_fbc = -1, best_num_samp = -1; 13916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 14016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com int i; 14116bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com for (i = 0; i < fbcount; ++i) { 142373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); 14316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com if (vi) { 14416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com int samp_buf, samples; 145373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); 146373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples); 14716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 14816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," 14916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // " SAMPLES = %d\n", 15016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // i, (unsigned int)vi->visualid, samp_buf, samples); 15116bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 15219eb8435cbce1200667024079750c6494b02079fMike Klein if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) { 15319eb8435cbce1200667024079750c6494b02079fMike Klein best_fbc = i; 15419eb8435cbce1200667024079750c6494b02079fMike Klein best_num_samp = samples; 15519eb8435cbce1200667024079750c6494b02079fMike Klein } 156fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 15716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com XFree(vi); 15816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 15916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 16016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com GLXFBConfig bestFbc = fbc[best_fbc]; 16116bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 16216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Be sure to free the FBConfig list allocated by glXChooseFBConfig() 16316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com XFree(fbc); 16416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 16516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Get a visual 166373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); 16716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); 16816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 169373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); 17016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 171373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com if (!fPixmap) { 17216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com SkDebugf("Failed to create pixmap.\n"); 173373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com this->destroyGLContext(); 17430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 17516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 17616bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 177373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); 17816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 17916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Done with the visual info data 18016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com XFree(vi); 18116bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 18216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Get the default screen's GLX extension list 18316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com const char *glxExts = glXQueryExtensionsString( 184373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com fDisplay, DefaultScreen(fDisplay) 18516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com ); 18616bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Check for the GLX_ARB_create_context extension string and the function. 18716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // If either is not present, use GLX 1.3 context creation method. 18880549fcdd50269d7e069d6db02b395fca128056ckkinnunen if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"), 18980549fcdd50269d7e069d6db02b395fca128056ckkinnunen reinterpret_cast<const GLubyte*>(glxExts))) { 19080549fcdd50269d7e069d6db02b395fca128056ckkinnunen if (kGLES_GrGLStandard != forcedGpuAPI) { 19180549fcdd50269d7e069d6db02b395fca128056ckkinnunen fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); 19280549fcdd50269d7e069d6db02b395fca128056ckkinnunen } 193c863ab07c207aac5aae8b1593a2767a946682bcajoshualitt } else { 19480549fcdd50269d7e069d6db02b395fca128056ckkinnunen if (kGLES_GrGLStandard == forcedGpuAPI) { 19580549fcdd50269d7e069d6db02b395fca128056ckkinnunen if (gluCheckExtension( 19680549fcdd50269d7e069d6db02b395fca128056ckkinnunen reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"), 19780549fcdd50269d7e069d6db02b395fca128056ckkinnunen reinterpret_cast<const GLubyte*>(glxExts))) { 198fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova fContext = CreateBestContext(true, fDisplay, bestFbc, glxShareContext); 19980549fcdd50269d7e069d6db02b395fca128056ckkinnunen } 20016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } else { 201fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova fContext = CreateBestContext(false, fDisplay, bestFbc, glxShareContext); 20216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 20316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 204fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova if (!fContext) { 20516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com SkDebugf("Failed to create an OpenGL context.\n"); 206373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com this->destroyGLContext(); 20730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 20816bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 20916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 21016bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com // Verify that context is a direct context 211373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com if (!glXIsDirect(fDisplay, fContext)) { 21216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Indirect GLX rendering context obtained.\n"); 21316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } else { 21416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Direct GLX rendering context obtained.\n"); 21516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 21616bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 21716bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com //SkDebugf("Making context current.\n"); 218373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { 21916bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com SkDebugf("Could not set the context.\n"); 220373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com this->destroyGLContext(); 22130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 22216bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 22316bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com 2241b612a89fba2275e3effe12bdc9b6cdc2f4d9eeeHal Canary sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface()); 22596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == gl.get()) { 226373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com SkDebugf("Failed to create gl interface"); 227373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com this->destroyGLContext(); 22830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 22930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 23030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 231d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!gl->validate()) { 23230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen SkDebugf("Failed to validate gl interface"); 23330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen this->destroyGLContext(); 23430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 23530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 236d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton 23718300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein this->init(gl.release()); 23830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen} 23930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 24030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 241273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGLXGLTestContext::~GLXGLTestContext() { 242d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton this->teardown(); 24330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen this->destroyGLContext(); 24430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen} 24530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 246273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonvoid GLXGLTestContext::destroyGLContext() { 24730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fDisplay) { 24830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen glXMakeCurrent(fDisplay, 0, 0); 24930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 25030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fContext) { 25130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen glXDestroyContext(fDisplay, fContext); 25296fcdcc219d2a0d3579719b84b28bede76efba64halcanary fContext = nullptr; 25330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 25430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 25530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fGlxPixmap) { 25630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen glXDestroyGLXPixmap(fDisplay, fGlxPixmap); 25730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fGlxPixmap = 0; 25830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 25930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 26030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fPixmap) { 26130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen XFreePixmap(fDisplay, fPixmap); 26230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fPixmap = 0; 26330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 26430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 26596fcdcc219d2a0d3579719b84b28bede76efba64halcanary fDisplay = nullptr; 266373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com } 267373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com} 268373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com 269fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova/* Create a context with the highest possible version. 270fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * 271fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * Disable Xlib errors for the duration of this function (by default they abort 272fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * the program) and try to get a context starting from the highest version 273fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * number - there is no way to just directly ask what the highest supported 274fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * version is. 275fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * 276fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova * Returns the correct context or NULL on failure. 277fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova */ 278fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarovaGLXContext GLXGLTestContext::CreateBestContext(bool isES, Display* display, GLXFBConfig bestFbc, 279fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova GLXContext glxShareContext) { 280fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova auto glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) 281fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB"); 282fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova if (!glXCreateContextAttribsARB) { 283fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova SkDebugf("Failed to get address of glXCreateContextAttribsARB"); 284fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova return nullptr; 285fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova } 286fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova GLXContext context = nullptr; 287fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // Install Xlib error handler that will set ctxErrorOccurred. 288fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // WARNING: It is global for all threads. 289fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova ctxErrorOccurred = false; 290fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); 291fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova 292fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova auto versions = isES ? gles_versions : gl_versions; 293fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // Well, unfortunately GLX will not just give us the highest context so 294fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // instead we have to do this nastiness 295fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova for (int i = versions.size() - 1; i >= 0 ; i--) { 296fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // WARNING: Don't try to optimize this and make this array static. The 297fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // glXCreateContextAttribsARB call writes to it upon failure and the 298fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // next call would fail too. 299fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova std::vector<int> flags = { 300fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova GLX_CONTEXT_MAJOR_VERSION_ARB, versions[i].first, 301fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova GLX_CONTEXT_MINOR_VERSION_ARB, versions[i].second, 302fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova }; 303fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova if (isES) { 304fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova flags.push_back(GLX_CONTEXT_PROFILE_MASK_ARB); 305fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // the ES2 flag should work even for higher versions 306fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova flags.push_back(GLX_CONTEXT_ES2_PROFILE_BIT_EXT); 307fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova } else if (versions[i].first > 2) { 308fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova flags.push_back(GLX_CONTEXT_PROFILE_MASK_ARB); 309fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // TODO When Nvidia implements NVPR on Core profiles, we should start 310fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // requesting core here - currently Nv Path rendering on Nvidia 311fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // requires a compatibility profile. 312fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova flags.push_back(GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); 313fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova } 314fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova flags.push_back(0); 315fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova context = glXCreateContextAttribsARB(display, bestFbc, glxShareContext, true, 316fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova &flags[0]); 317fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // Sync to ensure any errors generated are processed. 318fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova XSync(display, False); 319fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova 320fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova if (!ctxErrorOccurred && context) { 321fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova break; 322fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova } 323fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // try again 324fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova ctxErrorOccurred = false; 325fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova } 326fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova // Restore the original error handler. 327fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova XSetErrorHandler(oldHandler); 328fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova return context; 329fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova} 330fc3ea41cebb8272c3f683f9cf585ff780b18f09bmartina.kollarova 331273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonvoid GLXGLTestContext::onPlatformMakeCurrent() const { 332373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { 333373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com SkDebugf("Could not set the context.\n"); 33416bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com } 33516bab87a78cfaf6a4f334e1af910c46883f460afbungeman@google.com} 336c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com 337273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonvoid GLXGLTestContext::onPlatformSwapBuffers() const { 338c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com glXSwapBuffers(fDisplay, fGlxPixmap); 339c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com} 3409e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen 341273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGrGLFuncPtr GLXGLTestContext::onPlatformGetProcAddress(const char* procName) const { 342d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton return glXGetProcAddress(reinterpret_cast<const GLubyte*>(procName)); 343d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton} 344d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton 3453724e574a744491b7cfb8187ac865a70ef3d4528bsalomon} // anonymous namespace 3469e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen 3473724e574a744491b7cfb8187ac865a70ef3d4528bsalomonnamespace sk_gpu_test { 348273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGLTestContext *CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, 349273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon GLTestContext *shareContext) { 350273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon GLXGLTestContext *glxShareContext = reinterpret_cast<GLXGLTestContext *>(shareContext); 351273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon GLXGLTestContext *ctx = new GLXGLTestContext(forcedGpuAPI, glxShareContext); 35230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (!ctx->isValid()) { 353385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete ctx; 35496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 35530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 35630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return ctx; 3579e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen} 3583724e574a744491b7cfb8187ac865a70ef3d4528bsalomon} // namespace sk_gpu_test 359