25static bool gCtxErrorOccurred =
false;
26static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
27 gCtxErrorOccurred =
true;
34 ~GLWindowContext_xlib()
override;
47 GLXFBConfig* fFBConfig;
48 XVisualInfo* fVisualInfo;
49 GLXContext fGLContext;
54 , fDisplay(winInfo.fDisplay)
55 , fWindow(winInfo.fWindow)
56 , fFBConfig(winInfo.fFBConfig)
57 , fVisualInfo(winInfo.fVisualInfo)
61 this->initializeContext();
64using CreateContextAttribsFn = GLXContext(Display*, GLXFBConfig, GLXContext, Bool,
const int*);
82 CreateContextAttribsFn* createContextAttribs = (CreateContextAttribsFn*)glXGetProcAddressARB(
83 (
const GLubyte*)
"glXCreateContextAttribsARB");
84 if (createContextAttribs && fFBConfig) {
86 int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler);
90 for (
int minor = 2; minor >= 0 && !fGLContext; --minor) {
92 for (
int profile : {GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
93 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB}) {
94 gCtxErrorOccurred =
false;
96 GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, minor,
97 GLX_CONTEXT_PROFILE_MASK_ARB,
profile,
100 fGLContext = createContextAttribs(fDisplay, *fFBConfig,
nullptr, True, attribs);
103 XSync(fDisplay,
False);
104 if (gCtxErrorOccurred) {
continue; }
106 if (fGLContext &&
profile == GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
107 glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
111 interface = make_interface();
112 if (interface && interface->
fExtensions.
has(
"GL_EXT_debug_tool")) {
114 glXMakeCurrent(fDisplay, None,
nullptr);
115 glXDestroyContext(fDisplay, fGLContext);
117 fGLContext =
nullptr;
126 XSetErrorHandler(oldHandler);
129 fGLContext = glXCreateContext(fDisplay, fVisualInfo,
nullptr, GL_TRUE);
135 if (!current && !glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
139 const char* glxExtensions = glXQueryExtensionsString(fDisplay, DefaultScreen(fDisplay));
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);
150 glClearColor(0, 0, 0, 0);
151 glStencilMask(0xffffffff);
152 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
154 glXGetConfig(fDisplay, fVisualInfo, GLX_STENCIL_SIZE, &fStencilBits);
155 glXGetConfig(fDisplay, fVisualInfo, GLX_SAMPLES_ARB, &fSampleCount);
156 fSampleCount =
std::max(fSampleCount, 1);
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);
165 return interface ? interface : make_interface();
168GLWindowContext_xlib::~GLWindowContext_xlib() {
169 this->destroyContext();
172void GLWindowContext_xlib::onDestroyContext() {
173 if (!fDisplay || !fGLContext) {
176 glXMakeCurrent(fDisplay, None,
nullptr);
177 glXDestroyContext(fDisplay, fGLContext);
178 fGLContext =
nullptr;
181void GLWindowContext_xlib::onSwapBuffers() {
182 if (fDisplay && fGLContext) {
183 glXSwapBuffers(fDisplay, fWindow);
193 std::unique_ptr<WindowContext> ctx(
new GLWindowContext_xlib(winInfo,
params));
194 if (!ctx->isValid()) {
bool has(const char[]) const
void reset(T *ptr=nullptr)
virtual void onSwapBuffers()=0
virtual sk_sp< const GrGLInterface > onInitializeContext()=0
virtual void onDestroyContext()=0
const EmbeddedViewParams * params
static float max(float r, float g, float b)
SK_API sk_sp< const GrGLInterface > MakeGLX()
std::unique_ptr< WindowContext > MakeGLForXlib(const XlibWindowInfo &winInfo, const DisplayParams ¶ms)
GrGLExtensions fExtensions