22static bool gCtxErrorOccurred =
false;
23static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
24 gCtxErrorOccurred =
true;
31 ~GLWindowContext_xlib()
override;
44 GLXFBConfig* fFBConfig;
45 XVisualInfo* fVisualInfo;
46 GLXContext fGLContext;
51 , fDisplay(winInfo.fDisplay)
52 , fWindow(winInfo.fWindow)
53 , fFBConfig(winInfo.fFBConfig)
54 , fVisualInfo(winInfo.fVisualInfo)
58 this->initializeContext();
61using CreateContextAttribsFn = GLXContext(Display*, GLXFBConfig, GLXContext, Bool,
const int*);
71 CreateContextAttribsFn* createContextAttribs = (CreateContextAttribsFn*)glXGetProcAddressARB(
72 (
const GLubyte*)
"glXCreateContextAttribsARB");
73 if (createContextAttribs && fFBConfig) {
75 int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler);
79 for (
int minor = 2; minor >= 0 && !fGLContext; --minor) {
81 for (
int profile : {GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
82 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB}) {
83 gCtxErrorOccurred =
false;
85 GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, minor,
86 GLX_CONTEXT_PROFILE_MASK_ARB,
profile,
89 fGLContext = createContextAttribs(fDisplay, *fFBConfig,
nullptr, True, attribs);
92 XSync(fDisplay, False);
93 if (gCtxErrorOccurred) {
continue; }
95 if (fGLContext && profile == GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB &&
96 glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
101 if (interface && interface->fExtensions.has(
"GL_EXT_debug_tool")) {
103 glXMakeCurrent(fDisplay, None,
nullptr);
104 glXDestroyContext(fDisplay, fGLContext);
106 fGLContext =
nullptr;
115 XSetErrorHandler(oldHandler);
118 fGLContext = glXCreateContext(fDisplay, fVisualInfo,
nullptr, GL_TRUE);
124 if (!current && !glXMakeCurrent(fDisplay, fWindow, fGLContext)) {
128 const char* glxExtensions = glXQueryExtensionsString(fDisplay, DefaultScreen(fDisplay));
130 if (strstr(glxExtensions,
"GLX_EXT_swap_control")) {
131 PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT =
132 (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB(
133 (
const GLubyte*)
"glXSwapIntervalEXT");
134 glXSwapIntervalEXT(fDisplay, fWindow, fDisplayParams.fDisableVsync ? 0 : 1);
139 glClearColor(0, 0, 0, 0);
140 glStencilMask(0xffffffff);
141 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
143 glXGetConfig(fDisplay, fVisualInfo, GLX_STENCIL_SIZE, &fStencilBits);
144 glXGetConfig(fDisplay, fVisualInfo, GLX_SAMPLES_ARB, &fSampleCount);
145 fSampleCount = std::max(fSampleCount, 1);
149 unsigned int border_width, depth;
150 XGetGeometry(fDisplay, fWindow, &root, &
x, &
y, (
unsigned int*)&fWidth, (
unsigned int*)&fHeight,
151 &border_width, &depth);
152 glViewport(0, 0, fWidth, fHeight);
157GLWindowContext_xlib::~GLWindowContext_xlib() {
158 this->destroyContext();
161void GLWindowContext_xlib::onDestroyContext() {
162 if (!fDisplay || !fGLContext) {
165 glXMakeCurrent(fDisplay, None,
nullptr);
166 glXDestroyContext(fDisplay, fGLContext);
167 fGLContext =
nullptr;
170void GLWindowContext_xlib::onSwapBuffers() {
171 if (fDisplay && fGLContext) {
172 glXSwapBuffers(fDisplay, fWindow);
180std::unique_ptr<WindowContext> MakeGLForXlib(
const XlibWindowInfo& winInfo,
182 std::unique_ptr<WindowContext> ctx(
new GLWindowContext_xlib(winInfo,
params));
183 if (!ctx->isValid()) {
Type::kYUV Type::kRGBA() int(0.7 *637)
void reset(T *ptr=nullptr)
virtual void onSwapBuffers()=0
virtual sk_sp< const GrGLInterface > onInitializeContext()=0
virtual void onDestroyContext()=0
const EmbeddedViewParams * params
SK_API sk_sp< const GrGLInterface > MakeGLX()