1 2 /* 3 * Copyright 2016 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #include <GL/gl.h> 10 #include "../GLWindowContext.h" 11 #include "WindowContextFactory_unix.h" 12 #include "gl/GrGLInterface.h" 13 14 using sk_app::window_context_factory::XlibWindowInfo; 15 using sk_app::DisplayParams; 16 using sk_app::GLWindowContext; 17 18 namespace { 19 20 class GLWindowContext_xlib : public GLWindowContext { 21 public: 22 GLWindowContext_xlib(const XlibWindowInfo&, const DisplayParams&); 23 ~GLWindowContext_xlib() override; 24 25 void onSwapBuffers() override; 26 27 void onDestroyContext() override; 28 29 protected: 30 sk_sp<const GrGLInterface> onInitializeContext() override; 31 32 private: 33 GLWindowContext_xlib(void*, const DisplayParams&); 34 35 Display* fDisplay; 36 XWindow fWindow; 37 GLXFBConfig* fFBConfig; 38 XVisualInfo* fVisualInfo; 39 GLXContext fGLContext; 40 41 typedef GLWindowContext INHERITED; 42 }; 43 44 GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const DisplayParams& params) 45 : INHERITED(params) 46 , fDisplay(winInfo.fDisplay) 47 , fWindow(winInfo.fWindow) 48 , fFBConfig(winInfo.fFBConfig) 49 , fVisualInfo(winInfo.fVisualInfo) 50 , fGLContext() { 51 fWidth = winInfo.fWidth; 52 fHeight = winInfo.fHeight; 53 this->initializeContext(); 54 } 55 56 using CreateContextAttribsFn = GLXContext(Display*, GLXFBConfig, GLXContext, Bool, const int*); 57 58 sk_sp<const GrGLInterface> GLWindowContext_xlib::onInitializeContext() { 59 SkASSERT(fDisplay); 60 SkASSERT(!fGLContext); 61 // We attempt to use glXCreateContextAttribsARB as RenderDoc requires that the context be 62 // created with this rather than glXCreateContext. 63 CreateContextAttribsFn* createContextAttribs = (CreateContextAttribsFn*)glXGetProcAddressARB( 64 (const GLubyte*)"glXCreateContextAttribsARB"); 65 if (createContextAttribs && fFBConfig) { 66 // Specifying 3.2 allows an arbitrarily high context version (so long as no 3.2 features 67 // have been removed). 68 for (int minor = 2; minor >= 0 && !fGLContext; --minor) { 69 // Ganesh prefers a compatibility profile for possible NVPR support. However, RenderDoc 70 // requires a core profile. Edit this code to use RenderDoc. 71 for (int profile : {GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 72 GLX_CONTEXT_CORE_PROFILE_BIT_ARB}) { 73 int attribs[] = { 74 GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, minor, 75 GLX_CONTEXT_PROFILE_MASK_ARB, profile, 76 0 77 }; 78 fGLContext = createContextAttribs(fDisplay, *fFBConfig, nullptr, True, attribs); 79 if (fGLContext) { 80 break; 81 } 82 } 83 } 84 } 85 if (!fGLContext) { 86 fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE); 87 } 88 if (!fGLContext) { 89 return nullptr; 90 } 91 92 if (!glXMakeCurrent(fDisplay, fWindow, fGLContext)) { 93 return nullptr; 94 } 95 glClearStencil(0); 96 glClearColor(0, 0, 0, 0); 97 glStencilMask(0xffffffff); 98 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 99 100 glXGetConfig(fDisplay, fVisualInfo, GLX_STENCIL_SIZE, &fStencilBits); 101 glXGetConfig(fDisplay, fVisualInfo, GLX_SAMPLES_ARB, &fSampleCount); 102 fSampleCount = SkTMax(fSampleCount, 1); 103 104 XWindow root; 105 int x, y; 106 unsigned int border_width, depth; 107 XGetGeometry(fDisplay, fWindow, &root, &x, &y, (unsigned int*)&fWidth, (unsigned int*)&fHeight, 108 &border_width, &depth); 109 glViewport(0, 0, fWidth, fHeight); 110 111 return GrGLMakeNativeInterface(); 112 } 113 114 GLWindowContext_xlib::~GLWindowContext_xlib() { 115 this->destroyContext(); 116 } 117 118 void GLWindowContext_xlib::onDestroyContext() { 119 if (!fDisplay || !fGLContext) { 120 return; 121 } 122 glXMakeCurrent(fDisplay, None, nullptr); 123 glXDestroyContext(fDisplay, fGLContext); 124 fGLContext = nullptr; 125 } 126 127 void GLWindowContext_xlib::onSwapBuffers() { 128 if (fDisplay && fGLContext) { 129 glXSwapBuffers(fDisplay, fWindow); 130 } 131 } 132 133 } // anonymous namespace 134 135 namespace sk_app { 136 137 namespace window_context_factory { 138 139 WindowContext* NewGLForXlib(const XlibWindowInfo& winInfo, const DisplayParams& params) { 140 WindowContext* ctx = new GLWindowContext_xlib(winInfo, params); 141 if (!ctx->isValid()) { 142 delete ctx; 143 return nullptr; 144 } 145 return ctx; 146 } 147 148 } // namespace window_context_factory 149 150 } // namespace sk_app 151