Display* fDisplay;
XWindow fWindow;
+ GLXFBConfig* fFBConfig;
XVisualInfo* fVisualInfo;
GLXContext fGLContext;
};
: GLWindowContext(params)
, fDisplay(winInfo.fDisplay)
, fWindow(winInfo.fWindow)
+ , fFBConfig(winInfo.fFBConfig)
, fVisualInfo(winInfo.fVisualInfo)
, fGLContext() {
fWidth = winInfo.fWidth;
this->initializeContext();
}
+using CreateContextAttribsFn = GLXContext(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+
void GLWindowContext_xlib::onInitializeContext() {
- // any config code here (particularly for msaa)?
SkASSERT(fDisplay);
- fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE);
+ SkASSERT(!fGLContext);
+ // We attempt to use glXCreateContextAttribsARB as RenderDoc requires that the context be
+ // created with this rather than glXCreateContext.
+ CreateContextAttribsFn* createContextAttribs = (CreateContextAttribsFn*)glXGetProcAddressARB(
+ (const GLubyte*)"glXCreateContextAttribsARB");
+ if (createContextAttribs && fFBConfig) {
+ // Specifying 3.2 allows an arbitrarily high context version (so long as no 3.2 features
+ // have been removed).
+ for (int minor = 2; minor >= 0 && !fGLContext; --minor) {
+ // Ganesh prefers a compatibility profile for possible NVPR support. However, RenderDoc
+ // requires a core profile. Edit this code to use RenderDoc.
+ for (int profile : {GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+ GLX_CONTEXT_CORE_PROFILE_BIT_ARB}) {
+ int attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, minor,
+ GLX_CONTEXT_PROFILE_MASK_ARB, profile,
+ 0
+ };
+ fGLContext = createContextAttribs(fDisplay, *fFBConfig, nullptr, True, attribs);
+ if (fGLContext) {
+ break;
+ }
+ }
+ }
+ }
+ if (!fGLContext) {
+ fGLContext = glXCreateContext(fDisplay, fVisualInfo, nullptr, GL_TRUE);
+ }
if (!fGLContext) {
return;
}
constexpr int initialHeight = 960;
// Attempt to create a window that supports GL
- GLint att[] = {
+
+ // We prefer the more recent glXChooseFBConfig but fall back to glXChooseVisual. They have
+ // slight differences in how attributes are specified.
+ static int constexpr kChooseFBConfigAtt[] = {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DOUBLEBUFFER, True,
+ GLX_STENCIL_SIZE, 8,
+ None
+ };
+ // For some reason glXChooseVisual takes a non-const pointer to the attributes.
+ int chooseVisualAtt[] = {
GLX_RGBA,
- GLX_DEPTH_SIZE, 24,
GLX_DOUBLEBUFFER,
GLX_STENCIL_SIZE, 8,
None
};
SkASSERT(nullptr == fVisualInfo);
if (fRequestedDisplayParams.fMSAASampleCount > 0) {
- static const GLint kAttCount = SK_ARRAY_COUNT(att);
- GLint msaaAtt[kAttCount + 4];
- memcpy(msaaAtt, att, sizeof(att));
- SkASSERT(None == msaaAtt[kAttCount - 1]);
- msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
- msaaAtt[kAttCount + 0] = 1;
- msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
- msaaAtt[kAttCount + 2] = fRequestedDisplayParams.fMSAASampleCount;
- msaaAtt[kAttCount + 3] = None;
- fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaAtt);
+ static const GLint kChooseFBConifgAttCnt = SK_ARRAY_COUNT(kChooseFBConfigAtt);
+ GLint msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 4];
+ memcpy(msaaChooseFBConfigAtt, kChooseFBConfigAtt, sizeof(kChooseFBConfigAtt));
+ SkASSERT(None == msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1]);
+ msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
+ msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 0] = 1;
+ msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 1] = GLX_SAMPLES_ARB;
+ msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 2] = fRequestedDisplayParams.fMSAASampleCount;
+ msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 3] = None;
+ int n;
+ fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), msaaChooseFBConfigAtt, &n);
+ if (n > 0) {
+ fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
+ } else {
+ static const GLint kChooseVisualAttCnt = SK_ARRAY_COUNT(chooseVisualAtt);
+ GLint msaaChooseVisualAtt[kChooseVisualAttCnt + 4];
+ memcpy(msaaChooseVisualAtt, chooseVisualAtt, sizeof(chooseVisualAtt));
+ SkASSERT(None == msaaChooseVisualAtt[kChooseVisualAttCnt - 1]);
+ msaaChooseFBConfigAtt[kChooseVisualAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
+ msaaChooseFBConfigAtt[kChooseVisualAttCnt + 0] = 1;
+ msaaChooseFBConfigAtt[kChooseVisualAttCnt + 1] = GLX_SAMPLES_ARB;
+ msaaChooseFBConfigAtt[kChooseVisualAttCnt + 2] =
+ fRequestedDisplayParams.fMSAASampleCount;
+ msaaChooseFBConfigAtt[kChooseVisualAttCnt + 3] = None;
+ fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaChooseVisualAtt);
+ fFBConfig = nullptr;
+ }
}
if (nullptr == fVisualInfo) {
- fVisualInfo = glXChooseVisual(display, DefaultScreen(display), att);
+ int n;
+ fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), kChooseFBConfigAtt, &n);
+ if (n > 0) {
+ fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
+ } else {
+ fVisualInfo = glXChooseVisual(display, DefaultScreen(display), chooseVisualAtt);
+ fFBConfig = nullptr;
+ }
}
if (fVisualInfo) {
gWindowMap.remove(fWindow);
XDestroyWindow(fDisplay, fWindow);
fWindow = 0;
- fVisualInfo = nullptr;
+ if (fFBConfig) {
+ XFree(fFBConfig);
+ fFBConfig = nullptr;
+ }
+ if (fVisualInfo) {
+ XFree(fVisualInfo);
+ fVisualInfo = nullptr;
+ }
fDisplay = nullptr;
}
}
window_context_factory::XlibWindowInfo winInfo;
winInfo.fDisplay = fDisplay;
winInfo.fWindow = fWindow;
+ winInfo.fFBConfig = fFBConfig;
winInfo.fVisualInfo = fVisualInfo;
XWindowAttributes attrs;