Example #1
0
static gboolean
allocate_custom_egl_image_external (CoglTexture2D *tex_2d,
                                    CoglTextureLoader *loader,
                                    CoglError **error)
{
  CoglTexture *tex = COGL_TEXTURE (tex_2d);
  CoglContext *ctx = tex->context;
  CoglPixelFormat external_format;
  CoglPixelFormat internal_format;

  external_format = loader->src.egl_image_external.format;
  internal_format = _cogl_texture_determine_internal_format (tex,
                                                             external_format);

  _cogl_gl_util_clear_gl_errors (ctx);

  GE (ctx, glActiveTexture (GL_TEXTURE0));
  GE (ctx, glGenTextures (1, &tex_2d->gl_texture));

  GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES,
                          tex_2d->gl_texture));

  if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR)
    {
      _cogl_set_error (error,
                       COGL_TEXTURE_ERROR,
                       COGL_TEXTURE_ERROR_BAD_PARAMETER,
                       "Could not create a CoglTexture2D from a given "
                       "EGLImage");
      GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) );
      return FALSE;
    }

  GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
                           GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
  GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
                           GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

  if (!loader->src.egl_image_external.alloc (tex_2d,
                                             tex_2d->egl_image_external.user_data,
                                             error))
    {
      GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0));
      GE (ctx, glDeleteTextures (1, &tex_2d->gl_texture));
      return FALSE;
    }

  GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0));

  tex_2d->internal_format = internal_format;
  tex_2d->gl_target = GL_TEXTURE_EXTERNAL_OES;

  return TRUE;
}
Example #2
0
static gboolean
allocate_from_egl_image (CoglTexture2D *tex_2d,
                         CoglTextureLoader *loader,
                         CoglError **error)
{
  CoglTexture *tex = COGL_TEXTURE (tex_2d);
  CoglContext *ctx = tex->context;
  CoglPixelFormat internal_format = loader->src.egl_image.format;

  tex_2d->gl_texture =
    ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format);
  _cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
                                   tex_2d->gl_texture,
                                   FALSE);
  _cogl_gl_util_clear_gl_errors (ctx);

  ctx->glEGLImageTargetTexture2D (GL_TEXTURE_2D, loader->src.egl_image.image);
  if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR)
    {
      _cogl_set_error (error,
                       COGL_TEXTURE_ERROR,
                       COGL_TEXTURE_ERROR_BAD_PARAMETER,
                       "Could not create a CoglTexture2D from a given "
                       "EGLImage");
      GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) );
      return FALSE;
    }

  tex_2d->internal_format = internal_format;

  _cogl_texture_set_allocated (tex,
                               internal_format,
                               loader->src.egl_image.width,
                               loader->src.egl_image.height);

  return TRUE;
}
Example #3
0
static gboolean
allocate_from_gl_foreign (CoglTexture2D *tex_2d,
                          CoglTextureLoader *loader,
                          CoglError **error)
{
  CoglTexture *tex = COGL_TEXTURE (tex_2d);
  CoglContext *ctx = tex->context;
  CoglPixelFormat format = loader->src.gl_foreign.format;
  GLint gl_compressed = GL_FALSE;
  GLenum gl_int_format = 0;

  if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D))
    {
      _cogl_set_error (error,
                       COGL_SYSTEM_ERROR,
                       COGL_SYSTEM_ERROR_UNSUPPORTED,
                       "Foreign GL_TEXTURE_2D textures are not "
                       "supported by your system");
      return FALSE;
    }

  /* Make sure binding succeeds */
  _cogl_gl_util_clear_gl_errors (ctx);

  _cogl_bind_gl_texture_transient (GL_TEXTURE_2D,
                                   loader->src.gl_foreign.gl_handle, TRUE);
  if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR)
    {
      _cogl_set_error (error,
                       COGL_SYSTEM_ERROR,
                       COGL_SYSTEM_ERROR_UNSUPPORTED,
                       "Failed to bind foreign GL_TEXTURE_2D texture");
      return FALSE;
    }

  /* Obtain texture parameters
     (only level 0 we are interested in) */

#ifdef HAVE_COGL_GL
  if (_cogl_has_private_feature
      (ctx, COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS))
    {
      GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
                                         GL_TEXTURE_COMPRESSED,
                                         &gl_compressed) );

      {
        GLint val;

        GE( ctx, glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,
                                           GL_TEXTURE_INTERNAL_FORMAT,
                                           &val) );

        gl_int_format = val;
      }

      /* If we can query GL for the actual pixel format then we'll ignore
         the passed in format and use that. */
      if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx,
                                                              gl_int_format,
                                                              &format))
        {
          _cogl_set_error (error,
                           COGL_SYSTEM_ERROR,
                           COGL_SYSTEM_ERROR_UNSUPPORTED,
                           "Unsupported internal format for foreign texture");
          return FALSE;
        }
    }
  else
