static void clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self) { ClutterGLXTexturePixmapPrivate *priv; priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, CLUTTER_GLX_TYPE_TEXTURE_PIXMAP, ClutterGLXTexturePixmapPrivate); if (_ext_check_done == FALSE) { const gchar *glx_extensions = NULL; glx_extensions = glXQueryExtensionsString (clutter_x11_get_default_display (), clutter_x11_get_default_screen ()); /* Check for the texture from pixmap extension */ if (cogl_check_extension ("GLX_EXT_texture_from_pixmap", glx_extensions)) { _gl_bind_tex_image = (BindTexImage)cogl_get_proc_address ("glXBindTexImageEXT"); _gl_release_tex_image = (ReleaseTexImage)cogl_get_proc_address ("glXReleaseTexImageEXT"); if (_gl_bind_tex_image && _gl_release_tex_image) _have_tex_from_pixmap_ext = TRUE; } _ext_check_done = TRUE; } }
static gboolean load_gl_symbol (const char *name, void **func) { *func = cogl_get_proc_address (name); if (!*func) { meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name); return FALSE; } return TRUE; }
void test_conform_get_gl_functions (TestConformGLFunctions *functions) { functions->glGetString = (void *) cogl_get_proc_address ("glGetString"); g_assert (functions->glGetString != NULL); functions->glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv"); g_assert (functions->glGetIntegerv != NULL); functions->glPixelStorei = (void *) cogl_get_proc_address ("glPixelStorei"); g_assert (functions->glPixelStorei != NULL); functions->glBindTexture = (void *) cogl_get_proc_address ("glBindTexture"); g_assert (functions->glBindTexture != NULL); functions->glGenTextures = (void *) cogl_get_proc_address ("glGenTextures"); g_assert (functions->glGenTextures != NULL); functions->glGetError = (void *) cogl_get_proc_address ("glGetError"); g_assert (functions->glGetError != NULL); functions->glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures"); g_assert (functions->glDeleteTextures != NULL); functions->glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D"); g_assert (functions->glTexImage2D != NULL); functions->glTexParameteri = (void *) cogl_get_proc_address ("glTexParameteri"); g_assert (functions->glTexParameteri != NULL); }
static ClutterFeatureFlags clutter_backend_glx_get_features (ClutterBackend *backend) { ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend); const gchar *glx_extensions = NULL; const gchar *gl_extensions = NULL; ClutterFeatureFlags flags; gboolean use_dri = FALSE; flags = clutter_backend_x11_get_features (backend); flags |= CLUTTER_FEATURE_STAGE_MULTIPLE; /* this will make sure that the GL context exists */ g_assert (backend_glx->gl_context != None); g_assert (glXGetCurrentDrawable () != None); CLUTTER_NOTE (BACKEND, "Checking features\n" " GL_VENDOR: %s\n" " GL_RENDERER: %s\n" " GL_VERSION: %s\n" " GL_EXTENSIONS: %s", glGetString (GL_VENDOR), glGetString (GL_RENDERER), glGetString (GL_VERSION), glGetString (GL_EXTENSIONS)); glx_extensions = glXQueryExtensionsString (clutter_x11_get_default_display (), clutter_x11_get_default_screen ()); CLUTTER_NOTE (BACKEND, " GLX Extensions: %s", glx_extensions); gl_extensions = (const gchar *)glGetString (GL_EXTENSIONS); /* When using glBlitFramebuffer or glXCopySubBufferMESA for sub stage * redraws, we cannot rely on glXSwapIntervalSGI to throttle the blits * so we need to resort to manually synchronizing with the vblank so we * always check for the video_sync extension... */ if (_cogl_check_extension ("GLX_SGI_video_sync", glx_extensions) && /* Note: the GLX_SGI_video_sync spec explicitly states this extension * only works for direct contexts. */ glXIsDirect (clutter_x11_get_default_display (), backend_glx->gl_context)) { backend_glx->get_video_sync = (GetVideoSyncProc) cogl_get_proc_address ("glXGetVideoSyncSGI"); backend_glx->wait_video_sync = (WaitVideoSyncProc) cogl_get_proc_address ("glXWaitVideoSyncSGI"); } use_dri = check_vblank_env ("dri"); /* First check for explicit disabling or it set elsewhere (eg NVIDIA) */ if (check_vblank_env ("none")) { CLUTTER_NOTE (BACKEND, "vblank sync: disabled at user request"); goto vblank_setup_done; } if (g_getenv ("__GL_SYNC_TO_VBLANK") != NULL) { backend_glx->vblank_type = CLUTTER_VBLANK_GLX_SWAP; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; CLUTTER_NOTE (BACKEND, "Using __GL_SYNC_TO_VBLANK hint"); goto vblank_setup_done; } /* We try two GL vblank syncing mechanisms. * glXSwapIntervalSGI is tried first, then glXGetVideoSyncSGI. * * glXSwapIntervalSGI is known to work with Mesa and in particular * the Intel drivers. glXGetVideoSyncSGI has serious problems with * Intel drivers causing terrible frame rate so it only tried as a * fallback. * * How well glXGetVideoSyncSGI works with other driver (ATI etc) needs * to be investigated. glXGetVideoSyncSGI on ATI at least seems to have * no effect. */ if (!use_dri && _cogl_check_extension ("GLX_SGI_swap_control", glx_extensions)) { backend_glx->swap_interval = (SwapIntervalProc) cogl_get_proc_address ("glXSwapIntervalSGI"); CLUTTER_NOTE (BACKEND, "attempting glXSwapIntervalSGI vblank setup"); if (backend_glx->swap_interval != NULL && backend_glx->swap_interval (1) == 0) { backend_glx->vblank_type = CLUTTER_VBLANK_GLX_SWAP; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; CLUTTER_NOTE (BACKEND, "glXSwapIntervalSGI setup success"); #ifdef GLX_INTEL_swap_event /* GLX_INTEL_swap_event allows us to avoid blocking the CPU * while we wait for glXSwapBuffers to complete, and instead * we get an X event notifying us of completion... */ if (!(clutter_paint_debug_flags & CLUTTER_DEBUG_DISABLE_SWAP_EVENTS) && _cogl_check_extension ("GLX_INTEL_swap_event", glx_extensions)) { flags |= CLUTTER_FEATURE_SWAP_EVENTS; } #endif /* GLX_INTEL_swap_event */ goto vblank_setup_done; } CLUTTER_NOTE (BACKEND, "glXSwapIntervalSGI vblank setup failed"); } if (!use_dri && !(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK) && _cogl_check_extension ("GLX_SGI_video_sync", glx_extensions)) { CLUTTER_NOTE (BACKEND, "attempting glXGetVideoSyncSGI vblank setup"); if ((backend_glx->get_video_sync != NULL) && (backend_glx->wait_video_sync != NULL)) { CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup success"); backend_glx->vblank_type = CLUTTER_VBLANK_GLX; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; goto vblank_setup_done; } CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup failed"); } #ifdef __linux__ /* * DRI is really an extreme fallback -rumoured to work with Via chipsets */ if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK)) { CLUTTER_NOTE (BACKEND, "attempting DRI vblank setup"); backend_glx->dri_fd = open("/dev/dri/card0", O_RDWR); if (backend_glx->dri_fd >= 0) { CLUTTER_NOTE (BACKEND, "DRI vblank setup success"); backend_glx->vblank_type = CLUTTER_VBLANK_DRI; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; goto vblank_setup_done; } CLUTTER_NOTE (BACKEND, "DRI vblank setup failed"); } #endif /* __linux__ */ CLUTTER_NOTE (BACKEND, "no use-able vblank mechanism found"); vblank_setup_done: if (_cogl_check_extension ("GLX_MESA_copy_sub_buffer", glx_extensions)) { backend_glx->copy_sub_buffer = (CopySubBufferProc) cogl_get_proc_address ("glXCopySubBufferMESA"); backend_glx->can_blit_sub_buffer = TRUE; backend_glx->blit_sub_buffer_is_synchronized = TRUE; } else if (_cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions)) { CLUTTER_NOTE (BACKEND, "Using glBlitFramebuffer fallback for sub_buffer copies"); backend_glx->blit_framebuffer = (BlitFramebufferProc) cogl_get_proc_address ("glBlitFramebuffer"); backend_glx->can_blit_sub_buffer = TRUE; backend_glx->blit_sub_buffer_is_synchronized = FALSE; } CLUTTER_NOTE (BACKEND, "backend features checked"); return flags; }
void _cogl_features_init (void) { CoglFeatureFlags flags = 0; const gchar *gl_extensions; GLint max_clip_planes = 0; GLint num_stencil_bits = 0; _COGL_GET_CONTEXT (ctx, NO_RETVAL); flags = COGL_FEATURE_TEXTURE_READ_PIXELS; gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS); if (cogl_check_extension ("GL_ARB_texture_non_power_of_two", gl_extensions)) { #ifdef HAVE_CLUTTER_OSX if (really_enable_npot ()) #endif flags |= COGL_FEATURE_TEXTURE_NPOT; } #ifdef GL_YCBCR_MESA if (cogl_check_extension ("GL_MESA_ycbcr_texture", gl_extensions)) { flags |= COGL_FEATURE_TEXTURE_YUV; } #endif if (cogl_check_extension ("GL_ARB_shader_objects", gl_extensions) && cogl_check_extension ("GL_ARB_vertex_shader", gl_extensions) && cogl_check_extension ("GL_ARB_fragment_shader", gl_extensions)) { ctx->pf_glCreateProgramObjectARB = (COGL_PFNGLCREATEPROGRAMOBJECTARBPROC) cogl_get_proc_address ("glCreateProgramObjectARB"); ctx->pf_glCreateShaderObjectARB = (COGL_PFNGLCREATESHADEROBJECTARBPROC) cogl_get_proc_address ("glCreateShaderObjectARB"); ctx->pf_glShaderSourceARB = (COGL_PFNGLSHADERSOURCEARBPROC) cogl_get_proc_address ("glShaderSourceARB"); ctx->pf_glCompileShaderARB = (COGL_PFNGLCOMPILESHADERARBPROC) cogl_get_proc_address ("glCompileShaderARB"); ctx->pf_glAttachObjectARB = (COGL_PFNGLATTACHOBJECTARBPROC) cogl_get_proc_address ("glAttachObjectARB"); ctx->pf_glLinkProgramARB = (COGL_PFNGLLINKPROGRAMARBPROC) cogl_get_proc_address ("glLinkProgramARB"); ctx->pf_glUseProgramObjectARB = (COGL_PFNGLUSEPROGRAMOBJECTARBPROC) cogl_get_proc_address ("glUseProgramObjectARB"); ctx->pf_glGetUniformLocationARB = (COGL_PFNGLGETUNIFORMLOCATIONARBPROC) cogl_get_proc_address ("glGetUniformLocationARB"); ctx->pf_glDeleteObjectARB = (COGL_PFNGLDELETEOBJECTARBPROC) cogl_get_proc_address ("glDeleteObjectARB"); ctx->pf_glGetInfoLogARB = (COGL_PFNGLGETINFOLOGARBPROC) cogl_get_proc_address ("glGetInfoLogARB"); ctx->pf_glGetObjectParameterivARB = (COGL_PFNGLGETOBJECTPARAMETERIVARBPROC) cogl_get_proc_address ("glGetObjectParameterivARB"); ctx->pf_glUniform1fARB = (COGL_PFNGLUNIFORM1FARBPROC) cogl_get_proc_address ("glUniform1fARB"); ctx->pf_glVertexAttribPointerARB = (COGL_PFNGLVERTEXATTRIBPOINTERARBPROC) cogl_get_proc_address ("glVertexAttribPointerARB"); ctx->pf_glEnableVertexAttribArrayARB = (COGL_PFNGLENABLEVERTEXATTRIBARRAYARBPROC) cogl_get_proc_address ("glEnableVertexAttribArrayARB"); ctx->pf_glDisableVertexAttribArrayARB = (COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) cogl_get_proc_address ("glDisableVertexAttribArrayARB"); ctx->pf_glUniform2fARB = (COGL_PFNGLUNIFORM2FARBPROC) cogl_get_proc_address ("glUniform2fARB"); ctx->pf_glUniform3fARB = (COGL_PFNGLUNIFORM3FARBPROC) cogl_get_proc_address ("glUniform3fARB"); ctx->pf_glUniform4fARB = (COGL_PFNGLUNIFORM4FARBPROC) cogl_get_proc_address ("glUniform4fARB"); ctx->pf_glUniform1fvARB = (COGL_PFNGLUNIFORM1FVARBPROC) cogl_get_proc_address ("glUniform1fvARB"); ctx->pf_glUniform2fvARB = (COGL_PFNGLUNIFORM2FVARBPROC) cogl_get_proc_address ("glUniform2fvARB"); ctx->pf_glUniform3fvARB = (COGL_PFNGLUNIFORM3FVARBPROC) cogl_get_proc_address ("glUniform3fvARB"); ctx->pf_glUniform4fvARB = (COGL_PFNGLUNIFORM4FVARBPROC) cogl_get_proc_address ("glUniform4fvARB"); ctx->pf_glUniform1iARB = (COGL_PFNGLUNIFORM1IARBPROC) cogl_get_proc_address ("glUniform1iARB"); ctx->pf_glUniform2iARB = (COGL_PFNGLUNIFORM2IARBPROC) cogl_get_proc_address ("glUniform2iARB"); ctx->pf_glUniform3iARB = (COGL_PFNGLUNIFORM3IARBPROC) cogl_get_proc_address ("glUniform3iARB"); ctx->pf_glUniform4iARB = (COGL_PFNGLUNIFORM4IARBPROC) cogl_get_proc_address ("glUniform4iARB"); ctx->pf_glUniform1ivARB = (COGL_PFNGLUNIFORM1IVARBPROC) cogl_get_proc_address ("glUniform1ivARB"); ctx->pf_glUniform2ivARB = (COGL_PFNGLUNIFORM2IVARBPROC) cogl_get_proc_address ("glUniform2ivARB"); ctx->pf_glUniform3ivARB = (COGL_PFNGLUNIFORM3IVARBPROC) cogl_get_proc_address ("glUniform3ivARB"); ctx->pf_glUniform4ivARB = (COGL_PFNGLUNIFORM4IVARBPROC) cogl_get_proc_address ("glUniform4ivARB"); ctx->pf_glUniformMatrix2fvARB = (COGL_PFNGLUNIFORMMATRIX2FVARBPROC) cogl_get_proc_address ("glUniformMatrix2fvARB"); ctx->pf_glUniformMatrix3fvARB = (COGL_PFNGLUNIFORMMATRIX3FVARBPROC) cogl_get_proc_address ("glUniformMatrix3fvARB"); ctx->pf_glUniformMatrix4fvARB = (COGL_PFNGLUNIFORMMATRIX4FVARBPROC) cogl_get_proc_address ("glUniformMatrix4fvARB"); if (ctx->pf_glCreateProgramObjectARB && ctx->pf_glCreateShaderObjectARB && ctx->pf_glShaderSourceARB && ctx->pf_glCompileShaderARB && ctx->pf_glAttachObjectARB && ctx->pf_glLinkProgramARB && ctx->pf_glUseProgramObjectARB && ctx->pf_glGetUniformLocationARB && ctx->pf_glDeleteObjectARB && ctx->pf_glGetInfoLogARB && ctx->pf_glGetObjectParameterivARB && ctx->pf_glUniform1fARB && ctx->pf_glUniform2fARB && ctx->pf_glUniform3fARB && ctx->pf_glUniform4fARB && ctx->pf_glUniform1fvARB && ctx->pf_glUniform2fvARB && ctx->pf_glUniform3fvARB && ctx->pf_glUniform4fvARB && ctx->pf_glUniform1iARB && ctx->pf_glUniform2iARB && ctx->pf_glUniform3iARB && ctx->pf_glUniform4iARB && ctx->pf_glUniform1ivARB && ctx->pf_glUniform2ivARB && ctx->pf_glUniform3ivARB && ctx->pf_glUniform4ivARB && ctx->pf_glUniformMatrix2fvARB && ctx->pf_glUniformMatrix3fvARB && ctx->pf_glUniformMatrix4fvARB && ctx->pf_glVertexAttribPointerARB && ctx->pf_glEnableVertexAttribArrayARB && ctx->pf_glDisableVertexAttribArrayARB) flags |= COGL_FEATURE_SHADERS_GLSL; } if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) || cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions)) { ctx->pf_glGenRenderbuffersEXT = (COGL_PFNGLGENRENDERBUFFERSEXTPROC) cogl_get_proc_address ("glGenRenderbuffersEXT"); ctx->pf_glDeleteRenderbuffersEXT = (COGL_PFNGLDELETERENDERBUFFERSEXTPROC) cogl_get_proc_address ("glDeleteRenderbuffersEXT"); ctx->pf_glBindRenderbufferEXT = (COGL_PFNGLBINDRENDERBUFFEREXTPROC) cogl_get_proc_address ("glBindRenderbufferEXT"); ctx->pf_glRenderbufferStorageEXT = (COGL_PFNGLRENDERBUFFERSTORAGEEXTPROC) cogl_get_proc_address ("glRenderbufferStorageEXT"); ctx->pf_glGenFramebuffersEXT = (COGL_PFNGLGENFRAMEBUFFERSEXTPROC) cogl_get_proc_address ("glGenFramebuffersEXT"); ctx->pf_glBindFramebufferEXT = (COGL_PFNGLBINDFRAMEBUFFEREXTPROC) cogl_get_proc_address ("glBindFramebufferEXT"); ctx->pf_glFramebufferTexture2DEXT = (COGL_PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) cogl_get_proc_address ("glFramebufferTexture2DEXT"); ctx->pf_glFramebufferRenderbufferEXT = (COGL_PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) cogl_get_proc_address ("glFramebufferRenderbufferEXT"); ctx->pf_glCheckFramebufferStatusEXT = (COGL_PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) cogl_get_proc_address ("glCheckFramebufferStatusEXT"); ctx->pf_glDeleteFramebuffersEXT = (COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC) cogl_get_proc_address ("glDeleteFramebuffersEXT"); ctx->pf_glGenerateMipmapEXT = (COGL_PFNGLGENERATEMIPMAPEXTPROC) cogl_get_proc_address ("glGenerateMipmapEXT"); if (ctx->pf_glGenRenderbuffersEXT && ctx->pf_glBindRenderbufferEXT && ctx->pf_glRenderbufferStorageEXT && ctx->pf_glGenFramebuffersEXT && ctx->pf_glBindFramebufferEXT && ctx->pf_glFramebufferTexture2DEXT && ctx->pf_glFramebufferRenderbufferEXT && ctx->pf_glCheckFramebufferStatusEXT && ctx->pf_glDeleteFramebuffersEXT && ctx->pf_glGenerateMipmapEXT) flags |= COGL_FEATURE_OFFSCREEN; } if (cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions)) { ctx->pf_glBlitFramebufferEXT = (COGL_PFNGLBLITFRAMEBUFFEREXTPROC) cogl_get_proc_address ("glBlitFramebufferEXT"); if (ctx->pf_glBlitFramebufferEXT) flags |= COGL_FEATURE_OFFSCREEN_BLIT; } if (cogl_check_extension ("GL_EXT_framebuffer_multisample", gl_extensions)) { ctx->pf_glRenderbufferStorageMultisampleEXT = (COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) cogl_get_proc_address ("glRenderbufferStorageMultisampleEXT"); if (ctx->pf_glRenderbufferStorageMultisampleEXT) flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE; } GE( glGetIntegerv (GL_STENCIL_BITS, &num_stencil_bits) ); /* We need at least three stencil bits to combine clips */ if (num_stencil_bits > 2) flags |= COGL_FEATURE_STENCIL_BUFFER; GE( glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); if (max_clip_planes >= 4) flags |= COGL_FEATURE_FOUR_CLIP_PLANES; if (cogl_check_extension ("GL_ARB_vertex_buffer_object", gl_extensions)) { ctx->pf_glGenBuffersARB = (COGL_PFNGLGENBUFFERSARBPROC) cogl_get_proc_address ("glGenBuffersARB"); ctx->pf_glBindBufferARB = (COGL_PFNGLBINDBUFFERARBPROC) cogl_get_proc_address ("glBindBufferARB"); ctx->pf_glBufferDataARB = (COGL_PFNGLBUFFERDATAARBPROC) cogl_get_proc_address ("glBufferDataARB"); ctx->pf_glBufferSubDataARB = (COGL_PFNGLBUFFERSUBDATAARBPROC) cogl_get_proc_address ("glBufferSubDataARB"); ctx->pf_glDeleteBuffersARB = (COGL_PFNGLDELETEBUFFERSARBPROC) cogl_get_proc_address ("glDeleteBuffersARB"); ctx->pf_glMapBufferARB = (COGL_PFNGLMAPBUFFERARBPROC) cogl_get_proc_address ("glMapBufferARB"); ctx->pf_glUnmapBufferARB = (COGL_PFNGLUNMAPBUFFERARBPROC) cogl_get_proc_address ("glUnmapBufferARB"); if (ctx->pf_glGenBuffersARB && ctx->pf_glBindBufferARB && ctx->pf_glBufferDataARB && ctx->pf_glBufferSubDataARB && ctx->pf_glDeleteBuffersARB && ctx->pf_glMapBufferARB && ctx->pf_glUnmapBufferARB) flags |= COGL_FEATURE_VBOS; } /* These should always be available because they are defined in GL 1.2, but we can't call it directly because under Windows functions > 1.1 aren't exported */ ctx->pf_glDrawRangeElements = (COGL_PFNGLDRAWRANGEELEMENTSPROC) cogl_get_proc_address ("glDrawRangeElements"); ctx->pf_glActiveTexture = (COGL_PFNGLACTIVETEXTUREPROC) cogl_get_proc_address ("glActiveTexture"); ctx->pf_glClientActiveTexture = (COGL_PFNGLCLIENTACTIVETEXTUREPROC) cogl_get_proc_address ("glClientActiveTexture"); ctx->pf_glBlendEquation = (COGL_PFNGLBLENDEQUATIONPROC) cogl_get_proc_address ("glBlendEquation"); ctx->pf_glBlendColor = (COGL_PFNGLBLENDCOLORPROC) cogl_get_proc_address ("glBlendColor"); /* Available in 1.4 */ ctx->pf_glBlendFuncSeparate = (COGL_PFNGLBLENDFUNCSEPARATEPROC) cogl_get_proc_address ("glBlendFuncSeparate"); /* Available in 2.0 */ ctx->pf_glBlendEquationSeparate = (COGL_PFNGLBLENDEQUATIONSEPARATEPROC) cogl_get_proc_address ("glBlendEquationSeparate"); /* Cache features */ ctx->feature_flags = flags; ctx->features_cached = TRUE; }
static GSList * clutter_gst_build_renderers_list (ClutterGstSymbols *syms) { GSList *list = NULL; const gchar *gl_extensions; GLint nb_texture_units = 0; gint features = 0, i; /* The order of the list of renderers is important. They will be prepended * to a GSList and we'll iterate over that list to choose the first matching * renderer. Thus if you want to use the fp renderer over the glsl one, the * fp renderer has to be put after the glsl one in this array */ ClutterGstRenderer *renderers[] = { &rgb24_renderer, &rgb32_renderer, &yv12_glsl_renderer, &i420_glsl_renderer, #ifdef CLUTTER_COGL_HAS_GL &yv12_fp_renderer, &i420_fp_renderer, #endif &ayuv_glsl_renderer, NULL }; /* get the features */ gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS); glGetIntegerv (CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &nb_texture_units); if (nb_texture_units >= 3) features |= CLUTTER_GST_MULTI_TEXTURE; #ifdef CLUTTER_COGL_HAS_GL if (cogl_check_extension ("GL_ARB_fragment_program", gl_extensions)) { /* the shaders we'll feed to the GPU are simple enough, we don't need * to check GL limits for GL_FRAGMENT_PROGRAM_ARB */ syms->glGenProgramsARB = (GLGENPROGRAMSPROC) cogl_get_proc_address ("glGenProgramsARB"); syms->glBindProgramARB = (GLBINDPROGRAMPROC) cogl_get_proc_address ("glBindProgramARB"); syms->glProgramStringARB = (GLPROGRAMSTRINGPROC) cogl_get_proc_address ("glProgramStringARB"); if (syms->glGenProgramsARB && syms->glBindProgramARB && syms->glProgramStringARB) { features |= CLUTTER_GST_FP; } } #endif if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) features |= CLUTTER_GST_GLSL; GST_INFO ("GL features: 0x%08x", features); for (i = 0; renderers[i]; i++) { gint needed = renderers[i]->flags; if ((needed & features) == needed) list = g_slist_prepend (list, renderers[i]); } return list; }
static ClutterFeatureFlags clutter_backend_glx_get_features (ClutterBackend *backend) { ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend); const gchar *glx_extensions = NULL; ClutterFeatureFlags flags; flags = clutter_backend_x11_get_features (backend); flags |= CLUTTER_FEATURE_STAGE_MULTIPLE; /* this will make sure that the GL context exists and * it's bound to a drawable */ g_assert (backend_glx->gl_context != None); g_assert (glXGetCurrentDrawable () != None); CLUTTER_NOTE (BACKEND, "Checking features\n" "GL_VENDOR: %s\n" "GL_RENDERER: %s\n" "GL_VERSION: %s\n" "GL_EXTENSIONS: %s\n", glGetString (GL_VENDOR), glGetString (GL_RENDERER), glGetString (GL_VERSION), glGetString (GL_EXTENSIONS)); glx_extensions = glXQueryExtensionsString (clutter_x11_get_default_display (), clutter_x11_get_default_screen ()); CLUTTER_NOTE (BACKEND, "GLX Extensions: %s", glx_extensions); /* First check for explicit disabling or it set elsewhere (eg NVIDIA) */ if (getenv("__GL_SYNC_TO_VBLANK") || check_vblank_env ("none")) { CLUTTER_NOTE (BACKEND, "vblank sync: disabled at user request"); } else { /* We try two GL vblank syncing mechanisms. * glXSwapIntervalSGI is tried first, then glXGetVideoSyncSGI. * * glXSwapIntervalSGI is known to work with Mesa and in particular * the Intel drivers. glXGetVideoSyncSGI has serious problems with * Intel drivers causing terrible frame rate so it only tried as a * fallback. * * How well glXGetVideoSyncSGI works with other driver (ATI etc) needs * to be investigated. glXGetVideoSyncSGI on ATI at least seems to have * no effect. */ if (!check_vblank_env ("dri") && cogl_check_extension ("GLX_SGI_swap_control", glx_extensions)) { backend_glx->swap_interval = (SwapIntervalProc) cogl_get_proc_address ("glXSwapIntervalSGI"); CLUTTER_NOTE (BACKEND, "attempting glXSwapIntervalSGI vblank setup"); if (backend_glx->swap_interval != NULL) { if (backend_glx->swap_interval (1) == 0) { backend_glx->vblank_type = CLUTTER_VBLANK_GLX_SWAP; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; CLUTTER_NOTE (BACKEND, "glXSwapIntervalSGI setup success"); } } if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK)) CLUTTER_NOTE (BACKEND, "glXSwapIntervalSGI vblank setup failed"); } if (!check_vblank_env ("dri") && !(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK) && cogl_check_extension ("GLX_SGI_video_sync", glx_extensions)) { CLUTTER_NOTE (BACKEND, "attempting glXGetVideoSyncSGI vblank setup"); backend_glx->get_video_sync = (GetVideoSyncProc) cogl_get_proc_address ("glXGetVideoSyncSGI"); backend_glx->wait_video_sync = (WaitVideoSyncProc) cogl_get_proc_address ("glXWaitVideoSyncSGI"); if ((backend_glx->get_video_sync != NULL) && (backend_glx->wait_video_sync != NULL)) { CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup success"); backend_glx->vblank_type = CLUTTER_VBLANK_GLX; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; } if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK)) CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup failed"); } #ifdef __linux__ /* * DRI is really an extreme fallback -rumoured to work with Via chipsets */ if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK)) { CLUTTER_NOTE (BACKEND, "attempting DRI vblank setup"); backend_glx->dri_fd = open("/dev/dri/card0", O_RDWR); if (backend_glx->dri_fd >= 0) { CLUTTER_NOTE (BACKEND, "DRI vblank setup success"); backend_glx->vblank_type = CLUTTER_VBLANK_DRI; flags |= CLUTTER_FEATURE_SYNC_TO_VBLANK; } if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK)) CLUTTER_NOTE (BACKEND, "DRI vblank setup failed"); } #endif if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK)) { CLUTTER_NOTE (BACKEND, "no use-able vblank mechanism found"); } } CLUTTER_NOTE (MISC, "backend features checked"); return flags; }
CoglHandle meta_texture_rectangle_new (unsigned int width, unsigned int height, CoglTextureFlags flags, CoglPixelFormat format, GLenum internal_gl_format, GLenum internal_format, unsigned int rowstride, const guint8 *data) { CoglHandle cogl_tex = COGL_INVALID_HANDLE; #ifdef GL_TEXTURE_RECTANGLE_ARB static CoglUserDataKey user_data_key; GLint old_binding; GLuint tex; if (pf_glGenTextures == NULL) { pf_glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv"); pf_glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D"); pf_glGenTextures = (void *) cogl_get_proc_address ("glGenTextures"); pf_glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures"); pf_glBindTexture = (void *) cogl_get_proc_address ("glBindTexture"); } pf_glGenTextures (1, &tex); pf_glGetIntegerv (GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding); pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex); pf_glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, internal_gl_format, width, height, 0, internal_gl_format, GL_UNSIGNED_BYTE, NULL); pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, old_binding); cogl_tex = cogl_texture_new_from_foreign (tex, GL_TEXTURE_RECTANGLE_ARB, width, height, 0, 0, /* no waste */ internal_format); /* Cogl won't destroy the GL texture when a foreign texture is used so we need to destroy it manually. We can set a destroy notification callback to do this transparently */ cogl_object_set_user_data (cogl_tex, &user_data_key, GUINT_TO_POINTER (tex), rectangle_texture_destroy_cb); /* Use cogl_texture_set_region instead of uploading the data directly with GL calls so that we can let Cogl deal with setting the pixel store parameters and handling format conversion */ if (data) cogl_texture_set_region (cogl_tex, 0, 0, /* src x/y */ 0, 0, /* dst x/y */ width, height, /* dst width/height */ width, height, /* src width/height */ format, rowstride, data); #endif /* GL_TEXTURE_RECTANGLE_ARB */ return cogl_tex; }