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; }
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; }
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; }
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); } } }