Use glXCreateContextAttribsARB in viewer to make it easier to attach RenderDoc.

Change-Id: I0cc82fe826b81a082b579f60af3d9ef35d5fe351
Reviewed-on: https://skia-review.googlesource.com/9407
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Salomon 2017-03-08 10:50:21 -05:00 committed by Skia Commit-Bot
parent 3012d187a4
commit 837fcb68ff
4 changed files with 90 additions and 16 deletions

View File

@ -34,6 +34,7 @@ private:
Display* fDisplay;
XWindow fWindow;
GLXFBConfig* fFBConfig;
XVisualInfo* fVisualInfo;
GLXContext fGLContext;
};
@ -42,6 +43,7 @@ GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const
: GLWindowContext(params)
, fDisplay(winInfo.fDisplay)
, fWindow(winInfo.fWindow)
, fFBConfig(winInfo.fFBConfig)
, fVisualInfo(winInfo.fVisualInfo)
, fGLContext() {
fWidth = winInfo.fWidth;
@ -49,10 +51,38 @@ GLWindowContext_xlib::GLWindowContext_xlib(const XlibWindowInfo& winInfo, const
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;
}

View File

@ -23,6 +23,7 @@ namespace window_context_factory {
struct XlibWindowInfo {
Display* fDisplay;
XWindow fWindow;
GLXFBConfig* fFBConfig;
XVisualInfo* fVisualInfo;
int fWidth;
int fHeight;

View File

@ -55,28 +55,61 @@ bool Window_unix::initWindow(Display* display) {
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) {
@ -139,7 +172,14 @@ void Window_unix::closeWindow() {
gWindowMap.remove(fWindow);
XDestroyWindow(fDisplay, fWindow);
fWindow = 0;
fVisualInfo = nullptr;
if (fFBConfig) {
XFree(fFBConfig);
fFBConfig = nullptr;
}
if (fVisualInfo) {
XFree(fVisualInfo);
fVisualInfo = nullptr;
}
fDisplay = nullptr;
}
}
@ -298,6 +338,7 @@ bool Window_unix::attach(BackendType attachType) {
window_context_factory::XlibWindowInfo winInfo;
winInfo.fDisplay = fDisplay;
winInfo.fWindow = fWindow;
winInfo.fFBConfig = fFBConfig;
winInfo.fVisualInfo = fVisualInfo;
XWindowAttributes attrs;

View File

@ -24,6 +24,7 @@ public:
, fDisplay(nullptr)
, fWindow(0)
, fGC(nullptr)
, fFBConfig(nullptr)
, fVisualInfo(nullptr)
, fMSAASampleCount(0) {}
~Window_unix() override { this->closeWindow(); }
@ -77,6 +78,7 @@ private:
Display* fDisplay;
XWindow fWindow;
GC fGC;
GLXFBConfig* fFBConfig;
XVisualInfo* fVisualInfo;
int fMSAASampleCount;