#endif
    {
      /* Otherwise we'll assume we can derive the GL format from the
         passed in format */
      ctx->driver_vtable->pixel_format_to_gl (ctx,
                                              format,
                                              &gl_int_format,
                                              NULL,
                                              NULL);
    }

  /* Compressed texture images not supported */
  if (gl_compressed == GL_TRUE)
    {
      _cogl_set_error (error,
                       COGL_SYSTEM_ERROR,
                       COGL_SYSTEM_ERROR_UNSUPPORTED,
                       "Compressed foreign textures aren't currently supported");
      return FALSE;
    }

  /* Note: previously this code would query the texture object for
     whether it has GL_GENERATE_MIPMAP enabled to determine whether to
     auto-generate the mipmap. This doesn't make much sense any more
     since Cogl switch to using glGenerateMipmap. Ideally I think
     cogl_texture_2d_gl_new_from_foreign should take a flags parameter so
     that the application can decide whether it wants
     auto-mipmapping. To be compatible with existing code, Cogl now
     disables its own auto-mipmapping but leaves the value of
     GL_GENERATE_MIPMAP alone so that it would still work but without
     the dirtiness tracking that Cogl would do. */

  _cogl_texture_2d_set_auto_mipmap (COGL_TEXTURE (tex_2d), FALSE);

  /* Setup bitmap info */
  tex_2d->is_foreign = TRUE;
  tex_2d->mipmaps_dirty = TRUE;

  tex_2d->gl_texture = loader->src.gl_foreign.gl_handle;
  tex_2d->gl_internal_format = gl_int_format;

  /* Unknown filter */
  tex_2d->gl_legacy_texobj_min_filter = GL_FALSE;
  tex_2d->gl_legacy_texobj_mag_filter = GL_FALSE;

  tex_2d->internal_format = format;

  _cogl_texture_set_allocated (tex,
                               format,
                               loader->src.gl_foreign.width,
                               loader->src.gl_foreign.height);
  return TRUE;
}
Example #4
0
void
_cogl_shader_compile_real (CoglHandle handle,
                           CoglPipeline *pipeline)
{
  CoglShader *shader = handle;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

#ifdef HAVE_COGL_GL
  if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
    {
#ifdef COGL_GL_DEBUG
      GLenum gl_error;
#endif

      if (shader->gl_handle)
        return;

      GE (ctx, glGenPrograms (1, &shader->gl_handle));

      GE (ctx, glBindProgram (GL_FRAGMENT_PROGRAM_ARB, shader->gl_handle));

      if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE)))
        g_message ("user ARBfp program:\n%s", shader->source);

#ifdef COGL_GL_DEBUG
      _cogl_gl_util_clear_gl_errors (ctx);
#endif
      ctx->glProgramString (GL_FRAGMENT_PROGRAM_ARB,
                            GL_PROGRAM_FORMAT_ASCII_ARB,
                            strlen (shader->source),
                            shader->source);
#ifdef COGL_GL_DEBUG
      gl_error = _cogl_gl_util_get_error (ctx);
      if (gl_error != GL_NO_ERROR)
        {
          g_warning ("%s: GL error (%d): Failed to compile ARBfp:\n%s\n%s",
                     G_STRLOC,
                     gl_error,
                     shader->source,
                     ctx->glGetString (GL_PROGRAM_ERROR_STRING_ARB));
        }
#endif
    }
  else
#endif
    {
      GLenum gl_type;
      GLint status;

      if (shader->gl_handle)
        {
          CoglPipeline *prev = shader->compilation_pipeline;

          /* XXX: currently the only things that will affect the
           * boilerplate for user shaders, apart from driver features,
           * are the pipeline layer-indices and texture-unit-indices
           */
          if (pipeline == prev ||
              _cogl_pipeline_layer_and_unit_numbers_equal (prev, pipeline))
            return;
        }

      if (shader->gl_handle)
        delete_shader (shader);

      switch (shader->type)
        {
        case COGL_SHADER_TYPE_VERTEX:
          gl_type = GL_VERTEX_SHADER;
          break;
        case COGL_SHADER_TYPE_FRAGMENT:
          gl_type = GL_FRAGMENT_SHADER;
          break;
        default:
          g_assert_not_reached ();
          break;
        }

      shader->gl_handle = ctx->glCreateShader (gl_type);

      _cogl_glsl_shader_set_source_with_boilerplate (ctx,
                                                     shader->gl_handle,
                                                     gl_type,
                                                     pipeline,
                                                     1,
                                                     (const char **)
                                                      &shader->source,
                                                     NULL);

      GE (ctx, glCompileShader (shader->gl_handle));

      shader->compilation_pipeline = cogl_object_ref (pipeline);

      GE (ctx, glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
      if (!status)
        {
          char buffer[512];
          int len = 0;

          ctx->glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
          buffer[len] = '\0';

          g_warning ("Failed to compile GLSL program:\n"
                     "src:\n%s\n"
                     "error:\n%s\n",
                     shader->source,
                     buffer);
        }
    }
}