Flutter Engine
The Flutter Engine
GLWindowContext_unix.cpp
Go to the documentation of this file.
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
12
13#if defined(SK_GLX)
15#endif
16
17#include <GL/gl.h>
18
22
23namespace {
24
25static bool gCtxErrorOccurred = false;
26static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
27 gCtxErrorOccurred = true;
28 return 0;
29}
30
31class GLWindowContext_xlib : public GLWindowContext {
32public:
33 GLWindowContext_xlib(const XlibWindowInfo&, const DisplayParams&);
34 ~GLWindowContext_xlib() override;
35
36 void onDestroyContext() override;
37
38protected:
40 void onSwapBuffers() override;
41
42private:
43 GLWindowContext_xlib(void*, const DisplayParams&);
44
45 Display* fDisplay;
46 XWindow fWindow;
47 GLXFBConfig* fFBConfig;
48 XVisualInfo* fVisualInfo;
49 GLXContext fGLContext;
50};
51
52GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const DisplayParams& params)
54 , fDisplay(winInfo.fDisplay)
55 , fWindow(winInfo.fWindow)
56 , fFBConfig(winInfo.fFBConfig)
57 , fVisualInfo(winInfo.fVisualInfo)
58 , fGLContext() {
59 fWidth = winInfo.fWidth;
60 fHeight = winInfo.fHeight;
61 this->initializeContext();
62}
63
64using CreateContextAttribsFn = GLXContext(Display*, GLXFBConfig, GLXContext, Bool, const int*);
65
66static sk_sp<const GrGLInterface> make_interface() {
67#if defined(SK_GLX)
69#else
70 return nullptr;
71#endif
72}
73
74sk_sp<const GrGLInterface> GLWindowContext_xlib::onInitializeContext() {
75 SkASSERT(fDisplay);
76 SkASSERT(!fGLContext);
78 bool current = false;
79
80 // We attempt to use glXCreateContextAttribsARB as RenderDoc requires that the context be
81 // created with this rather than glXCreateContext.
82 CreateContextAttribsFn* createContextAttribs = (CreateContextAttribsFn*)glXGetProcAddressARB(
83 (const GLubyte*)"glXCreateContextAttribsARB");
84 if (createContextAttribs && fFBConfig) {
85 // Install Xlib error handler that will set gCtxErrorOccurred
86 int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler);
87
88 // Specifying 3.2 allows an arbitrarily high context version (so long as no 3.2 features
89 // have been removed).
90 for (int minor = 2; minor >= 0 && !fGLContext; --minor) {
91 // Ganesh prefers a core profile which incidentally allows RenderDoc to work correctly.
92 for (int profile : {GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
93 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB}) {
94 gCtxErrorOccurred = false;
95 int attribs[] = {
96 GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, minor,
97 GLX_CONTEXT_PROFILE_MASK_ARB, profile,
98 0
99 };
100 fGLContext = createContextAttribs(fDisplay, *fFBConfig, nullptr, True, attribs);
101
102 // Sync to ensure any errors generated are processed.
103 XSync(fDisplay, False);
104 if (gCtxErrorOccurred) { continue; }
105
106 if (fGLContext && profile == GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
107 glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
108 current = true;
109 // Look to see if RenderDoc is attached. If so, re-create the context with a
110 // core profile.
111 interface = make_interface();
112 if (interface && interface->fExtensions.has("GL_EXT_debug_tool")) {
113 interface.reset();
114 glXMakeCurrent(fDisplay, None, nullptr);
115 glXDestroyContext(fDisplay, fGLContext);
116 current = false;
117 fGLContext = nullptr;
118 }
119 }
120 if (fGLContext) {
121 break;
122 }
123 }
124 }
125 // Restore the original error handler
126 XSetErrorHandler(oldHandler);
127 }
128 if (!fGLContext) {
129 fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE);
130 }
131 if (!fGLContext) {
132 return nullptr;
133 }
134
135 if (!current && !glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
136 return nullptr;
137 }
138
139 const char* glxExtensions = glXQueryExtensionsString(fDisplay, DefaultScreen(fDisplay));
140 if (glxExtensions) {
141 if (strstr(glxExtensions, "GLX_EXT_swap_control")) {
142 PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT =
143 (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB(
144 (const GLubyte*)"glXSwapIntervalEXT");
145 glXSwapIntervalEXT(fDisplay, fWindow, fDisplayParams.fDisableVsync ? 0 : 1);
146 }
147 }
148
149 glClearStencil(0);
150 glClearColor(0, 0, 0, 0);
151 glStencilMask(0xffffffff);
152 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
153
154 glXGetConfig(fDisplay, fVisualInfo, GLX_STENCIL_SIZE, &fStencilBits);
155 glXGetConfig(fDisplay, fVisualInfo, GLX_SAMPLES_ARB, &fSampleCount);
156 fSampleCount = std::max(fSampleCount, 1);
157
159 int x, y;
160 unsigned int border_width, depth;
161 XGetGeometry(fDisplay, fWindow, &root, &x, &y, (unsigned int*)&fWidth, (unsigned int*)&fHeight,
162 &border_width, &depth);
163 glViewport(0, 0, fWidth, fHeight);
164
165 return interface ? interface : make_interface();
166}
167
168GLWindowContext_xlib::~GLWindowContext_xlib() {
169 this->destroyContext();
170}
171
172void GLWindowContext_xlib::onDestroyContext() {
173 if (!fDisplay || !fGLContext) {
174 return;
175 }
176 glXMakeCurrent(fDisplay, None, nullptr);
177 glXDestroyContext(fDisplay, fGLContext);
178 fGLContext = nullptr;
179}
180
181void GLWindowContext_xlib::onSwapBuffers() {
182 if (fDisplay && fGLContext) {
183 glXSwapBuffers(fDisplay, fWindow);
184 }
185}
186
187} // anonymous namespace
188
189namespace skwindow {
190
191std::unique_ptr<WindowContext> MakeGLForXlib(const XlibWindowInfo& winInfo,
192 const DisplayParams& params) {
193 std::unique_ptr<WindowContext> ctx(new GLWindowContext_xlib(winInfo, params));
194 if (!ctx->isValid()) {
195 return nullptr;
196 }
197 return ctx;
198}
199
200} // namespace skwindow
#define SkASSERT(cond)
Definition: SkAssert.h:116
bool has(const char[]) const
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
virtual void onSwapBuffers()=0
virtual sk_sp< const GrGLInterface > onInitializeContext()=0
const EmbeddedViewParams * params
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Definition: dart.idl:411
double y
double x
SK_API sk_sp< const GrGLInterface > MakeGLX()
string root
Definition: scale_cpu.py:20
std::unique_ptr< WindowContext > MakeGLForXlib(const XlibWindowInfo &winInfo, const DisplayParams &params)
GrGLExtensions fExtensions
Definition: GrGLInterface.h:82