• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GLWindowContext_xlib(const XlibWindowInfo & winInfo,const DisplayParams & params)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 
onInitializeContext()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 
~GLWindowContext_xlib()114 GLWindowContext_xlib::~GLWindowContext_xlib() {
115     this->destroyContext();
116 }
117 
onDestroyContext()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 
onSwapBuffers()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 
NewGLForXlib(const XlibWindowInfo & winInfo,const DisplayParams & params)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