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;
    }
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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;
}