int main(int argc, char **argv) { int i; Pixmap pixmap; for(i = 1; i < argc; ++i) { if (!strcmp(argv[i], "-auto")) piglit_automatic = 1; else fprintf(stderr, "Unknown option: %s\n", argv[i]); } XInitThreads(); dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "couldn't open display\n"); piglit_report_result(PIGLIT_FAIL); } visinfo = piglit_get_glx_visual(dpy); draw_win = piglit_get_glx_window(dpy, visinfo); pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), piglit_width, piglit_height, visinfo->depth); load_win = glXCreateGLXPixmap(dpy, visinfo, pixmap); XMapWindow(dpy, draw_win); piglit_glx_event_loop(dpy, draw); return 0; }
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; }
std::unique_ptr<GLContextGLX> GLContextGLX::createPixmapContext(PlatformDisplay& platformDisplay, GLXContext sharingContext) { static int visualAttributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, 0 }; Display* display = downcast<PlatformDisplayX11>(platformDisplay).native(); XUniquePtr<XVisualInfo> visualInfo(glXChooseVisual(display, DefaultScreen(display), visualAttributes)); if (!visualInfo) return nullptr; XUniqueGLXContext context(glXCreateContext(display, visualInfo.get(), sharingContext, GL_TRUE)); if (!context) return nullptr; XUniquePixmap pixmap(XCreatePixmap(display, DefaultRootWindow(display), 1, 1, visualInfo->depth)); if (!pixmap) return nullptr; XUniqueGLXPixmap glxPixmap(glXCreateGLXPixmap(display, visualInfo.get(), pixmap.get())); if (!glxPixmap) return nullptr; return std::unique_ptr<GLContextGLX>(new GLContextGLX(platformDisplay, WTFMove(context), WTFMove(pixmap), WTFMove(glxPixmap))); }
int glx_1_2_pixmap_dummy(Display *dpy) { /* untested. based on http://glprogramming.com/blue/ch07.html */ XVisualInfo *vi; GLXContext cx; GLXPixmap glx_pixmap; Pixmap x11_pixmap; int dummyAttributes_1_2[] = { GLX_RGBA, None }; dpy = XOpenDisplay(0); vi = glXChooseVisual(dpy, DefaultScreen(dpy), dummyAttributes_1_2 ); dump_vinfo(vi); x11_pixmap = XCreatePixmap( dpy, DefaultRootWindow(dpy) , 10, 10, 32 ); glx_pixmap = glXCreateGLXPixmap( dpy, vi, x11_pixmap ); cx = glXCreateContext(dpy, vi, 0, GL_FALSE); glXMakeCurrent(dpy, glx_pixmap, cx); }
static GLXPixmap make_pixmap( Display *dpy, Window win, unsigned int width, unsigned int height, Pixmap *pixmap) { Pixmap pm; GLXPixmap glxpm; XWindowAttributes attr; pm = XCreatePixmap( dpy, win, width, height, visinfo->depth ); if (!pm) { printf("Error: XCreatePixmap failed\n"); exit(-1); } XGetWindowAttributes( dpy, win, &attr ); printf("pm %lx\n", pm); /* * IMPORTANT: * Use the glXCreateGLXPixmapMESA funtion when using Mesa because * Mesa needs to know the colormap associated with a pixmap in order * to render correctly. This is because Mesa allows RGB rendering * into any kind of visual, not just TrueColor or DirectColor. */ #ifdef GLX_MESA_pixmap_colormap if (strstr(glXQueryExtensionsString(dpy, 0), "GLX_MESA_pixmap_colormap")) { /* stand-alone Mesa, specify the colormap */ glxpm = glXCreateGLXPixmapMESA( dpy, visinfo, pm, attr.colormap ); } else { glxpm = glXCreateGLXPixmap( dpy, visinfo, pm ); } #else /* This will work with Mesa too if the visual is TrueColor or DirectColor */ glxpm = glXCreateGLXPixmap( dpy, visinfo, pm ); #endif if (!glxpm) { printf("Error: GLXCreateGLXPixmap failed\n"); exit(-1); } *pixmap = pm; return glxpm; }
static GF_Err X11_SetupGLPixmap(GF_VideoOutput *vout, u32 width, u32 height) { XWindow *xWin = (XWindow *)vout->opaque; if (xWin->glx_context) { glXMakeCurrent(xWin->display, None, NULL); glXDestroyContext(xWin->display, xWin->glx_context); xWin->glx_context = NULL; } if (xWin->gl_offscreen) glXDestroyGLXPixmap(xWin->display, xWin->gl_offscreen); xWin->gl_offscreen = 0; if (xWin->gl_pixmap) XFreePixmap(xWin->display, xWin->gl_pixmap); xWin->gl_pixmap = 0; if (xWin->offscreen_type) { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using offscreen GL context through XWindow\n")); if (xWin->offscreen_type==2) { XSync(xWin->display, False); XMapWindow (xWin->display, (Window) xWin->gl_wnd); XSync(xWin->display, False); // XSetWMNormalHints (xWin->display, xWin->gl_wnd, Hints); XStoreName (xWin->display, xWin->gl_wnd, "GPAC Offscreeen Window - debug mode"); } XSync(xWin->display, False); xWin->glx_context = glXCreateContext(xWin->display,xWin->glx_visualinfo, NULL, True); XSync(xWin->display, False); if (!xWin->glx_context) return GF_IO_ERR; if ( ! glXMakeCurrent(xWin->display, xWin->gl_wnd, xWin->glx_context) ) return GF_IO_ERR; XSync(xWin->display, False); } else { GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Using offscreen GL context through glXPixmap\n")); xWin->gl_pixmap = XCreatePixmap(xWin->display, xWin->gl_wnd, width, height, xWin->depth); if (!xWin->gl_pixmap) return GF_IO_ERR; xWin->gl_offscreen = glXCreateGLXPixmap(xWin->display, xWin->glx_visualinfo, xWin->gl_pixmap); if (!xWin->gl_offscreen) return GF_IO_ERR; XSync(xWin->display, False); xWin->glx_context = glXCreateContext(xWin->display, xWin->glx_visualinfo, 0, GL_FALSE); XSync(xWin->display, False); if (!xWin->glx_context) return GF_IO_ERR; XSync(xWin->display, False); GF_LOG(GF_LOG_WARNING, GF_LOG_MMIO, ("[X11] Activating GLContext on GLPixmap - this may crash !!\n")); glXMakeCurrent(xWin->display, xWin->gl_offscreen, xWin->glx_context); } GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[X11] Offscreen GL context setup\n")); return GF_OK; }
JNIEXPORT jint JNICALL GLX_NATIVE(glXCreateGLXPixmap) (JNIEnv *env, jclass that, jint arg0, jobject arg1, jint arg2) { XVisualInfo _arg1, *lparg1=NULL; jint rc = 0; GLX_NATIVE_ENTER(env, that, glXCreateGLXPixmap_FUNC); if (arg1) if ((lparg1 = getXVisualInfoFields(env, arg1, &_arg1)) == NULL) goto fail; rc = (jint)glXCreateGLXPixmap(arg0, lparg1, arg2); fail: if (arg1 && lparg1) setXVisualInfoFields(env, arg1, lparg1); GLX_NATIVE_EXIT(env, that, glXCreateGLXPixmap_FUNC); return rc; }
static SbBool glxglue_context_create_software(struct glxglue_contextdata * context) { /* Note that the value of the last argument (which indicates whether or not we're asking for a DRI-capable context) is "False" on purpose, as the man pages for glXCreateContext() says: [...] direct rendering contexts [...] may be unable to render to GLX pixmaps [...] Rendering to a GLX pixmap is of course exactly what we want to be able to do. */ Display * display = glxglue_get_display(NULL); context->glxcontext = glXCreateContext(display, context->visinfo, 0, False); if (context->glxcontext == NULL) { cc_debugerror_postwarning("glxglue_context_create_software", "Couldn't create GLX context."); return FALSE; } if (coin_glglue_debug()) { cc_debugerror_postinfo("glxglue_context_create_software", "made new offscreen context == %p", context->glxcontext); } context->pixmap = XCreatePixmap(display, DefaultRootWindow(display), context->width, context->height, context->visinfo->depth); if (context->pixmap == 0) { cc_debugerror_postwarning("glxglue_context_create_software", "Couldn't create %dx%dx%d X11 Pixmap.", context->width, context->height, context->visinfo->depth); return FALSE; } context->glxpixmap = glXCreateGLXPixmap(display, context->visinfo, context->pixmap); if (context->glxpixmap == 0) { cc_debugerror_postwarning("glxglue_context_create_software", "Couldn't create GLX Pixmap."); return FALSE; } return TRUE; }
int main(int argc, char **argv) { Pixmap p; GLXPixmap g; GLXContext ctx; dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "couldn't open display\n"); piglit_report_result(PIGLIT_FAIL); } piglit_glx_get_error(dpy, NULL); piglit_require_glx_version(dpy, 1, 3); visinfo = piglit_get_glx_visual(dpy); p = XCreatePixmap(dpy, DefaultRootWindow(dpy), piglit_width, piglit_height, visinfo->depth); g = glXCreateGLXPixmap(dpy, visinfo, p); ctx = piglit_get_glx_context(dpy, visinfo); glXMakeCurrent(dpy, g, ctx); piglit_dispatch_default_init(PIGLIT_DISPATCH_GL); /* Clear to green */ glClearColor(0.0, 1.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* Noop */ XSetErrorHandler(handler); glXSwapBuffers(dpy, p); /* We want to actually catch any X error that leaks through as * a result of glXSwapBuffers() before we go saying "pass" or * "fail". */ XSync(dpy, False); glXDestroyPixmap(dpy, g); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); return 0; }
SkNativeSharedGLContext::SkNativeSharedGLContext(GrGLSharedContext sharedContext, void *extra) : fContext(NULL) , fGrContext(NULL) , fGL(NULL) , fSharedContext(sharedContext) , fFBO(0) , fTextureID(0) , fDepthStencilBufferID(0) { fDisplay = (Display *)extra; SkASSERT(NULL != fDisplay); int screen = DefaultScreen(fDisplay); GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, None }; XVisualInfo *visinfo = glXChooseVisual(fDisplay, screen, att); Drawable root = RootWindow(fDisplay, screen); fPixmap = XCreatePixmap(fDisplay, root, 10, 10, visinfo->depth); fGlxPixmap = glXCreateGLXPixmap(fDisplay, visinfo, fPixmap); }
GraphicsContext3DPrivate* GraphicsContext3DPrivate::createPixmapContext() { static int visualAttributes[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, GLX_DOUBLEBUFFER, 0 }; XVisualInfo* visualInfo = glXChooseVisual(sharedDisplay(), DefaultScreen(sharedDisplay()), visualAttributes); if (!visualInfo) return 0; GLXContext context = glXCreateContext(sharedDisplay(), visualInfo, 0, GL_TRUE); if (!context) { XFree(visualInfo); return 0; } Pixmap pixmap = XCreatePixmap(sharedDisplay(), DefaultRootWindow(sharedDisplay()), 1, 1, visualInfo->depth); if (!pixmap) { XFree(visualInfo); return 0; } GLXPixmap glxPixmap = glXCreateGLXPixmap(sharedDisplay(), visualInfo, pixmap); if (!glxPixmap) { XFreePixmap(sharedDisplay(), pixmap); XFree(visualInfo); return 0; } return new GraphicsContext3DPrivate(context, pixmap, glxPixmap); }
int glx_1_3_pixmap_dummy(Display *dpy, Bool hybrid) { XVisualInfo *vInfo; GLXFBConfig *fbConfigs; GLXContext context; GLXPixmap glx_pixmap; Pixmap x11_pixmap; int numReturned; int result; int dummyAttributes_1_3[] = { GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, None }; fbConfigs = glXChooseFBConfig( dpy, DefaultScreen(dpy), dummyAttributes_1_3, &numReturned ); vInfo = glXGetVisualFromFBConfig( dpy, fbConfigs[0] ); dump_vinfo(vInfo); x11_pixmap = XCreatePixmap( dpy, DefaultRootWindow(dpy) , 10, 10, 8 ); if (hybrid) glx_pixmap = glXCreateGLXPixmap( dpy, vInfo, x11_pixmap ); //GLX 1.2 else glx_pixmap = glXCreatePixmap( dpy, fbConfigs[0], x11_pixmap, NULL ); // GLX 1.3 context = glXCreateNewContext( dpy, fbConfigs[0], GLX_RGBA_TYPE, NULL, True ); glXMakeContextCurrent( dpy, glx_pixmap, glx_pixmap, context ); return 1; }
bool P3DGLMemoryContextPixmap::Create (unsigned int Width, unsigned int Height, bool NeedAlpha) { bool Result; XVisualInfo *VisualInfo; Result = true; if (Connection == NULL) { OwnConnection = true; Connection = XOpenDisplay(NULL); if (Connection == NULL) { return(false); } } else { OwnConnection = false; } Result = true; if (NeedAlpha) { VisualInfo = glXChooseVisual(Connection, DefaultScreen(Connection), VisualAttrArrayAlpha); } else { VisualInfo = glXChooseVisual(Connection, DefaultScreen(Connection), VisualAttrArray); } if (VisualInfo != NULL) { TargetPixmap = XCreatePixmap(Connection, DefaultRootWindow(Connection), Width, Height, VisualInfo->depth); TargetGLXPixmap = glXCreateGLXPixmap(Connection,VisualInfo,TargetPixmap); /*FIXME: check for errors here */ OffScreenGLXContext = glXCreateContext(Connection,VisualInfo,NULL,False); if (OffScreenGLXContext != NULL) { Ok = true; Result = MakeCurrent(); if (Result) { Result = P3DGLExtInit(); } Ok = Result; } else { Result = false; } if (!Result) { glXDestroyGLXPixmap(Connection,TargetGLXPixmap); XFreePixmap(Connection,TargetPixmap); } XFree(VisualInfo); } else { Result = false; } if (!Result) { if (OwnConnection) { XCloseDisplay(Connection); } Connection = NULL; } Ok = Result; return(Result); }
// VLC wants to display a video frame. static void vlcdisplay(void *data, void *id) { struct context *c = (struct context*)data; unsigned int *videoTexture = c->videoTexture; bool isStereo = c->isStereo; //std::cerr << "**** display: " << videoTexture[0] << std::endl; //setup GL context by OS #if __APPLE__ static bool init2 = false; if(!init2) { init2 = true; setupVideoGLContext(c->data); } #else #ifdef WIN32 makeCurrentGL = (void(*)())c->data; makeCurrentGL(); #else // Create the pixmap, where one designs the scene static Pixmap pix = XCreatePixmap(c->dpy, c->root, VIDEOWIDTH, VIDEOHEIGHT, vi->depth); static GLXPixmap px = glXCreateGLXPixmap(c->dpy, vi, pix); static GLXContext ctx = glXCreateContext(c->dpy, vi, context, GL_TRUE); static bool r = glXMakeCurrent(c->dpy, px, ctx); if(!r) { std::cerr << "* failed to create GL for video" << std::endl; } #endif #endif static bool init = false; if(!init) { init = true; c->player->createVideoTextures(c->isStereo, VIDEOWIDTH, VIDEOHEIGHT); c->player->width = VIDEOWIDTH; c->player->height = VIDEOHEIGHT; unsigned int width,height; if(libvlc_video_get_size(c->mp, 0, &width, & height) == 0) { c->player->width = width; c->player->height = height; std::cerr << "***************** " << VIDEOWIDTH << "x" << VIDEOHEIGHT << " ==> " << width << "x" << height << std::endl; } isStereo = false; } const GLuint width = VIDEOWIDTH; const GLuint height = VIDEOHEIGHT; bool first = true; if(isStereo) { glBindTexture(GL_TEXTURE_2D, videoTexture[1]); int stride = width*2; glPixelStorei(GL_UNPACK_ROW_LENGTH,stride); if(first) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height/2, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); glBindTexture(GL_TEXTURE_2D, videoTexture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height/2, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels+(width*3)); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height/2, GL_RGB, GL_UNSIGNED_BYTE, pixels); glBindTexture(GL_TEXTURE_2D, videoTexture[0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height/2, GL_RGB, GL_UNSIGNED_BYTE, pixels+(width*3)); } } else { glBindTexture(GL_TEXTURE_2D, videoTexture[0]); if(first) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, pixels); } } glFlush(); //struct context *c = (context *)data; // WIDTH/HEIGHT VIDEOWIDTH/VIDEOHEIGHT }
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; }
bool QGLContext::chooseContext( const QGLContext* shareContext ) { Display* disp = d->paintDevice->x11Display(); vi = chooseVisual(); if ( !vi ) return FALSE; if ( deviceIsPixmap() && (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() || ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) ) { XFree( vi ); XVisualInfo appVisInfo; memset( &appVisInfo, 0, sizeof(XVisualInfo) ); appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() ); appVisInfo.screen = d->paintDevice->x11Screen(); int nvis; vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis ); if ( !vi ) return FALSE; int useGL; glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL ); if ( !useGL ) return FALSE; //# Chickening out already... } int res; glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res ); glFormat.setPlane( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res ); glFormat.setDoubleBuffer( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res ); glFormat.setDepth( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res ); glFormat.setRgba( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res ); glFormat.setAlpha( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res ); glFormat.setAccum( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res ); glFormat.setStencil( res ); glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res ); glFormat.setStereo( res ); Bool direct = format().directRendering() ? True : False; if ( shareContext && ( !shareContext->isValid() || !shareContext->cx ) ) { #if defined(QT_CHECK_NULL) qWarning("QGLContext::chooseContext(): Cannot share with invalid context"); #endif shareContext = 0; } // 1. Sharing between rgba and color-index will give wrong colors. // 2. Contexts cannot be shared btw. direct/non-direct renderers. // 3. Pixmaps cannot share contexts that are set up for direct rendering. if ( shareContext && (format().rgba() != shareContext->format().rgba() || (deviceIsPixmap() && glXIsDirect( disp, (GLXContext)shareContext->cx )))) shareContext = 0; cx = 0; if ( shareContext ) { cx = glXCreateContext( disp, (XVisualInfo *)vi, (GLXContext)shareContext->cx, direct ); if ( cx ) d->sharing = TRUE; } if ( !cx ) cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct ); if ( !cx ) return FALSE; glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) ); if ( deviceIsPixmap() ) { #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT) gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi, d->paintDevice->handle(), choose_cmap( disp, (XVisualInfo *)vi ) ); #else gpm = (Q_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi, d->paintDevice->handle() ); #endif if ( !gpm ) return FALSE; } return TRUE; }
bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); const QX11Info *xinfo = qt_x11Info(d->paintDevice); Display* disp = xinfo->display(); d->vi = chooseVisual(); if (!d->vi) return false; if (deviceIsPixmap() && (((XVisualInfo*)d->vi)->depth != xinfo->depth() || ((XVisualInfo*)d->vi)->screen != xinfo->screen())) { XFree(d->vi); XVisualInfo appVisInfo; memset(&appVisInfo, 0, sizeof(XVisualInfo)); appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual()); appVisInfo.screen = xinfo->screen(); int nvis; d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis); if (!d->vi) return false; int useGL; glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL); if (!useGL) return false; //# Chickening out already... } int res; glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res); d->glFormat.setPlane(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res); d->glFormat.setDoubleBuffer(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res); d->glFormat.setDepth(res); if (d->glFormat.depth()) d->glFormat.setDepthBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res); d->glFormat.setRgba(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res); d->glFormat.setRedBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res); d->glFormat.setGreenBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res); d->glFormat.setBlueBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res); d->glFormat.setAlpha(res); if (d->glFormat.alpha()) d->glFormat.setAlphaBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res); d->glFormat.setAccum(res); if (d->glFormat.accum()) d->glFormat.setAccumBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res); d->glFormat.setStencil(res); if (d->glFormat.stencil()) d->glFormat.setStencilBufferSize(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res); d->glFormat.setStereo(res); glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res); d->glFormat.setSampleBuffers(res); if (d->glFormat.sampleBuffers()) { glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res); d->glFormat.setSamples(res); } Bool direct = format().directRendering() ? True : False; if (shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) { qWarning("QGLContext::chooseContext(): Cannot share with invalid context"); shareContext = 0; } // 1. Sharing between rgba and color-index will give wrong colors. // 2. Contexts cannot be shared btw. direct/non-direct renderers. // 3. Pixmaps cannot share contexts that are set up for direct rendering. // 4. If the contexts are not created on the same screen, they can't be shared if (shareContext && (format().rgba() != shareContext->format().rgba() || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx)) || (shareContext->d_func()->screen != xinfo->screen()))) { shareContext = 0; } d->cx = 0; if (shareContext) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, (GLXContext)shareContext->d_func()->cx, direct); d->screen = ((XVisualInfo*)d->vi)->screen; if (d->cx) { QGLContext *share = const_cast<QGLContext *>(shareContext); d->sharing = true; share->d_func()->sharing = true; } } if (!d->cx) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); d->screen = ((XVisualInfo*)d->vi)->screen; } if (!d->cx) return false; d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx)); if (deviceIsPixmap()) { #if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT) d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi, qt_x11Handle(d->paintDevice), qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi)); #else d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi, qt_x11Handle(d->paintDevice)); #endif if (!d->gpm) return false; } QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS))); if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { if (d->glFormat.swapInterval() == -1) d->glFormat.setSwapInterval(0); } else { d->glFormat.setSwapInterval(-1); } return true; }
// VLC wants to display a video frame. static void vlcdisplay(void *data, void *id) { try { struct context *c = (struct context*)data; unsigned int *videoTexture = c->videoTexture; bool isStereo = c->isStereo; //std::cerr << "**** display: " << videoTexture[0] << std::endl; //setup GL context by OS #if __APPLE__ // TODO: probably delete this, confirm no static init and only run-once init needed before getting rid of //static bool init2 = false; //if(!init2) { // init2 = true; // setupVideoGLContext(c->data); //} #else #ifdef WIN32 makeCurrentGL = (void(*)())c->data; makeCurrentGL(); #else // TODO: GET RID OF THIS STATIC STUFF! MOVE INTO INIT FUNCTION OR SOMETHING // Create the pixmap, where one designs the scene static Pixmap pix = XCreatePixmap(c->dpy, c->root, VIDEOWIDTH, VIDEOHEIGHT, vi->depth); static GLXPixmap px = glXCreateGLXPixmap(c->dpy, vi, pix); static GLXContext ctx = glXCreateContext(c->dpy, vi, context, GL_TRUE); static bool r = glXMakeCurrent(c->dpy, px, ctx); if(!r) { std::cerr << "* failed to create GL for video" << std::endl; } #endif #endif if(!c->init) { c->init = true; #if __APPLE__ setupVideoGLContext(c->data); #endif c->player->createVideoTextures(c->isStereo, VIDEOWIDTH, VIDEOHEIGHT); c->player->width = VIDEOWIDTH; c->player->height = VIDEOHEIGHT; unsigned int width,height; if(libvlc_video_get_size(c->mp, 0, &width, & height) == 0) { // first = true; c->player->width = width; c->player->height = height; std::cerr << "***************** " << VIDEOWIDTH << "x" << VIDEOHEIGHT << " ==> " << width << "x" << height << std::endl; // if(VIDEOWIDTH != width && VIDEOHEIGHT != height) { // VIDEOWIDTH = width; // VIDEOHEIGHT = height; // libvlc_video_set_format(c->mp, "RV32", VIDEOWIDTH, VIDEOHEIGHT, VIDEOWIDTH*sizeof(uint32_t)); // return; // } } } const GLuint width = VIDEOWIDTH; const GLuint height = VIDEOHEIGHT; // const GLuint width = c->player->width; // const GLuint height = c->player->height; if(isStereo) { glBindTexture(GL_TEXTURE_2D, videoTexture[1]); // std::cerr << width << " " << stride << std::endl; glPixelStorei(GL_UNPACK_ROW_LENGTH,width*2); glPixelStorei(GL_UNPACK_ALIGNMENT,1); if(first) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height/2, 0, GL_BGRA, IBEX_VIDEO_GL_PIX_FORMAT, pixels); glBindTexture(GL_TEXTURE_2D, videoTexture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height/2, 0, GL_BGRA, IBEX_VIDEO_GL_PIX_FORMAT, &pixels[width]); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height/2, GL_BGRA, IBEX_VIDEO_GL_PIX_FORMAT, pixels); glBindTexture(GL_TEXTURE_2D, videoTexture[0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height/2, GL_BGRA, IBEX_VIDEO_GL_PIX_FORMAT , &pixels[width]); } } else { glBindTexture(GL_TEXTURE_2D, videoTexture[0]); glPixelStorei(GL_UNPACK_ROW_LENGTH,width); glPixelStorei(GL_UNPACK_ALIGNMENT,1); if(first) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, IBEX_VIDEO_GL_PIX_FORMAT, pixels); } else { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, IBEX_VIDEO_GL_PIX_FORMAT, pixels); } } first = false; glFlush(); //struct context *c = (context *)data; // WIDTH/HEIGHT VIDEOWIDTH/VIDEOHEIGHT }catch(...) { } }
Bool asimage2drawable_gl( ASVisual *asv, Drawable d, ASImage *im, int src_x, int src_y, int dest_x, int dest_y, int width, int height, int d_width, int d_height, Bool force_direct ) { if( im != NULL && get_flags( asv->glx_support, ASGLX_Available ) && d != None ) { #ifdef HAVE_GLX int glbuf_size = (get_flags( asv->glx_support, ASGLX_RGBA )? 4 : 3 ) * width * height; CARD8 *glbuf = NULL; ASImageDecoder *imdec = NULL ; GLXPixmap glxp = None; if ((imdec = start_image_decoding( asv, im, get_flags( asv->glx_support, ASGLX_RGBA )?SCL_DO_ALL:SCL_DO_COLOR, src_x, src_y, width, height, NULL)) != NULL ) { int i, l = glbuf_size; glbuf = safemalloc( glbuf_size ); for (i = 0; i < (int)height; i++) { int k = width; imdec->decode_image_scanline( imdec ); if( get_flags( asv->glx_support, ASGLX_RGBA ) ) { while( --k >= 0 ) { glbuf[--l] = imdec->buffer.alpha[k] ; glbuf[--l] = imdec->buffer.blue[k] ; glbuf[--l] = imdec->buffer.green[k] ; glbuf[--l] = imdec->buffer.red[k] ; } }else { while( --k >= 0 ) { glbuf[--l] = imdec->buffer.blue[k] ; glbuf[--l] = imdec->buffer.green[k] ; glbuf[--l] = imdec->buffer.red[k] ; } } } stop_image_decoding( &imdec ); }else return False; if( !force_direct ) { glxp = glXCreateGLXPixmap( asv->dpy, &(asv->visual_info), d); /* d is either invalid drawable or is a window */ if( glxp == None ) force_direct = True ; } if( glxp == None ) { if( asv->glx_scratch_gc_direct != NULL ) glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_direct); else glXMakeCurrent (asv->dpy, d, asv->glx_scratch_gc_indirect); }else glXMakeCurrent (asv->dpy, glxp, asv->glx_scratch_gc_indirect); if( glGetError() != 0 ) return False; if ( get_flags( asv->glx_support, ASGLX_DoubleBuffer ) ) glDrawBuffer (GL_FRONT); glDisable(GL_BLEND); /* optimize pixel transfer rates */ glDisable (GL_DEPTH_TEST); glDisable (GL_DITHER); glDisable (GL_FOG); glDisable (GL_LIGHTING); glViewport( 0, 0, d_width, d_height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); /* gluOrtho2D (0, d_width, 0, d_height); */ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glTranslatef (0.375, 0.375, 0.0); #if 1 if( !IS_POWER_OF2(width) || !IS_POWER_OF2(height)) { /* now put pixels on */ glRasterPos2i( dest_x, d_height - (dest_y+height) ); glDrawPixels( width, height, get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, glbuf ); }else #endif { /* this stuff might be faster : */ GLuint texture ; #define TARGET_TEXTURE_ID GL_TEXTURE_2D #if TARGET_TEXTURE_ID!=GL_TEXTURE_2D glEnable(GL_TEXTURE_2D); #endif glEnable(TARGET_TEXTURE_ID); glGenTextures(1, &texture); glBindTexture(TARGET_TEXTURE_ID, texture); glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(TARGET_TEXTURE_ID, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(TARGET_TEXTURE_ID, 0, get_flags( asv->glx_support, ASGLX_RGBA )?GL_RGBA:GL_RGB, /* width and height must be the power of 2 !!! */ width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, glbuf); glBegin(GL_QUADS); /* bottom-left */ glTexCoord2d(0., 0.); glVertex2i(dest_x, d_height - (dest_y+height) ); /* bottom-right */ glTexCoord2d(1.0, 0.0); glVertex2i(dest_x+width, d_height - (dest_y+height)); /* top-right */ glTexCoord2d(1.0, 1.0); glVertex2i(dest_x+width, d_height - dest_y); /* top-left */ glTexCoord2d(0.0, 1.0); glVertex2i(dest_x, d_height - dest_y); glEnd(); glBindTexture(TARGET_TEXTURE_ID, 0); glFinish(); } free( glbuf ); glXMakeCurrent (asv->dpy, None, NULL); if( glxp ) glXDestroyGLXPixmap( asv->dpy, glxp); glFinish(); return True; #endif /* #ifdef HAVE_GLX */ } { static Bool warning_shown = False ; if( !warning_shown ) { warning_shown = True ; show_warning( "Support for GLX is unavailable."); } } return False; }
int main(int argc, char **argv) { Pixmap p; GLXPixmap g; static const float green_alpha_zero[4] = {0.0, 1.0, 0.0, 0.0}; static const float green_alpha_one[4] = {0.0, 1.0, 0.0, 1.0}; GLXContext ctx; bool pass; GLint alpha_bits; dpy = XOpenDisplay(NULL); if (dpy == NULL) { fprintf(stderr, "couldn't open display\n"); piglit_report_result(PIGLIT_FAIL); } piglit_glx_get_error(dpy, NULL); piglit_require_glx_version(dpy, 1, 3); visinfo = piglit_get_glx_visual(dpy); p = XCreatePixmap(dpy, DefaultRootWindow(dpy), piglit_width, piglit_height, visinfo->depth); g = glXCreateGLXPixmap(dpy, visinfo, p); ctx = piglit_get_glx_context(dpy, visinfo); glXMakeCurrent(dpy, g, ctx); piglit_dispatch_default_init(PIGLIT_DISPATCH_GL); /* Clear to green */ glClearColor(0.0, 1.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* Noop */ glXSwapBuffers(dpy, g); /* We want to actually catch any X error that leaks through as * a result of glXSwapBuffers() before we go saying "pass" or * "fail". */ XSync(dpy, False); /* If the visual has no alpha, then the GL spec requires that 1.0 be * read back. Otherwise, we should read back the 0.0 that we wrote. */ glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); if (alpha_bits == 0) { pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green_alpha_one); } else { pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green_alpha_zero); } glXDestroyPixmap(dpy, g); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); return 0; }
Bool bindPixmapToTexture (CompScreen *screen, CompTexture *texture, Pixmap pixmap, int width, int height, int depth) { XVisualInfo *visinfo; unsigned int target; int success = 0; visinfo = screen->glxPixmapVisuals[depth]; if (!visinfo) { fprintf (stderr, "%s: No GL visual for depth %d\n", programName, depth); return FALSE; } texture->pixmap = glXCreateGLXPixmap (screen->display->display, visinfo, pixmap); if (!texture->pixmap) { fprintf (stderr, "%s: glXCreateGLXPixmap failed\n", programName); return FALSE; } if (screen->queryDrawable (screen->display->display, texture->pixmap, GLX_TEXTURE_TARGET_EXT, &target)) { fprintf (stderr, "%s: glXQueryDrawable failed\n", programName); glXDestroyGLXPixmap (screen->display->display, texture->pixmap); texture->pixmap = None; return FALSE; } switch (target) { case GLX_TEXTURE_2D_EXT: texture->target = GL_TEXTURE_2D; texture->matrix.xx = 1.0f / width; texture->matrix.yy = -1.0f / height; texture->matrix.y0 = 1.0f; break; case GLX_TEXTURE_RECTANGLE_EXT: texture->target = GL_TEXTURE_RECTANGLE_ARB; texture->matrix.xx = 1.0f; texture->matrix.yy = -1.0f; texture->matrix.y0 = height; break; default: fprintf (stderr, "%s: pixmap 0x%x can't be bound to texture\n", programName, (int) pixmap); glXDestroyGLXPixmap (screen->display->display, texture->pixmap); texture->pixmap = None; return FALSE; } if (!texture->name) glGenTextures (1, &texture->name); glBindTexture (texture->target, texture->name); if (screen->bindTexImageExt) success = screen->bindTexImageExt(screen->display->display, texture->pixmap, GLX_FRONT_LEFT_EXT, NULL); else if (screen->bindTexImageMesa) success = screen->bindTexImageMesa(screen->display->display, texture->pixmap, GLX_FRONT_LEFT_EXT); if (!success) { fprintf (stderr, "%s: glXBindTexImage failed\n", programName); glXDestroyGLXPixmap (screen->display->display, texture->pixmap); texture->pixmap = None; return FALSE; } texture->filter = COMP_TEXTURE_FILTER_FAST; glTexParameteri (texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture (texture->target, 0); return TRUE; }
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; }
Handle gl_context_create( Handle widget, GLRequest * request) { int attr_list[64], *attr = attr_list; XVisualInfo * visual; GLXContext context; Context * ret; if ( pguts == NULL ) pguts = (UnixGuts*) apc_system_action("unix_guts"); CLEAR_ERROR; XCHECKPOINT; #define ATTR(in,out) \ if ( request-> in) { \ *(attr++) = out; \ *(attr++) = request-> in; \ } *(attr++) = GLX_USE_GL; if ( request-> pixels == GLREQ_PIXEL_RGBA) *(attr++) = GLX_RGBA; if ( request-> double_buffer == GLREQ_TRUE) *(attr++) = GLX_DOUBLEBUFFER; if ( request-> stereo == GLREQ_TRUE) *(attr++) = GLX_STEREO; ATTR( layer , GLX_LEVEL ) ATTR( color_bits , GLX_BUFFER_SIZE ) ATTR( aux_buffers , GLX_AUX_BUFFERS ) ATTR( red_bits , GLX_RED_SIZE ) ATTR( green_bits , GLX_GREEN_SIZE ) ATTR( blue_bits , GLX_BLUE_SIZE ) ATTR( alpha_bits , GLX_ALPHA_SIZE ) ATTR( depth_bits , GLX_DEPTH_SIZE ) ATTR( stencil_bits , GLX_STENCIL_SIZE ) ATTR( accum_red_bits , GLX_ACCUM_RED_SIZE ) ATTR( accum_green_bits, GLX_ACCUM_GREEN_SIZE ) ATTR( accum_blue_bits , GLX_ACCUM_BLUE_SIZE ) ATTR( accum_alpha_bits, GLX_ACCUM_ALPHA_SIZE ) *(attr++) = 0; if ( request-> target == GLREQ_TARGET_WINDOW && sys-> flags. layered) { visual = sys-> visual; } else if ( !( visual = glXChooseVisual( DISP, SCREEN, attr_list ))) { if ( request-> pixels != GLREQ_PIXEL_RGBA) { /* emulate win32 which does it softly, i.e. if RGBA fails, it proposes PALETTED */ request-> pixels = GLREQ_PIXEL_RGBA; return gl_context_create( widget, request); } if ( request-> double_buffer == GLREQ_DONTCARE) { request-> double_buffer = GLREQ_TRUE; return gl_context_create( widget, request ); } SET_ERROR( ERROR_CHOOSE_VISUAL ); return (Handle) 0; } XCHECKPOINT; if ( !( context = glXCreateContext( DISP, visual, 0, request-> render != GLREQ_RENDER_XSERVER))) { SET_ERROR( ERROR_CREATE_CONTEXT ); return (Handle) 0; } ret = malloc( sizeof( Context )); memset( ret, 0, sizeof( Context)); ret-> context = context; switch ( request-> target) { case GLREQ_TARGET_WINDOW: ret-> drawable = var-> handle; break; case GLREQ_TARGET_APPLICATION: /* doesn't work with gnome and kde anyway */ ret-> drawable = RootWindow( DISP, SCREEN); break; case GLREQ_TARGET_BITMAP: case GLREQ_TARGET_IMAGE: { GLXContext old_context; GLXDrawable old_drawable; Bool success; XCHECKPOINT; ret-> drawable = glXCreateGLXPixmap( DISP, visual, sys-> gdrawable); ret-> pixmap = 1; /* check if pixmaps are supported on this visual at all */ old_context = glXGetCurrentContext(); old_drawable = glXGetCurrentDrawable(); success = glXMakeCurrent( DISP, ret-> drawable, ret-> context); glXMakeCurrent( DISP, old_drawable, old_context); if ( !success ) { SET_ERROR( ERROR_NO_PIXMAPS ); glXDestroyGLXPixmap( DISP, ret-> drawable); glXDestroyContext( DISP, ret-> context ); free(ret); return 0; } break; } case GLREQ_TARGET_PRINTER: SET_ERROR(ERROR_NO_PRINTER); free(ret); return 0; } return (Handle) ret; }
/** * gdk_gl_pixmap_new: * @glconfig: a #GdkGLConfig. * @pixmap: the #GdkPixmap to be used as the rendering area. * @attrib_list: this must be set to NULL or empty (first attribute of None). * * Creates an off-screen rendering area. * attrib_list is currently unused. This must be set to NULL or empty * (first attribute of None). See GLX 1.3 spec. * * Return value: the new #GdkGLPixmap. **/ GdkGLPixmap * gdk_gl_pixmap_new (GdkGLConfig *glconfig, GdkPixmap *pixmap, const int *attrib_list) { GdkGLPixmap *glpixmap; GdkGLPixmapImplX11 *impl; Display *xdisplay; XVisualInfo *xvinfo; Pixmap xpixmap; GLXPixmap glxpixmap; Window root_return; int x_return, y_return; unsigned int width_return, height_return; unsigned int border_width_return; unsigned int depth_return; GdkGL_GLX_MESA_pixmap_colormap *mesa_ext; GDK_GL_NOTE_FUNC (); g_return_val_if_fail (GDK_IS_GL_CONFIG_IMPL_X11 (glconfig), NULL); g_return_val_if_fail (GDK_IS_PIXMAP (pixmap), NULL); xdisplay = GDK_GL_CONFIG_XDISPLAY (glconfig); xvinfo = GDK_GL_CONFIG_XVINFO (glconfig); /* * Get X Pixmap. */ xpixmap = GDK_DRAWABLE_XID (GDK_DRAWABLE (pixmap)); /* * Check depth of the X pixmap. */ if (!XGetGeometry (xdisplay, xpixmap, &root_return, &x_return, &y_return, &width_return, &height_return, &border_width_return, &depth_return)) return NULL; if (depth_return != (unsigned int) xvinfo->depth) return NULL; /* * Create GLXPixmap. */ mesa_ext = gdk_gl_get_GLX_MESA_pixmap_colormap (glconfig); if (mesa_ext) { /* If GLX_MESA_pixmap_colormap is supported. */ GDK_GL_NOTE_FUNC_IMPL ("glXCreateGLXPixmapMESA"); glxpixmap = mesa_ext->glXCreateGLXPixmapMESA (xdisplay, xvinfo, xpixmap, GDK_GL_CONFIG_XCOLORMAP (glconfig)); } else { GDK_GL_NOTE_FUNC_IMPL ("glXCreateGLXPixmap"); glxpixmap = glXCreateGLXPixmap (xdisplay, xvinfo, xpixmap); } if (glxpixmap == None) return NULL; /* * Instantiate the GdkGLPixmapImplX11 object. */ glpixmap = g_object_new (GDK_TYPE_GL_PIXMAP_IMPL_X11, NULL); impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap); glpixmap->drawable = GDK_DRAWABLE (pixmap); g_object_add_weak_pointer (G_OBJECT (glpixmap->drawable), (gpointer *) &(glpixmap->drawable)); impl->glxpixmap = glxpixmap; impl->glconfig = glconfig; g_object_ref (G_OBJECT (impl->glconfig)); impl->is_destroyed = FALSE; return glpixmap; }