bool SkExampleWindow::setupBackend(DeviceType type) { fType = type; this->setConfig(SkBitmap::kARGB_8888_Config); this->setVisibleP(true); this->setClipToBounds(false); bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, &fAttachmentInfo); if (false == result) { SkDebugf("Not possible to create backend.\n"); detach(); return false; } fInterface = GrGLCreateNativeInterface(); SkASSERT(NULL != fInterface); fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface); SkASSERT(NULL != fContext); setupRenderTarget(); return true; }
const GrGLInterface* SkNativeSharedGLContext::createGLContext(const int width, const int height) { SkASSERT(NULL == fContext); // Create the base pixmap and GLX pixmap. // // TODO(pcwalton): This is inefficient. It would be better to have the caller pass in the // pixmap. int screen = DefaultScreen(fDisplay); Drawable root = RootWindow(fDisplay, screen); fPixmap = XCreatePixmap(fDisplay, root, width, height, fVisualInfo->depth); fGlxPixmap = glXCreateGLXPixmap(fDisplay, fVisualInfo, fPixmap); fContext = glXCreateContext(fDisplay, fVisualInfo, NULL, true); if (NULL == fContext) { SkDebugf("glXCreateContext failed with %d.", fContext); return NULL; } glXMakeCurrent(fDisplay, fGlxPixmap, fContext); const GrGLInterface* interface = GrGLCreateNativeInterface(); if (NULL == interface) { SkDebugf("Context could not create GL interface.\n"); this->destroyGLContext(); return NULL; } return interface; }
void SkV8ExampleWindow::windowSizeChanged() { if (FLAGS_gpu) { SkOSWindow::AttachmentInfo attachmentInfo; bool result = this->attach( SkOSWindow::kNativeGL_BackEndType, 0, false, &attachmentInfo); if (!result) { printf("Failed to attach."); exit(1); } fCurIntf = GrGLCreateNativeInterface(); fCurContext = GrContext::Create( kOpenGL_GrBackend, (GrBackendContext) fCurIntf); if (NULL == fCurIntf || NULL == fCurContext) { printf("Failed to initialize GL."); exit(1); } GrBackendRenderTargetDesc desc; desc.fWidth = SkScalarRoundToInt(this->width()); desc.fHeight = SkScalarRoundToInt(this->height()); desc.fConfig = kSkia8888_GrPixelConfig; desc.fOrigin = kBottomLeft_GrSurfaceOrigin; desc.fSampleCnt = attachmentInfo.fSampleCount; desc.fStencilBits = attachmentInfo.fStencilBits; GrGLint buffer; GR_GL_GetIntegerv(fCurIntf, GR_GL_FRAMEBUFFER_BINDING, &buffer); desc.fRenderTargetHandle = buffer; SkSafeUnref(fCurSurface); fCurSurface = SkSurface::MakeFromBackendRenderTarget(fCurContext, desc, nullptr, nullptr).release(); } }
const GrGLInterface* SkNativeGLContext::createGLContext() { HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); if (!gWC) { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hInstance = hInstance; wc.lpfnWndProc = (WNDPROC) DefWindowProc; wc.lpszClassName = TEXT("Griffin"); wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; gWC = RegisterClass(&wc); if (!gWC) { SkDebugf("Could not register window class.\n"); return NULL; } } if (!(fWindow = CreateWindow(TEXT("Griffin"), TEXT("The Invisible Man"), WS_OVERLAPPEDWINDOW, 0, 0, 1, 1, NULL, NULL, hInstance, NULL))) { SkDebugf("Could not create window.\n"); return NULL; } if (!(fDeviceContext = GetDC(fWindow))) { SkDebugf("Could not get device context.\n"); this->destroyGLContext(); return NULL; } // Requesting a Core profile would bar us from using NVPR. So we pass false. if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false))) { SkDebugf("Could not create rendering context.\n"); this->destroyGLContext(); return NULL; } if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); return NULL; } const GrGLInterface* interface = GrGLCreateNativeInterface(); if (NULL == interface) { SkDebugf("Could not create GL interface.\n"); this->destroyGLContext(); return NULL; } return interface; }
const GrGLInterface* SkNativeSharedGLContext::createGLContext() { SkASSERT(NULL == fContext); XVisualInfo *visinfo; int screen = DefaultScreen(fDisplay); GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, None }; visinfo = glXChooseVisual(fDisplay, screen, att); fContext = glXCreateContext(fDisplay, visinfo, fSharedContext, true); if (NULL == fContext) { SkDebugf("glXCreateContext failed with %d.", fContext); return NULL; } glXMakeCurrent(fDisplay, fGlxPixmap, fContext); const GrGLInterface* interface = GrGLCreateNativeInterface(); if (NULL == interface) { SkDebugf("Context could not create GL interface.\n"); this->destroyGLContext(); return NULL; } return interface; }
void VisualBench::resetContext() { fInterface.reset(GrGLCreateNativeInterface()); SkASSERT(fInterface); // setup contexts fContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface.get())); SkASSERT(fContext); // setup rendertargets this->setupRenderTarget(); }
Renderer(int width, int height) { canvas = NULL; context = NULL; renderTarget = NULL; //Initialize SkGraphics::Init(); const GrGLInterface* interface = GrGLCreateNativeInterface(); SkASSERT(NULL != interface); context = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)(interface)); SkASSERT(NULL != context); updateRenderTarget(width, height); // if (NULL != context && NULL != renderTarget) { // SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(context, renderTarget)); // canvas = new SkCanvas(device); // } }
void SkGLWidget::initializeGL() { fCurIntf = GrGLCreateNativeInterface(); if (!fCurIntf) { return; } glStencilMask(0xffffffff); glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); fCurContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf); GrBackendRenderTargetDesc desc = this->getDesc(this->width(), this->height()); desc.fOrigin = kBottomLeft_GrSurfaceOrigin; GrRenderTarget* curRenderTarget = fCurContext->wrapBackendRenderTarget(desc); fGpuDevice = SkGpuDevice::Create(curRenderTarget); fCanvas = new SkCanvas(fGpuDevice); curRenderTarget->unref(); }
const GrGLInterface* SkNativeGLContext::createGLContext() { fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLint majorVersion; EGLint minorVersion; eglInitialize(fDisplay, &majorVersion, &minorVersion); EGLint numConfigs; static const EGLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE }; EGLConfig surfaceConfig; eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); static const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs); static const EGLint surfaceAttribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs); eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); const GrGLInterface* interface = GrGLCreateNativeInterface(); if (!interface) { SkDebugf("Failed to create gl interface"); this->destroyGLContext(); return NULL; } return interface; }
void SkGLWidget::initializeGL() { if (!fCurIntf) { fCurIntf.reset(GrGLCreateNativeInterface()); } if (!fCurIntf) { return; } // The call may come multiple times, for example after setSampleCount(). The QGLContext will be // different, but we do not have a mechanism to catch the destroying of QGLContext, so that // proper resource cleanup could be made. if (fCurContext) { fCurContext->abandonContext(); } fGpuDevice.reset(NULL); fCanvas.reset(NULL); fCurContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf.get())); }
bool HelloWorldWindow::setUpBackend() { this->setVisibleP(true); this->setClipToBounds(false); bool result = attach(kNativeGL_BackEndType, 0 /*msaa*/, false, &fAttachmentInfo); if (false == result) { SkDebugf("Not possible to create backend.\n"); release(); return false; } fInterface = GrGLCreateNativeInterface(); SkASSERT(NULL != fInterface); fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInterface); SkASSERT(NULL != fContext); this->setUpGpuBackedSurface(); return true; }
const GrGLInterface* SkNativeGLContext::createGLContext() { GLint major, minor; AGLContext ctx; aglGetVersion(&major, &minor); //SkDebugf("---- agl version %d %d\n", major, minor); const GLint pixelAttrs[] = { AGL_RGBA, AGL_ACCELERATED, AGL_NONE }; AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs); if (NULL == format) { SkDebugf("Format could not be found.\n"); this->destroyGLContext(); return NULL; } fContext = aglCreateContext(format, NULL); if (NULL == fContext) { SkDebugf("Context could not be created.\n"); this->destroyGLContext(); return NULL; } aglDestroyPixelFormat(format); aglSetCurrentContext(fContext); const GrGLInterface* interface = GrGLCreateNativeInterface(); if (NULL == interface) { SkDebugf("Context could not create GL interface.\n"); this->destroyGLContext(); return NULL; } return interface; }
const GrGLInterface* GrGLDefaultInterface() { return GrGLCreateNativeInterface(); }
const GrGLInterface* SkNativeGLContext::createGLContext() { fDisplay = XOpenDisplay(0); if (!fDisplay) { SkDebugf("Failed to open X display.\n"); this->destroyGLContext(); return NULL; } // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, None }; #ifdef GLX_1_3 //SkDebugf("Getting matching framebuffer configs.\n"); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), visual_attribs, &fbcount); if (!fbc) { SkDebugf("Failed to retrieve a framebuffer config.\n"); this->destroyGLContext(); return NULL; } //SkDebugf("Found %d matching FB configs.\n", fbcount); // Pick the FB config/visual with the most samples per pixel //SkDebugf("Getting XVisualInfos.\n"); int best_fbc = -1, best_num_samp = -1; int i; for (i = 0; i < fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples); //SkDebugf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," // " SAMPLES = %d\n", // i, (unsigned int)vi->visualid, samp_buf, samples); if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) best_fbc = i, best_num_samp = samples; } XFree(vi); } GLXFBConfig bestFbc = fbc[best_fbc]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree(fbc); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); #else int numVisuals; XVisualInfo visTemplate, *visReturn; visReturn = XGetVisualInfo(fDisplay, VisualNoMask, &visTemplate, &numVisuals); if (NULL == visReturn) { SkDebugf("Failed to get visual information.\n"); this->destroyGLContext(); return NULL; } int best = -1, best_num_samp = -1; for (int i = 0; i < numVisuals; ++i) { int samp_buf, samples; glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetConfig(fDisplay, &visReturn[i], GLX_SAMPLES, &samples); if (best < 0 || (samp_buf && samples > best_num_samp)) best = i, best_num_samp = samples; } XVisualInfo temp = visReturn[best]; XVisualInfo *vi = &temp; XFree(visReturn); #endif fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); if (!fPixmap) { SkDebugf("Failed to create pixmap.\n"); this->destroyGLContext(); return NULL; } fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); #ifdef GLX_1_3 // Done with the visual info data XFree(vi); #endif // Create the context // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. // All display connections in all threads of a process use the same // error handler, so be sure to guard against other threads issuing // X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( fDisplay, DefaultScreen(fDisplay) ); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if (!gluCheckExtension( reinterpret_cast<const GLubyte*>("GLX_ARB_create_context") , reinterpret_cast<const GLubyte*>(glxExts))) { //SkDebugf("GLX_ARB_create_context not found." // " Using old-style GLX context.\n"); #ifdef GLX_1_3 fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); #else fContext = glXCreateContext(fDisplay, vi, 0, True); #endif } #ifdef GLX_1_3 else { //SkDebugf("Creating context.\n"); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB"); int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; fContext = glXCreateContextAttribsARB( fDisplay, bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. XSync(fDisplay, False); if (!ctxErrorOccurred && fContext) { //SkDebugf( "Created GL 3.0 context.\n" ); } else { // Couldn't create GL 3.0 context. // Fall back to old-style 2.x context. // When a context version below 3.0 is requested, // implementations will return the newest context version compatible // with OpenGL versions less than version 3.0. // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 context_attribs[1] = 1; // GLX_CONTEXT_MINOR_VERSION_ARB = 0 context_attribs[3] = 0; ctxErrorOccurred = false; //SkDebugf("Failed to create GL 3.0 context." // " Using old-style GLX context.\n"); fContext = glXCreateContextAttribsARB( fDisplay, bestFbc, 0, True, context_attribs ); } } #endif // Sync to ensure any errors generated are processed. XSync(fDisplay, False); // Restore the original error handler XSetErrorHandler(oldHandler); if (ctxErrorOccurred || !fContext) { SkDebugf("Failed to create an OpenGL context.\n"); this->destroyGLContext(); return NULL; } // Verify that context is a direct context if (!glXIsDirect(fDisplay, fContext)) { //SkDebugf("Indirect GLX rendering context obtained.\n"); } else { //SkDebugf("Direct GLX rendering context obtained.\n"); } //SkDebugf("Making context current.\n"); if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); return NULL; } const GrGLInterface* interface = GrGLCreateNativeInterface(); if (!interface) { SkDebugf("Failed to create gl interface"); this->destroyGLContext(); return NULL; } return interface; }
extern "C" SkiaGrGLInterfaceRef SkiaGrGLCreateNativeInterface() { return GrGLCreateNativeInterface(); }
sk_sp<const GrGLInterface> GlesDriver::getSkiaInterface() { sk_sp<const GrGLInterface> skiaInterface(GrGLCreateNativeInterface()); return skiaInterface; }
const GrGLInterface* SkNativeGLContext::createGLContext() { HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); if (!gWC) { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hInstance = hInstance; wc.lpfnWndProc = (WNDPROC) DefWindowProc; wc.lpszClassName = TEXT("Griffin"); wc.lpszMenuName = NULL; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; gWC = RegisterClass(&wc); if (!gWC) { SkDebugf("Could not register window class.\n"); return NULL; } } if (!(fWindow = CreateWindow(TEXT("Griffin"), TEXT("The Invisible Man"), WS_OVERLAPPEDWINDOW, 0, 0, 1, 1, NULL, NULL, hInstance, NULL))) { SkDebugf("Could not create window.\n"); return NULL; } if (!(fDeviceContext = GetDC(fWindow))) { SkDebugf("Could not get device context.\n"); this->destroyGLContext(); return NULL; } PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_SUPPORT_OPENGL; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 0; pfd.cStencilBits = 0; pfd.iLayerType = PFD_MAIN_PLANE; int pixelFormat = 0; if (!(pixelFormat = ChoosePixelFormat(fDeviceContext, &pfd))) { SkDebugf("No matching pixel format descriptor.\n"); this->destroyGLContext(); return NULL; } if (!SetPixelFormat(fDeviceContext, pixelFormat, &pfd)) { SkDebugf("Could not set the pixel format %d.\n", pixelFormat); this->destroyGLContext(); return NULL; } if (!(fGlRenderContext = wglCreateContext(fDeviceContext))) { SkDebugf("Could not create rendering context.\n"); this->destroyGLContext(); return NULL; } if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); return NULL; } const GrGLInterface* interface = GrGLCreateNativeInterface(); if (NULL == interface) { SkDebugf("Could not create GL interface.\n"); this->destroyGLContext(); return NULL; } return interface; }
const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) { fDisplay = XOpenDisplay(0); if (!fDisplay) { SkDebugf("Failed to open X display.\n"); this->destroyGLContext(); return NULL; } // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if (!glXQueryVersion(fDisplay, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) { SkDebugf("GLX version 1.3 or higher required.\n"); this->destroyGLContext(); return NULL; } //SkDebugf("Getting matching framebuffer configs.\n"); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), visual_attribs, &fbcount); if (!fbc) { SkDebugf("Failed to retrieve a framebuffer config.\n"); this->destroyGLContext(); return NULL; } //SkDebugf("Found %d matching FB configs.\n", fbcount); // Pick the FB config/visual with the most samples per pixel //SkDebugf("Getting XVisualInfos.\n"); int best_fbc = -1, best_num_samp = -1; int i; for (i = 0; i < fbcount; ++i) { XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, fbc[i]); if (vi) { int samp_buf, samples; glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); glXGetFBConfigAttrib(fDisplay, fbc[i], GLX_SAMPLES, &samples); //SkDebugf(" Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," // " SAMPLES = %d\n", // i, (unsigned int)vi->visualid, samp_buf, samples); if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) best_fbc = i, best_num_samp = samples; } XFree(vi); } GLXFBConfig bestFbc = fbc[best_fbc]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree(fbc); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig(fDisplay, bestFbc); //SkDebugf("Chosen visual ID = 0x%x\n", (unsigned int)vi->visualid); fPixmap = XCreatePixmap(fDisplay, RootWindow(fDisplay, vi->screen), 10, 10, vi->depth); if (!fPixmap) { SkDebugf("Failed to create pixmap.\n"); this->destroyGLContext(); return NULL; } fGlxPixmap = glXCreateGLXPixmap(fDisplay, vi, fPixmap); // Done with the visual info data XFree(vi); // Create the context // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. // All display connections in all threads of a process use the same // error handler, so be sure to guard against other threads issuing // X commands while this code is running. ctxErrorOccurred = false; int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( fDisplay, DefaultScreen(fDisplay) ); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"), reinterpret_cast<const GLubyte*>(glxExts))) { if (kGLES_GrGLStandard != forcedGpuAPI) { fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True); } } else { //SkDebugf("Creating context.\n"); PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB"); if (kGLES_GrGLStandard == forcedGpuAPI) { if (gluCheckExtension( reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"), reinterpret_cast<const GLubyte*>(glxExts))) { static const int context_attribs_gles[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, None }; fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gles); } } else { // Well, unfortunately GLX will not just give us the highest context so instead we have // to do this nastiness for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) { /* don't bother below GL 3.0 */ if (gl_versions[i].major == 3 && gl_versions[i].minor == 0) { break; } // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the // time being. // TODO when Nvidia implements NVPR on Core profiles, we should start requesting // core here static const int context_attribs_gl[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major, GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor, GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, None }; fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl); // Sync to ensure any errors generated are processed. XSync(fDisplay, False); if (!ctxErrorOccurred && fContext) { break; } // try again ctxErrorOccurred = false; } // Couldn't create GL 3.0 context. // Fall back to old-style 2.x context. // When a context version below 3.0 is requested, // implementations will return the newest context version // compatible with OpenGL versions less than version 3.0. if (ctxErrorOccurred || !fContext) { static const int context_attribs_gl_fallback[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 1, GLX_CONTEXT_MINOR_VERSION_ARB, 0, None }; ctxErrorOccurred = false; fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, 0, True, context_attribs_gl_fallback); } } } // Sync to ensure any errors generated are processed. XSync(fDisplay, False); // Restore the original error handler XSetErrorHandler(oldHandler); if (ctxErrorOccurred || !fContext) { SkDebugf("Failed to create an OpenGL context.\n"); this->destroyGLContext(); return NULL; } // Verify that context is a direct context if (!glXIsDirect(fDisplay, fContext)) { //SkDebugf("Indirect GLX rendering context obtained.\n"); } else { //SkDebugf("Direct GLX rendering context obtained.\n"); } //SkDebugf("Making context current.\n"); if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) { SkDebugf("Could not set the context.\n"); this->destroyGLContext(); return NULL; } const GrGLInterface* interface = GrGLCreateNativeInterface(); if (!interface) { SkDebugf("Failed to create gl interface"); this->destroyGLContext(); return NULL; } return interface; }