static void * _cogl_buffer_bind_no_create (CoglBuffer *buffer, CoglBufferBindTarget target) { CoglContext *ctx = buffer->context; _COGL_RETURN_VAL_IF_FAIL (buffer != NULL, NULL); /* Don't allow binding the buffer to multiple targets at the same time */ _COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[buffer->last_target] != buffer, NULL); /* Don't allow nesting binds to the same target */ _COGL_RETURN_VAL_IF_FAIL (ctx->current_buffer[target] == NULL, NULL); buffer->last_target = target; ctx->current_buffer[target] = buffer; if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) { GLenum gl_target = convert_bind_target_to_gl_target (buffer->last_target); GE( ctx, glBindBuffer (gl_target, buffer->gl_handle) ); return NULL; } else return buffer->data; }
CoglTexture2D * cogl_texture_2d_gl_new_from_foreign (CoglContext *ctx, unsigned int gl_handle, int width, int height, CoglPixelFormat format) { CoglTextureLoader *loader; /* NOTE: width, height and internal format are not queriable * in GLES, hence such a function prototype. */ /* Note: We always trust the given width and height without querying * the texture object because the user may be creating a Cogl * texture for a texture_from_pixmap object where glTexImage2D may * not have been called and the texture_from_pixmap spec doesn't * clarify that it is reliable to query back the size from OpenGL. */ /* Assert it is a valid GL texture object */ _COGL_RETURN_VAL_IF_FAIL (ctx->glIsTexture (gl_handle), FALSE); /* Validate width and height */ _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN; loader->src.gl_foreign.gl_handle = gl_handle; loader->src.gl_foreign.width = width; loader->src.gl_foreign.height = height; loader->src.gl_foreign.format = format; return _cogl_texture_2d_create_base (ctx, width, height, format, loader); }
/* NB: The reason we require the width, height and format to be passed * even though they may seem redundant is because GLES 1/2 don't * provide a way to query these properties. */ CoglTexture2D * _cogl_egl_texture_2d_new_from_image (CoglContext *ctx, int width, int height, CoglPixelFormat format, EGLImageKHR image, CoglError **error) { CoglTextureLoader *loader; _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & COGL_RENDERER_CONSTRAINT_USES_EGL, NULL); _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE; loader->src.egl_image.image = image; loader->src.egl_image.width = width; loader->src.egl_image.height = height; loader->src.egl_image.format = format; return _cogl_texture_2d_create_base (ctx, width, height, format, loader); }
CoglTexture * cogl_texture_new_from_data (CoglContext *ctx, int width, int height, CoglTextureFlags flags, CoglPixelFormat format, CoglPixelFormat internal_format, int rowstride, const uint8_t *data, CoglError **error) { CoglBitmap *bmp; CoglTexture *tex; _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); _COGL_RETURN_VAL_IF_FAIL (data != NULL, NULL); /* Rowstride from width if not given */ if (rowstride == 0) rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, width, height, format, rowstride, (uint8_t *) data); tex = cogl_texture_new_from_bitmap (bmp, flags, internal_format, error); cogl_object_unref (bmp); return tex; }
CoglBitmap * cogl_bitmap_new_with_size (CoglContext *context, unsigned int width, unsigned int height, CoglPixelFormat format) { CoglPixelBuffer *pixel_buffer; CoglBitmap *bitmap; unsigned int rowstride; /* creating a buffer to store "any" format does not make sense */ _COGL_RETURN_VAL_IF_FAIL (format != COGL_PIXEL_FORMAT_ANY, NULL); /* for now we fallback to cogl_pixel_buffer_new, later, we could ask * libdrm a tiled buffer for instance */ rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); pixel_buffer = cogl_pixel_buffer_new (context, height * rowstride, NULL, /* data */ NULL); /* don't catch errors */ _COGL_RETURN_VAL_IF_FAIL (pixel_buffer != NULL, NULL); bitmap = cogl_bitmap_new_from_buffer (COGL_BUFFER (pixel_buffer), format, width, height, rowstride, 0 /* offset */); cogl_object_unref (pixel_buffer); return bitmap; }
/* NB: The reason we require the width, height and format to be passed * even though they may seem redundant is because GLES 1/2 don't * provide a way to query these properties. */ CoglTexture2D * _cogl_egl_texture_2d_new_from_image (CoglContext *ctx, int width, int height, CoglPixelFormat format, EGLImageKHR image, CoglError **error) { _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & COGL_RENDERER_CONSTRAINT_USES_EGL, NULL); _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), NULL); if (ctx->driver_vtable->egl_texture_2d_new_from_image) return ctx->driver_vtable->egl_texture_2d_new_from_image (ctx, width, height, format, image, error); else { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "Creating 2D textures from EGL images is not " "supported by the current driver"); return NULL; } }
CoglTextureRectangle * cogl_texture_rectangle_new_from_foreign (CoglContext *ctx, unsigned int gl_handle, int width, int height, CoglPixelFormat format) { CoglTextureLoader *loader; /* NOTE: width, height and internal format are not queriable in * GLES, hence such a function prototype. Also in the case of full * opengl the user may be creating a Cogl texture for a * texture_from_pixmap object where glTexImage2D may not have been * called and the texture_from_pixmap spec doesn't clarify that it * is reliable to query back the size from OpenGL. */ /* Assert that it is a valid GL texture object */ _COGL_RETURN_VAL_IF_FAIL (ctx->glIsTexture (gl_handle), NULL); /* Validate width and height */ _COGL_RETURN_VAL_IF_FAIL (width > 0 && height > 0, NULL); loader = _cogl_texture_create_loader (); loader->src_type = COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN; loader->src.gl_foreign.gl_handle = gl_handle; loader->src.gl_foreign.width = width; loader->src.gl_foreign.height = height; loader->src.gl_foreign.format = format; return _cogl_texture_rectangle_create_base (ctx, width, height, format, loader); }
CoglBool cogl_color_equal (const void *v1, const void *v2) { _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); return memcmp (v1, v2, sizeof (CoglColor)) == 0; }
CoglBool cogl_vector4_equal (const void *v0, const void *v1) { _COGL_RETURN_VAL_IF_FAIL (v1 != NULL, FALSE); _COGL_RETURN_VAL_IF_FAIL (v2 != NULL, FALSE); return memcmp (v1, v2, sizeof (float) * 4) == 0 ? TRUE : FALSE; }
CoglBitmap * cogl_bitmap_new_from_file (CoglContext *ctx, const char *filename, CoglError **error) { _COGL_RETURN_VAL_IF_FAIL (filename != NULL, NULL); _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); return _cogl_bitmap_from_file (ctx, filename, error); }
CoglBitmap * cogl_android_bitmap_new_from_asset (CoglContext *ctx, AAssetManager *manager, const char *filename, CoglError **error) { _COGL_RETURN_VAL_IF_FAIL (ctx != NULL, NULL); _COGL_RETURN_VAL_IF_FAIL (manager != NULL, NULL); _COGL_RETURN_VAL_IF_FAIL (filename != NULL, NULL); _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); return _cogl_android_bitmap_new_from_asset (ctx, manager, filename, error); }
CoglSubTexture * cogl_sub_texture_new (CoglContext *ctx, CoglTexture *next_texture, int sub_x, int sub_y, int sub_width, int sub_height) { CoglTexture *full_texture; CoglSubTexture *sub_tex; CoglTexture *tex; unsigned int next_width, next_height; next_width = cogl_texture_get_width (next_texture); next_height = cogl_texture_get_height (next_texture); /* The region must specify a non-zero subset of the full texture */ _COGL_RETURN_VAL_IF_FAIL (sub_x >= 0 && sub_y >= 0, NULL); _COGL_RETURN_VAL_IF_FAIL (sub_width > 0 && sub_height > 0, NULL); _COGL_RETURN_VAL_IF_FAIL (sub_x + sub_width <= next_width, NULL); _COGL_RETURN_VAL_IF_FAIL (sub_y + sub_height <= next_height, NULL); sub_tex = g_new (CoglSubTexture, 1); tex = COGL_TEXTURE (sub_tex); _cogl_texture_init (tex, ctx, sub_width, sub_height, _cogl_texture_get_format (next_texture), NULL, /* no loader */ &cogl_sub_texture_vtable); /* If the next texture is also a sub texture we can avoid one level of indirection by referencing the full texture of that texture instead. */ if (cogl_is_sub_texture (next_texture)) { CoglSubTexture *other_sub_tex = COGL_SUB_TEXTURE (next_texture); full_texture = other_sub_tex->full_texture; sub_x += other_sub_tex->sub_x; sub_y += other_sub_tex->sub_y; } else full_texture = next_texture; sub_tex->next_texture = cogl_object_ref (next_texture); sub_tex->full_texture = cogl_object_ref (full_texture); sub_tex->sub_x = sub_x; sub_tex->sub_y = sub_y; return _cogl_sub_texture_object_new (sub_tex); }
CoglBool cogl_buffer_set_data (CoglBuffer *buffer, size_t offset, const void *data, size_t size) { _COGL_RETURN_VAL_IF_FAIL (cogl_is_buffer (buffer), FALSE); _COGL_RETURN_VAL_IF_FAIL ((offset + size) <= buffer->size, FALSE); if (G_UNLIKELY (buffer->immutable_ref)) warn_about_midscene_changes (); return buffer->vtable.set_data (buffer, offset, data, size); }
CoglBool cogl_pipeline_set_depth_state (CoglPipeline *pipeline, const CoglDepthState *depth_state, CoglError **error) { CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; CoglPipeline *authority; CoglDepthState *orig_state; _COGL_GET_CONTEXT (ctx, FALSE); _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); _COGL_RETURN_VAL_IF_FAIL (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); authority = _cogl_pipeline_get_authority (pipeline, state); orig_state = &authority->big_state->depth_state; if (orig_state->test_enabled == depth_state->test_enabled && orig_state->write_enabled == depth_state->write_enabled && orig_state->test_function == depth_state->test_function && orig_state->range_near == depth_state->range_near && orig_state->range_far == depth_state->range_far) return TRUE; if (ctx->driver == COGL_DRIVER_GLES1 && (depth_state->range_near != 0 || depth_state->range_far != 1)) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "glDepthRange not available on GLES 1"); return FALSE; } /* - Flush journal primitives referencing the current state. * - Make sure the pipeline has no dependants so it may be modified. * - If the pipeline isn't currently an authority for the state being * changed, then initialize that state from the current authority. */ _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); pipeline->big_state->depth_state = *depth_state; _cogl_pipeline_update_authority (pipeline, authority, state, _cogl_pipeline_depth_state_equal); return TRUE; }
CoglBool cogl_vector3_equal_with_epsilon (const float *vector0, const float *vector1, float epsilon) { _COGL_RETURN_VAL_IF_FAIL (vector0 != NULL, FALSE); _COGL_RETURN_VAL_IF_FAIL (vector1 != NULL, FALSE); if (fabsf (vector0[X] - vector1[X]) < epsilon && fabsf (vector0[Y] - vector1[Y]) < epsilon && fabsf (vector0[Z] - vector1[Z]) < epsilon) return TRUE; else return FALSE; }
gboolean _cogl_texture_2d_gl_allocate (CoglTexture *tex, CoglError **error) { CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); CoglTextureLoader *loader = tex->loader; _COGL_RETURN_VAL_IF_FAIL (loader, FALSE); switch (loader->src_type) { case COGL_TEXTURE_SOURCE_TYPE_SIZED: return allocate_with_size (tex_2d, loader, error); case COGL_TEXTURE_SOURCE_TYPE_BITMAP: return allocate_from_bitmap (tex_2d, loader, error); case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE: #if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) return allocate_from_egl_image (tex_2d, loader, error); #else g_return_val_if_reached (FALSE); #endif case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN: return allocate_from_gl_foreign (tex_2d, loader, error); case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL: #if defined (COGL_HAS_EGL_SUPPORT) return allocate_custom_egl_image_external (tex_2d, loader, error); #else g_return_val_if_reached (FALSE); #endif } g_return_val_if_reached (FALSE); }
CoglBitmap * _cogl_bitmap_from_file (const char *filename, GError **error) { static CoglUserDataKey bitmap_data_key; CoglBitmap *bmp; int stb_pixel_format; int width; int height; uint8_t *pixels; _COGL_GET_CONTEXT (ctx, NULL); _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, FALSE); /* Load from file using stb */ pixels = stbi_load (filename, &width, &height, &stb_pixel_format, STBI_rgb_alpha); if (pixels == NULL) return FALSE; /* Store bitmap info */ bmp = cogl_bitmap_new_for_data (ctx, width, height, COGL_PIXEL_FORMAT_RGBA_8888, width * 4, /* rowstride */ pixels); /* Register a destroy function so the pixel data will be freed automatically when the bitmap object is destroyed */ cogl_object_set_user_data (COGL_OBJECT (bmp), &bitmap_data_key, pixels, free); return bmp; }
CoglPathFillRule cogl_path_get_fill_rule (CoglPath *path) { _COGL_RETURN_VAL_IF_FAIL (cogl_is_path (path), COGL_PATH_FILL_RULE_NON_ZERO); return path->data->fill_rule; }
int cogl_sdl_renderer_get_event_type (CoglRenderer *renderer) { _COGL_RETURN_VAL_IF_FAIL (renderer->sdl_event_type_set, SDL_USEREVENT); return renderer->sdl_event_type; }
static CoglBool toggle_texcood_attribute_enabled_cb (int bit_num, void *user_data) { ForeachChangedBitState *state = user_data; CoglContext *context = state->context; _COGL_RETURN_VAL_IF_FAIL ((context->private_feature_flags & COGL_PRIVATE_FEATURE_FIXED_FUNCTION), FALSE); #if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES) { CoglBool enabled = _cogl_bitmask_get (state->new_bits, bit_num); GE( context, glClientActiveTexture (GL_TEXTURE0 + bit_num) ); if (enabled) GE( context, glEnableClientState (GL_TEXTURE_COORD_ARRAY) ); else GE( context, glDisableClientState (GL_TEXTURE_COORD_ARRAY) ); } #endif return TRUE; }
CoglTexture * cogl_texture_new_from_file (const char *filename, CoglTextureFlags flags, CoglPixelFormat internal_format, CoglError **error) { CoglBitmap *bmp; CoglTexture *texture = NULL; _COGL_GET_CONTEXT (ctx, NULL); _COGL_RETURN_VAL_IF_FAIL (error == NULL || *error == NULL, NULL); bmp = cogl_bitmap_new_from_file (filename, error); if (bmp == NULL) return NULL; texture = _cogl_texture_new_from_bitmap (bmp, flags, internal_format, TRUE, /* can convert in-place */ error); cogl_object_unref (bmp); return texture; }
CoglVerticesMode cogl_primitive_get_mode (CoglPrimitive *primitive) { _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), 0); return primitive->mode; }
CoglPrimitive * cogl_primitive_new_with_attributes (CoglVerticesMode mode, int n_vertices, CoglAttribute **attributes, int n_attributes) { CoglPrimitive *primitive; int i; primitive = g_slice_alloc (sizeof (CoglPrimitive) + sizeof (CoglAttribute *) * (n_attributes - 1)); primitive->mode = mode; primitive->first_vertex = 0; primitive->n_vertices = n_vertices; primitive->indices = NULL; primitive->immutable_ref = 0; primitive->n_attributes = n_attributes; primitive->n_embedded_attributes = n_attributes; primitive->attributes = &primitive->embedded_attribute; for (i = 0; i < n_attributes; i++) { CoglAttribute *attribute = attributes[i]; cogl_object_ref (attribute); _COGL_RETURN_VAL_IF_FAIL (cogl_is_attribute (attribute), NULL); primitive->attributes[i] = attribute; } return _cogl_primitive_object_new (primitive); }
int cogl_primitive_get_first_vertex (CoglPrimitive *primitive) { _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), 0); return primitive->first_vertex; }
int cogl_primitive_get_n_vertices (CoglPrimitive *primitive) { _COGL_RETURN_VAL_IF_FAIL (cogl_is_primitive (primitive), 0); return primitive->n_vertices; }
EGLImageKHR _cogl_egl_create_image (CoglContext *ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attribs) { CoglDisplayEGL *egl_display = ctx->display->winsys; CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; EGLContext egl_ctx; _COGL_RETURN_VAL_IF_FAIL (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR); /* The EGL_KHR_image_pixmap spec explicitly states that EGL_NO_CONTEXT must * always be used in conjunction with the EGL_NATIVE_PIXMAP_KHR target */ #ifdef EGL_KHR_image_pixmap if (target == EGL_NATIVE_PIXMAP_KHR) egl_ctx = EGL_NO_CONTEXT; else #endif egl_ctx = egl_display->egl_context; return egl_renderer->pf_eglCreateImage (egl_renderer->edpy, egl_ctx, target, buffer, attribs); }
static gboolean _cogl_winsys_context_init (CoglContext *context, GError **error) { CoglRenderer *renderer = context->display->renderer; CoglDisplayEGL *egl_display = context->display->winsys; CoglRendererEGL *egl_renderer = renderer->winsys; context->winsys = g_new0 (CoglContextEGL, 1); _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); memset (context->winsys_features, 0, sizeof (context->winsys_features)); check_egl_extensions (renderer); if (!_cogl_context_update_features (context, error)) return FALSE; if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION) { COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); } if (egl_renderer->platform_vtable->context_init && !egl_renderer->platform_vtable->context_init (context, error)) return FALSE; return TRUE; }
Display * cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer) { _COGL_RETURN_VAL_IF_FAIL (cogl_is_renderer (renderer), NULL); return renderer->foreign_xdpy; }
CoglWinsysID cogl_renderer_get_winsys_id (CoglRenderer *renderer) { _COGL_RETURN_VAL_IF_FAIL (renderer->connected, 0); return renderer->winsys_vtable->id; }
CoglDriver cogl_renderer_get_driver (CoglRenderer *renderer) { _COGL_RETURN_VAL_IF_FAIL (renderer->connected, 0); return renderer->driver; }