diff options
Diffstat (limited to 'cogl/cogl')
285 files changed, 0 insertions, 85576 deletions
diff --git a/cogl/cogl/cogl-atlas-texture-private.h b/cogl/cogl/cogl-atlas-texture-private.h deleted file mode 100644 index 336bf1cfa..000000000 --- a/cogl/cogl/cogl-atlas-texture-private.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef _COGL_ATLAS_TEXTURE_PRIVATE_H_ -#define _COGL_ATLAS_TEXTURE_PRIVATE_H_ - -#include "cogl-object-private.h" -#include "cogl-texture-private.h" -#include "cogl-rectangle-map.h" -#include "cogl-atlas.h" -#include "cogl-atlas-texture.h" - -struct _CoglAtlasTexture -{ - CoglTexture _parent; - - /* The format that the texture is in. This isn't necessarily the - same format as the atlas texture because we can store - pre-multiplied and non-pre-multiplied textures together */ - CoglPixelFormat internal_format; - - /* The rectangle that was used to add this texture to the - atlas. This includes the 1-pixel border */ - CoglRectangleMapEntry rectangle; - - /* The atlas that this texture is in. If the texture is no longer in - an atlas then this will be NULL. A reference is taken on the - atlas by the texture (but not vice versa so there is no cycle) */ - CoglAtlas *atlas; - - /* Either a CoglSubTexture representing the atlas region for easy - * rendering or if the texture has been migrated out of the atlas it - * may be some other texture type such as CoglTexture2D */ - CoglTexture *sub_texture; -}; - -CoglAtlasTexture * -_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, - gboolean can_convert_in_place); - -COGL_EXPORT void -_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data); - -COGL_EXPORT void -_cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data); - -gboolean -_cogl_is_atlas_texture (void *object); - -#endif /* _COGL_ATLAS_TEXTURE_PRIVATE_H_ */ diff --git a/cogl/cogl/cogl-atlas-texture.c b/cogl/cogl/cogl-atlas-texture.c deleted file mode 100644 index 9ec19b755..000000000 --- a/cogl/cogl/cogl-atlas-texture.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-atlas-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-sub-texture-private.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-texture-driver.h" -#include "cogl-rectangle-map.h" -#include "cogl-journal-private.h" -#include "cogl-atlas.h" -#include "cogl1-context.h" -#include "cogl-sub-texture.h" -#include "cogl-gtype-private.h" -#include "driver/gl/cogl-texture-gl-private.h" - -#include <stdlib.h> - -static void _cogl_atlas_texture_free (CoglAtlasTexture *sub_tex); - -COGL_TEXTURE_DEFINE (AtlasTexture, atlas_texture); -COGL_GTYPE_DEFINE_CLASS (AtlasTexture, atlas_texture); - -static const CoglTextureVtable cogl_atlas_texture_vtable; - -static CoglSubTexture * -_cogl_atlas_texture_create_sub_texture (CoglTexture *full_texture, - const CoglRectangleMapEntry *rectangle) -{ - CoglContext *ctx = full_texture->context; - /* Create a subtexture for the given rectangle not including the - 1-pixel border */ - return cogl_sub_texture_new (ctx, - full_texture, - rectangle->x + 1, - rectangle->y + 1, - rectangle->width - 2, - rectangle->height - 2); -} - -static void -_cogl_atlas_texture_update_position_cb (void *user_data, - CoglTexture *new_texture, - const CoglRectangleMapEntry *rectangle) -{ - CoglAtlasTexture *atlas_tex = user_data; - - /* Update the sub texture */ - if (atlas_tex->sub_texture) - cogl_object_unref (atlas_tex->sub_texture); - atlas_tex->sub_texture = COGL_TEXTURE ( - _cogl_atlas_texture_create_sub_texture (new_texture, rectangle)); - - /* Update the position */ - atlas_tex->rectangle = *rectangle; -} - -static void -_cogl_atlas_texture_pre_reorganize_foreach_cb - (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data) -{ - CoglAtlasTexture *atlas_tex = rectangle_data; - - /* Keep a reference to the texture because we don't want it to be - destroyed during the reorganization */ - cogl_object_ref (atlas_tex); - - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (atlas_tex)); -} - -static void -_cogl_atlas_texture_pre_reorganize_cb (void *data) -{ - CoglAtlas *atlas = data; - - /* We don't know if any journal entries currently depend on OpenGL - * texture coordinates that would be invalidated by reorganizing - * this atlas so we flush all journals before migrating. - * - * We are assuming that texture atlas migration never happens - * during a flush so we don't have to consider recursion here. - */ - cogl_flush (); - - if (atlas->map) - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_texture_pre_reorganize_foreach_cb, - NULL); -} - -typedef struct -{ - CoglAtlasTexture **textures; - /* Number of textures found so far */ - unsigned int n_textures; -} CoglAtlasTextureGetRectanglesData; - -static void -_cogl_atlas_texture_get_rectangles_cb (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data) -{ - CoglAtlasTextureGetRectanglesData *data = user_data; - - data->textures[data->n_textures++] = rectangle_data; -} - -static void -_cogl_atlas_texture_post_reorganize_cb (void *user_data) -{ - CoglAtlas *atlas = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (atlas->map) - { - CoglAtlasTextureGetRectanglesData data; - unsigned int i; - - data.textures = g_new (CoglAtlasTexture *, - _cogl_rectangle_map_get_n_rectangles (atlas->map)); - data.n_textures = 0; - - /* We need to remove all of the references that we took during - the preorganize callback. We have to get a separate array of - the textures because CoglRectangleMap doesn't support - removing rectangles during iteration */ - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_texture_get_rectangles_cb, - &data); - - for (i = 0; i < data.n_textures; i++) - { - /* Ignore textures that don't have an atlas yet. This will - happen when a new texture is added because we allocate - the structure for the texture so that it can get stored - in the atlas but it isn't a valid object yet */ - if (data.textures[i]->atlas) - cogl_object_unref (data.textures[i]); - } - - g_free (data.textures); - } - - /* Notify any listeners that an atlas has changed */ - g_hook_list_invoke (&ctx->atlas_reorganize_callbacks, FALSE); -} - -static void -_cogl_atlas_texture_atlas_destroyed_cb (void *user_data) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Remove the atlas from the global list */ - ctx->atlases = g_slist_remove (ctx->atlases, user_data); -} - -static CoglAtlas * -_cogl_atlas_texture_create_atlas (CoglContext *ctx) -{ - static CoglUserDataKey atlas_private_key; - - CoglAtlas *atlas = _cogl_atlas_new (COGL_PIXEL_FORMAT_RGBA_8888, - 0, - _cogl_atlas_texture_update_position_cb); - - _cogl_atlas_add_reorganize_callback (atlas, - _cogl_atlas_texture_pre_reorganize_cb, - _cogl_atlas_texture_post_reorganize_cb, - atlas); - - ctx->atlases = g_slist_prepend (ctx->atlases, atlas); - - /* Set some data on the atlas so we can get notification when it is - destroyed in order to remove it from the list. ctx->atlases - effectively holds a weak reference. We don't need a strong - reference because the atlas textures take a reference on the - atlas so it will stay alive */ - cogl_object_set_user_data (COGL_OBJECT (atlas), &atlas_private_key, atlas, - _cogl_atlas_texture_atlas_destroyed_cb); - - return atlas; -} - -static void -_cogl_atlas_texture_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - CoglMetaTexture *meta_texture = COGL_META_TEXTURE (atlas_tex->sub_texture); - - /* Forward on to the sub texture */ - cogl_meta_texture_foreach_in_region (meta_texture, - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - callback, - user_data); -} - -static void -_cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (atlas_tex->sub_texture, - wrap_mode_s, - wrap_mode_t); -} - -static void -_cogl_atlas_texture_remove_from_atlas (CoglAtlasTexture *atlas_tex) -{ - if (atlas_tex->atlas) - { - _cogl_atlas_remove (atlas_tex->atlas, - &atlas_tex->rectangle); - - cogl_object_unref (atlas_tex->atlas); - atlas_tex->atlas = NULL; - } -} - -static void -_cogl_atlas_texture_free (CoglAtlasTexture *atlas_tex) -{ - _cogl_atlas_texture_remove_from_atlas (atlas_tex); - - if (atlas_tex->sub_texture) - cogl_object_unref (atlas_tex->sub_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (atlas_tex)); -} - -static int -_cogl_atlas_texture_get_max_waste (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_max_waste (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_is_sliced (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_is_sliced (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_can_hardware_repeat (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_can_hardware_repeat (atlas_tex->sub_texture); -} - -static void -_cogl_atlas_texture_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_transform_coords_to_gl (atlas_tex->sub_texture, s, t); -} - -static CoglTransformResult -_cogl_atlas_texture_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_transform_quad_coords_to_gl (atlas_tex->sub_texture, - coords); -} - -static gboolean -_cogl_atlas_texture_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return cogl_texture_get_gl_texture (atlas_tex->sub_texture, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_atlas_texture_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - _cogl_texture_gl_flush_legacy_texobj_filters (atlas_tex->sub_texture, - min_filter, mag_filter); -} - -static void -_cogl_atlas_texture_migrate_out_of_atlas (CoglAtlasTexture *atlas_tex) -{ - CoglTexture *standalone_tex; - - /* Make sure this texture is not in the atlas */ - if (!atlas_tex->atlas) - return; - - COGL_NOTE (ATLAS, "Migrating texture out of the atlas"); - - /* We don't know if any journal entries currently depend on - * OpenGL texture coordinates that would be invalidated by - * migrating textures in this atlas so we flush all journals - * before migrating. - * - * We are assuming that texture atlas migration never happens - * during a flush so we don't have to consider recursion here. - */ - cogl_flush (); - - standalone_tex = - _cogl_atlas_copy_rectangle (atlas_tex->atlas, - atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y + 1, - atlas_tex->rectangle.width - 2, - atlas_tex->rectangle.height - 2, - atlas_tex->internal_format); - /* Note: we simply silently ignore failures to migrate a texture - * out (most likely due to lack of memory) and hope for the - * best. - * - * Maybe we should find a way to report the problem back to the - * app. - */ - if (!standalone_tex) - return; - - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (atlas_tex)); - - /* We need to unref the sub texture after doing the copy because - the copy can involve rendering which might cause the texture - to be used if it is used from a layer that is left in a - texture unit */ - cogl_object_unref (atlas_tex->sub_texture); - atlas_tex->sub_texture = standalone_tex; - - _cogl_atlas_texture_remove_from_atlas (atlas_tex); -} - -static void -_cogl_atlas_texture_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP)) - /* Mipmaps do not work well with the current atlas so instead - we'll just migrate the texture out and use a regular texture */ - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* Forward on to the sub texture */ - _cogl_texture_pre_paint (atlas_tex->sub_texture, flags); -} - -static void -_cogl_atlas_texture_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Sub textures can't support non-quad rendering so we'll just - migrate the texture out */ - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* Forward on to the sub texture */ - _cogl_texture_ensure_non_quad_rendering (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_set_region_with_border (CoglAtlasTexture *atlas_tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - CoglBitmap *bmp, - GError **error) -{ - CoglAtlas *atlas = atlas_tex->atlas; - - /* Copy the central data */ - if (!_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - dst_width, - dst_height, - bmp, - dst_x + atlas_tex->rectangle.x + 1, - dst_y + atlas_tex->rectangle.y + 1, - 0, /* level 0 */ - error)) - return FALSE; - - /* Update the left edge pixels */ - if (dst_x == 0 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - 1, dst_height, - bmp, - atlas_tex->rectangle.x, - dst_y + atlas_tex->rectangle.y + 1, - 0, /* level 0 */ - error)) - return FALSE; - /* Update the right edge pixels */ - if (dst_x + dst_width == atlas_tex->rectangle.width - 2 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x + dst_width - 1, src_y, - 1, dst_height, - bmp, - atlas_tex->rectangle.x + - atlas_tex->rectangle.width - 1, - dst_y + atlas_tex->rectangle.y + 1, - 0, /* level 0 */ - error)) - return FALSE; - /* Update the top edge pixels */ - if (dst_y == 0 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y, - dst_width, 1, - bmp, - dst_x + atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y, - 0, /* level 0 */ - error)) - return FALSE; - /* Update the bottom edge pixels */ - if (dst_y + dst_height == atlas_tex->rectangle.height - 2 && - !_cogl_texture_set_region_from_bitmap (atlas->texture, - src_x, src_y + dst_height - 1, - dst_width, 1, - bmp, - dst_x + atlas_tex->rectangle.x + 1, - atlas_tex->rectangle.y + - atlas_tex->rectangle.height - 1, - 0, /* level 0 */ - error)) - return FALSE; - - return TRUE; -} - -static CoglBitmap * -_cogl_atlas_texture_convert_bitmap_for_upload (CoglAtlasTexture *atlas_tex, - CoglBitmap *bmp, - CoglPixelFormat internal_format, - gboolean can_convert_in_place, - GError **error) -{ - CoglBitmap *upload_bmp; - CoglBitmap *override_bmp; - - /* We'll prepare to upload using the format of the actual texture of - the atlas texture instead of the format reported by - _cogl_texture_get_format which would be the original internal - format specified when the texture was created. However we'll - preserve the premult status of the internal format because the - images are all stored in the original premult format of the - original format so we do need to trigger the conversion */ - - internal_format = (COGL_PIXEL_FORMAT_RGBA_8888 | - (internal_format & COGL_PREMULT_BIT)); - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - can_convert_in_place, - error); - if (upload_bmp == NULL) - return NULL; - - /* We'll create another bitmap which uses the same data but - overrides the format to remove the premult flag so that uploads - to the atlas texture won't trigger the conversion again */ - - override_bmp = - _cogl_bitmap_new_shared (upload_bmp, - cogl_bitmap_get_format (upload_bmp) & - ~COGL_PREMULT_BIT, - cogl_bitmap_get_width (upload_bmp), - cogl_bitmap_get_height (upload_bmp), - cogl_bitmap_get_rowstride (upload_bmp)); - - cogl_object_unref (upload_bmp); - - return override_bmp; -} - -static gboolean -_cogl_atlas_texture_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - if (level != 0 && atlas_tex->atlas) - _cogl_atlas_texture_migrate_out_of_atlas (atlas_tex); - - /* If the texture is in the atlas then we need to copy the edge - pixels to the border */ - if (atlas_tex->atlas) - { - gboolean ret; - CoglBitmap *upload_bmp = - _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex, - bmp, - atlas_tex->internal_format, - FALSE, /* can't convert - in place */ - error); - if (!upload_bmp) - return FALSE; - - /* Upload the data ignoring the premult bit */ - ret = _cogl_atlas_texture_set_region_with_border (atlas_tex, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - upload_bmp, - error); - - cogl_object_unref (upload_bmp); - - return ret; - } - else - /* Otherwise we can just forward on to the sub texture */ - return _cogl_texture_set_region_from_bitmap (atlas_tex->sub_texture, - src_x, src_y, - dst_width, dst_height, - bmp, - dst_x, dst_y, - level, - error); -} - -static CoglPixelFormat -_cogl_atlas_texture_get_format (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* We don't want to forward this on the sub-texture because it isn't - the necessarily the same format. This will happen if the texture - isn't pre-multiplied */ - return atlas_tex->internal_format; -} - -static GLenum -_cogl_atlas_texture_get_gl_format (CoglTexture *tex) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - - /* Forward on to the sub texture */ - return _cogl_texture_gl_get_format (atlas_tex->sub_texture); -} - -static gboolean -_cogl_atlas_texture_can_use_format (CoglPixelFormat format) -{ - /* We don't care about the ordering or the premult status and we can - accept RGBA or RGB textures. Although we could also accept - luminance and alpha only textures or 16-bit formats it seems that - if the application is explicitly using these formats then they've - got a reason to want the lower memory requirements so putting - them in the atlas might not be a good idea */ - format &= ~(COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT); - return (format == COGL_PIXEL_FORMAT_RGB_888 || - format == COGL_PIXEL_FORMAT_RGBA_8888); -} - -static CoglAtlasTexture * -_cogl_atlas_texture_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglAtlasTexture *atlas_tex; - - COGL_NOTE (ATLAS, "Adding texture of size %ix%i", width, height); - - /* We need to allocate the texture now because we need the pointer - to set as the data for the rectangle in the atlas */ - atlas_tex = g_new0 (CoglAtlasTexture, 1); - /* Mark it as having no atlas so we don't try to unref it in - _cogl_atlas_texture_post_reorganize_cb */ - atlas_tex->atlas = NULL; - - _cogl_texture_init (COGL_TEXTURE (atlas_tex), - ctx, - width, height, - internal_format, - loader, - &cogl_atlas_texture_vtable); - - atlas_tex->sub_texture = NULL; - - atlas_tex->atlas = NULL; - - return _cogl_atlas_texture_object_new (atlas_tex); -} - -CoglAtlasTexture * -cogl_atlas_texture_new_with_size (CoglContext *ctx, - int width, - int height) -{ - CoglTextureLoader *loader; - - /* We can't atlas zero-sized textures because it breaks the atlas - * data structure */ - g_return_val_if_fail (width > 0 && height > 0, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; - loader->src.sized.width = width; - loader->src.sized.height = height; - - return _cogl_atlas_texture_create_base (ctx, width, height, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - loader); -} - -static gboolean -allocate_space (CoglAtlasTexture *atlas_tex, - int width, - int height, - CoglPixelFormat internal_format, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (atlas_tex); - CoglContext *ctx = tex->context; - CoglAtlas *atlas; - GSList *l; - - /* If the texture is in a strange format then we won't use it */ - if (!_cogl_atlas_texture_can_use_format (internal_format)) - { - COGL_NOTE (ATLAS, "Texture can not be added because the " - "format is unsupported"); - g_set_error_literal (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_FORMAT, - "Texture format unsuitable for atlasing"); - return FALSE; - } - - /* Look for an existing atlas that can hold the texture */ - for (l = ctx->atlases; l; l = l->next) - { - /* We need to take a reference on the atlas before trying to - * reserve space because in some circumstances atlas migration - * can cause the atlas to be freed */ - atlas = cogl_object_ref (l->data); - /* Try to make some space in the atlas for the texture */ - if (_cogl_atlas_reserve_space (atlas, - /* Add two pixels for the border */ - width + 2, height + 2, - atlas_tex)) - { - /* keep the atlas reference */ - break; - } - else - { - cogl_object_unref (atlas); - } - } - - /* If we couldn't find a suitable atlas then start another */ - if (l == NULL) - { - atlas = _cogl_atlas_texture_create_atlas (ctx); - COGL_NOTE (ATLAS, "Created new atlas for textures: %p", atlas); - if (!_cogl_atlas_reserve_space (atlas, - /* Add two pixels for the border */ - width + 2, height + 2, - atlas_tex)) - { - /* Ok, this means we really can't add it to the atlas */ - cogl_object_unref (atlas); - - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Not enough memory to atlas texture"); - return FALSE; - } - } - - atlas_tex->internal_format = internal_format; - - atlas_tex->atlas = atlas; - - return TRUE; -} - -static gboolean -allocate_with_size (CoglAtlasTexture *atlas_tex, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (atlas_tex); - CoglPixelFormat internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (allocate_space (atlas_tex, - loader->src.sized.width, - loader->src.sized.height, - internal_format, - error)) - { - _cogl_texture_set_allocated (COGL_TEXTURE (atlas_tex), - internal_format, - loader->src.sized.width, - loader->src.sized.height); - return TRUE; - } - else - return FALSE; -} - -static gboolean -allocate_from_bitmap (CoglAtlasTexture *atlas_tex, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (atlas_tex); - CoglBitmap *bmp = loader->src.bitmap.bitmap; - CoglPixelFormat bmp_format = cogl_bitmap_get_format (bmp); - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; - CoglPixelFormat internal_format; - CoglBitmap *upload_bmp; - - g_return_val_if_fail (atlas_tex->atlas == NULL, FALSE); - - internal_format = _cogl_texture_determine_internal_format (tex, bmp_format); - - upload_bmp = - _cogl_atlas_texture_convert_bitmap_for_upload (atlas_tex, - bmp, - internal_format, - can_convert_in_place, - error); - if (upload_bmp == NULL) - return FALSE; - - if (!allocate_space (atlas_tex, - width, - height, - internal_format, - error)) - { - cogl_object_unref (upload_bmp); - return FALSE; - } - - /* Defer to set_region so that we can share the code for copying the - edge pixels to the border. */ - if (!_cogl_atlas_texture_set_region_with_border (atlas_tex, - 0, /* src_x */ - 0, /* src_y */ - 0, /* dst_x */ - 0, /* dst_y */ - width, /* dst_width */ - height, /* dst_height */ - upload_bmp, - error)) - { - _cogl_atlas_texture_remove_from_atlas (atlas_tex); - cogl_object_unref (upload_bmp); - return FALSE; - } - - cogl_object_unref (upload_bmp); - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static gboolean -_cogl_atlas_texture_allocate (CoglTexture *tex, - GError **error) -{ - CoglAtlasTexture *atlas_tex = COGL_ATLAS_TEXTURE (tex); - CoglTextureLoader *loader = tex->loader; - - g_return_val_if_fail (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZED: - return allocate_with_size (atlas_tex, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (atlas_tex, loader, error); - default: - break; - } - - g_return_val_if_reached (FALSE); -} - -CoglAtlasTexture * -_cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp, - gboolean can_convert_in_place) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (cogl_is_bitmap (bmp), NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = cogl_object_ref (bmp); - loader->src.bitmap.can_convert_in_place = can_convert_in_place; - - return _cogl_atlas_texture_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - cogl_bitmap_get_format (bmp), - loader); -} - -CoglAtlasTexture * -cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp) -{ - return _cogl_atlas_texture_new_from_bitmap (bmp, FALSE); -} - -CoglAtlasTexture * -cogl_atlas_texture_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error) -{ - CoglBitmap *bmp; - CoglAtlasTexture *atlas_tex; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_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, 0); - - /* Wrap the data into a bitmap */ - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - atlas_tex = cogl_atlas_texture_new_from_bitmap (bmp); - - cogl_object_unref (bmp); - - if (atlas_tex && - !cogl_texture_allocate (COGL_TEXTURE (atlas_tex), error)) - { - cogl_object_unref (atlas_tex); - return NULL; - } - - return atlas_tex; -} - -CoglAtlasTexture * -cogl_atlas_texture_new_from_file (CoglContext *ctx, - const char *filename, - GError **error) -{ - CoglBitmap *bmp; - CoglAtlasTexture *atlas_tex = NULL; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - bmp = cogl_bitmap_new_from_file (filename, error); - if (bmp == NULL) - return NULL; - - atlas_tex = _cogl_atlas_texture_new_from_bitmap (bmp, - TRUE); /* convert in-place */ - - cogl_object_unref (bmp); - - return atlas_tex; -} - -void -_cogl_atlas_texture_add_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data) -{ - GHook *hook = g_hook_alloc (&ctx->atlas_reorganize_callbacks); - hook->func = callback; - hook->data = user_data; - g_hook_prepend (&ctx->atlas_reorganize_callbacks, hook); -} - -void -_cogl_atlas_texture_remove_reorganize_callback (CoglContext *ctx, - GHookFunc callback, - void *user_data) -{ - GHook *hook = g_hook_find_func_data (&ctx->atlas_reorganize_callbacks, - FALSE, - callback, - user_data); - - if (hook) - g_hook_destroy_link (&ctx->atlas_reorganize_callbacks, hook); -} - -static const CoglTextureVtable -cogl_atlas_texture_vtable = - { - FALSE, /* not primitive */ - _cogl_atlas_texture_allocate, - _cogl_atlas_texture_set_region, - NULL, /* is_get_data_supported */ - NULL, /* get_data */ - _cogl_atlas_texture_foreach_sub_texture_in_region, - _cogl_atlas_texture_get_max_waste, - _cogl_atlas_texture_is_sliced, - _cogl_atlas_texture_can_hardware_repeat, - _cogl_atlas_texture_transform_coords_to_gl, - _cogl_atlas_texture_transform_quad_coords_to_gl, - _cogl_atlas_texture_get_gl_texture, - _cogl_atlas_texture_gl_flush_legacy_texobj_filters, - _cogl_atlas_texture_pre_paint, - _cogl_atlas_texture_ensure_non_quad_rendering, - _cogl_atlas_texture_gl_flush_legacy_texobj_wrap_modes, - _cogl_atlas_texture_get_format, - _cogl_atlas_texture_get_gl_format, - NULL /* set_auto_mipmap */ - }; diff --git a/cogl/cogl/cogl-atlas-texture.h b/cogl/cogl/cogl-atlas-texture.h deleted file mode 100644 index 5c6184a42..000000000 --- a/cogl/cogl/cogl-atlas-texture.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef _COGL_ATLAS_TEXTURE_H_ -#define _COGL_ATLAS_TEXTURE_H_ - -#include <cogl/cogl-context.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-atlas-texture - * @short_description: Functions for managing textures in Cogl's global - * set of texture atlases - * - * A texture atlas is a texture that contains many smaller images that - * an application is interested in. These are packed together as a way - * of optimizing drawing with those images by avoiding the costs of - * repeatedly telling the hardware to change what texture it should - * sample from. This can enable more geometry to be batched together - * into few draw calls. - * - * Each #CoglContext has an shared, pool of texture atlases that are - * are managed by Cogl. - * - * This api lets applications upload texture data into one of Cogl's - * shared texture atlases using a high-level #CoglAtlasTexture which - * represents a sub-region of one of these atlases. - * - * <note>A #CoglAtlasTexture is a high-level meta texture which has - * some limitations to be aware of. Please see the documentation for - * #CoglMetaTexture for more details.</note> - */ - - -typedef struct _CoglAtlasTexture CoglAtlasTexture; -#define COGL_ATLAS_TEXTURE(tex) ((CoglAtlasTexture *) tex) - -/** - * cogl_atlas_texture_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_atlas_texture_get_gtype (void); - -/** - * cogl_atlas_texture_new_with_size: - * @ctx: A #CoglContext - * @width: The width of your atlased texture. - * @height: The height of your atlased texture. - * - * Creates a #CoglAtlasTexture with a given @width and @height. A - * #CoglAtlasTexture represents a sub-region within one of Cogl's - * shared texture atlases. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * <note>Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases.</note> - * - * <note>The returned #CoglAtlasTexture is a high-level meta-texture - * with some limitations. See the documentation for #CoglMetaTexture - * for more details.</note> - * - * Returns: (transfer full): A new #CoglAtlasTexture object. - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT CoglAtlasTexture * -cogl_atlas_texture_new_with_size (CoglContext *ctx, - int width, - int height); - -/** - * cogl_atlas_texture_new_from_file: - * @ctx: A #CoglContext - * @filename: the file to load - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a #CoglAtlasTexture from an image file. A #CoglAtlasTexture - * represents a sub-region within one of Cogl's shared texture - * atlases. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * <note>Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases.</note> - * - * <note>The returned #CoglAtlasTexture is a high-level meta-texture - * with some limitations. See the documentation for #CoglMetaTexture - * for more details.</note> - * - * Return value: (transfer full): A new #CoglAtlasTexture object or - * %NULL on failure and @error will be updated. - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT CoglAtlasTexture * -cogl_atlas_texture_new_from_file (CoglContext *ctx, - const char *filename, - GError **error); - -/** - * cogl_atlas_texture_new_from_data: - * @ctx: A #CoglContext - * @width: width of texture in pixels - * @height: height of texture in pixels - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @rowstride: the memory offset in bytes between the start of each - * row in @data. A value of 0 will make Cogl automatically - * calculate @rowstride from @width and @format. - * @data: pointer to the memory region where the source buffer resides - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a new #CoglAtlasTexture texture based on data residing in - * memory. A #CoglAtlasTexture represents a sub-region within one of - * Cogl's shared texture atlases. - * - * <note>This api will always immediately allocate GPU memory for the - * texture and upload the given data so that the @data pointer does - * not need to remain valid once this function returns. This means it - * is not possible to configure the texture before it is allocated. If - * you do need to configure the texture before allocation (to specify - * constraints on the internal format for example) then you can - * instead create a #CoglBitmap for your data and use - * cogl_atlas_texture_new_from_bitmap() or use - * cogl_atlas_texture_new_with_size() and then upload data using - * cogl_texture_set_data()</note> - * - * <note>Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases.</note> - * - * <note>The returned #CoglAtlasTexture is a high-level - * meta-texture with some limitations. See the documentation for - * #CoglMetaTexture for more details.</note> - * - * Return value: (transfer full): A new #CoglAtlasTexture object or - * %NULL on failure and @error will be updated. - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT CoglAtlasTexture * -cogl_atlas_texture_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error); - -/** - * cogl_atlas_texture_new_from_bitmap: - * @bitmap: A #CoglBitmap - * - * Creates a new #CoglAtlasTexture texture based on data residing in a - * @bitmap. A #CoglAtlasTexture represents a sub-region within one of - * Cogl's shared texture atlases. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * <note>Allocate call can fail if Cogl considers the internal - * format to be incompatible with the format of its internal - * atlases.</note> - * - * <note>The returned #CoglAtlasTexture is a high-level meta-texture - * with some limitations. See the documentation for #CoglMetaTexture - * for more details.</note> - * - * Returns: (transfer full): A new #CoglAtlasTexture object. - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT CoglAtlasTexture * -cogl_atlas_texture_new_from_bitmap (CoglBitmap *bmp); - -/** - * cogl_is_atlas_texture: - * @object: a #CoglObject - * - * Checks whether the given object references a #CoglAtlasTexture - * - * Return value: %TRUE if the passed object represents an atlas - * texture and %FALSE otherwise - * - * Since: 1.16 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_atlas_texture (void *object); - -G_END_DECLS - -#endif /* _COGL_ATLAS_TEXTURE_H_ */ diff --git a/cogl/cogl/cogl-atlas.c b/cogl/cogl/cogl-atlas.c deleted file mode 100644 index 3333f2f94..000000000 --- a/cogl/cogl/cogl-atlas.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-atlas.h" -#include "cogl-rectangle-map.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-2d-sliced.h" -#include "cogl-texture-driver.h" -#include "cogl-debug.h" -#include "cogl-framebuffer-private.h" -#include "cogl-blit.h" -#include "cogl-private.h" - -#include <stdlib.h> - -static void _cogl_atlas_free (CoglAtlas *atlas); - -COGL_OBJECT_INTERNAL_DEFINE (Atlas, atlas); - -CoglAtlas * -_cogl_atlas_new (CoglPixelFormat texture_format, - CoglAtlasFlags flags, - CoglAtlasUpdatePositionCallback update_position_cb) -{ - CoglAtlas *atlas = g_new (CoglAtlas, 1); - - atlas->update_position_cb = update_position_cb; - atlas->map = NULL; - atlas->texture = NULL; - atlas->flags = flags; - atlas->texture_format = texture_format; - g_hook_list_init (&atlas->pre_reorganize_callbacks, sizeof (GHook)); - g_hook_list_init (&atlas->post_reorganize_callbacks, sizeof (GHook)); - - return _cogl_atlas_object_new (atlas); -} - -static void -_cogl_atlas_free (CoglAtlas *atlas) -{ - COGL_NOTE (ATLAS, "%p: Atlas destroyed", atlas); - - if (atlas->texture) - cogl_object_unref (atlas->texture); - if (atlas->map) - _cogl_rectangle_map_free (atlas->map); - - g_hook_list_clear (&atlas->pre_reorganize_callbacks); - g_hook_list_clear (&atlas->post_reorganize_callbacks); - - g_free (atlas); -} - -typedef struct _CoglAtlasRepositionData -{ - /* The current user data for this texture */ - void *user_data; - /* The old and new positions of the texture */ - CoglRectangleMapEntry old_position; - CoglRectangleMapEntry new_position; -} CoglAtlasRepositionData; - -static void -_cogl_atlas_migrate (CoglAtlas *atlas, - unsigned int n_textures, - CoglAtlasRepositionData *textures, - CoglTexture *old_texture, - CoglTexture *new_texture, - void *skip_user_data) -{ - unsigned int i; - CoglBlitData blit_data; - - /* If the 'disable migrate' flag is set then we won't actually copy - the textures to their new location. Instead we'll just invoke the - callback to update the position */ - if ((atlas->flags & COGL_ATLAS_DISABLE_MIGRATION)) - for (i = 0; i < n_textures; i++) - /* Update the texture position */ - atlas->update_position_cb (textures[i].user_data, - new_texture, - &textures[i].new_position); - else - { - _cogl_blit_begin (&blit_data, new_texture, old_texture); - - for (i = 0; i < n_textures; i++) - { - /* Skip the texture that is being added because it doesn't contain - any data yet */ - if (textures[i].user_data != skip_user_data) - _cogl_blit (&blit_data, - textures[i].old_position.x, - textures[i].old_position.y, - textures[i].new_position.x, - textures[i].new_position.y, - textures[i].new_position.width, - textures[i].new_position.height); - - /* Update the texture position */ - atlas->update_position_cb (textures[i].user_data, - new_texture, - &textures[i].new_position); - } - - _cogl_blit_end (&blit_data); - } -} - -typedef struct _CoglAtlasGetRectanglesData -{ - CoglAtlasRepositionData *textures; - /* Number of textures found so far */ - unsigned int n_textures; -} CoglAtlasGetRectanglesData; - -static void -_cogl_atlas_get_rectangles_cb (const CoglRectangleMapEntry *rectangle, - void *rect_data, - void *user_data) -{ - CoglAtlasGetRectanglesData *data = user_data; - - data->textures[data->n_textures].old_position = *rectangle; - data->textures[data->n_textures++].user_data = rect_data; -} - -static void -_cogl_atlas_get_next_size (unsigned int *map_width, - unsigned int *map_height) -{ - /* Double the size of the texture by increasing whichever dimension - is smaller */ - if (*map_width < *map_height) - *map_width <<= 1; - else - *map_height <<= 1; -} - -static void -_cogl_atlas_get_initial_size (CoglPixelFormat format, - unsigned int *map_width, - unsigned int *map_height) -{ - unsigned int size; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_intformat, - &gl_format, - &gl_type); - - /* At least on Intel hardware, the texture size will be rounded up - to at least 1MB so we might as well try to aim for that as an - initial minimum size. If the format is only 1 byte per pixel we - can use 1024x1024, otherwise we'll assume it will take 4 bytes - per pixel and use 512x512. */ - if (cogl_pixel_format_get_bytes_per_pixel (format, 0) == 1) - size = 1024; - else - size = 512; - - /* Some platforms might not support this large size so we'll - decrease the size until it can */ - while (size > 1 && - !ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_2D, - gl_intformat, - gl_format, - gl_type, - size, size)) - size >>= 1; - - *map_width = size; - *map_height = size; -} - -static CoglRectangleMap * -_cogl_atlas_create_map (CoglPixelFormat format, - unsigned int map_width, - unsigned int map_height, - unsigned int n_textures, - CoglAtlasRepositionData *textures) -{ - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - _COGL_GET_CONTEXT (ctx, NULL); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_intformat, - &gl_format, - &gl_type); - - /* Keep trying increasingly larger atlases until we can fit all of - the textures */ - while (ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_2D, - gl_intformat, - gl_format, - gl_type, - map_width, map_height)) - { - CoglRectangleMap *new_atlas = _cogl_rectangle_map_new (map_width, - map_height, - NULL); - unsigned int i; - - COGL_NOTE (ATLAS, "Trying to resize the atlas to %ux%u", - map_width, map_height); - - /* Add all of the textures and keep track of the new position */ - for (i = 0; i < n_textures; i++) - if (!_cogl_rectangle_map_add (new_atlas, - textures[i].old_position.width, - textures[i].old_position.height, - textures[i].user_data, - &textures[i].new_position)) - break; - - /* If the atlas can contain all of the textures then we have a - winner */ - if (i >= n_textures) - return new_atlas; - else - COGL_NOTE (ATLAS, "Atlas size abandoned after trying " - "%u out of %u textures", - i, n_textures); - - _cogl_rectangle_map_free (new_atlas); - _cogl_atlas_get_next_size (&map_width, &map_height); - } - - /* If we get here then there's no atlas that can accommodate all of - the rectangles */ - - return NULL; -} - -static CoglTexture2D * -_cogl_atlas_create_texture (CoglAtlas *atlas, - int width, - int height) -{ - CoglTexture2D *tex; - GError *ignore_error = NULL; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail ( - cogl_pixel_format_get_n_planes (atlas->texture_format) == 1, - NULL); - - if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE)) - { - uint8_t *clear_data; - CoglBitmap *clear_bmp; - int bpp = cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format, - 0); - - /* Create a buffer of zeroes to initially clear the texture */ - clear_data = g_malloc0 (width * height * bpp); - clear_bmp = cogl_bitmap_new_for_data (ctx, - width, - height, - atlas->texture_format, - width * bpp, - clear_data); - - tex = cogl_texture_2d_new_from_bitmap (clear_bmp); - - _cogl_texture_set_internal_format (COGL_TEXTURE (tex), - atlas->texture_format); - - if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error)) - { - g_error_free (ignore_error); - cogl_object_unref (tex); - tex = NULL; - } - - cogl_object_unref (clear_bmp); - - g_free (clear_data); - } - else - { - tex = cogl_texture_2d_new_with_size (ctx, width, height); - - _cogl_texture_set_internal_format (COGL_TEXTURE (tex), - atlas->texture_format); - - if (!cogl_texture_allocate (COGL_TEXTURE (tex), &ignore_error)) - { - g_error_free (ignore_error); - cogl_object_unref (tex); - tex = NULL; - } - } - - return tex; -} - -static int -_cogl_atlas_compare_size_cb (const void *a, - const void *b) -{ - const CoglAtlasRepositionData *ta = a; - const CoglAtlasRepositionData *tb = b; - unsigned int a_size, b_size; - - a_size = ta->old_position.width * ta->old_position.height; - b_size = tb->old_position.width * tb->old_position.height; - - return a_size < b_size ? 1 : a_size > b_size ? -1 : 0; -} - -static void -_cogl_atlas_notify_pre_reorganize (CoglAtlas *atlas) -{ - g_hook_list_invoke (&atlas->pre_reorganize_callbacks, FALSE); -} - -static void -_cogl_atlas_notify_post_reorganize (CoglAtlas *atlas) -{ - g_hook_list_invoke (&atlas->post_reorganize_callbacks, FALSE); -} - -gboolean -_cogl_atlas_reserve_space (CoglAtlas *atlas, - unsigned int width, - unsigned int height, - void *user_data) -{ - CoglAtlasGetRectanglesData data; - CoglRectangleMap *new_map; - CoglTexture2D *new_tex; - unsigned int map_width = 0, map_height = 0; - gboolean ret; - CoglRectangleMapEntry new_position; - - /* Check if we can fit the rectangle into the existing map */ - if (atlas->map && - _cogl_rectangle_map_add (atlas->map, width, height, - user_data, - &new_position)) - { - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - /* waste as a percentage */ - _cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); - - atlas->update_position_cb (user_data, - atlas->texture, - &new_position); - - return TRUE; - } - - /* If we make it here then we need to reorganize the atlas. First - we'll notify any users of the atlas that this is going to happen - so that for example in CoglAtlasTexture it can notify that the - storage has changed and cause a flush */ - _cogl_atlas_notify_pre_reorganize (atlas); - - /* Get an array of all the textures currently in the atlas. */ - data.n_textures = 0; - if (atlas->map == NULL) - data.textures = g_malloc (sizeof (CoglAtlasRepositionData)); - else - { - unsigned int n_rectangles = - _cogl_rectangle_map_get_n_rectangles (atlas->map); - data.textures = g_malloc (sizeof (CoglAtlasRepositionData) * - (n_rectangles + 1)); - _cogl_rectangle_map_foreach (atlas->map, - _cogl_atlas_get_rectangles_cb, - &data); - } - - /* Add the new rectangle as a dummy texture so that it can be - positioned with the rest */ - data.textures[data.n_textures].old_position.x = 0; - data.textures[data.n_textures].old_position.y = 0; - data.textures[data.n_textures].old_position.width = width; - data.textures[data.n_textures].old_position.height = height; - data.textures[data.n_textures++].user_data = user_data; - - /* The atlasing algorithm works a lot better if the rectangles are - added in decreasing order of size so we'll first sort the - array */ - qsort (data.textures, data.n_textures, - sizeof (CoglAtlasRepositionData), - _cogl_atlas_compare_size_cb); - - /* Try to create a new atlas that can contain all of the textures */ - if (atlas->map) - { - map_width = _cogl_rectangle_map_get_width (atlas->map); - map_height = _cogl_rectangle_map_get_height (atlas->map); - - /* If there is enough space in for the new rectangle in the - existing atlas with at least 6% waste we'll start with the - same size, otherwise we'll immediately double it */ - if ((map_width * map_height - - _cogl_rectangle_map_get_remaining_space (atlas->map) + - width * height) * 53 / 50 > - map_width * map_height) - _cogl_atlas_get_next_size (&map_width, &map_height); - } - else - _cogl_atlas_get_initial_size (atlas->texture_format, - &map_width, &map_height); - - new_map = _cogl_atlas_create_map (atlas->texture_format, - map_width, map_height, - data.n_textures, data.textures); - - /* If we can't create a map with the texture then give up */ - if (new_map == NULL) - { - COGL_NOTE (ATLAS, "%p: Could not fit texture in the atlas", atlas); - ret = FALSE; - } - /* We need to migrate the existing textures into a new texture */ - else if ((new_tex = _cogl_atlas_create_texture - (atlas, - _cogl_rectangle_map_get_width (new_map), - _cogl_rectangle_map_get_height (new_map))) == NULL) - { - COGL_NOTE (ATLAS, "%p: Could not create a CoglTexture2D", atlas); - _cogl_rectangle_map_free (new_map); - ret = FALSE; - } - else - { - int waste; - - COGL_NOTE (ATLAS, - "%p: Atlas %s with size %ix%i", - atlas, - atlas->map == NULL || - _cogl_rectangle_map_get_width (atlas->map) != - _cogl_rectangle_map_get_width (new_map) || - _cogl_rectangle_map_get_height (atlas->map) != - _cogl_rectangle_map_get_height (new_map) ? - "resized" : "reorganized", - _cogl_rectangle_map_get_width (new_map), - _cogl_rectangle_map_get_height (new_map)); - - if (atlas->map) - { - /* Move all the textures to the right position in the new - texture. This will also update the texture's rectangle */ - _cogl_atlas_migrate (atlas, - data.n_textures, - data.textures, - atlas->texture, - COGL_TEXTURE (new_tex), - user_data); - _cogl_rectangle_map_free (atlas->map); - cogl_object_unref (atlas->texture); - } - else - /* We know there's only one texture so we can just directly - update the rectangle from its new position */ - atlas->update_position_cb (data.textures[0].user_data, - COGL_TEXTURE (new_tex), - &data.textures[0].new_position); - - atlas->map = new_map; - atlas->texture = COGL_TEXTURE (new_tex); - - waste = (_cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); - - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - waste); - - ret = TRUE; - } - - g_free (data.textures); - - _cogl_atlas_notify_post_reorganize (atlas); - - return ret; -} - -void -_cogl_atlas_remove (CoglAtlas *atlas, - const CoglRectangleMapEntry *rectangle) -{ - _cogl_rectangle_map_remove (atlas->map, rectangle); - - COGL_NOTE (ATLAS, "%p: Removed rectangle sized %ix%i", - atlas, - rectangle->width, - rectangle->height); - COGL_NOTE (ATLAS, "%p: Atlas is %ix%i, has %i textures and is %i%% waste", - atlas, - _cogl_rectangle_map_get_width (atlas->map), - _cogl_rectangle_map_get_height (atlas->map), - _cogl_rectangle_map_get_n_rectangles (atlas->map), - _cogl_rectangle_map_get_remaining_space (atlas->map) * - 100 / (_cogl_rectangle_map_get_width (atlas->map) * - _cogl_rectangle_map_get_height (atlas->map))); -}; - -static CoglTexture * -create_migration_texture (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - GError *skip_error = NULL; - - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - - _cogl_texture_set_internal_format (tex, internal_format); - - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - cogl_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - CoglTexture2DSliced *tex_2ds = - cogl_texture_2d_sliced_new_with_size (ctx, - width, - height, - COGL_TEXTURE_MAX_WASTE); - - _cogl_texture_set_internal_format (COGL_TEXTURE (tex_2ds), - internal_format); - - tex = COGL_TEXTURE (tex_2ds); - } - - return tex; -} - -CoglTexture * -_cogl_atlas_copy_rectangle (CoglAtlas *atlas, - int x, - int y, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - CoglBlitData blit_data; - GError *ignore_error = NULL; - - _COGL_GET_CONTEXT (ctx, NULL); - - /* Create a new texture at the right size */ - tex = create_migration_texture (ctx, width, height, internal_format); - if (!cogl_texture_allocate (tex, &ignore_error)) - { - g_error_free (ignore_error); - cogl_object_unref (tex); - return NULL; - } - - /* Blit the data out of the atlas to the new texture. If FBOs - aren't available this will end up having to copy the entire - atlas texture */ - _cogl_blit_begin (&blit_data, tex, atlas->texture); - _cogl_blit (&blit_data, - x, y, - 0, 0, - width, height); - _cogl_blit_end (&blit_data); - - return tex; -} - -void -_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data) -{ - if (pre_callback) - { - GHook *hook = g_hook_alloc (&atlas->post_reorganize_callbacks); - hook->func = pre_callback; - hook->data = user_data; - g_hook_prepend (&atlas->pre_reorganize_callbacks, hook); - } - if (post_callback) - { - GHook *hook = g_hook_alloc (&atlas->pre_reorganize_callbacks); - hook->func = post_callback; - hook->data = user_data; - g_hook_prepend (&atlas->post_reorganize_callbacks, hook); - } -} - -void -_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data) -{ - if (pre_callback) - { - GHook *hook = g_hook_find_func_data (&atlas->pre_reorganize_callbacks, - FALSE, - pre_callback, - user_data); - if (hook) - g_hook_destroy_link (&atlas->pre_reorganize_callbacks, hook); - } - if (post_callback) - { - GHook *hook = g_hook_find_func_data (&atlas->post_reorganize_callbacks, - FALSE, - post_callback, - user_data); - if (hook) - g_hook_destroy_link (&atlas->post_reorganize_callbacks, hook); - } -} diff --git a/cogl/cogl/cogl-atlas.h b/cogl/cogl/cogl-atlas.h deleted file mode 100644 index 304161046..000000000 --- a/cogl/cogl/cogl-atlas.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __COGL_ATLAS_H -#define __COGL_ATLAS_H - -#include "cogl-rectangle-map.h" -#include "cogl-object-private.h" -#include "cogl-texture.h" - -typedef void -(* CoglAtlasUpdatePositionCallback) (void *user_data, - CoglTexture *new_texture, - const CoglRectangleMapEntry *rect); - -typedef enum -{ - COGL_ATLAS_CLEAR_TEXTURE = (1 << 0), - COGL_ATLAS_DISABLE_MIGRATION = (1 << 1) -} CoglAtlasFlags; - -typedef struct _CoglAtlas CoglAtlas; - -#define COGL_ATLAS(object) ((CoglAtlas *) object) - -struct _CoglAtlas -{ - CoglObject _parent; - - CoglRectangleMap *map; - - CoglTexture *texture; - CoglPixelFormat texture_format; - CoglAtlasFlags flags; - - CoglAtlasUpdatePositionCallback update_position_cb; - - GHookList pre_reorganize_callbacks; - GHookList post_reorganize_callbacks; -}; - -COGL_EXPORT CoglAtlas * -_cogl_atlas_new (CoglPixelFormat texture_format, - CoglAtlasFlags flags, - CoglAtlasUpdatePositionCallback update_position_cb); - -COGL_EXPORT gboolean -_cogl_atlas_reserve_space (CoglAtlas *atlas, - unsigned int width, - unsigned int height, - void *user_data); - -void -_cogl_atlas_remove (CoglAtlas *atlas, - const CoglRectangleMapEntry *rectangle); - -CoglTexture * -_cogl_atlas_copy_rectangle (CoglAtlas *atlas, - int x, - int y, - int width, - int height, - CoglPixelFormat format); - -COGL_EXPORT void -_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data); - -void -_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, - GHookFunc pre_callback, - GHookFunc post_callback, - void *user_data); - -gboolean -_cogl_is_atlas (void *object); - -#endif /* __COGL_ATLAS_H */ diff --git a/cogl/cogl/cogl-attribute-buffer-private.h b/cogl/cogl/cogl-attribute-buffer-private.h deleted file mode 100644 index c5e8a276d..000000000 --- a/cogl/cogl/cogl-attribute-buffer-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_ATTRIBUTE_BUFFER_PRIVATE_H -#define __COGL_ATTRIBUTE_BUFFER_PRIVATE_H - -#include "cogl-buffer-private.h" - -struct _CoglAttributeBuffer -{ - CoglBuffer _parent; -}; - -#endif /* __COGL_ATTRIBUTE_BUFFER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-attribute-buffer.c b/cogl/cogl/cogl-attribute-buffer.c deleted file mode 100644 index 072fcfd32..000000000 --- a/cogl/cogl/cogl-attribute-buffer.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-object-private.h" -#include "cogl-attribute-buffer.h" -#include "cogl-attribute-buffer-private.h" -#include "cogl-context-private.h" -#include "cogl-gtype-private.h" - -static void _cogl_attribute_buffer_free (CoglAttributeBuffer *array); - -COGL_BUFFER_DEFINE (AttributeBuffer, attribute_buffer); -COGL_GTYPE_DEFINE_CLASS (AttributeBuffer, attribute_buffer); - -CoglAttributeBuffer * -cogl_attribute_buffer_new_with_size (CoglContext *context, - size_t bytes) -{ - CoglAttributeBuffer *buffer = g_new0 (CoglAttributeBuffer, 1); - - /* parent's constructor */ - _cogl_buffer_initialize (COGL_BUFFER (buffer), - context, - bytes, - COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, - COGL_BUFFER_USAGE_HINT_ATTRIBUTE_BUFFER, - COGL_BUFFER_UPDATE_HINT_STATIC); - - return _cogl_attribute_buffer_object_new (buffer); -} - -CoglAttributeBuffer * -cogl_attribute_buffer_new (CoglContext *context, - size_t bytes, - const void *data) -{ - CoglAttributeBuffer *buffer; - - buffer = cogl_attribute_buffer_new_with_size (context, bytes); - - /* Note: to keep the common cases simple this API doesn't throw - * GErrors, so developers can assume this function never returns - * NULL and we will simply abort on error. - * - * Developers wanting to catch errors can use - * cogl_attribute_buffer_new_with_size() and catch errors when later - * calling cogl_buffer_set_data() or cogl_buffer_map(). - */ - - /* XXX: NB: for Cogl 2.0 we don't allow NULL data here but we can't - * break the api for 1.x and so we keep the check for now. */ - if (data) - _cogl_buffer_set_data (COGL_BUFFER (buffer), - 0, - data, - bytes, - NULL); - - return buffer; -} - -static void -_cogl_attribute_buffer_free (CoglAttributeBuffer *array) -{ - /* parent's destructor */ - _cogl_buffer_fini (COGL_BUFFER (array)); - - g_free (array); -} - diff --git a/cogl/cogl/cogl-attribute-buffer.h b/cogl/cogl/cogl-attribute-buffer.h deleted file mode 100644 index 9175a8b66..000000000 --- a/cogl/cogl/cogl-attribute-buffer.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_ATTRIBUTE_BUFFER_H__ -#define __COGL_ATTRIBUTE_BUFFER_H__ - -/* We forward declare the CoglAttributeBuffer type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglAttributeBuffer CoglAttributeBuffer; - -#include <cogl/cogl-context.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-attribute-buffer - * @short_description: Functions for creating and manipulating attribute - * buffers - * - * FIXME - */ - -#define COGL_ATTRIBUTE_BUFFER(buffer) ((CoglAttributeBuffer *)(buffer)) - -/** - * cogl_attribute_buffer_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_attribute_buffer_get_gtype (void); - -/** - * cogl_attribute_buffer_new_with_size: - * @context: A #CoglContext - * @bytes: The number of bytes to allocate for vertex attribute data. - * - * Describes a new #CoglAttributeBuffer of @size bytes to contain - * arrays of vertex attribute data. Afterwards data can be set using - * cogl_buffer_set_data() or by mapping it into the application's - * address space using cogl_buffer_map(). - * - * The underlying storage of this buffer isn't allocated by this - * function so that you have an opportunity to use the - * cogl_buffer_set_update_hint() and cogl_buffer_set_usage_hint() - * functions which may influence how the storage is allocated. The - * storage will be allocated once you upload data to the buffer. - * - * Note: You can assume this function always succeeds and won't return - * %NULL - * - * Return value: (transfer full): A newly allocated #CoglAttributeBuffer. Never %NULL. - * - * Stability: Unstable - */ -COGL_EXPORT CoglAttributeBuffer * -cogl_attribute_buffer_new_with_size (CoglContext *context, - size_t bytes); - -/** - * cogl_attribute_buffer_new: - * @context: A #CoglContext - * @bytes: The number of bytes to allocate for vertex attribute data. - * @data: (array length=bytes): An optional pointer to vertex data to - * upload immediately. - * - * Describes a new #CoglAttributeBuffer of @size bytes to contain - * arrays of vertex attribute data and also uploads @size bytes read - * from @data to the new buffer. - * - * You should never pass a %NULL data pointer. - * - * <note>This function does not report out-of-memory errors back to - * the caller by returning %NULL and so you can assume this function - * always succeeds.</note> - * - * <note>In the unlikely case that there is an out of memory problem - * then Cogl will abort the application with a message. If your - * application needs to gracefully handle out-of-memory errors then - * you can use cogl_attribute_buffer_new_with_size() and then - * explicitly catch errors with cogl_buffer_set_data() or - * cogl_buffer_map().</note> - * - * Return value: (transfer full): A newly allocated #CoglAttributeBuffer (never %NULL) - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT CoglAttributeBuffer * -cogl_attribute_buffer_new (CoglContext *context, - size_t bytes, - const void *data); - -/** - * cogl_is_attribute_buffer: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglAttributeBuffer. - * - * Returns: %TRUE if @object references a #CoglAttributeBuffer, - * %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_attribute_buffer (void *object); - -G_END_DECLS - -#endif /* __COGL_ATTRIBUTE_BUFFER_H__ */ - diff --git a/cogl/cogl/cogl-attribute-private.h b/cogl/cogl/cogl-attribute-private.h deleted file mode 100644 index e97cb7d0f..000000000 --- a/cogl/cogl/cogl-attribute-private.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_ATTRIBUTE_PRIVATE_H -#define __COGL_ATTRIBUTE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-attribute.h" -#include "cogl-framebuffer.h" -#include "cogl-pipeline-private.h" -#include "cogl-boxed-value.h" - -typedef enum -{ - COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, - COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, - COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY, - COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, - COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY, - COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY -} CoglAttributeNameID; - -typedef struct _CoglAttributeNameState -{ - const char *name; - CoglAttributeNameID name_id; - int name_index; - gboolean normalized_default; - int layer_number; -} CoglAttributeNameState; - -struct _CoglAttribute -{ - CoglObject _parent; - - const CoglAttributeNameState *name_state; - gboolean normalized; - - gboolean is_buffered; - - union { - struct { - CoglAttributeBuffer *attribute_buffer; - size_t stride; - size_t offset; - int n_components; - CoglAttributeType type; - } buffered; - struct { - CoglContext *context; - CoglBoxedValue boxed; - } constant; - } d; - - int immutable_ref; -}; - -typedef enum -{ - COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0, - COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1, - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2, - /* By default the vertex attribute drawing code will assume that if - there is a color attribute array enabled then we can't determine - if the colors will be opaque so we need to enabling - blending. However when drawing from the journal we know what the - contents of the color array is so we can override this by passing - this flag. */ - COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 3, - /* This forcibly disables the debug option to divert all drawing to - * wireframes */ - COGL_DRAW_SKIP_DEBUG_WIREFRAME = 1 << 4 -} CoglDrawFlags; - -/* During CoglContext initialization we register the "cogl_color_in" - * attribute name so it gets a global name_index of 0. We need to know - * the name_index for "cogl_color_in" in - * _cogl_pipeline_flush_gl_state() */ -#define COGL_ATTRIBUTE_COLOR_NAME_INDEX 0 - -CoglAttributeNameState * -_cogl_attribute_register_attribute_name (CoglContext *context, - const char *name); - -CoglAttribute * -_cogl_attribute_immutable_ref (CoglAttribute *attribute); - -void -_cogl_attribute_immutable_unref (CoglAttribute *attribute); - -typedef struct -{ - int unit; - CoglPipelineFlushOptions options; - uint32_t fallback_layers; -} CoglFlushLayerState; - -void -_cogl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); - -int -_cogl_attribute_get_n_components (CoglAttribute *attribute); - -#endif /* __COGL_ATTRIBUTE_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-attribute.c b/cogl/cogl/cogl-attribute.c deleted file mode 100644 index 3ccd7b9dd..000000000 --- a/cogl/cogl/cogl-attribute.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-journal-private.h" -#include "cogl-attribute.h" -#include "cogl-attribute-private.h" -#include "cogl-pipeline.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-indices-private.h" -#include "cogl-private.h" -#include "cogl-gtype-private.h" - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -static void _cogl_attribute_free (CoglAttribute *attribute); - -COGL_OBJECT_DEFINE (Attribute, attribute); -COGL_GTYPE_DEFINE_CLASS (Attribute, attribute); - -static gboolean -validate_cogl_attribute_name (const char *name, - const char **real_attribute_name, - CoglAttributeNameID *name_id, - gboolean *normalized, - int *layer_number) -{ - name = name + 5; /* skip "cogl_" */ - - *normalized = FALSE; - *layer_number = 0; - - if (strcmp (name, "position_in") == 0) - *name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY; - else if (strcmp (name, "color_in") == 0) - { - *name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY; - *normalized = TRUE; - } - else if (strcmp (name, "tex_coord_in") == 0) - { - *real_attribute_name = "cogl_tex_coord0_in"; - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - } - else if (strncmp (name, "tex_coord", strlen ("tex_coord")) == 0) - { - char *endptr; - *layer_number = strtoul (name + 9, &endptr, 10); - if (strcmp (endptr, "_in") != 0) - { - g_warning ("Texture coordinate attributes should either be named " - "\"cogl_tex_coord_in\" or named with a texture unit index " - "like \"cogl_tex_coord2_in\"\n"); - return FALSE; - } - *name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY; - } - else if (strcmp (name, "normal_in") == 0) - { - *name_id = COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY; - *normalized = TRUE; - } - else if (strcmp (name, "point_size_in") == 0) - *name_id = COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY; - else - { - g_warning ("Unknown cogl_* attribute name cogl_%s\n", name); - return FALSE; - } - - return TRUE; -} - -CoglAttributeNameState * -_cogl_attribute_register_attribute_name (CoglContext *context, - const char *name) -{ - CoglAttributeNameState *name_state = g_new (CoglAttributeNameState, 1); - int name_index = context->n_attribute_names++; - char *name_copy = g_strdup (name); - - name_state->name = NULL; - name_state->name_index = name_index; - if (strncmp (name, "cogl_", 5) == 0) - { - if (!validate_cogl_attribute_name (name, - &name_state->name, - &name_state->name_id, - &name_state->normalized_default, - &name_state->layer_number)) - goto error; - } - else - { - name_state->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY; - name_state->normalized_default = FALSE; - name_state->layer_number = 0; - } - - if (name_state->name == NULL) - name_state->name = name_copy; - - g_hash_table_insert (context->attribute_name_states_hash, - name_copy, name_state); - - if (G_UNLIKELY (context->attribute_name_index_map == NULL)) - context->attribute_name_index_map = - g_array_new (FALSE, FALSE, sizeof (void *)); - - g_array_set_size (context->attribute_name_index_map, name_index + 1); - - g_array_index (context->attribute_name_index_map, - CoglAttributeNameState *, name_index) = name_state; - - return name_state; - -error: - g_free (name_state); - return NULL; -} - -static gboolean -validate_n_components (const CoglAttributeNameState *name_state, - int n_components) -{ - switch (name_state->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_POINT_SIZE_ARRAY: - if (G_UNLIKELY (n_components != 1)) - { - g_critical ("The point size attribute can only have one " - "component"); - return FALSE; - } - break; - case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY: - case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY: - return TRUE; - } - - return TRUE; -} - -CoglAttribute * -cogl_attribute_new (CoglAttributeBuffer *attribute_buffer, - const char *name, - size_t stride, - size_t offset, - int n_components, - CoglAttributeType type) -{ - CoglAttribute *attribute = g_new0 (CoglAttribute, 1); - CoglBuffer *buffer = COGL_BUFFER (attribute_buffer); - CoglContext *ctx = buffer->context; - - attribute->is_buffered = TRUE; - - attribute->name_state = - g_hash_table_lookup (ctx->attribute_name_states_hash, name); - if (!attribute->name_state) - { - CoglAttributeNameState *name_state = - _cogl_attribute_register_attribute_name (ctx, name); - if (!name_state) - goto error; - attribute->name_state = name_state; - } - - attribute->d.buffered.attribute_buffer = cogl_object_ref (attribute_buffer); - attribute->d.buffered.stride = stride; - attribute->d.buffered.offset = offset; - attribute->d.buffered.n_components = n_components; - attribute->d.buffered.type = type; - - attribute->immutable_ref = 0; - - if (attribute->name_state->name_id != COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY) - { - if (!validate_n_components (attribute->name_state, n_components)) - return NULL; - attribute->normalized = - attribute->name_state->normalized_default; - } - else - attribute->normalized = FALSE; - - return _cogl_attribute_object_new (attribute); - -error: - _cogl_attribute_free (attribute); - return NULL; -} - -static CoglAttribute * -_cogl_attribute_new_const (CoglContext *context, - const char *name, - int n_components, - int n_columns, - gboolean transpose, - const float *value) -{ - CoglAttribute *attribute = g_new0 (CoglAttribute, 1); - - attribute->name_state = - g_hash_table_lookup (context->attribute_name_states_hash, name); - if (!attribute->name_state) - { - CoglAttributeNameState *name_state = - _cogl_attribute_register_attribute_name (context, name); - if (!name_state) - goto error; - attribute->name_state = name_state; - } - - if (!validate_n_components (attribute->name_state, n_components)) - goto error; - - attribute->is_buffered = FALSE; - attribute->normalized = FALSE; - - attribute->d.constant.context = cogl_object_ref (context); - - attribute->d.constant.boxed.v.array = NULL; - - if (n_columns == 1) - { - _cogl_boxed_value_set_float (&attribute->d.constant.boxed, - n_components, - 1, - value); - } - else - { - /* FIXME: Up until GL[ES] 3 only square matrices were supported - * and we don't currently expose non-square matrices in Cogl. - */ - g_return_val_if_fail (n_columns == n_components, NULL); - _cogl_boxed_value_set_matrix (&attribute->d.constant.boxed, - n_columns, - 1, - transpose, - value); - } - - return _cogl_attribute_object_new (attribute); - -error: - _cogl_attribute_free (attribute); - return NULL; -} - -CoglAttribute * -cogl_attribute_new_const_1f (CoglContext *context, - const char *name, - float value) -{ - return _cogl_attribute_new_const (context, - name, - 1, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - &value); -} - -CoglAttribute * -cogl_attribute_new_const_2fv (CoglContext *context, - const char *name, - const float *value) -{ - return _cogl_attribute_new_const (context, - name, - 2, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - value); -} - -CoglAttribute * -cogl_attribute_new_const_3fv (CoglContext *context, - const char *name, - const float *value) -{ - return _cogl_attribute_new_const (context, - name, - 3, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - value); -} - -CoglAttribute * -cogl_attribute_new_const_4fv (CoglContext *context, - const char *name, - const float *value) -{ - return _cogl_attribute_new_const (context, - name, - 4, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - value); -} - -CoglAttribute * -cogl_attribute_new_const_2f (CoglContext *context, - const char *name, - float component0, - float component1) -{ - float vec2[2] = { component0, component1 }; - return _cogl_attribute_new_const (context, - name, - 2, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - vec2); -} - -CoglAttribute * -cogl_attribute_new_const_3f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2) -{ - float vec3[3] = { component0, component1, component2 }; - return _cogl_attribute_new_const (context, - name, - 3, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - vec3); -} - -CoglAttribute * -cogl_attribute_new_const_4f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2, - float component3) -{ - float vec4[4] = { component0, component1, component2, component3 }; - return _cogl_attribute_new_const (context, - name, - 4, /* n_components */ - 1, /* 1 column vector */ - FALSE, /* no transpose */ - vec4); -} - -CoglAttribute * -cogl_attribute_new_const_2x2fv (CoglContext *context, - const char *name, - const float *matrix2x2, - gboolean transpose) -{ - return _cogl_attribute_new_const (context, - name, - 2, /* n_components */ - 2, /* 2 column vector */ - FALSE, /* no transpose */ - matrix2x2); -} - -CoglAttribute * -cogl_attribute_new_const_3x3fv (CoglContext *context, - const char *name, - const float *matrix3x3, - gboolean transpose) -{ - return _cogl_attribute_new_const (context, - name, - 3, /* n_components */ - 3, /* 3 column vector */ - FALSE, /* no transpose */ - matrix3x3); -} - -CoglAttribute * -cogl_attribute_new_const_4x4fv (CoglContext *context, - const char *name, - const float *matrix4x4, - gboolean transpose) -{ - return _cogl_attribute_new_const (context, - name, - 4, /* n_components */ - 4, /* 4 column vector */ - FALSE, /* no transpose */ - matrix4x4); -} - -gboolean -cogl_attribute_get_normalized (CoglAttribute *attribute) -{ - g_return_val_if_fail (cogl_is_attribute (attribute), FALSE); - - return attribute->normalized; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of attributes has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_attribute_set_normalized (CoglAttribute *attribute, - gboolean normalized) -{ - g_return_if_fail (cogl_is_attribute (attribute)); - - if (G_UNLIKELY (attribute->immutable_ref)) - warn_about_midscene_changes (); - - attribute->normalized = normalized; -} - -CoglAttributeBuffer * -cogl_attribute_get_buffer (CoglAttribute *attribute) -{ - g_return_val_if_fail (cogl_is_attribute (attribute), NULL); - g_return_val_if_fail (attribute->is_buffered, NULL); - - return attribute->d.buffered.attribute_buffer; -} - -void -cogl_attribute_set_buffer (CoglAttribute *attribute, - CoglAttributeBuffer *attribute_buffer) -{ - g_return_if_fail (cogl_is_attribute (attribute)); - g_return_if_fail (attribute->is_buffered); - - if (G_UNLIKELY (attribute->immutable_ref)) - warn_about_midscene_changes (); - - cogl_object_ref (attribute_buffer); - - cogl_object_unref (attribute->d.buffered.attribute_buffer); - attribute->d.buffered.attribute_buffer = attribute_buffer; -} - -CoglAttribute * -_cogl_attribute_immutable_ref (CoglAttribute *attribute) -{ - CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer); - - g_return_val_if_fail (cogl_is_attribute (attribute), NULL); - - attribute->immutable_ref++; - _cogl_buffer_immutable_ref (buffer); - return attribute; -} - -void -_cogl_attribute_immutable_unref (CoglAttribute *attribute) -{ - CoglBuffer *buffer = COGL_BUFFER (attribute->d.buffered.attribute_buffer); - - g_return_if_fail (cogl_is_attribute (attribute)); - g_return_if_fail (attribute->immutable_ref > 0); - - attribute->immutable_ref--; - _cogl_buffer_immutable_unref (buffer); -} - -static void -_cogl_attribute_free (CoglAttribute *attribute) -{ - if (attribute->is_buffered) - cogl_object_unref (attribute->d.buffered.attribute_buffer); - else - _cogl_boxed_value_destroy (&attribute->d.constant.boxed); - - g_free (attribute); -} - -static gboolean -validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - CoglTexture *texture = - cogl_pipeline_get_layer_texture (pipeline, layer_index); - CoglFlushLayerState *state = user_data; - gboolean status = TRUE; - - /* invalid textures will be handled correctly in - * _cogl_pipeline_flush_layers_gl_state */ - if (texture == NULL) - goto validated; - - _cogl_texture_flush_journal_rendering (texture); - - /* Give the texture a chance to know that we're rendering - non-quad shaped primitives. If the texture is in an atlas it - will be migrated */ - _cogl_texture_ensure_non_quad_rendering (texture); - - /* We need to ensure the mipmaps are ready before deciding - * anything else about the texture because the texture storate - * could completely change if it needs to be migrated out of the - * atlas and will affect how we validate the layer. - */ - _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); - - if (!_cogl_texture_can_hardware_repeat (texture)) - { - g_warning ("Disabling layer %d of the current source material, " - "because texturing with the vertex buffer API is not " - "currently supported using sliced textures, or textures " - "with waste\n", layer_index); - - /* XXX: maybe we can add a mechanism for users to forcibly use - * textures with waste where it would be their responsibility to use - * texture coords in the range [0,1] such that sampling outside isn't - * required. We can then use a texture matrix (or a modification of - * the users own matrix) to map 1 to the edge of the texture data. - * - * Potentially, given the same guarantee as above we could also - * support a single sliced layer too. We would have to redraw the - * vertices once for each layer, each time with a fiddled texture - * matrix. - */ - state->fallback_layers |= (1 << state->unit); - state->options.flags |= COGL_PIPELINE_FLUSH_FALLBACK_MASK; - } - -validated: - state->unit++; - return status; -} - -void -_cogl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFlushLayerState layers_state; - CoglPipeline *copy = NULL; - - if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH)) - _cogl_framebuffer_flush_journal (framebuffer); - - layers_state.unit = 0; - layers_state.options.flags = 0; - layers_state.fallback_layers = 0; - - if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION)) - cogl_pipeline_foreach_layer (pipeline, - validate_layer_cb, - &layers_state); - - /* NB: cogl_context_flush_framebuffer_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. We need to do this - * before setting up the array pointers because setting up the clip - * stack can cause some drawing which would change the array - * pointers. */ - if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH)) - { - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_ALL); - } - - /* In cogl_read_pixels we have a fast-path when reading a single - * pixel and the scene is just comprised of simple rectangles still - * in the journal. For this optimization to work we need to track - * when the framebuffer really does get drawn to. */ - _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); - - ctx->driver_vtable->flush_attributes_state (framebuffer, - pipeline, - &layers_state, - flags, - attributes, - n_attributes); - - if (copy) - cogl_object_unref (copy); -} - -int -_cogl_attribute_get_n_components (CoglAttribute *attribute) -{ - if (attribute->is_buffered) - return attribute->d.buffered.n_components; - else - return attribute->d.constant.boxed.size; -} diff --git a/cogl/cogl/cogl-attribute.h b/cogl/cogl/cogl-attribute.h deleted file mode 100644 index 39a62d2dd..000000000 --- a/cogl/cogl/cogl-attribute.h +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_ATTRIBUTE_H__ -#define __COGL_ATTRIBUTE_H__ - -/* We forward declare the CoglAttribute type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglAttribute CoglAttribute; - -#include <cogl/cogl-attribute-buffer.h> -#include <cogl/cogl-indices.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-attribute - * @short_description: Functions for declaring and drawing vertex - * attributes - * - * FIXME - */ - -/** - * cogl_attribute_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_attribute_get_gtype (void); - -/** - * cogl_attribute_new: (constructor) - * @attribute_buffer: The #CoglAttributeBuffer containing the actual - * attribute data - * @name: The name of the attribute (used to reference it from GLSL) - * @stride: The number of bytes to jump to get to the next attribute - * value for the next vertex. (Usually - * <literal>sizeof (MyVertex)</literal>) - * @offset: The byte offset from the start of @attribute_buffer for - * the first attribute value. (Usually - * <literal>offsetof (MyVertex, component0)</literal> - * @components: The number of components (e.g. 4 for an rgba color or - * 3 for and (x,y,z) position) - * @type: FIXME - * - * Describes the layout for a list of vertex attribute values (For - * example, a list of texture coordinates or colors). - * - * The @name is used to access the attribute inside a GLSL vertex - * shader and there are some special names you should use if they are - * applicable: - * <itemizedlist> - * <listitem>"cogl_position_in" (used for vertex positions)</listitem> - * <listitem>"cogl_color_in" (used for vertex colors)</listitem> - * <listitem>"cogl_tex_coord0_in", "cogl_tex_coord1", ... - * (used for vertex texture coordinates)</listitem> - * <listitem>"cogl_normal_in" (used for vertex normals)</listitem> - * <listitem>"cogl_point_size_in" (used to set the size of points - * per-vertex. Note this can only be used if - * %COGL_FEATURE_ID_POINT_SIZE_ATTRIBUTE is advertised and - * cogl_pipeline_set_per_vertex_point_size() is called on the pipeline. - * </listitem> - * </itemizedlist> - * - * The attribute values corresponding to different vertices can either - * be tightly packed or interleaved with other attribute values. For - * example it's common to define a structure for a single vertex like: - * |[ - * typedef struct - * { - * float x, y, z; /<!-- -->* position attribute *<!-- -->/ - * float s, t; /<!-- -->* texture coordinate attribute *<!-- -->/ - * } MyVertex; - * ]| - * - * And then create an array of vertex data something like: - * |[ - * MyVertex vertices[100] = { .... } - * ]| - * - * In this case, to describe either the position or texture coordinate - * attribute you have to move <literal>sizeof (MyVertex)</literal> bytes to - * move from one vertex to the next. This is called the attribute - * @stride. If you weren't interleving attributes and you instead had - * a packed array of float x, y pairs then the attribute stride would - * be <literal>(2 * sizeof (float))</literal>. So the @stride is the number of - * bytes to move to find the attribute value of the next vertex. - * - * Normally a list of attributes starts at the beginning of an array. - * So for the <literal>MyVertex</literal> example above the @offset is the - * offset inside the <literal>MyVertex</literal> structure to the first - * component of the attribute. For the texture coordinate attribute - * the offset would be <literal>offsetof (MyVertex, s)</literal> or instead of - * using the offsetof macro you could use <literal>sizeof (float) * - * 3</literal>. If you've divided your @array into blocks of non-interleved - * attributes then you will need to calculate the @offset as the number of - * bytes in blocks preceding the attribute you're describing. - * - * An attribute often has more than one component. For example a color - * is often comprised of 4 red, green, blue and alpha @components, and a - * position may be comprised of 2 x and y @components. You should aim - * to keep the number of components to a minimum as more components - * means more data needs to be mapped into the GPU which can be a - * bottleneck when dealing with a large number of vertices. - * - * Finally you need to specify the component data type. Here you - * should aim to use the smallest type that meets your precision - * requirements. Again the larger the type then more data needs to be - * mapped into the GPU which can be a bottleneck when dealing with - * a large number of vertices. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * describing the layout for a list of attribute values - * stored in @array. - * - * Since: 1.4 - * Stability: Unstable - */ -/* XXX: look for a precedent to see if the stride/offset args should - * have a different order. */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new (CoglAttributeBuffer *attribute_buffer, - const char *name, - size_t stride, - size_t offset, - int components, - CoglAttributeType type); - -/** - * cogl_attribute_new_const_1f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: The constant value for the attribute - * - * Creates a new, single component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constant @value is a single precision floating point scalar - * which should have a corresponding declaration in GLSL code like: - * - * [| - * attribute float name; - * |] - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant @value. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_1f (CoglContext *context, - const char *name, - float value); - -/** - * cogl_attribute_new_const_2f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @component0: The first component of a 2 component vector - * @component1: The second component of a 2 component vector - * - * Creates a new, 2 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (@component0, @component1) represent a 2 component - * float vector which should have a corresponding declaration in GLSL - * code like: - * - * [| - * attribute vec2 name; - * |] - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_2f (CoglContext *context, - const char *name, - float component0, - float component1); - -/** - * cogl_attribute_new_const_3f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @component0: The first component of a 3 component vector - * @component1: The second component of a 3 component vector - * @component2: The third component of a 3 component vector - * - * Creates a new, 3 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (@component0, @component1, @component2) represent a 3 - * component float vector which should have a corresponding - * declaration in GLSL code like: - * - * [| - * attribute vec3 name; - * |] - * - * unless the built in name "cogl_normal_in" is being used where no - * explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_3f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2); - -/** - * cogl_attribute_new_const_4f: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @component0: The first component of a 4 component vector - * @component1: The second component of a 4 component vector - * @component2: The third component of a 4 component vector - * @component3: The fourth component of a 4 component vector - * - * Creates a new, 4 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (@component0, @component1, @component2, @constant3) - * represent a 4 component float vector which should have a - * corresponding declaration in GLSL code like: - * - * [| - * attribute vec4 name; - * |] - * - * unless one of the built in names "cogl_color_in", - * "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where - * no explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_4f (CoglContext *context, - const char *name, - float component0, - float component1, - float component2, - float component3); - -/** - * cogl_attribute_new_const_2fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: A pointer to a 2 component float vector - * - * Creates a new, 2 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (value[0], value[1]) represent a 2 component float - * vector which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute vec2 name; - * |] - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_2fv (CoglContext *context, - const char *name, - const float *value); - -/** - * cogl_attribute_new_const_3fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: A pointer to a 3 component float vector - * - * Creates a new, 3 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (value[0], value[1], value[2]) represent a 3 - * component float vector which should have a corresponding - * declaration in GLSL code like: - * - * [| - * attribute vec3 name; - * |] - * - * unless the built in name "cogl_normal_in" is being used where no - * explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_3fv (CoglContext *context, - const char *name, - const float *value); - -/** - * cogl_attribute_new_const_4fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @value: A pointer to a 4 component float vector - * - * Creates a new, 4 component, attribute whose value remains - * constant across all the vertices of a primitive without needing to - * duplicate the value for each vertex. - * - * The constants (value[0], value[1], value[2], value[3]) represent a - * 4 component float vector which should have a corresponding - * declaration in GLSL code like: - * - * [| - * attribute vec4 name; - * |] - * - * unless one of the built in names "cogl_color_in", - * "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where - * no explicit GLSL declaration need be made. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant vector. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_4fv (CoglContext *context, - const char *name, - const float *value); - -/** - * cogl_attribute_new_const_2x2fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @matrix2x2: A pointer to a 2 by 2 matrix - * @transpose: Whether the matrix should be transposed on upload or - * not - * - * Creates a new matrix attribute whose value remains constant - * across all the vertices of a primitive without needing to duplicate - * the value for each vertex. - * - * @matrix2x2 represent a square 2 by 2 matrix specified in - * column-major order (each pair of consecutive numbers represents a - * column) which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute mat2 name; - * |] - * - * If @transpose is %TRUE then all matrix components are rotated - * around the diagonal of the matrix such that the first column - * becomes the first row and the second column becomes the second row. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant matrix. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_2x2fv (CoglContext *context, - const char *name, - const float *matrix2x2, - gboolean transpose); - -/** - * cogl_attribute_new_const_3x3fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @matrix3x3: A pointer to a 3 by 3 matrix - * @transpose: Whether the matrix should be transposed on upload or - * not - * - * Creates a new matrix attribute whose value remains constant - * across all the vertices of a primitive without needing to duplicate - * the value for each vertex. - * - * @matrix3x3 represent a square 3 by 3 matrix specified in - * column-major order (each triple of consecutive numbers represents a - * column) which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute mat3 name; - * |] - * - * If @transpose is %TRUE then all matrix components are rotated - * around the diagonal of the matrix such that the first column - * becomes the first row and the second column becomes the second row - * etc. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant matrix. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_3x3fv (CoglContext *context, - const char *name, - const float *matrix3x3, - gboolean transpose); - -/** - * cogl_attribute_new_const_4x4fv: - * @context: A #CoglContext - * @name: The name of the attribute (used to reference it from GLSL) - * @matrix4x4: A pointer to a 4 by 4 matrix - * @transpose: Whether the matrix should be transposed on upload or - * not - * - * Creates a new matrix attribute whose value remains constant - * across all the vertices of a primitive without needing to duplicate - * the value for each vertex. - * - * @matrix4x4 represent a square 4 by 4 matrix specified in - * column-major order (each 4-tuple of consecutive numbers represents a - * column) which should have a corresponding declaration in GLSL code - * like: - * - * [| - * attribute mat4 name; - * |] - * - * If @transpose is %TRUE then all matrix components are rotated - * around the diagonal of the matrix such that the first column - * becomes the first row and the second column becomes the second row - * etc. - * - * Return value: (transfer full): A newly allocated #CoglAttribute - * representing the given constant matrix. - */ -COGL_EXPORT CoglAttribute * -cogl_attribute_new_const_4x4fv (CoglContext *context, - const char *name, - const float *matrix4x4, - gboolean transpose); - -/** - * cogl_attribute_set_normalized: - * @attribute: A #CoglAttribute - * @normalized: The new value for the normalized property. - * - * Sets whether fixed point attribute types are mapped to the range - * 0→1. For example when this property is TRUE and a - * %COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE type is used then the value 255 - * will be mapped to 1.0. - * - * The default value of this property depends on the name of the - * attribute. For the builtin properties cogl_color_in and - * cogl_normal_in it will default to TRUE and for all other names it - * will default to FALSE. - * - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT void -cogl_attribute_set_normalized (CoglAttribute *attribute, - gboolean normalized); - -/** - * cogl_attribute_get_normalized: - * @attribute: A #CoglAttribute - * - * Return value: the value of the normalized property set with - * cogl_attribute_set_normalized(). - * - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT gboolean -cogl_attribute_get_normalized (CoglAttribute *attribute); - -/** - * cogl_attribute_get_buffer: - * @attribute: A #CoglAttribute - * - * Return value: (transfer none): the #CoglAttributeBuffer that was - * set with cogl_attribute_set_buffer() or cogl_attribute_new(). - * - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT CoglAttributeBuffer * -cogl_attribute_get_buffer (CoglAttribute *attribute); - -/** - * cogl_attribute_set_buffer: - * @attribute: A #CoglAttribute - * @attribute_buffer: A #CoglAttributeBuffer - * - * Sets a new #CoglAttributeBuffer for the attribute. - * - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT void -cogl_attribute_set_buffer (CoglAttribute *attribute, - CoglAttributeBuffer *attribute_buffer); - -/** - * cogl_is_attribute: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglAttribute. - * - * Return value: %TRUE if the @object references a #CoglAttribute, - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_is_attribute (void *object); - -G_END_DECLS - -#endif /* __COGL_ATTRIBUTE_H__ */ - diff --git a/cogl/cogl/cogl-bitmap-conversion.c b/cogl/cogl/cogl-bitmap-conversion.c deleted file mode 100644 index ab8251fc5..000000000 --- a/cogl/cogl/cogl-bitmap-conversion.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" - -#include <string.h> - -#define component_type uint8_t -#define component_size 8 -/* We want to specially optimise the packing when we are converting - to/from an 8-bit type so that it won't do anything. That way for - example if we are just doing a swizzle conversion then the inner - loop for the conversion will be really simple */ -#define UNPACK_BYTE(b) (b) -#define PACK_BYTE(b) (b) -#include "cogl-bitmap-packing.h" -#undef PACK_BYTE -#undef UNPACK_BYTE -#undef component_type -#undef component_size - -#define component_type uint16_t -#define component_size 16 -#define UNPACK_BYTE(b) (((b) * 65535 + 127) / 255) -#define PACK_BYTE(b) (((b) * 255 + 32767) / 65535) -#include "cogl-bitmap-packing.h" -#undef PACK_BYTE -#undef UNPACK_BYTE -#undef component_type -#undef component_size - -/* (Un)Premultiplication */ - -inline static void -_cogl_unpremult_alpha_0 (uint8_t *dst) -{ - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; -} - -inline static void -_cogl_unpremult_alpha_last (uint8_t *dst) -{ - uint8_t alpha = dst[3]; - - dst[0] = (dst[0] * 255) / alpha; - dst[1] = (dst[1] * 255) / alpha; - dst[2] = (dst[2] * 255) / alpha; -} - -inline static void -_cogl_unpremult_alpha_first (uint8_t *dst) -{ - uint8_t alpha = dst[0]; - - dst[1] = (dst[1] * 255) / alpha; - dst[2] = (dst[2] * 255) / alpha; - dst[3] = (dst[3] * 255) / alpha; -} - -/* No division form of floor((c*a + 128)/255) (I first encountered - * this in the RENDER implementation in the X server.) Being exact - * is important for a == 255 - we want to get exactly c. - */ -#define MULT(d,a,t) \ - G_STMT_START { \ - t = d * a + 128; \ - d = ((t >> 8) + t) >> 8; \ - } G_STMT_END - -inline static void -_cogl_premult_alpha_last (uint8_t *dst) -{ - uint8_t alpha = dst[3]; - /* Using a separate temporary per component has given slightly better - * code generation with GCC in the past; it shouldn't do any worse in - * any case. - */ - unsigned int t1, t2, t3; - MULT(dst[0], alpha, t1); - MULT(dst[1], alpha, t2); - MULT(dst[2], alpha, t3); -} - -inline static void -_cogl_premult_alpha_first (uint8_t *dst) -{ - uint8_t alpha = dst[0]; - unsigned int t1, t2, t3; - - MULT(dst[1], alpha, t1); - MULT(dst[2], alpha, t2); - MULT(dst[3], alpha, t3); -} - -#undef MULT - -/* Use the SSE optimized version to premult four pixels at once when - it is available. The same assembler code works for x86 and x86-64 - because it doesn't refer to any non-SSE registers directly */ -#if defined(__SSE2__) && defined(__GNUC__) \ - && (defined(__x86_64) || defined(__i386)) -#define COGL_USE_PREMULT_SSE2 -#endif - -#ifdef COGL_USE_PREMULT_SSE2 - -inline static void -_cogl_premult_alpha_last_four_pixels_sse2 (uint8_t *p) -{ - /* 8 copies of 128 used below */ - static const int16_t eight_halves[8] __attribute__ ((aligned (16))) = - { 128, 128, 128, 128, 128, 128, 128, 128 }; - /* Mask of the rgb components of the four pixels */ - static const int8_t just_rgb[16] __attribute__ ((aligned (16))) = - { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, - 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00 }; - /* Each SSE register only holds two pixels because we need to work - with 16-bit intermediate values. We still do four pixels by - interleaving two registers in the hope that it will pipeline - better */ - asm (/* Load eight_halves into xmm5 for later */ - "movdqa (%1), %%xmm5\n" - /* Clear xmm3 */ - "pxor %%xmm3, %%xmm3\n" - /* Load two pixels from p into the low half of xmm0 */ - "movlps (%0), %%xmm0\n" - /* Load the next set of two pixels from p into the low half of xmm1 */ - "movlps 8(%0), %%xmm1\n" - /* Unpack 8 bytes from the low quad-words in each register to 8 - 16-bit values */ - "punpcklbw %%xmm3, %%xmm0\n" - "punpcklbw %%xmm3, %%xmm1\n" - /* Copy alpha values of the first pixel in xmm0 to all - components of the first pixel in xmm2 */ - "pshuflw $255, %%xmm0, %%xmm2\n" - /* same for xmm1 and xmm3 */ - "pshuflw $255, %%xmm1, %%xmm3\n" - /* The above also copies the second pixel directly so we now - want to replace the RGB components with copies of the alpha - components */ - "pshufhw $255, %%xmm2, %%xmm2\n" - "pshufhw $255, %%xmm3, %%xmm3\n" - /* Multiply the rgb components by the alpha */ - "pmullw %%xmm2, %%xmm0\n" - "pmullw %%xmm3, %%xmm1\n" - /* Add 128 to each component */ - "paddw %%xmm5, %%xmm0\n" - "paddw %%xmm5, %%xmm1\n" - /* Copy the results to temporary registers xmm4 and xmm5 */ - "movdqa %%xmm0, %%xmm4\n" - "movdqa %%xmm1, %%xmm5\n" - /* Divide the results by 256 */ - "psrlw $8, %%xmm0\n" - "psrlw $8, %%xmm1\n" - /* Add the temporaries back in */ - "paddw %%xmm4, %%xmm0\n" - "paddw %%xmm5, %%xmm1\n" - /* Divide again */ - "psrlw $8, %%xmm0\n" - "psrlw $8, %%xmm1\n" - /* Pack the results back as bytes */ - "packuswb %%xmm1, %%xmm0\n" - /* Load just_rgb into xmm3 for later */ - "movdqa (%2), %%xmm3\n" - /* Reload all four pixels into xmm2 */ - "movups (%0), %%xmm2\n" - /* Mask out the alpha from the results */ - "andps %%xmm3, %%xmm0\n" - /* Mask out the RGB from the original four pixels */ - "andnps %%xmm2, %%xmm3\n" - /* Combine the two to get the right alpha values */ - "orps %%xmm3, %%xmm0\n" - /* Write to memory */ - "movdqu %%xmm0, (%0)\n" - : /* no outputs */ - : "r" (p), "r" (eight_halves), "r" (just_rgb) - : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5"); -} - -#endif /* COGL_USE_PREMULT_SSE2 */ - -static void -_cogl_bitmap_premult_unpacked_span_8 (uint8_t *data, - int width) -{ -#ifdef COGL_USE_PREMULT_SSE2 - - /* Process 4 pixels at a time */ - while (width >= 4) - { - _cogl_premult_alpha_last_four_pixels_sse2 (data); - data += 4 * 4; - width -= 4; - } - - /* If there are any pixels left we will fall through and - handle them below */ - -#endif /* COGL_USE_PREMULT_SSE2 */ - - while (width-- > 0) - { - _cogl_premult_alpha_last (data); - data += 4; - } -} - -static void -_cogl_bitmap_unpremult_unpacked_span_8 (uint8_t *data, - int width) -{ - int x; - - for (x = 0; x < width; x++) - { - if (data[3] == 0) - _cogl_unpremult_alpha_0 (data); - else - _cogl_unpremult_alpha_last (data); - data += 4; - } -} - -static void -_cogl_bitmap_unpremult_unpacked_span_16 (uint16_t *data, - int width) -{ - while (width-- > 0) - { - uint16_t alpha = data[3]; - - if (alpha == 0) - memset (data, 0, sizeof (uint16_t) * 3); - else - { - data[0] = (data[0] * 65535) / alpha; - data[1] = (data[1] * 65535) / alpha; - data[2] = (data[2] * 65535) / alpha; - } - } -} - -static void -_cogl_bitmap_premult_unpacked_span_16 (uint16_t *data, - int width) -{ - while (width-- > 0) - { - uint16_t alpha = data[3]; - - data[0] = (data[0] * alpha) / 65535; - data[1] = (data[1] * alpha) / 65535; - data[2] = (data[2] * alpha) / 65535; - } -} - -static gboolean -_cogl_bitmap_can_fast_premult (CoglPixelFormat format) -{ - switch (format & ~COGL_PREMULT_BIT) - { - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - return TRUE; - - default: - return FALSE; - } -} - -static gboolean -_cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format) -{ - /* If the format is using more than 8 bits per component then we'll - unpack into a 16-bit per component buffer instead of 8-bit so we - won't lose as much precision. If we ever add support for formats - with more than 16 bits for at least one of the components then we - should probably do something else here, maybe convert to - floats */ - switch (format) - { - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_32: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_RG_88: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_G_8: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - return FALSE; - - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - return TRUE; - } - - g_assert_not_reached (); - return FALSE; -} - -gboolean -_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, - CoglBitmap *dst_bmp, - GError **error) -{ - uint8_t *src_data; - uint8_t *dst_data; - uint8_t *src; - uint8_t *dst; - void *tmp_row; - int src_rowstride; - int dst_rowstride; - int y; - int width, height; - CoglPixelFormat src_format; - CoglPixelFormat dst_format; - gboolean use_16; - gboolean need_premult; - - src_format = cogl_bitmap_get_format (src_bmp); - src_rowstride = cogl_bitmap_get_rowstride (src_bmp); - dst_format = cogl_bitmap_get_format (dst_bmp); - dst_rowstride = cogl_bitmap_get_rowstride (dst_bmp); - width = cogl_bitmap_get_width (src_bmp); - height = cogl_bitmap_get_height (src_bmp); - - g_return_val_if_fail (width == cogl_bitmap_get_width (dst_bmp), FALSE); - g_return_val_if_fail (height == cogl_bitmap_get_height (dst_bmp), FALSE); - - need_premult - = ((src_format & COGL_PREMULT_BIT) != (dst_format & COGL_PREMULT_BIT) && - src_format != COGL_PIXEL_FORMAT_A_8 && - dst_format != COGL_PIXEL_FORMAT_A_8 && - (src_format & dst_format & COGL_A_BIT)); - - /* If the base format is the same then we can just copy the bitmap - instead */ - if ((src_format & ~COGL_PREMULT_BIT) == (dst_format & ~COGL_PREMULT_BIT) && - (!need_premult || _cogl_bitmap_can_fast_premult (dst_format))) - { - if (!_cogl_bitmap_copy_subregion (src_bmp, dst_bmp, - 0, 0, /* src_x / src_y */ - 0, 0, /* dst_x / dst_y */ - width, height, - error)) - return FALSE; - - if (need_premult) - { - if ((dst_format & COGL_PREMULT_BIT)) - { - if (!_cogl_bitmap_premult (dst_bmp, error)) - return FALSE; - } - else - { - if (!_cogl_bitmap_unpremult (dst_bmp, error)) - return FALSE; - } - } - - return TRUE; - } - - src_data = _cogl_bitmap_map (src_bmp, COGL_BUFFER_ACCESS_READ, 0, error); - if (src_data == NULL) - return FALSE; - dst_data = _cogl_bitmap_map (dst_bmp, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - error); - if (dst_data == NULL) - { - _cogl_bitmap_unmap (src_bmp); - return FALSE; - } - - use_16 = _cogl_bitmap_needs_short_temp_buffer (dst_format); - - /* Allocate a buffer to hold a temporary RGBA row */ - tmp_row = g_malloc (width * - (use_16 ? sizeof (uint16_t) : sizeof (uint8_t)) * 4); - - /* FIXME: Optimize */ - for (y = 0; y < height; y++) - { - src = src_data + y * src_rowstride; - dst = dst_data + y * dst_rowstride; - - if (use_16) - _cogl_unpack_16 (src_format, src, tmp_row, width); - else - _cogl_unpack_8 (src_format, src, tmp_row, width); - - /* Handle premultiplication */ - if (need_premult) - { - if (dst_format & COGL_PREMULT_BIT) - { - if (use_16) - _cogl_bitmap_premult_unpacked_span_16 (tmp_row, width); - else - _cogl_bitmap_premult_unpacked_span_8 (tmp_row, width); - } - else - { - if (use_16) - _cogl_bitmap_unpremult_unpacked_span_16 (tmp_row, width); - else - _cogl_bitmap_unpremult_unpacked_span_8 (tmp_row, width); - } - } - - if (use_16) - _cogl_pack_16 (dst_format, tmp_row, dst, width); - else - _cogl_pack_8 (dst_format, tmp_row, dst, width); - } - - _cogl_bitmap_unmap (src_bmp); - _cogl_bitmap_unmap (dst_bmp); - - g_free (tmp_row); - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_convert (CoglBitmap *src_bmp, - CoglPixelFormat dst_format, - GError **error) -{ - CoglBitmap *dst_bmp; - int width, height; - - _COGL_GET_CONTEXT (ctx, NULL); - - width = cogl_bitmap_get_width (src_bmp); - height = cogl_bitmap_get_height (src_bmp); - - dst_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - width, height, - dst_format, - error); - if (!dst_bmp) - return NULL; - - if (!_cogl_bitmap_convert_into_bitmap (src_bmp, dst_bmp, error)) - { - cogl_object_unref (dst_bmp); - return NULL; - } - - return dst_bmp; -} - -static gboolean -driver_can_convert (CoglContext *ctx, - CoglPixelFormat src_format, - CoglPixelFormat internal_format) -{ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_FORMAT_CONVERSION)) - return FALSE; - - if (src_format == internal_format) - return TRUE; - - /* If the driver doesn't natively support alpha textures then it - * won't work correctly to convert to/from component-alpha - * textures */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && - (src_format == COGL_PIXEL_FORMAT_A_8 || - internal_format == COGL_PIXEL_FORMAT_A_8)) - return FALSE; - - /* Same for red-green textures. If red-green textures aren't - * supported then the internal format should never be RG_88 but we - * should still be able to convert from an RG source image */ - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RG) && - src_format == COGL_PIXEL_FORMAT_RG_88) - return FALSE; - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, - CoglPixelFormat internal_format, - gboolean can_convert_in_place, - GError **error) -{ - CoglContext *ctx = _cogl_bitmap_get_context (src_bmp); - CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp); - CoglBitmap *dst_bmp; - - g_return_val_if_fail (internal_format != COGL_PIXEL_FORMAT_ANY, NULL); - - /* OpenGL supports specifying a different format for the internal - format when uploading texture data. We should use this to convert - formats because it is likely to be faster and support more types - than the Cogl bitmap code. However under GLES the internal format - must be the same as the bitmap format and it only supports a - limited number of formats so we must convert using the Cogl - bitmap code instead */ - - if (driver_can_convert (ctx, src_format, internal_format)) - { - /* If the source format does not have the same premult flag as the - internal_format then we need to copy and convert it */ - if (_cogl_texture_needs_premult_conversion (src_format, - internal_format)) - { - if (can_convert_in_place) - { - if (_cogl_bitmap_convert_premult_status (src_bmp, - (src_format ^ - COGL_PREMULT_BIT), - error)) - { - dst_bmp = cogl_object_ref (src_bmp); - } - else - return NULL; - } - else - { - dst_bmp = _cogl_bitmap_convert (src_bmp, - src_format ^ COGL_PREMULT_BIT, - error); - if (dst_bmp == NULL) - return NULL; - } - } - else - dst_bmp = cogl_object_ref (src_bmp); - } - else - { - CoglPixelFormat closest_format; - - closest_format = - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - NULL, /* ignore gl intformat */ - NULL, /* ignore gl format */ - NULL); /* ignore gl type */ - - if (closest_format != src_format) - dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format, error); - else - dst_bmp = cogl_object_ref (src_bmp); - } - - return dst_bmp; -} - -gboolean -_cogl_bitmap_unpremult (CoglBitmap *bmp, - GError **error) -{ - uint8_t *p, *data; - uint16_t *tmp_row; - int x,y; - CoglPixelFormat format; - int width, height; - int rowstride; - - format = cogl_bitmap_get_format (bmp); - width = cogl_bitmap_get_width (bmp); - height = cogl_bitmap_get_height (bmp); - rowstride = cogl_bitmap_get_rowstride (bmp); - - if ((data = _cogl_bitmap_map (bmp, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0, - error)) == NULL) - return FALSE; - - /* If we can't directly unpremult the data inline then we'll - allocate a temporary row and unpack the data. This assumes if we - can fast premult then we can also fast unpremult */ - if (_cogl_bitmap_can_fast_premult (format)) - tmp_row = NULL; - else - tmp_row = g_malloc (sizeof (uint16_t) * 4 * width); - - for (y = 0; y < height; y++) - { - p = (uint8_t*) data + y * rowstride; - - if (tmp_row) - { - _cogl_unpack_16 (format, p, tmp_row, width); - _cogl_bitmap_unpremult_unpacked_span_16 (tmp_row, width); - _cogl_pack_16 (format, tmp_row, p, width); - } - else - { - if (format & COGL_AFIRST_BIT) - { - for (x = 0; x < width; x++) - { - if (p[0] == 0) - _cogl_unpremult_alpha_0 (p); - else - _cogl_unpremult_alpha_first (p); - p += 4; - } - } - else - _cogl_bitmap_unpremult_unpacked_span_8 (p, width); - } - } - - g_free (tmp_row); - - _cogl_bitmap_unmap (bmp); - - _cogl_bitmap_set_format (bmp, format & ~COGL_PREMULT_BIT); - - return TRUE; -} - -gboolean -_cogl_bitmap_premult (CoglBitmap *bmp, - GError **error) -{ - uint8_t *p, *data; - uint16_t *tmp_row; - int x,y; - CoglPixelFormat format; - int width, height; - int rowstride; - - format = cogl_bitmap_get_format (bmp); - width = cogl_bitmap_get_width (bmp); - height = cogl_bitmap_get_height (bmp); - rowstride = cogl_bitmap_get_rowstride (bmp); - - if ((data = _cogl_bitmap_map (bmp, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0, - error)) == NULL) - return FALSE; - - /* If we can't directly premult the data inline then we'll allocate - a temporary row and unpack the data. */ - if (_cogl_bitmap_can_fast_premult (format)) - tmp_row = NULL; - else - tmp_row = g_malloc (sizeof (uint16_t) * 4 * width); - - for (y = 0; y < height; y++) - { - p = (uint8_t*) data + y * rowstride; - - if (tmp_row) - { - _cogl_unpack_16 (format, p, tmp_row, width); - _cogl_bitmap_premult_unpacked_span_16 (tmp_row, width); - _cogl_pack_16 (format, tmp_row, p, width); - } - else - { - if (format & COGL_AFIRST_BIT) - { - for (x = 0; x < width; x++) - { - _cogl_premult_alpha_first (p); - p += 4; - } - } - else - _cogl_bitmap_premult_unpacked_span_8 (p, width); - } - } - - g_free (tmp_row); - - _cogl_bitmap_unmap (bmp); - - _cogl_bitmap_set_format (bmp, format | COGL_PREMULT_BIT); - - return TRUE; -} diff --git a/cogl/cogl/cogl-bitmap-packing.h b/cogl/cogl/cogl-bitmap-packing.h deleted file mode 100644 index f668b0bea..000000000 --- a/cogl/cogl/cogl-bitmap-packing.h +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This file is included multiple times with different definitions for - the component_type type (either uint8_t or uint16_t). The code ends - up exactly the same for both but we only want to end up hitting the - 16-bit path when one of the types in the conversion is > 8 bits per - component. */ - -/* Unpacking to RGBA */ - -#define UNPACK_1(b) ((b) * ((1 << (sizeof (component_type) * 8)) - 1)) -#define UNPACK_2(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 1) / 3) -#define UNPACK_4(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 7) / 0xf) -#define UNPACK_5(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0xf) / 0x1f) -#define UNPACK_6(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0x1f) / 0x3f) -#define UNPACK_10(b) (((b) * ((1 << (sizeof (component_type) * 8)) - 1) + \ - 0x1ff) / 0x3ff) - -inline static void -G_PASTE (_cogl_unpack_a_8_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - dst[3] = UNPACK_BYTE (*src); - dst += 4; - src++; - } -} - -inline static void -G_PASTE (_cogl_unpack_g_8_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - /* FIXME: I'm not sure if this is right. It looks like Nvidia and - Mesa handle luminance textures differently. Maybe we should - consider just removing luminance textures for Cogl 2.0 because - they have been removed in GL 3.0 */ - while (width-- > 0) - { - component_type v = UNPACK_BYTE (src[0]); - dst[0] = v; - dst[1] = v; - dst[2] = v; - dst[3] = UNPACK_BYTE (255); - dst += 4; - src++; - } -} - -inline static void -G_PASTE (_cogl_unpack_rg_88_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = 0; - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgb_888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[2]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 3; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgr_888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[2]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[0]); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 3; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgra_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[2]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[0]); - dst[3] = UNPACK_BYTE (src[3]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_argb_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[1]); - dst[1] = UNPACK_BYTE (src[2]); - dst[2] = UNPACK_BYTE (src[3]); - dst[3] = UNPACK_BYTE (src[0]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_abgr_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[3]); - dst[1] = UNPACK_BYTE (src[2]); - dst[2] = UNPACK_BYTE (src[1]); - dst[3] = UNPACK_BYTE (src[0]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_8888_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = UNPACK_BYTE (src[0]); - dst[1] = UNPACK_BYTE (src[1]); - dst[2] = UNPACK_BYTE (src[2]); - dst[3] = UNPACK_BYTE (src[3]); - dst += 4; - src += 4; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgb_565_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint16_t v = *(const uint16_t *) src; - - dst[0] = UNPACK_5 (v >> 11); - dst[1] = UNPACK_6 ((v >> 5) & 0x3f); - dst[2] = UNPACK_5 (v & 0x1f); - dst[3] = UNPACK_BYTE (255); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_4444_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint16_t v = *(const uint16_t *) src; - - dst[0] = UNPACK_4 (v >> 12); - dst[1] = UNPACK_4 ((v >> 8) & 0xf); - dst[2] = UNPACK_4 ((v >> 4) & 0xf); - dst[3] = UNPACK_4 (v & 0xf); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_5551_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint16_t v = *(const uint16_t *) src; - - dst[0] = UNPACK_5 (v >> 11); - dst[1] = UNPACK_5 ((v >> 6) & 0x1f); - dst[2] = UNPACK_5 ((v >> 1) & 0x1f); - dst[3] = UNPACK_1 (v & 1); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_rgba_1010102_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[0] = UNPACK_10 (v >> 22); - dst[1] = UNPACK_10 ((v >> 12) & 0x3ff); - dst[2] = UNPACK_10 ((v >> 2) & 0x3ff); - dst[3] = UNPACK_2 (v & 3); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_bgra_1010102_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[2] = UNPACK_10 (v >> 22); - dst[1] = UNPACK_10 ((v >> 12) & 0x3ff); - dst[0] = UNPACK_10 ((v >> 2) & 0x3ff); - dst[3] = UNPACK_2 (v & 3); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_argb_2101010_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[3] = UNPACK_2 (v >> 30); - dst[0] = UNPACK_10 ((v >> 20) & 0x3ff); - dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); - dst[2] = UNPACK_10 (v & 0x3ff); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_abgr_2101010_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - while (width-- > 0) - { - uint32_t v = *(const uint32_t *) src; - - dst[3] = UNPACK_2 (v >> 30); - dst[2] = UNPACK_10 ((v >> 20) & 0x3ff); - dst[1] = UNPACK_10 ((v >> 10) & 0x3ff); - dst[0] = UNPACK_10 (v & 0x3ff); - dst += 4; - src += 2; - } -} - -inline static void -G_PASTE (_cogl_unpack_argb_fp_16161616_, component_size) (const uint8_t *src, - component_type *dst, - int width) -{ - g_warning ("Not implemented"); -} - -#undef UNPACK_1 -#undef UNPACK_2 -#undef UNPACK_4 -#undef UNPACK_5 -#undef UNPACK_6 -#undef UNPACK_10 - -inline static void -G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format, - const uint8_t *src, - component_type *dst, - int width) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - G_PASTE (_cogl_unpack_a_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_G_8: - G_PASTE (_cogl_unpack_g_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RG_88: - G_PASTE (_cogl_unpack_rg_88_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_888: - G_PASTE (_cogl_unpack_rgb_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGR_888: - G_PASTE (_cogl_unpack_bgr_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - G_PASTE (_cogl_unpack_rgba_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - G_PASTE (_cogl_unpack_bgra_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - G_PASTE (_cogl_unpack_argb_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - G_PASTE (_cogl_unpack_abgr_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_565: - G_PASTE (_cogl_unpack_rgb_565_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - G_PASTE (_cogl_unpack_rgba_4444_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - G_PASTE (_cogl_unpack_rgba_5551_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - G_PASTE (_cogl_unpack_rgba_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - G_PASTE (_cogl_unpack_bgra_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - G_PASTE (_cogl_unpack_argb_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - G_PASTE (_cogl_unpack_abgr_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - G_PASTE (_cogl_unpack_argb_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_32: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - } -} - -/* Packing from RGBA */ - -/* Pack and round to nearest */ -#define PACK_SIZE(b, max) \ - (((b) * (max) + (1 << (sizeof (component_type) * 8 - 1)) - 1) / \ - ((1 << (sizeof (component_type) * 8)) - 1)) - -#define PACK_1(b) PACK_SIZE (b, 1) -#define PACK_2(b) PACK_SIZE (b, 3) -#define PACK_4(b) PACK_SIZE (b, 0xf) -#define PACK_5(b) PACK_SIZE (b, 0x1f) -#define PACK_6(b) PACK_SIZE (b, 0x3f) -#define PACK_10(b) PACK_SIZE (b, 0x3ff) - -inline static void -G_PASTE (_cogl_pack_a_8_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - *dst = PACK_BYTE (src[3]); - src += 4; - dst++; - } -} - -inline static void -G_PASTE (_cogl_pack_g_8_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - /* FIXME: I'm not sure if this is right. It looks like Nvidia and - Mesa handle luminance textures differently. Maybe we should - consider just removing luminance textures for Cogl 2.0 because - they have been removed in GL 3.0 */ - while (width-- > 0) - { - component_type v = (src[0] + src[1] + src[2]) / 3; - *dst = PACK_BYTE (v); - src += 4; - dst++; - } -} - -inline static void -G_PASTE (_cogl_pack_rg_88_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgb_888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[2] = PACK_BYTE (src[2]); - src += 4; - dst += 3; - } -} - -inline static void -G_PASTE (_cogl_pack_bgr_888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[2] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[0] = PACK_BYTE (src[2]); - src += 4; - dst += 3; - } -} - -inline static void -G_PASTE (_cogl_pack_bgra_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[2] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[0] = PACK_BYTE (src[2]); - dst[3] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_argb_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[1] = PACK_BYTE (src[0]); - dst[2] = PACK_BYTE (src[1]); - dst[3] = PACK_BYTE (src[2]); - dst[0] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_abgr_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[3] = PACK_BYTE (src[0]); - dst[2] = PACK_BYTE (src[1]); - dst[1] = PACK_BYTE (src[2]); - dst[0] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_8888_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - dst[0] = PACK_BYTE (src[0]); - dst[1] = PACK_BYTE (src[1]); - dst[2] = PACK_BYTE (src[2]); - dst[3] = PACK_BYTE (src[3]); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_rgb_565_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - *v = ((PACK_5 (src[0]) << 11) | - (PACK_6 (src[1]) << 5) | - PACK_5 (src[2])); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_4444_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - *v = ((PACK_4 (src[0]) << 12) | - (PACK_4 (src[1]) << 8) | - (PACK_4 (src[2]) << 4) | - PACK_4 (src[3])); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_5551_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint16_t *v = (uint16_t *) dst; - - *v = ((PACK_5 (src[0]) << 11) | - (PACK_5 (src[1]) << 6) | - (PACK_5 (src[2]) << 1) | - PACK_1 (src[3])); - src += 4; - dst += 2; - } -} - -inline static void -G_PASTE (_cogl_pack_rgba_1010102_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_10 (src[0]) << 22) | - (PACK_10 (src[1]) << 12) | - (PACK_10 (src[2]) << 2) | - PACK_2 (src[3])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_bgra_1010102_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_10 (src[2]) << 22) | - (PACK_10 (src[1]) << 12) | - (PACK_10 (src[0]) << 2) | - PACK_2 (src[3])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_argb_2101010_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_2 (src[3]) << 30) | - (PACK_10 (src[0]) << 20) | - (PACK_10 (src[1]) << 10) | - PACK_10 (src[2])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_abgr_2101010_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - while (width-- > 0) - { - uint32_t *v = (uint32_t *) dst; - - *v = ((PACK_2 (src[3]) << 30) | - (PACK_10 (src[2]) << 20) | - (PACK_10 (src[1]) << 10) | - PACK_10 (src[0])); - src += 4; - dst += 4; - } -} - -inline static void -G_PASTE (_cogl_pack_argb_fp_16161616_, component_size) (const component_type *src, - uint8_t *dst, - int width) -{ - g_warning ("Not implemented"); -} - -#undef PACK_SIZE -#undef PACK_1 -#undef PACK_2 -#undef PACK_4 -#undef PACK_5 -#undef PACK_6 -#undef PACK_10 - -inline static void -G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format, - const component_type *src, - uint8_t *dst, - int width) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - G_PASTE (_cogl_pack_a_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_G_8: - G_PASTE (_cogl_pack_g_8_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RG_88: - G_PASTE (_cogl_pack_rg_88_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_888: - G_PASTE (_cogl_pack_rgb_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGR_888: - G_PASTE (_cogl_pack_bgr_888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - G_PASTE (_cogl_pack_rgba_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - G_PASTE (_cogl_pack_bgra_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - G_PASTE (_cogl_pack_argb_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - G_PASTE (_cogl_pack_abgr_8888_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGB_565: - G_PASTE (_cogl_pack_rgb_565_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - G_PASTE (_cogl_pack_rgba_4444_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - G_PASTE (_cogl_pack_rgba_5551_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - G_PASTE (_cogl_pack_rgba_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - G_PASTE (_cogl_pack_bgra_1010102_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - G_PASTE (_cogl_pack_argb_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - G_PASTE (_cogl_pack_abgr_2101010_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - G_PASTE (_cogl_pack_argb_fp_16161616_, component_size) (src, dst, width); - break; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_32: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - } -} diff --git a/cogl/cogl/cogl-bitmap-pixbuf.c b/cogl/cogl/cogl-bitmap-pixbuf.c deleted file mode 100644 index 8a32e6eff..000000000 --- a/cogl/cogl/cogl-bitmap-pixbuf.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-bitmap-private.h" -#include "cogl-context-private.h" -#include "cogl-private.h" - -#include <string.h> - -#include <gdk-pixbuf/gdk-pixbuf.h> - -gboolean -_cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height) -{ - g_return_val_if_fail (filename != NULL, FALSE); - - if (gdk_pixbuf_get_file_info (filename, width, height) != NULL) - return TRUE; - - return FALSE; -} - -CoglBitmap * -_cogl_bitmap_from_file (CoglContext *ctx, - const char *filename, - GError **error) -{ - static CoglUserDataKey pixbuf_key; - GdkPixbuf *pixbuf; - gboolean has_alpha; - GdkColorspace color_space; - CoglPixelFormat pixel_format; - int width; - int height; - int rowstride; - int bits_per_sample; - int n_channels; - CoglBitmap *bmp; - GError *glib_error = NULL; - - /* Load from file using GdkPixbuf */ - pixbuf = gdk_pixbuf_new_from_file (filename, &glib_error); - if (pixbuf == NULL) - { - g_propagate_error (error, glib_error); - return FALSE; - } - - /* Get pixbuf properties */ - has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); - color_space = gdk_pixbuf_get_colorspace (pixbuf); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf); - n_channels = gdk_pixbuf_get_n_channels (pixbuf); - - /* According to current docs this should be true and so - * the translation to cogl pixel format below valid */ - g_assert (bits_per_sample == 8); - - if (has_alpha) - g_assert (n_channels == 4); - else - g_assert (n_channels == 3); - - /* Translate to cogl pixel format */ - switch (color_space) - { - case GDK_COLORSPACE_RGB: - /* The only format supported by GdkPixbuf so far */ - pixel_format = has_alpha ? - COGL_PIXEL_FORMAT_RGBA_8888 : - COGL_PIXEL_FORMAT_RGB_888; - break; - - default: - /* Ouch, spec changed! */ - g_object_unref (pixbuf); - return FALSE; - } - - /* We just use the data directly from the pixbuf so that we don't - have to copy to a separate buffer. Note that Cogl is expected not - to read past the end of bpp*width on the last row even if the - rowstride is much larger so we don't need to worry about - GdkPixbuf's semantics that it may under-allocate the buffer. */ - bmp = cogl_bitmap_new_for_data (ctx, - width, - height, - pixel_format, - rowstride, - gdk_pixbuf_get_pixels (pixbuf)); - - cogl_object_set_user_data (COGL_OBJECT (bmp), - &pixbuf_key, - pixbuf, - g_object_unref); - - return bmp; -} diff --git a/cogl/cogl/cogl-bitmap-private.h b/cogl/cogl/cogl-bitmap-private.h deleted file mode 100644 index a92d6af48..000000000 --- a/cogl/cogl/cogl-bitmap-private.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_BITMAP_H -#define __COGL_BITMAP_H - -#include <glib.h> - -#include "cogl-object-private.h" -#include "cogl-buffer.h" -#include "cogl-bitmap.h" - -struct _CoglBitmap -{ - CoglObject _parent; - - /* Pointer back to the context that this bitmap was created with */ - CoglContext *context; - - CoglPixelFormat format; - int width; - int height; - int rowstride; - - uint8_t *data; - - gboolean mapped; - gboolean bound; - - /* If this is non-null then 'data' is ignored and instead it is - fetched from this shared bitmap. */ - CoglBitmap *shared_bmp; - - /* If this is non-null then 'data' is treated as an offset into the - buffer and map will divert to mapping the buffer */ - CoglBuffer *buffer; -}; - - -/* - * _cogl_bitmap_new_with_malloc_buffer: - * @context: A #CoglContext - * @width: width of the bitmap in pixels - * @height: height of the bitmap in pixels - * @format: the format of the pixels the array will store - * @error: A #GError for catching exceptional errors or %NULL - * - * This is equivalent to cogl_bitmap_new_with_size() except that it - * allocated the buffer using g_malloc() instead of creating a - * #CoglPixelBuffer. The buffer will be automatically destroyed when - * the bitmap is freed. - * - * Return value: a #CoglPixelBuffer representing the newly created array - * - * Since: 1.10 - * Stability: Unstable - */ -CoglBitmap * -_cogl_bitmap_new_with_malloc_buffer (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format, - GError **error); - -/* The idea of this function is that it will create a bitmap that - shares the actual data with another bitmap. This is needed for the - atlas texture backend because it needs upload a bitmap to a sub - texture but override the format so that it ignores the premult - flag. */ -CoglBitmap * -_cogl_bitmap_new_shared (CoglBitmap *shared_bmp, - CoglPixelFormat format, - int width, - int height, - int rowstride); - -CoglBitmap * -_cogl_bitmap_convert (CoglBitmap *bmp, - CoglPixelFormat dst_format, - GError **error); - -CoglBitmap * -_cogl_bitmap_convert_for_upload (CoglBitmap *src_bmp, - CoglPixelFormat internal_format, - gboolean can_convert_in_place, - GError **error); - -gboolean -_cogl_bitmap_convert_into_bitmap (CoglBitmap *src_bmp, - CoglBitmap *dst_bmp, - GError **error); - -CoglBitmap * -_cogl_bitmap_from_file (CoglContext *ctx, - const char *filename, - GError **error); - -gboolean -_cogl_bitmap_unpremult (CoglBitmap *dst_bmp, - GError **error); - -gboolean -_cogl_bitmap_premult (CoglBitmap *dst_bmp, - GError **error); - -gboolean -_cogl_bitmap_convert_premult_status (CoglBitmap *bmp, - CoglPixelFormat dst_format, - GError **error); - -gboolean -_cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error); - -/* Creates a deep copy of the source bitmap */ -CoglBitmap * -_cogl_bitmap_copy (CoglBitmap *src_bmp, - GError **error); - -gboolean -_cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height); - -void -_cogl_bitmap_set_format (CoglBitmap *bitmap, - CoglPixelFormat format); - -/* Maps the bitmap so that the pixels can be accessed directly or if - the bitmap is just a memory bitmap then it just returns the pointer - to memory. Note that the bitmap isn't guaranteed to allocated to - the full size of rowstride*height so it is not safe to read up to - the rowstride of the last row. This will be the case if the user - uploads data using gdk_pixbuf_new_subpixbuf with a sub region - containing the last row of the pixbuf because in that case the - rowstride can be much larger than the width of the image */ -uint8_t * -_cogl_bitmap_map (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -void -_cogl_bitmap_unmap (CoglBitmap *bitmap); - -CoglContext * -_cogl_bitmap_get_context (CoglBitmap *bitmap); - -#endif /* __COGL_BITMAP_H */ diff --git a/cogl/cogl/cogl-bitmap.c b/cogl/cogl/cogl-bitmap.c deleted file mode 100644 index e44b1f955..000000000 --- a/cogl/cogl/cogl-bitmap.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-debug.h" -#include "cogl-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-buffer-private.h" -#include "cogl-pixel-buffer.h" -#include "cogl-context-private.h" -#include "cogl-gtype-private.h" - -#include <string.h> - -static void _cogl_bitmap_free (CoglBitmap *bmp); - -COGL_OBJECT_DEFINE (Bitmap, bitmap); -COGL_GTYPE_DEFINE_CLASS (Bitmap, bitmap); - -static void -_cogl_bitmap_free (CoglBitmap *bmp) -{ - g_assert (!bmp->mapped); - g_assert (!bmp->bound); - - if (bmp->shared_bmp) - cogl_object_unref (bmp->shared_bmp); - - if (bmp->buffer) - cogl_object_unref (bmp->buffer); - - g_free (bmp); -} - -gboolean -_cogl_bitmap_convert_premult_status (CoglBitmap *bmp, - CoglPixelFormat dst_format, - GError **error) -{ - /* Do we need to unpremultiply? */ - if ((bmp->format & COGL_PREMULT_BIT) > 0 && - (dst_format & COGL_PREMULT_BIT) == 0 && - COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (dst_format)) - return _cogl_bitmap_unpremult (bmp, error); - - /* Do we need to premultiply? */ - if ((bmp->format & COGL_PREMULT_BIT) == 0 && - COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (bmp->format) && - (dst_format & COGL_PREMULT_BIT) > 0) - /* Try premultiplying using imaging library */ - return _cogl_bitmap_premult (bmp, error); - - return TRUE; -} - -CoglBitmap * -_cogl_bitmap_copy (CoglBitmap *src_bmp, - GError **error) -{ - CoglBitmap *dst_bmp; - CoglPixelFormat src_format = cogl_bitmap_get_format (src_bmp); - int width = cogl_bitmap_get_width (src_bmp); - int height = cogl_bitmap_get_height (src_bmp); - - dst_bmp = - _cogl_bitmap_new_with_malloc_buffer (src_bmp->context, - width, height, - src_format, - error); - if (!dst_bmp) - return NULL; - - if (!_cogl_bitmap_copy_subregion (src_bmp, - dst_bmp, - 0, 0, /* src_x/y */ - 0, 0, /* dst_x/y */ - width, height, - error)) - { - cogl_object_unref (dst_bmp); - return NULL; - } - - return dst_bmp; -} - -gboolean -_cogl_bitmap_copy_subregion (CoglBitmap *src, - CoglBitmap *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error) -{ - uint8_t *srcdata; - uint8_t *dstdata; - int bpp; - int line; - gboolean succeeded = FALSE; - - /* Intended only for fast copies when format is equal! */ - g_return_val_if_fail ((src->format & ~COGL_PREMULT_BIT) == - (dst->format & ~COGL_PREMULT_BIT), - FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (src->format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (src->format, 0); - - if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0, error))) - { - if ((dstdata = - _cogl_bitmap_map (dst, COGL_BUFFER_ACCESS_WRITE, 0, error))) - { - srcdata += src_y * src->rowstride + src_x * bpp; - dstdata += dst_y * dst->rowstride + dst_x * bpp; - - for (line = 0; line < height; ++line) - { - memcpy (dstdata, srcdata, width * bpp); - srcdata += src->rowstride; - dstdata += dst->rowstride; - } - - succeeded = TRUE; - - _cogl_bitmap_unmap (dst); - } - - _cogl_bitmap_unmap (src); - } - - return succeeded; -} - -gboolean -cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height) -{ - return _cogl_bitmap_get_size_from_file (filename, width, height); -} - -CoglBitmap * -cogl_bitmap_new_for_data (CoglContext *context, - int width, - int height, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglBitmap *bmp; - - g_return_val_if_fail (cogl_is_context (context), NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* Rowstride from width if not given */ - if (rowstride == 0) - rowstride = width * cogl_pixel_format_get_bytes_per_pixel (format, 0); - - bmp = g_new0 (CoglBitmap, 1); - bmp->context = context; - bmp->format = format; - bmp->width = width; - bmp->height = height; - bmp->rowstride = rowstride; - bmp->data = data; - bmp->mapped = FALSE; - bmp->bound = FALSE; - bmp->shared_bmp = NULL; - bmp->buffer = NULL; - - return _cogl_bitmap_object_new (bmp); -} - -CoglBitmap * -_cogl_bitmap_new_with_malloc_buffer (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format, - GError **error) -{ - static CoglUserDataKey bitmap_free_key; - int bpp; - int rowstride; - uint8_t *data; - CoglBitmap *bitmap; - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* Try to malloc the data */ - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - rowstride = ((width * bpp) + 3) & ~3; - data = g_try_malloc (rowstride * height); - - if (!data) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Failed to allocate memory for bitmap"); - return NULL; - } - - /* Now create the bitmap */ - bitmap = cogl_bitmap_new_for_data (context, - width, height, - format, - rowstride, - data); - cogl_object_set_user_data (COGL_OBJECT (bitmap), - &bitmap_free_key, - data, - g_free); - - return bitmap; -} - -CoglBitmap * -_cogl_bitmap_new_shared (CoglBitmap *shared_bmp, - CoglPixelFormat format, - int width, - int height, - int rowstride) -{ - CoglBitmap *bmp; - - bmp = cogl_bitmap_new_for_data (shared_bmp->context, - width, height, - format, - rowstride, - NULL /* data */); - - bmp->shared_bmp = cogl_object_ref (shared_bmp); - - return bmp; -} - -CoglBitmap * -cogl_bitmap_new_from_file (const char *filename, - GError **error) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (filename != NULL, NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - return _cogl_bitmap_from_file (ctx, filename, error); -} - -CoglBitmap * -cogl_bitmap_new_from_buffer (CoglBuffer *buffer, - CoglPixelFormat format, - int width, - int height, - int rowstride, - int offset) -{ - CoglBitmap *bmp; - - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - - bmp = cogl_bitmap_new_for_data (buffer->context, - width, height, - format, - rowstride, - NULL /* data */); - - bmp->buffer = cogl_object_ref (buffer); - bmp->data = GINT_TO_POINTER (offset); - - return bmp; -} - -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 */ - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, 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, 0); - - pixel_buffer = - cogl_pixel_buffer_new (context, - height * rowstride, - NULL); /* data */ - - g_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; -} - -CoglPixelFormat -cogl_bitmap_get_format (CoglBitmap *bitmap) -{ - return bitmap->format; -} - -void -_cogl_bitmap_set_format (CoglBitmap *bitmap, - CoglPixelFormat format) -{ - bitmap->format = format; -} - -int -cogl_bitmap_get_width (CoglBitmap *bitmap) -{ - return bitmap->width; -} - -int -cogl_bitmap_get_height (CoglBitmap *bitmap) -{ - return bitmap->height; -} - -int -cogl_bitmap_get_rowstride (CoglBitmap *bitmap) -{ - return bitmap->rowstride; -} - -CoglPixelBuffer * -cogl_bitmap_get_buffer (CoglBitmap *bitmap) -{ - while (bitmap->shared_bmp) - bitmap = bitmap->shared_bmp; - - return COGL_PIXEL_BUFFER (bitmap->buffer); -} - -uint32_t -cogl_bitmap_error_quark (void) -{ - return g_quark_from_static_string ("cogl-bitmap-error-quark"); -} - -uint8_t * -_cogl_bitmap_map (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_map (bitmap->shared_bmp, access, hints, error); - - g_assert (!bitmap->mapped); - - if (bitmap->buffer) - { - uint8_t *data = _cogl_buffer_map (bitmap->buffer, - access, - hints, - error); - - COGL_NOTE (BITMAP, "A pixel array is being mapped from a bitmap. This " - "usually means that some conversion on the pixel array is " - "needed so a sub-optimal format is being used."); - - if (data) - { - bitmap->mapped = TRUE; - - return data + GPOINTER_TO_INT (bitmap->data); - } - else - return NULL; - } - else - { - bitmap->mapped = TRUE; - - return bitmap->data; - } -} - -void -_cogl_bitmap_unmap (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - { - _cogl_bitmap_unmap (bitmap->shared_bmp); - return; - } - - g_assert (bitmap->mapped); - bitmap->mapped = FALSE; - - if (bitmap->buffer) - cogl_buffer_unmap (bitmap->buffer); -} - -CoglContext * -_cogl_bitmap_get_context (CoglBitmap *bitmap) -{ - return bitmap->context; -} diff --git a/cogl/cogl/cogl-bitmap.h b/cogl/cogl/cogl-bitmap.h deleted file mode 100644 index 955fbb59d..000000000 --- a/cogl/cogl/cogl-bitmap.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_BITMAP_H__ -#define __COGL_BITMAP_H__ - -/* XXX: We forward declare CoglBitmap here to allow for circular - * dependencies between some headers */ -typedef struct _CoglBitmap CoglBitmap; - -#include <cogl/cogl-types.h> -#include <cogl/cogl-buffer.h> -#include <cogl/cogl-context.h> -#include <cogl/cogl-pixel-buffer.h> -#include <cogl/cogl-pixel-format.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * cogl_bitmap_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_bitmap_get_gtype (void); - -/** - * SECTION:cogl-bitmap - * @short_description: Functions for loading images - * - * Cogl allows loading image data into memory as CoglBitmaps without - * loading them immediately into GPU textures. - * - * #CoglBitmap is available since Cogl 1.0 - */ - - -/** - * cogl_bitmap_new_from_file: - * @filename: the file to load. - * @error: a #GError or %NULL. - * - * Loads an image file from disk. This function can be safely called from - * within a thread. - * - * Return value: (transfer full): a #CoglBitmap to the new loaded - * image data, or %NULL if loading the image failed. - * - * Since: 1.0 - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_from_file (const char *filename, - GError **error); - -/** - * cogl_bitmap_new_from_buffer: (skip) - * @buffer: A #CoglBuffer containing image data - * @format: The #CoglPixelFormat defining the format of the image data - * in the given @buffer. - * @width: The width of the image data in the given @buffer. - * @height: The height of the image data in the given @buffer. - * @rowstride: The rowstride in bytes of the image data in the given @buffer. - * @offset: The offset into the given @buffer to the first pixel that - * should be considered part of the #CoglBitmap. - * - * Wraps some image data that has been uploaded into a #CoglBuffer as - * a #CoglBitmap. The data is not copied in this process. - * - * Return value: (transfer full): a #CoglBitmap encapsulating the given @buffer. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_from_buffer (CoglBuffer *buffer, - CoglPixelFormat format, - int width, - int height, - int rowstride, - int offset); - -/** - * cogl_bitmap_new_with_size: (skip) - * @context: A #CoglContext - * @width: width of the bitmap in pixels - * @height: height of the bitmap in pixels - * @format: the format of the pixels the array will store - * - * Creates a new #CoglBitmap with the given width, height and format. - * The initial contents of the bitmap are undefined. - * - * The data for the bitmap will be stored in a newly created - * #CoglPixelBuffer. You can get a pointer to the pixel buffer using - * cogl_bitmap_get_buffer(). The #CoglBuffer API can then be - * used to fill the bitmap with data. - * - * <note>Cogl will try its best to provide a hardware array you can - * map, write into and effectively do a zero copy upload when creating - * a texture from it with cogl_texture_new_from_bitmap(). For various - * reasons, such arrays are likely to have a stride larger than width - * * bytes_per_pixel. The user must take the stride into account when - * writing into it. The stride can be retrieved with - * cogl_bitmap_get_rowstride().</note> - * - * Return value: (transfer full): a #CoglPixelBuffer representing the - * newly created array or %NULL on failure - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_with_size (CoglContext *context, - unsigned int width, - unsigned int height, - CoglPixelFormat format); - -/** - * cogl_bitmap_new_for_data: (skip) - * @context: A #CoglContext - * @width: The width of the bitmap. - * @height: The height of the bitmap. - * @format: The format of the pixel data. - * @rowstride: The rowstride of the bitmap (the number of bytes from - * the start of one row of the bitmap to the next). - * @data: A pointer to the data. The bitmap will take ownership of this data. - * - * Creates a bitmap using some existing data. The data is not copied - * so the application must keep the buffer alive for the lifetime of - * the #CoglBitmap. This can be used for example with - * cogl_framebuffer_read_pixels_into_bitmap() to read data directly - * into an application buffer with the specified rowstride. - * - * Return value: (transfer full): A new #CoglBitmap. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglBitmap * -cogl_bitmap_new_for_data (CoglContext *context, - int width, - int height, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - -/** - * cogl_bitmap_get_format: - * @bitmap: A #CoglBitmap - * - * Return value: the #CoglPixelFormat that the data for the bitmap is in. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglPixelFormat -cogl_bitmap_get_format (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_width: - * @bitmap: A #CoglBitmap - * - * Return value: the width of the bitmap - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT int -cogl_bitmap_get_width (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_height: - * @bitmap: A #CoglBitmap - * - * Return value: the height of the bitmap - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT int -cogl_bitmap_get_height (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_rowstride: - * @bitmap: A #CoglBitmap - * - * Return value: the rowstride of the bitmap. This is the number of - * bytes between the address of start of one row to the address of the - * next row in the image. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT int -cogl_bitmap_get_rowstride (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_buffer: (skip) - * @bitmap: A #CoglBitmap - * - * Return value: (transfer none): the #CoglPixelBuffer that this - * buffer uses for storage. Note that if the bitmap was created with - * cogl_bitmap_new_from_file() then it will not actually be using a - * pixel buffer and this function will return %NULL. - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT CoglPixelBuffer * -cogl_bitmap_get_buffer (CoglBitmap *bitmap); - -/** - * cogl_bitmap_get_size_from_file: - * @filename: the file to check - * @width: (out): return location for the bitmap width, or %NULL - * @height: (out): return location for the bitmap height, or %NULL - * - * Parses an image file enough to extract the width and height - * of the bitmap. - * - * Return value: %TRUE if the image was successfully parsed - * - * Since: 1.0 - */ -COGL_EXPORT gboolean -cogl_bitmap_get_size_from_file (const char *filename, - int *width, - int *height); - -/** - * cogl_is_bitmap: - * @object: a #CoglObject pointer - * - * Checks whether @object is a #CoglBitmap - * - * Return value: %TRUE if the passed @object represents a bitmap, - * and %FALSE otherwise - * - * Since: 1.0 - */ -COGL_EXPORT gboolean -cogl_is_bitmap (void *object); - -/** - * COGL_BITMAP_ERROR: - * - * #GError domain for bitmap errors. - * - * Since: 1.4 - */ -#define COGL_BITMAP_ERROR (cogl_bitmap_error_quark ()) - -/** - * CoglBitmapError: - * @COGL_BITMAP_ERROR_FAILED: Generic failure code, something went - * wrong. - * @COGL_BITMAP_ERROR_UNKNOWN_TYPE: Unknown image type. - * @COGL_BITMAP_ERROR_CORRUPT_IMAGE: An image file was broken somehow. - * - * Error codes that can be thrown when performing bitmap - * operations. Note that gdk_pixbuf_new_from_file() can also throw - * errors directly from the underlying image loading library. For - * example, if GdkPixbuf is used then errors #GdkPixbufError<!-- -->s - * will be used directly. - * - * Since: 1.4 - */ -typedef enum -{ - COGL_BITMAP_ERROR_FAILED, - COGL_BITMAP_ERROR_UNKNOWN_TYPE, - COGL_BITMAP_ERROR_CORRUPT_IMAGE -} CoglBitmapError; - -COGL_EXPORT -uint32_t cogl_bitmap_error_quark (void); - -G_END_DECLS - -#endif /* __COGL_BITMAP_H__ */ diff --git a/cogl/cogl/cogl-bitmask.c b/cogl/cogl/cogl-bitmask.c deleted file mode 100644 index 754c66fa8..000000000 --- a/cogl/cogl/cogl-bitmask.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <glib.h> -#include <string.h> - -#include <test-fixtures/test-unit.h> - -#include "cogl-bitmask.h" -#include "cogl-util.h" -#include "cogl-flags.h" - -/* This code assumes that we can cast an unsigned long to a pointer - and back without losing any data */ -_COGL_STATIC_ASSERT (sizeof (unsigned long) <= sizeof (void *), - "This toolchain breaks Cogl's assumption that it can " - "safely cast an unsigned long to a pointer without " - "losing data"); - -#define ARRAY_INDEX(bit_num) \ - ((bit_num) / (sizeof (unsigned long) * 8)) -#define BIT_INDEX(bit_num) \ - ((bit_num) & (sizeof (unsigned long) * 8 - 1)) -#define BIT_MASK(bit_num) \ - (1UL << BIT_INDEX (bit_num)) - -gboolean -_cogl_bitmask_get_from_array (const CoglBitmask *bitmask, - unsigned int bit_num) -{ - GArray *array = (GArray *) *bitmask; - - /* If the index is off the end of the array then assume the bit is - not set */ - if (bit_num >= sizeof (unsigned long) * 8 * array->len) - return FALSE; - else - return !!(g_array_index (array, unsigned long, ARRAY_INDEX (bit_num)) & - BIT_MASK (bit_num)); -} - -static void -_cogl_bitmask_convert_to_array (CoglBitmask *bitmask) -{ - GArray *array; - /* Fetch the old values */ - unsigned long old_values = _cogl_bitmask_to_bits (bitmask); - - array = g_array_new (FALSE, /* not zero-terminated */ - TRUE, /* do clear new entries */ - sizeof (unsigned long)); - /* Copy the old values back in */ - g_array_append_val (array, old_values); - - *bitmask = (struct _CoglBitmaskImaginaryType *) array; -} - -void -_cogl_bitmask_set_in_array (CoglBitmask *bitmask, - unsigned int bit_num, - gboolean value) -{ - GArray *array; - unsigned int array_index; - unsigned long new_value_mask; - - /* If the bitmask is not already an array then we need to allocate one */ - if (!_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_convert_to_array (bitmask); - - array = (GArray *) *bitmask; - - array_index = ARRAY_INDEX (bit_num); - /* Grow the array if necessary. This will clear the new data */ - if (array_index >= array->len) - g_array_set_size (array, array_index + 1); - - new_value_mask = BIT_MASK (bit_num); - - if (value) - g_array_index (array, unsigned long, array_index) |= new_value_mask; - else - g_array_index (array, unsigned long, array_index) &= ~new_value_mask; -} - -void -_cogl_bitmask_set_bits (CoglBitmask *dst, - const CoglBitmask *src) -{ - if (_cogl_bitmask_has_array (src)) - { - GArray *src_array, *dst_array; - int i; - - if (!_cogl_bitmask_has_array (dst)) - _cogl_bitmask_convert_to_array (dst); - - dst_array = (GArray *) *dst; - src_array = (GArray *) *src; - - if (dst_array->len < src_array->len) - g_array_set_size (dst_array, src_array->len); - - for (i = 0; i < src_array->len; i++) - g_array_index (dst_array, unsigned long, i) |= - g_array_index (src_array, unsigned long, i); - } - else if (_cogl_bitmask_has_array (dst)) - { - GArray *dst_array; - - dst_array = (GArray *) *dst; - - g_array_index (dst_array, unsigned long, 0) |= - _cogl_bitmask_to_bits (src); - } - else - *dst = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (dst) | - _cogl_bitmask_to_bits (src)); -} - -void -_cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value) -{ - GArray *array; - unsigned int array_index, bit_index; - - if (n_bits == 0) - return; - - /* If the bitmask is not already an array then we need to allocate one */ - if (!_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_convert_to_array (bitmask); - - array = (GArray *) *bitmask; - - /* Get the array index of the top most value that will be touched */ - array_index = ARRAY_INDEX (n_bits - 1); - /* Get the bit index of the top most value */ - bit_index = BIT_INDEX (n_bits - 1); - /* Grow the array if necessary. This will clear the new data */ - if (array_index >= array->len) - g_array_set_size (array, array_index + 1); - - if (value) - { - /* Set the bits that are touching this index */ - g_array_index (array, unsigned long, array_index) |= - ~0UL >> (sizeof (unsigned long) * 8 - 1 - bit_index); - - /* Set all of the bits in any lesser indices */ - memset (array->data, 0xff, sizeof (unsigned long) * array_index); - } - else - { - /* Clear the bits that are touching this index */ - g_array_index (array, unsigned long, array_index) &= ~1UL << bit_index; - - /* Clear all of the bits in any lesser indices */ - memset (array->data, 0x00, sizeof (unsigned long) * array_index); - } -} - -void -_cogl_bitmask_xor_bits (CoglBitmask *dst, - const CoglBitmask *src) -{ - if (_cogl_bitmask_has_array (src)) - { - GArray *src_array, *dst_array; - int i; - - if (!_cogl_bitmask_has_array (dst)) - _cogl_bitmask_convert_to_array (dst); - - dst_array = (GArray *) *dst; - src_array = (GArray *) *src; - - if (dst_array->len < src_array->len) - g_array_set_size (dst_array, src_array->len); - - for (i = 0; i < src_array->len; i++) - g_array_index (dst_array, unsigned long, i) ^= - g_array_index (src_array, unsigned long, i); - } - else if (_cogl_bitmask_has_array (dst)) - { - GArray *dst_array; - - dst_array = (GArray *) *dst; - - g_array_index (dst_array, unsigned long, 0) ^= - _cogl_bitmask_to_bits (src); - } - else - *dst = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (dst) ^ - _cogl_bitmask_to_bits (src)); -} - -void -_cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask) -{ - GArray *array = (GArray *) *bitmask; - - memset (array->data, 0, sizeof (unsigned long) * array->len); -} - -void -_cogl_bitmask_foreach (const CoglBitmask *bitmask, - CoglBitmaskForeachFunc func, - void *user_data) -{ - if (_cogl_bitmask_has_array (bitmask)) - { - GArray *array = (GArray *) *bitmask; - const unsigned long *values = &g_array_index (array, unsigned long, 0); - int bit_num; - - COGL_FLAGS_FOREACH_START (values, array->len, bit_num) - { - if (!func (bit_num, user_data)) - return; - } - COGL_FLAGS_FOREACH_END; - } - else - { - unsigned long mask = _cogl_bitmask_to_bits (bitmask); - int bit_num; - - COGL_FLAGS_FOREACH_START (&mask, 1, bit_num) - { - if (!func (bit_num, user_data)) - return; - } - COGL_FLAGS_FOREACH_END; - } -} - -void -_cogl_bitmask_set_flags_array (const CoglBitmask *bitmask, - unsigned long *flags) -{ - const GArray *array = (const GArray *) *bitmask; - int i; - - for (i = 0; i < array->len; i++) - flags[i] |= g_array_index (array, unsigned long, i); -} - -int -_cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask) -{ - const GArray *array = (const GArray *) *bitmask; - int pop = 0; - int i; - - for (i = 0; i < array->len; i++) - pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i)); - - return pop; -} - -int -_cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, - int upto) -{ - const GArray *array = (const GArray *) *bitmask; - - if (upto >= array->len * sizeof (unsigned long) * 8) - return _cogl_bitmask_popcount_in_array (bitmask); - else - { - unsigned long top_mask; - int array_index = ARRAY_INDEX (upto); - int bit_index = BIT_INDEX (upto); - int pop = 0; - int i; - - for (i = 0; i < array_index; i++) - pop += _cogl_util_popcountl (g_array_index (array, unsigned long, i)); - - top_mask = g_array_index (array, unsigned long, array_index); - - return pop + _cogl_util_popcountl (top_mask & ((1UL << bit_index) - 1)); - } -} - -typedef struct -{ - int n_bits; - int *bits; -} CheckData; - -static gboolean -check_bit (int bit_num, void *user_data) -{ - CheckData *data = user_data; - int i; - - for (i = 0; i < data->n_bits; i++) - if (data->bits[i] == bit_num) - { - data->bits[i] = -1; - return TRUE; - } - - g_assert_not_reached (); - - return TRUE; -} - -static void -verify_bits (const CoglBitmask *bitmask, - ...) -{ - CheckData data; - va_list ap, ap_copy; - int i; - - va_start (ap, bitmask); - G_VA_COPY (ap_copy, ap); - - for (data.n_bits = 0; va_arg (ap, int) != -1; data.n_bits++); - - data.bits = alloca (data.n_bits * (sizeof (int))); - - G_VA_COPY (ap, ap_copy); - - for (i = 0; i < data.n_bits; i++) - data.bits[i] = va_arg (ap, int); - - _cogl_bitmask_foreach (bitmask, check_bit, &data); - - for (i = 0; i < data.n_bits; i++) - g_assert_cmpint (data.bits[i], ==, -1); - - g_assert_cmpint (_cogl_bitmask_popcount (bitmask), ==, data.n_bits); - - for (i = 0; i < 1024; i++) - { - int upto_popcount = 0; - int j; - - G_VA_COPY (ap, ap_copy); - - for (j = 0; j < data.n_bits; j++) - if (va_arg (ap, int) < i) - upto_popcount++; - - g_assert_cmpint (_cogl_bitmask_popcount_upto (bitmask, i), - ==, - upto_popcount); - - G_VA_COPY (ap, ap_copy); - - for (j = 0; j < data.n_bits; j++) - if (va_arg (ap, int) == i) - break; - - g_assert_cmpint (_cogl_bitmask_get (bitmask, i), ==, (j < data.n_bits)); - } -} - -UNIT_TEST (check_bitmask_api, - 0 /* no requirements */, - 0 /* no failure cases */) -{ - CoglBitmask bitmask; - CoglBitmask other_bitmask; - /* A dummy bit to make it use arrays sometimes */ - int dummy_bit; - int i; - - for (dummy_bit = -1; dummy_bit < 256; dummy_bit += 40) - { - _cogl_bitmask_init (&bitmask); - _cogl_bitmask_init (&other_bitmask); - - if (dummy_bit != -1) - _cogl_bitmask_set (&bitmask, dummy_bit, TRUE); - - verify_bits (&bitmask, dummy_bit, -1); - - _cogl_bitmask_set (&bitmask, 1, TRUE); - _cogl_bitmask_set (&bitmask, 4, TRUE); - _cogl_bitmask_set (&bitmask, 5, TRUE); - - verify_bits (&bitmask, 1, 4, 5, dummy_bit, -1); - - _cogl_bitmask_set (&bitmask, 4, FALSE); - - verify_bits (&bitmask, 1, 5, dummy_bit, -1); - - _cogl_bitmask_clear_all (&bitmask); - - verify_bits (&bitmask, -1); - - if (dummy_bit != -1) - _cogl_bitmask_set (&bitmask, dummy_bit, TRUE); - - verify_bits (&bitmask, dummy_bit, -1); - - _cogl_bitmask_set (&bitmask, 1, TRUE); - _cogl_bitmask_set (&bitmask, 4, TRUE); - _cogl_bitmask_set (&bitmask, 5, TRUE); - _cogl_bitmask_set (&other_bitmask, 5, TRUE); - _cogl_bitmask_set (&other_bitmask, 6, TRUE); - - _cogl_bitmask_set_bits (&bitmask, &other_bitmask); - - verify_bits (&bitmask, 1, 4, 5, 6, dummy_bit, -1); - verify_bits (&other_bitmask, 5, 6, -1); - - _cogl_bitmask_set (&bitmask, 6, FALSE); - - verify_bits (&bitmask, 1, 4, 5, dummy_bit, -1); - - _cogl_bitmask_xor_bits (&bitmask, &other_bitmask); - - verify_bits (&bitmask, 1, 4, 6, dummy_bit, -1); - verify_bits (&other_bitmask, 5, 6, -1); - - _cogl_bitmask_set_range (&bitmask, 5, TRUE); - - verify_bits (&bitmask, 0, 1, 2, 3, 4, 6, dummy_bit, -1); - - _cogl_bitmask_set_range (&bitmask, 4, FALSE); - - verify_bits (&bitmask, 4, 6, dummy_bit, -1); - - _cogl_bitmask_destroy (&other_bitmask); - _cogl_bitmask_destroy (&bitmask); - } - - /* Extra tests for really long bitmasks */ - _cogl_bitmask_init (&bitmask); - _cogl_bitmask_set_range (&bitmask, 400, TRUE); - _cogl_bitmask_init (&other_bitmask); - _cogl_bitmask_set (&other_bitmask, 5, TRUE); - _cogl_bitmask_xor_bits (&bitmask, &other_bitmask); - - for (i = 0; i < 1024; i++) - g_assert_cmpint (_cogl_bitmask_get (&bitmask, i), - ==, - (i == 5 ? FALSE : - i < 400 ? TRUE : - FALSE)); - - _cogl_bitmask_set_range (&other_bitmask, 500, TRUE); - _cogl_bitmask_set_bits (&bitmask, &other_bitmask); - - for (i = 0; i < 1024; i++) - g_assert_cmpint (_cogl_bitmask_get (&bitmask, i), ==, (i < 500)); -} diff --git a/cogl/cogl/cogl-bitmask.h b/cogl/cogl/cogl-bitmask.h deleted file mode 100644 index 7d73db0db..000000000 --- a/cogl/cogl/cogl-bitmask.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#ifndef __COGL_BITMASK_H -#define __COGL_BITMASK_H - -#include <glib.h> -#include "cogl-util.h" - -G_BEGIN_DECLS - -/* - * CoglBitmask implements a growable array of bits. A CoglBitmask can - * be allocated on the stack but it must be initialised with - * _cogl_bitmask_init() before use and then destroyed with - * _cogl_bitmask_destroy(). A CoglBitmask will try to avoid allocating - * any memory unless more than the number of bits in a long - 1 bits - * are needed. - * - * Internally a CoglBitmask is a pointer. If the least significant bit - * of the pointer is 1 then the rest of the bits are directly used as - * part of the bitmask, otherwise it is a pointer to a GArray of - * unsigned ints. This relies on the fact the g_malloc will return a - * pointer aligned to at least two bytes (so that the least - * significant bit of the address is always 0). It also assumes that - * the size of a pointer is always greater than or equal to the size - * of a long (although there is a compile time assert to verify this). - * - * If the maximum possible bit number in the set is known at compile - * time, it may make more sense to use the macros in cogl-flags.h - * instead of this type. - */ - -typedef struct _CoglBitmaskImaginaryType *CoglBitmask; - -/* These are internal helper macros */ -#define _cogl_bitmask_to_number(bitmask) \ - ((unsigned long) (*bitmask)) -#define _cogl_bitmask_to_bits(bitmask) \ - (_cogl_bitmask_to_number (bitmask) >> 1UL) -/* The least significant bit is set to mark that no array has been - allocated yet */ -#define _cogl_bitmask_from_bits(bits) \ - ((void *) ((((unsigned long) (bits)) << 1UL) | 1UL)) - -/* Internal helper macro to determine whether this bitmask has a - GArray allocated or whether the pointer is just used directly */ -#define _cogl_bitmask_has_array(bitmask) \ - (!(_cogl_bitmask_to_number (bitmask) & 1UL)) - -/* Number of bits we can use before needing to allocate an array */ -#define COGL_BITMASK_MAX_DIRECT_BITS (sizeof (unsigned long) * 8 - 1) - -/* - * _cogl_bitmask_init: - * @bitmask: A pointer to a bitmask - * - * Initialises the cogl bitmask. This must be called before any other - * bitmask functions are called. Initially all of the values are - * zero - */ -#define _cogl_bitmask_init(bitmask) \ - G_STMT_START { *(bitmask) = _cogl_bitmask_from_bits (0); } G_STMT_END - -gboolean -_cogl_bitmask_get_from_array (const CoglBitmask *bitmask, - unsigned int bit_num); - -void -_cogl_bitmask_set_in_array (CoglBitmask *bitmask, - unsigned int bit_num, - gboolean value); - -void -_cogl_bitmask_set_range_in_array (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value); - -void -_cogl_bitmask_clear_all_in_array (CoglBitmask *bitmask); - -void -_cogl_bitmask_set_flags_array (const CoglBitmask *bitmask, - unsigned long *flags); - -int -_cogl_bitmask_popcount_in_array (const CoglBitmask *bitmask); - -int -_cogl_bitmask_popcount_upto_in_array (const CoglBitmask *bitmask, - int upto); - -/* - * cogl_bitmask_set_bits: - * @dst: The bitmask to modify - * @src: The bitmask to copy bits from - * - * This makes sure that all of the bits that are set in @src are also - * set in @dst. Any unset bits in @src are left alone in @dst. - */ -void -_cogl_bitmask_set_bits (CoglBitmask *dst, - const CoglBitmask *src); - -/* - * cogl_bitmask_xor_bits: - * @dst: The bitmask to modify - * @src: The bitmask to copy bits from - * - * For every bit that is set in src, the corresponding bit in dst is - * inverted. - */ -void -_cogl_bitmask_xor_bits (CoglBitmask *dst, - const CoglBitmask *src); - -/* The foreach function can return FALSE to stop iteration */ -typedef gboolean (* CoglBitmaskForeachFunc) (int bit_num, void *user_data); - -/* - * cogl_bitmask_foreach: - * @bitmask: A pointer to a bitmask - * @func: A callback function - * @user_data: A pointer to pass to the callback - * - * This calls @func for each bit that is set in @bitmask. - */ -void -_cogl_bitmask_foreach (const CoglBitmask *bitmask, - CoglBitmaskForeachFunc func, - void *user_data); - -/* - * _cogl_bitmask_get: - * @bitmask: A pointer to a bitmask - * @bit_num: A bit number - * - * Return value: whether bit number @bit_num is set in @bitmask - */ -static inline gboolean -_cogl_bitmask_get (const CoglBitmask *bitmask, unsigned int bit_num) -{ - if (_cogl_bitmask_has_array (bitmask)) - return _cogl_bitmask_get_from_array (bitmask, bit_num); - else if (bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) - return FALSE; - else - return !!(_cogl_bitmask_to_bits (bitmask) & (1UL << bit_num)); -} - -/* - * _cogl_bitmask_set: - * @bitmask: A pointer to a bitmask - * @bit_num: A bit number - * @value: The new value - * - * Sets or resets a bit number @bit_num in @bitmask according to @value. - */ -static inline void -_cogl_bitmask_set (CoglBitmask *bitmask, unsigned int bit_num, gboolean value) -{ - if (_cogl_bitmask_has_array (bitmask) || - bit_num >= COGL_BITMASK_MAX_DIRECT_BITS) - _cogl_bitmask_set_in_array (bitmask, bit_num, value); - else if (value) - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) | - (1UL << bit_num)); - else - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) & - ~(1UL << bit_num)); -} - -/* - * _cogl_bitmask_set_range: - * @bitmask: A pointer to a bitmask - * @n_bits: The number of bits to set - * @value: The value to set - * - * Sets the first @n_bits in @bitmask to @value. - */ -static inline void -_cogl_bitmask_set_range (CoglBitmask *bitmask, - unsigned int n_bits, - gboolean value) -{ - if (_cogl_bitmask_has_array (bitmask) || - n_bits > COGL_BITMASK_MAX_DIRECT_BITS) - _cogl_bitmask_set_range_in_array (bitmask, n_bits, value); - else if (value) - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) | - ~(~0UL << n_bits)); - else - *bitmask = _cogl_bitmask_from_bits (_cogl_bitmask_to_bits (bitmask) & - (~0UL << n_bits)); -} - -/* - * _cogl_bitmask_destroy: - * @bitmask: A pointer to a bitmask - * - * Destroys any resources allocated by the bitmask - */ -static inline void -_cogl_bitmask_destroy (CoglBitmask *bitmask) -{ - if (_cogl_bitmask_has_array (bitmask)) - g_array_free ((GArray *) *bitmask, TRUE); -} - -/* - * _cogl_bitmask_clear_all: - * @bitmask: A pointer to a bitmask - * - * Clears all the bits in a bitmask without destroying any resources. - */ -static inline void -_cogl_bitmask_clear_all (CoglBitmask *bitmask) -{ - if (_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_clear_all_in_array (bitmask); - else - *bitmask = _cogl_bitmask_from_bits (0); -} - -/* - * _cogl_bitmask_set_flags: - * @bitmask: A pointer to a bitmask - * @flags: An array of flags - * - * Bitwise or's the bits from @bitmask into the flags array (see - * cogl-flags) pointed to by @flags. - */ -static inline void -_cogl_bitmask_set_flags (const CoglBitmask *bitmask, - unsigned long *flags) -{ - if (_cogl_bitmask_has_array (bitmask)) - _cogl_bitmask_set_flags_array (bitmask, flags); - else - flags[0] |= _cogl_bitmask_to_bits (bitmask); -} - -/* - * _cogl_bitmask_popcount: - * @bitmask: A pointer to a bitmask - * - * Counts the number of bits that are set in the bitmask. - * - * Return value: the number of bits set in @bitmask. - */ -static inline int -_cogl_bitmask_popcount (const CoglBitmask *bitmask) -{ - return (_cogl_bitmask_has_array (bitmask) ? - _cogl_bitmask_popcount_in_array (bitmask) : - _cogl_util_popcountl (_cogl_bitmask_to_bits (bitmask))); -} - -/* - * _cogl_bitmask_popcount: - * @Bitmask: A pointer to a bitmask - * @upto: The maximum bit index to consider - * - * Counts the number of bits that are set and have an index which is - * less than @upto. - * - * Return value: the number of bits set in @bitmask that are less than @upto. - */ -static inline int -_cogl_bitmask_popcount_upto (const CoglBitmask *bitmask, - int upto) -{ - if (_cogl_bitmask_has_array (bitmask)) - return _cogl_bitmask_popcount_upto_in_array (bitmask, upto); - else if (upto >= (int) COGL_BITMASK_MAX_DIRECT_BITS) - return _cogl_util_popcountl (_cogl_bitmask_to_bits (bitmask)); - else - return _cogl_util_popcountl (_cogl_bitmask_to_bits (bitmask) & - ((1UL << upto) - 1)); -} - -G_END_DECLS - -#endif /* __COGL_BITMASK_H */ diff --git a/cogl/cogl/cogl-blend-string.c b/cogl/cogl/cogl-blend-string.c deleted file mode 100644 index ba8eb8e96..000000000 --- a/cogl/cogl/cogl-blend-string.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <stdlib.h> -#include <string.h> - -#include <glib.h> - -#include "cogl-context-private.h" -#include "cogl-debug.h" -#include "cogl-blend-string.h" - -typedef enum _ParserState -{ - PARSER_STATE_EXPECT_DEST_CHANNELS, - PARSER_STATE_SCRAPING_DEST_CHANNELS, - PARSER_STATE_EXPECT_FUNCTION_NAME, - PARSER_STATE_SCRAPING_FUNCTION_NAME, - PARSER_STATE_EXPECT_ARG_START, - PARSER_STATE_EXPECT_STATEMENT_END -} ParserState; - -typedef enum _ParserArgState -{ - PARSER_ARG_STATE_START, - PARSER_ARG_STATE_EXPECT_MINUS, - PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME, - PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME, - PARSER_ARG_STATE_MAYBE_COLOR_MASK, - PARSER_ARG_STATE_SCRAPING_MASK, - PARSER_ARG_STATE_MAYBE_MULT, - PARSER_ARG_STATE_EXPECT_OPEN_PAREN, - PARSER_ARG_STATE_EXPECT_FACTOR, - PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE, - PARSER_ARG_STATE_MAYBE_MINUS, - PARSER_ARG_STATE_EXPECT_CLOSE_PAREN, - PARSER_ARG_STATE_EXPECT_END -} ParserArgState; - - -#define DEFINE_COLOR_SOURCE(NAME, NAME_LEN) \ - {/*.type = */COGL_BLEND_STRING_COLOR_SOURCE_ ## NAME, \ - /*.name = */#NAME, \ - /*.name_len = */NAME_LEN} - -static CoglBlendStringColorSourceInfo blending_color_sources[] = { - DEFINE_COLOR_SOURCE (SRC_COLOR, 9), - DEFINE_COLOR_SOURCE (DST_COLOR, 9), - DEFINE_COLOR_SOURCE (CONSTANT, 8) -}; - -static CoglBlendStringColorSourceInfo tex_combine_color_sources[] = { - DEFINE_COLOR_SOURCE (TEXTURE, 7), - /* DEFINE_COLOR_SOURCE (TEXTURE_N, *) - handled manually */ - DEFINE_COLOR_SOURCE (PRIMARY, 7), - DEFINE_COLOR_SOURCE (CONSTANT, 8), - DEFINE_COLOR_SOURCE (PREVIOUS, 8) -}; - -static CoglBlendStringColorSourceInfo tex_combine_texture_n_color_source = { - /*.type = */COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N, - /*.name = */"TEXTURE_N", - /*.name_len = */0 -}; - -#undef DEFINE_COLOR_SOURCE - -#define DEFINE_FUNCTION(NAME, NAME_LEN, ARGC) \ - { /*.type = */COGL_BLEND_STRING_FUNCTION_ ## NAME, \ - /*.name = */#NAME, \ - /*.name_len = */NAME_LEN, \ - /*.argc = */ARGC } - -/* NB: These must be sorted so any name that's a subset of another - * comes later than the longer name. */ -static CoglBlendStringFunctionInfo tex_combine_functions[] = { - DEFINE_FUNCTION (REPLACE, 7, 1), - DEFINE_FUNCTION (MODULATE, 8, 2), - DEFINE_FUNCTION (ADD_SIGNED, 10, 2), - DEFINE_FUNCTION (ADD, 3, 2), - DEFINE_FUNCTION (INTERPOLATE, 11, 3), - DEFINE_FUNCTION (SUBTRACT, 8, 2), - DEFINE_FUNCTION (DOT3_RGBA, 9, 2), - DEFINE_FUNCTION (DOT3_RGB, 8, 2) -}; - -static CoglBlendStringFunctionInfo blend_functions[] = { - DEFINE_FUNCTION (ADD, 3, 2) -}; - -#undef DEFINE_FUNCTION - -uint32_t -cogl_blend_string_error_quark (void) -{ - return g_quark_from_static_string ("cogl-blend-string-error-quark"); -} - -void -_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, - CoglBlendStringStatement *rgb, - CoglBlendStringStatement *a) -{ - int i; - - memcpy (rgb, statement, sizeof (CoglBlendStringStatement)); - memcpy (a, statement, sizeof (CoglBlendStringStatement)); - - rgb->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - - for (i = 0; i < statement->function->argc; i++) - { - CoglBlendStringArgument *arg = &statement->args[i]; - CoglBlendStringArgument *rgb_arg = &rgb->args[i]; - CoglBlendStringArgument *a_arg = &a->args[i]; - - if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - rgb_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a_arg->source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - } - - if (arg->factor.is_color && - arg->factor.source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - rgb_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - a_arg->factor.source.mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - } - } -} - -static gboolean -validate_tex_combine_statements (CoglBlendStringStatement *statements, - int n_statements, - GError **error) -{ - int i, j; - const char *error_string; - CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; - - for (i = 0; i < n_statements; i++) - { - for (j = 0; j < statements[i].function->argc; j++) - { - CoglBlendStringArgument *arg = &statements[i].args[j]; - if (arg->source.is_zero) - { - error_string = "You can't use the constant '0' as a texture " - "combine argument"; - goto error; - } - if (!arg->factor.is_one) - { - error_string = "Argument factors are only relevant to blending " - "not texture combining"; - goto error; - } - } - } - - return TRUE; - -error: - g_set_error (error, COGL_BLEND_STRING_ERROR, detail, - "Invalid texture combine string: %s", error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Invalid texture combine string: %s", - error_string); - } - return FALSE; -} - -static gboolean -validate_blend_statements (CoglBlendStringStatement *statements, - int n_statements, - GError **error) -{ - int i, j; - const char *error_string; - CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; - - _COGL_GET_CONTEXT (ctx, 0); - - for (i = 0; i < n_statements; i++) - for (j = 0; j < statements[i].function->argc; j++) - { - CoglBlendStringArgument *arg = &statements[i].args[j]; - - if (arg->source.is_zero) - continue; - - if ((j == 0 && - arg->source.info->type != - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR) - || (j == 1 && - arg->source.info->type != - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR)) - { - error_string = "For blending you must always use SRC_COLOR " - "for arg0 and DST_COLOR for arg1"; - goto error; - } - } - - return TRUE; - -error: - g_set_error (error, COGL_BLEND_STRING_ERROR, detail, - "Invalid blend string: %s", error_string); - return FALSE; -} - -static gboolean -validate_statements_for_context (CoglBlendStringStatement *statements, - int n_statements, - CoglBlendStringContext context, - GError **error) -{ - const char *error_string; - - if (n_statements == 1) - { - if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - error_string = "You need to also give a blend statement for the RGB" - "channels"; - goto error; - } - else if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) - { - error_string = "You need to also give a blend statement for the " - "Alpha channel"; - goto error; - } - } - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - return validate_blend_statements (statements, n_statements, error); - else - return validate_tex_combine_statements (statements, n_statements, error); - -error: - g_set_error (error, COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - "Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Invalid %s string: %s", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - error_string); - } - - return FALSE; -} - -static void -print_argument (CoglBlendStringArgument *arg) -{ - const char *mask_names[] = { - "RGB", - "A", - "RGBA" - }; - - g_print (" Arg:\n"); - g_print (" is zero = %s\n", arg->source.is_zero ? "yes" : "no"); - if (!arg->source.is_zero) - { - g_print (" color source = %s\n", arg->source.info->name); - g_print (" one minus = %s\n", arg->source.one_minus ? "yes" : "no"); - g_print (" mask = %s\n", mask_names[arg->source.mask]); - g_print (" texture = %d\n", arg->source.texture); - g_print ("\n"); - g_print (" factor is_one = %s\n", arg->factor.is_one ? "yes" : "no"); - g_print (" factor is_src_alpha_saturate = %s\n", - arg->factor.is_src_alpha_saturate ? "yes" : "no"); - g_print (" factor is_color = %s\n", arg->factor.is_color ? "yes" : "no"); - if (arg->factor.is_color) - { - g_print (" factor color:is zero = %s\n", - arg->factor.source.is_zero ? "yes" : "no"); - g_print (" factor color:color source = %s\n", - arg->factor.source.info->name); - g_print (" factor color:one minus = %s\n", - arg->factor.source.one_minus ? "yes" : "no"); - g_print (" factor color:mask = %s\n", - mask_names[arg->factor.source.mask]); - g_print (" factor color:texture = %d\n", - arg->factor.source.texture); - } - } -} - -static void -print_statement (int num, CoglBlendStringStatement *statement) -{ - const char *mask_names[] = { - "RGB", - "A", - "RGBA" - }; - int i; - g_print ("Statement %d:\n", num); - g_print (" Destination channel mask = %s\n", - mask_names[statement->mask]); - g_print (" Function = %s\n", statement->function->name); - for (i = 0; i < statement->function->argc; i++) - print_argument (&statement->args[i]); -} - -static const CoglBlendStringFunctionInfo * -get_function_info (const char *mark, - const char *p, - CoglBlendStringContext context) -{ - size_t len = p - mark; - CoglBlendStringFunctionInfo *functions; - size_t array_len; - int i; - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - { - functions = blend_functions; - array_len = G_N_ELEMENTS (blend_functions); - } - else - { - functions = tex_combine_functions; - array_len = G_N_ELEMENTS (tex_combine_functions); - } - - for (i = 0; i < array_len; i++) - { - if (len >= functions[i].name_len - && strncmp (mark, functions[i].name, functions[i].name_len) == 0) - return &functions[i]; - } - return NULL; -} - -static const CoglBlendStringColorSourceInfo * -get_color_src_info (const char *mark, - const char *p, - CoglBlendStringContext context) -{ - size_t len = p - mark; - CoglBlendStringColorSourceInfo *sources; - size_t array_len; - int i; - - if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) - { - sources = blending_color_sources; - array_len = G_N_ELEMENTS (blending_color_sources); - } - else - { - sources = tex_combine_color_sources; - array_len = G_N_ELEMENTS (tex_combine_color_sources); - } - - if (len >= 8 && - strncmp (mark, "TEXTURE_", 8) == 0 && - g_ascii_isdigit (mark[8])) - { - return &tex_combine_texture_n_color_source; - } - - for (i = 0; i < array_len; i++) - { - if (len >= sources[i].name_len - && strncmp (mark, sources[i].name, sources[i].name_len) == 0) - return &sources[i]; - } - - return NULL; -} - -static gboolean -is_symbol_char (const char c) -{ - return (g_ascii_isalpha (c) || c == '_') ? TRUE : FALSE; -} - -static gboolean -is_alphanum_char (const char c) -{ - return (g_ascii_isalnum (c) || c == '_') ? TRUE : FALSE; -} - -static gboolean -parse_argument (const char *string, /* original user string */ - const char **ret_p, /* start of argument IN:OUT */ - const CoglBlendStringStatement *statement, - int current_arg, - CoglBlendStringArgument *arg, /* OUT */ - CoglBlendStringContext context, - GError **error) -{ - const char *p = *ret_p; - const char *mark = NULL; - const char *error_string = NULL; - ParserArgState state = PARSER_ARG_STATE_START; - gboolean parsing_factor = FALSE; - gboolean implicit_factor_brace = FALSE; - - arg->source.is_zero = FALSE; - arg->source.info = NULL; - arg->source.texture = 0; - arg->source.one_minus = FALSE; - arg->source.mask = statement->mask; - - arg->factor.is_one = FALSE; - arg->factor.is_color = FALSE; - arg->factor.is_src_alpha_saturate = FALSE; - - arg->factor.source.is_zero = FALSE; - arg->factor.source.info = NULL; - arg->factor.source.texture = 0; - arg->factor.source.one_minus = FALSE; - arg->factor.source.mask = statement->mask; - - do - { - if (g_ascii_isspace (*p)) - continue; - - if (*p == '\0') - { - error_string = "Unexpected end of string while parsing argument"; - goto error; - } - - switch (state) - { - case PARSER_ARG_STATE_START: - if (*p == '1') - state = PARSER_ARG_STATE_EXPECT_MINUS; - else if (*p == '0') - { - arg->source.is_zero = TRUE; - state = PARSER_ARG_STATE_EXPECT_END; - } - else - { - p--; /* backtrack */ - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - } - continue; - - case PARSER_ARG_STATE_EXPECT_MINUS: - if (*p != '-') - { - error_string = "expected a '-' following the 1"; - goto error; - } - arg->source.one_minus = TRUE; - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - continue; - - case PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME: - if (!is_symbol_char (*p)) - { - error_string = "expected a color source name"; - goto error; - } - state = PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME; - mark = p; - if (parsing_factor) - arg->factor.is_color = TRUE; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_SCRAPING_COLOR_SRC_NAME: - if (!is_symbol_char (*p)) - { - CoglBlendStringColorSource *source = - parsing_factor ? &arg->factor.source : &arg->source; - source->info = get_color_src_info (mark, p, context); - if (!source->info) - { - error_string = "Unknown color source name"; - goto error; - } - if (source->info->type == - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N) - { - char *endp; - source->texture = - strtoul (&mark[strlen ("TEXTURE_")], &endp, 10); - if (mark == endp) - { - error_string = "invalid texture number given with " - "TEXTURE_N color source"; - goto error; - } - p = endp; - } - state = PARSER_ARG_STATE_MAYBE_COLOR_MASK; - } - else - continue; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_MAYBE_COLOR_MASK: - if (*p != '[') - { - p--; /* backtrack */ - if (!parsing_factor) - state = PARSER_ARG_STATE_MAYBE_MULT; - else - state = PARSER_ARG_STATE_EXPECT_END; - continue; - } - state = PARSER_ARG_STATE_SCRAPING_MASK; - mark = p; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_SCRAPING_MASK: - if (*p == ']') - { - size_t len = p - mark; - CoglBlendStringColorSource *source = - parsing_factor ? &arg->factor.source : &arg->source; - - if (len == 5 && strncmp (mark, "[RGBA", len) == 0) - { - if (statement->mask != COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - error_string = "You can't use an RGBA color mask if the " - "statement hasn't also got an RGBA= mask"; - goto error; - } - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; - } - else if (len == 4 && strncmp (mark, "[RGB", len) == 0) - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - else if (len == 2 && strncmp (mark, "[A", len) == 0) - source->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - else - { - error_string = "Expected a channel mask of [RGBA]" - "[RGB] or [A]"; - goto error; - } - if (parsing_factor) - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - else - state = PARSER_ARG_STATE_MAYBE_MULT; - } - continue; - - case PARSER_ARG_STATE_EXPECT_OPEN_PAREN: - if (*p != '(') - { - if (is_alphanum_char (*p)) - { - p--; /* compensate for implicit brace and ensure this - * char gets considered part of the blend factor */ - implicit_factor_brace = TRUE; - } - else - { - error_string = "Expected '(' around blend factor or alpha " - "numeric character for blend factor name"; - goto error; - } - } - else - implicit_factor_brace = FALSE; - parsing_factor = TRUE; - state = PARSER_ARG_STATE_EXPECT_FACTOR; - continue; - - case PARSER_ARG_STATE_EXPECT_FACTOR: - if (*p == '1') - state = PARSER_ARG_STATE_MAYBE_MINUS; - else if (*p == '0') - { - arg->source.is_zero = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - else - { - state = PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE; - mark = p; - } - continue; - - case PARSER_ARG_STATE_MAYBE_SRC_ALPHA_SATURATE: - if (!is_symbol_char (*p)) - { - size_t len = p - mark; - if (len >= strlen ("SRC_ALPHA_SATURATE") && - strncmp (mark, "SRC_ALPHA_SATURATE", len) == 0) - { - arg->factor.is_src_alpha_saturate = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - else - { - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - p = mark - 1; /* backtrack */ - } - } - continue; - - case PARSER_ARG_STATE_MAYBE_MINUS: - if (*p == '-') - { - if (implicit_factor_brace) - { - error_string = "Expected ( ) braces around blend factor with " - "a subtraction"; - goto error; - } - arg->factor.source.one_minus = TRUE; - state = PARSER_ARG_STATE_EXPECT_COLOR_SRC_NAME; - } - else - { - arg->factor.is_one = TRUE; - state = PARSER_ARG_STATE_EXPECT_CLOSE_PAREN; - } - continue; - - case PARSER_ARG_STATE_EXPECT_CLOSE_PAREN: - if (implicit_factor_brace) - { - p--; - state = PARSER_ARG_STATE_EXPECT_END; - continue; - } - if (*p != ')') - { - error_string = "Expected closing parenthesis after blend factor"; - goto error; - } - state = PARSER_ARG_STATE_EXPECT_END; - continue; - - case PARSER_ARG_STATE_MAYBE_MULT: - if (*p == '*') - { - state = PARSER_ARG_STATE_EXPECT_OPEN_PAREN; - continue; - } - arg->factor.is_one = TRUE; - state = PARSER_ARG_STATE_EXPECT_END; - - G_GNUC_FALLTHROUGH; - case PARSER_ARG_STATE_EXPECT_END: - if (*p != ',' && *p != ')') - { - error_string = "expected , or )"; - goto error; - } - - *ret_p = p - 1; - return TRUE; - } - } - while (p++); - -error: - { - int offset = p - string; - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - "Syntax error for argument %d at offset %d: %s", - current_arg, - offset, - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Syntax error for argument %d at offset %d: %s", - current_arg, offset, error_string); - } - return FALSE; - } -} - -int -_cogl_blend_string_compile (const char *string, - CoglBlendStringContext context, - CoglBlendStringStatement *statements, - GError **error) -{ - const char *p = string; - const char *mark = NULL; - const char *error_string; - ParserState state = PARSER_STATE_EXPECT_DEST_CHANNELS; - CoglBlendStringStatement *statement = statements; - int current_statement = 0; - int current_arg = 0; - int remaining_argc = 0; - -#if 0 - COGL_DEBUG_SET_FLAG (COGL_DEBUG_BLEND_STRINGS); -#endif - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - COGL_NOTE (BLEND_STRINGS, "Compiling %s string:\n%s\n", - context == COGL_BLEND_STRING_CONTEXT_BLENDING ? - "blend" : "texture combine", - string); - } - - do - { - if (g_ascii_isspace (*p)) - continue; - - if (*p == '\0') - { - switch (state) - { - case PARSER_STATE_EXPECT_DEST_CHANNELS: - if (current_statement != 0) - goto finished; - error_string = "Empty statement"; - goto error; - case PARSER_STATE_SCRAPING_DEST_CHANNELS: - error_string = "Expected an '=' following the destination " - "channel mask"; - goto error; - case PARSER_STATE_EXPECT_FUNCTION_NAME: - error_string = "Expected a function name"; - goto error; - case PARSER_STATE_SCRAPING_FUNCTION_NAME: - error_string = "Expected parenthesis after the function name"; - goto error; - case PARSER_STATE_EXPECT_ARG_START: - error_string = "Expected to find the start of an argument"; - goto error; - case PARSER_STATE_EXPECT_STATEMENT_END: - error_string = "Expected closing parenthesis for statement"; - goto error; - } - } - - switch (state) - { - case PARSER_STATE_EXPECT_DEST_CHANNELS: - mark = p; - state = PARSER_STATE_SCRAPING_DEST_CHANNELS; - - G_GNUC_FALLTHROUGH; - case PARSER_STATE_SCRAPING_DEST_CHANNELS: - if (*p != '=') - continue; - if (strncmp (mark, "RGBA", 4) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGBA; - else if (strncmp (mark, "RGB", 3) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_RGB; - else if (strncmp (mark, "A", 1) == 0) - statement->mask = COGL_BLEND_STRING_CHANNEL_MASK_ALPHA; - else - { - error_string = "Unknown destination channel mask; " - "expected RGBA=, RGB= or A="; - goto error; - } - state = PARSER_STATE_EXPECT_FUNCTION_NAME; - continue; - - case PARSER_STATE_EXPECT_FUNCTION_NAME: - mark = p; - state = PARSER_STATE_SCRAPING_FUNCTION_NAME; - - G_GNUC_FALLTHROUGH; - case PARSER_STATE_SCRAPING_FUNCTION_NAME: - if (*p != '(') - { - if (!is_alphanum_char (*p)) - { - error_string = "non alpha numeric character in function" - "name"; - goto error; - } - continue; - } - statement->function = get_function_info (mark, p, context); - if (!statement->function) - { - error_string = "Unknown function name"; - goto error; - } - remaining_argc = statement->function->argc; - current_arg = 0; - state = PARSER_STATE_EXPECT_ARG_START; - - G_GNUC_FALLTHROUGH; - case PARSER_STATE_EXPECT_ARG_START: - if (*p != '(' && *p != ',') - continue; - if (remaining_argc) - { - p++; /* parse_argument expects to see the first char of the arg */ - if (!parse_argument (string, &p, statement, - current_arg, &statement->args[current_arg], - context, error)) - return 0; - current_arg++; - remaining_argc--; - } - if (!remaining_argc) - state = PARSER_STATE_EXPECT_STATEMENT_END; - continue; - - case PARSER_STATE_EXPECT_STATEMENT_END: - if (*p != ')') - { - error_string = "Expected end of statement"; - goto error; - } - state = PARSER_STATE_EXPECT_DEST_CHANNELS; - if (current_statement++ == 1) - goto finished; - statement = &statements[current_statement]; - } - } - while (p++); - -finished: - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - if (current_statement > 0) - print_statement (0, &statements[0]); - if (current_statement > 1) - print_statement (1, &statements[1]); - } - - if (!validate_statements_for_context (statements, - current_statement, - context, - error)) - return 0; - - return current_statement; - -error: - { - int offset = p - string; - g_set_error (error, - COGL_BLEND_STRING_ERROR, - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - "Syntax error at offset %d: %s", - offset, - error_string); - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) - { - g_debug ("Syntax error at offset %d: %s", - offset, error_string); - } - return 0; - } -} - -/* - * INTERNAL TESTING CODE ... - */ - -struct _TestString -{ - const char *string; - CoglBlendStringContext context; -}; - -/* FIXME: this should probably be moved to a unit test */ -int -_cogl_blend_string_test (void); - -int -_cogl_blend_string_test (void) -{ - struct _TestString strings[] = { - {" A = MODULATE ( TEXTURE[RGB], PREVIOUS[A], PREVIOUS[A] ) ", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {" RGB = MODULATE ( TEXTURE[RGB], PREVIOUS[A] ) ", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - {"A=ADD(TEXTURE[A],PREVIOUS[RGB])", - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE }, - - {"RGBA = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, DST_COLOR*(0))", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, 0)", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD()", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {"RGB = ADD(SRC_COLOR, 0, DST_COLOR)", - COGL_BLEND_STRING_CONTEXT_BLENDING }, - {NULL} - }; - int i; - - GError *error = NULL; - for (i = 0; strings[i].string; i++) - { - CoglBlendStringStatement statements[2]; - int count = _cogl_blend_string_compile (strings[i].string, - strings[i].context, - statements, - &error); - if (!count) - { - g_print ("Failed to parse string:\n%s\n%s\n", - strings[i].string, - error->message); - g_error_free (error); - error = NULL; - continue; - } - g_print ("Original:\n"); - g_print ("%s\n", strings[i].string); - if (count > 0) - print_statement (0, &statements[0]); - if (count > 1) - print_statement (1, &statements[1]); - } - - return 0; -} - diff --git a/cogl/cogl/cogl-blend-string.h b/cogl/cogl/cogl-blend-string.h deleted file mode 100644 index 8333abad4..000000000 --- a/cogl/cogl/cogl-blend-string.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef COGL_BLEND_STRING_H -#define COGL_BLEND_STRING_H - -#include <stdlib.h> -#include <glib.h> - -typedef enum _CoglBlendStringContext -{ - COGL_BLEND_STRING_CONTEXT_BLENDING, - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE -} CoglBlendStringContext; - -/* NB: debug stringify code will get upset if these - * are re-ordered */ -typedef enum _CoglBlendStringChannelMask -{ - COGL_BLEND_STRING_CHANNEL_MASK_RGB, - COGL_BLEND_STRING_CHANNEL_MASK_ALPHA, - COGL_BLEND_STRING_CHANNEL_MASK_RGBA -} CoglBlendStringChannelMask; - -typedef enum _CoglBlendStringColorSourceType -{ - /* blending */ - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR, - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR, - - /* shared */ - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT, - - /* texture combining */ - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE, - COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N, - COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY, - COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS -} CoglBlendStringColorSourceType; - -typedef struct _CoglBlendStringColorSourceInfo -{ - CoglBlendStringColorSourceType type; - const char *name; - size_t name_len; -} CoglBlendStringColorSourceInfo; - -typedef struct _CoglBlendStringColorSource -{ - gboolean is_zero; - const CoglBlendStringColorSourceInfo *info; - int texture; /* for the TEXTURE_N color source */ - gboolean one_minus; - CoglBlendStringChannelMask mask; -} CoglBlendStringColorSource; - -typedef struct _CoglBlendStringFactor -{ - gboolean is_one; - gboolean is_src_alpha_saturate; - gboolean is_color; - CoglBlendStringColorSource source; -} CoglBlendStringFactor; - -typedef struct _CoglBlendStringArgument -{ - CoglBlendStringColorSource source; - CoglBlendStringFactor factor; -} CoglBlendStringArgument; - -typedef enum _CoglBlendStringFunctionType -{ - /* shared */ - COGL_BLEND_STRING_FUNCTION_ADD, - - /* texture combine only */ - COGL_BLEND_STRING_FUNCTION_REPLACE, - COGL_BLEND_STRING_FUNCTION_MODULATE, - COGL_BLEND_STRING_FUNCTION_ADD_SIGNED, - COGL_BLEND_STRING_FUNCTION_INTERPOLATE, - COGL_BLEND_STRING_FUNCTION_SUBTRACT, - COGL_BLEND_STRING_FUNCTION_DOT3_RGB, - COGL_BLEND_STRING_FUNCTION_DOT3_RGBA -} CoglBlendStringFunctionType; - -typedef struct _CoglBlendStringFunctionInfo -{ - enum _CoglBlendStringFunctionType type; - const char *name; - size_t name_len; - int argc; -} CoglBlendStringFunctionInfo; - -typedef struct _CoglBlendStringStatement -{ - CoglBlendStringChannelMask mask; - const CoglBlendStringFunctionInfo *function; - CoglBlendStringArgument args[3]; -} CoglBlendStringStatement; - - -gboolean -_cogl_blend_string_compile (const char *string, - CoglBlendStringContext context, - CoglBlendStringStatement *statements, - GError **error); - -void -_cogl_blend_string_split_rgba_statement (CoglBlendStringStatement *statement, - CoglBlendStringStatement *rgb, - CoglBlendStringStatement *a); - -#endif /* COGL_BLEND_STRING_H */ - diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c deleted file mode 100644 index 57922f736..000000000 --- a/cogl/cogl/cogl-blit.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-util.h" -#include "cogl-blit.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-private.h" -#include "cogl1-context.h" - -static const CoglBlitMode *_cogl_blit_default_mode = NULL; - -static gboolean -_cogl_blit_texture_render_begin (CoglBlitData *data) -{ - CoglContext *ctx = data->src_tex->context; - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - CoglPipeline *pipeline; - unsigned int dst_width, dst_height; - GError *ignore_error = NULL; - - offscreen = _cogl_offscreen_new_with_texture_full - (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - fb = COGL_FRAMEBUFFER (offscreen); - if (!cogl_framebuffer_allocate (fb, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (fb); - return FALSE; - } - - data->dest_fb = fb; - - dst_width = cogl_texture_get_width (data->dst_tex); - dst_height = cogl_texture_get_height (data->dst_tex); - - /* Set up an orthographic projection so we can use pixel - coordinates to render to the texture */ - cogl_framebuffer_orthographic (fb, - 0, 0, dst_width, dst_height, - -1 /* near */, 1 /* far */); - - /* We cache a pipeline used for migrating on to the context so - that it doesn't have to continuously regenerate a shader - program */ - if (ctx->blit_texture_pipeline == NULL) - { - ctx->blit_texture_pipeline = cogl_pipeline_new (ctx); - - cogl_pipeline_set_layer_filters (ctx->blit_texture_pipeline, 0, - COGL_PIPELINE_FILTER_NEAREST, - COGL_PIPELINE_FILTER_NEAREST); - - /* Disable blending by just directly taking the contents of the - source texture */ - cogl_pipeline_set_blend (ctx->blit_texture_pipeline, - "RGBA = ADD(SRC_COLOR, 0)", - NULL); - } - - pipeline = ctx->blit_texture_pipeline; - - cogl_pipeline_set_layer_texture (pipeline, 0, data->src_tex); - - data->pipeline = pipeline; - - return TRUE; -} - -static void -_cogl_blit_texture_render_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - cogl_framebuffer_draw_textured_rectangle (data->dest_fb, - data->pipeline, - dst_x, dst_y, - dst_x + width, - dst_y + height, - src_x / (float) data->src_width, - src_y / (float) data->src_height, - (src_x + width) / - (float) data->src_width, - (src_y + height) / - (float) data->src_height); -} - -static void -_cogl_blit_texture_render_end (CoglBlitData *data) -{ - CoglContext *ctx = data->src_tex->context; - - /* Attach the target texture to the texture render pipeline so that - we don't keep a reference to the source texture forever. This is - assuming that the destination texture will live for a long time - which is currently the case when cogl_blit_* is used from the - atlas code. It may be better in future to keep around a set of - dummy 1x1 textures for each texture target that we could bind - instead. This would also be useful when using a pipeline as a - hash table key such as for the ARBfp program cache. */ - cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0, - data->dst_tex); - - g_object_unref (data->dest_fb); -} - -static gboolean -_cogl_blit_framebuffer_begin (CoglBlitData *data) -{ - CoglContext *ctx = data->src_tex->context; - CoglOffscreen *dst_offscreen = NULL, *src_offscreen = NULL; - CoglFramebuffer *dst_fb, *src_fb; - GError *ignore_error = NULL; - - /* We can only blit between FBOs if both textures have the same - premult convention and the blit framebuffer extension is - supported. */ - if ((_cogl_texture_get_format (data->src_tex) & COGL_PREMULT_BIT) != - (_cogl_texture_get_format (data->dst_tex) & COGL_PREMULT_BIT) || - !cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER)) - return FALSE; - - dst_offscreen = _cogl_offscreen_new_with_texture_full - (data->dst_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - dst_fb = COGL_FRAMEBUFFER (dst_offscreen); - if (!cogl_framebuffer_allocate (dst_fb, &ignore_error)) - { - g_error_free (ignore_error); - goto error; - } - - src_offscreen= _cogl_offscreen_new_with_texture_full - (data->src_tex, - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, - 0 /* level */); - - src_fb = COGL_FRAMEBUFFER (src_offscreen); - if (!cogl_framebuffer_allocate (src_fb, &ignore_error)) - { - g_error_free (ignore_error); - goto error; - } - - data->src_fb = src_fb; - data->dest_fb = dst_fb; - - return TRUE; - -error: - - g_clear_object (&dst_offscreen); - g_clear_object (&src_offscreen); - - return FALSE; -} - -static void -_cogl_blit_framebuffer_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - cogl_blit_framebuffer (data->src_fb, - data->dest_fb, - src_x, src_y, - dst_x, dst_y, - width, height, - NULL); -} - -static void -_cogl_blit_framebuffer_end (CoglBlitData *data) -{ - g_object_unref (data->src_fb); - g_object_unref (data->dest_fb); -} - -static gboolean -_cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data) -{ - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - GError *ignore_error = NULL; - - /* This will only work if the target texture is a CoglTexture2D */ - if (!cogl_is_texture_2d (data->dst_tex)) - return FALSE; - - offscreen = _cogl_offscreen_new_with_texture_full - (data->src_tex, COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, 0 /* level */); - - fb = COGL_FRAMEBUFFER (offscreen); - if (!cogl_framebuffer_allocate (fb, &ignore_error)) - { - g_error_free (ignore_error); - g_object_unref (fb); - return FALSE; - } - - data->src_fb = fb; - - return TRUE; -} - -static void -_cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - _cogl_texture_2d_copy_from_framebuffer (COGL_TEXTURE_2D (data->dst_tex), - src_x, src_y, - width, height, - data->src_fb, - dst_x, dst_y, - 0); /* level */ -} - -static void -_cogl_blit_copy_tex_sub_image_end (CoglBlitData *data) -{ - g_object_unref (data->src_fb); -} - -static gboolean -_cogl_blit_get_tex_data_begin (CoglBlitData *data) -{ - data->format = _cogl_texture_get_format (data->src_tex); - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (data->format) == 1, - FALSE); - - data->bpp = cogl_pixel_format_get_bytes_per_pixel (data->format, 0); - - data->image_data = g_malloc (data->bpp * data->src_width * - data->src_height); - cogl_texture_get_data (data->src_tex, data->format, - data->src_width * data->bpp, data->image_data); - - return TRUE; -} - -static void -_cogl_blit_get_tex_data_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - GError *ignore = NULL; - int rowstride = data->src_width * data->bpp; - int offset = rowstride * src_y + src_x * data->bpp; - - _cogl_texture_set_region (data->dst_tex, - width, height, - data->format, - rowstride, - data->image_data + offset, - dst_x, dst_y, - 0, /* level */ - &ignore); - /* TODO: support chaining up errors during the blit */ -} - -static void -_cogl_blit_get_tex_data_end (CoglBlitData *data) -{ - g_free (data->image_data); -} - -/* These should be specified in order of preference */ -static const CoglBlitMode -_cogl_blit_modes[] = - { - { - "texture-render", - _cogl_blit_texture_render_begin, - _cogl_blit_texture_render_blit, - _cogl_blit_texture_render_end - }, - { - "framebuffer", - _cogl_blit_framebuffer_begin, - _cogl_blit_framebuffer_blit, - _cogl_blit_framebuffer_end - }, - { - "copy-tex-sub-image", - _cogl_blit_copy_tex_sub_image_begin, - _cogl_blit_copy_tex_sub_image_blit, - _cogl_blit_copy_tex_sub_image_end - }, - { - "get-tex-data", - _cogl_blit_get_tex_data_begin, - _cogl_blit_get_tex_data_blit, - _cogl_blit_get_tex_data_end - } - }; - -void -_cogl_blit_begin (CoglBlitData *data, - CoglTexture *dst_tex, - CoglTexture *src_tex) -{ - int i; - - if (_cogl_blit_default_mode == NULL) - { - const char *default_mode_string; - - /* Allow the default to be specified with an environment - variable. For the time being these functions are only used - when blitting between atlas textures so the environment - variable is named to be specific to the atlas code. If we - want to use the code in other places we should create another - environment variable for each specific use case */ - if ((default_mode_string = g_getenv ("COGL_ATLAS_DEFAULT_BLIT_MODE"))) - { - for (i = 0; i < G_N_ELEMENTS (_cogl_blit_modes); i++) - if (!strcmp (_cogl_blit_modes[i].name, default_mode_string)) - { - _cogl_blit_default_mode = _cogl_blit_modes + i; - break; - } - - if (i >= G_N_ELEMENTS (_cogl_blit_modes)) - { - g_warning ("Unknown blit mode %s", default_mode_string); - _cogl_blit_default_mode = _cogl_blit_modes; - } - } - else - /* Default to the first blit mode */ - _cogl_blit_default_mode = _cogl_blit_modes; - } - - memset (data, 0, sizeof (CoglBlitData)); - - data->dst_tex = dst_tex; - data->src_tex = src_tex; - - data->src_width = cogl_texture_get_width (src_tex); - data->src_height = cogl_texture_get_height (src_tex); - - /* Try the default blit mode first */ - if (!_cogl_blit_default_mode->begin_func (data)) - { - COGL_NOTE (ATLAS, "Failed to set up blit mode %s", - _cogl_blit_default_mode->name); - - /* Try all of the other modes in order */ - for (i = 0; i < G_N_ELEMENTS (_cogl_blit_modes); i++) - if (_cogl_blit_modes + i != _cogl_blit_default_mode && - _cogl_blit_modes[i].begin_func (data)) - { - /* Use this mode as the default from now on */ - _cogl_blit_default_mode = _cogl_blit_modes + i; - break; - } - else - COGL_NOTE (ATLAS, - "Failed to set up blit mode %s", - _cogl_blit_modes[i].name); - - /* The last blit mode can't fail so this should never happen */ - g_return_if_fail (i < G_N_ELEMENTS (_cogl_blit_modes)); - } - - data->blit_mode = _cogl_blit_default_mode; - - COGL_NOTE (ATLAS, "Setup blit using %s", _cogl_blit_default_mode->name); -} - -void -_cogl_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height) -{ - data->blit_mode->blit_func (data, src_x, src_y, dst_x, dst_y, width, height); -} - -void -_cogl_blit_end (CoglBlitData *data) -{ - data->blit_mode->end_func (data); -} diff --git a/cogl/cogl/cogl-blit.h b/cogl/cogl/cogl-blit.h deleted file mode 100644 index d3e0da233..000000000 --- a/cogl/cogl/cogl-blit.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __COGL_BLIT_H -#define __COGL_BLIT_H - -#include <glib.h> -#include "cogl-object-private.h" -#include "cogl-texture.h" -#include "cogl-framebuffer.h" - -/* This structures and functions are used when a series of blits needs - to be performed between two textures. In this case there are - multiple methods we can use, most of which involve transferring - between an FBO bound to the texture. */ - -typedef struct _CoglBlitData CoglBlitData; - -typedef gboolean (* CoglBlitBeginFunc) (CoglBlitData *data); -typedef void (* CoglBlitEndFunc) (CoglBlitData *data); - -typedef void (* CoglBlitFunc) (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height); - -typedef struct -{ - const char *name; - CoglBlitBeginFunc begin_func; - CoglBlitFunc blit_func; - CoglBlitEndFunc end_func; -} CoglBlitMode; - -struct _CoglBlitData -{ - CoglTexture *src_tex, *dst_tex; - - unsigned int src_width; - unsigned int src_height; - - const CoglBlitMode *blit_mode; - - /* If we're not using an FBO then we g_malloc a buffer and copy the - complete texture data in */ - unsigned char *image_data; - CoglPixelFormat format; - - int bpp; - - CoglFramebuffer *src_fb; - CoglFramebuffer *dest_fb; - CoglPipeline *pipeline; -}; - -void -_cogl_blit_begin (CoglBlitData *data, - CoglTexture *dst_tex, - CoglTexture *src_tex); - -void -_cogl_blit (CoglBlitData *data, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height); - -void -_cogl_blit_end (CoglBlitData *data); - -#endif /* __COGL_BLIT_H */ diff --git a/cogl/cogl/cogl-boxed-value.c b/cogl/cogl/cogl-boxed-value.c deleted file mode 100644 index ef7099775..000000000 --- a/cogl/cogl/cogl-boxed-value.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-boxed-value.h" -#include "cogl-context-private.h" - -gboolean -_cogl_boxed_value_equal (const CoglBoxedValue *bva, - const CoglBoxedValue *bvb) -{ - const void *pa, *pb; - - if (bva->type != bvb->type) - return FALSE; - - switch (bva->type) - { - case COGL_BOXED_NONE: - return TRUE; - - case COGL_BOXED_INT: - if (bva->size != bvb->size || bva->count != bvb->count) - return FALSE; - - if (bva->count == 1) - { - pa = bva->v.int_value; - pb = bvb->v.int_value; - } - else - { - pa = bva->v.int_array; - pb = bvb->v.int_array; - } - - return !memcmp (pa, pb, sizeof (int) * bva->size * bva->count); - - case COGL_BOXED_FLOAT: - if (bva->size != bvb->size || bva->count != bvb->count) - return FALSE; - - if (bva->count == 1) - { - pa = bva->v.float_value; - pb = bvb->v.float_value; - } - else - { - pa = bva->v.float_array; - pb = bvb->v.float_array; - } - - return !memcmp (pa, pb, sizeof (float) * bva->size * bva->count); - - case COGL_BOXED_MATRIX: - if (bva->size != bvb->size || - bva->count != bvb->count) - return FALSE; - - if (bva->count == 1) - { - pa = bva->v.matrix; - pb = bvb->v.matrix; - } - else - { - pa = bva->v.array; - pb = bvb->v.array; - } - - return !memcmp (pa, pb, - sizeof (float) * bva->size * bva->size * bva->count); - } - - g_warn_if_reached (); - - return FALSE; -} - -static void -_cogl_boxed_value_tranpose (float *dst, - int size, - const float *src) -{ - int y, x; - - /* If the value is transposed we'll just transpose it now as it - * is copied into the boxed value instead of passing TRUE to - * glUniformMatrix because that is not supported on GLES and it - * doesn't seem like the GL driver would be able to do anything - * much smarter than this anyway */ - - for (y = 0; y < size; y++) - for (x = 0; x < size; x++) - *(dst++) = src[y + x * size]; -} - -static void -_cogl_boxed_value_set_x (CoglBoxedValue *bv, - int size, - int count, - CoglBoxedType type, - size_t value_size, - const void *value, - gboolean transpose) -{ - if (count == 1) - { - if (bv->count > 1) - g_free (bv->v.array); - - if (transpose) - _cogl_boxed_value_tranpose (bv->v.float_value, - size, - value); - else - memcpy (bv->v.float_value, value, value_size); - } - else - { - if (bv->count > 1) - { - if (bv->count != count || - bv->size != size || - bv->type != type) - { - g_free (bv->v.array); - bv->v.array = g_malloc (count * value_size); - } - } - else - bv->v.array = g_malloc (count * value_size); - - if (transpose) - { - int value_num; - - for (value_num = 0; value_num < count; value_num++) - _cogl_boxed_value_tranpose (bv->v.float_array + - value_num * size * size, - size, - (const float *) value + - value_num * size * size); - } - else - memcpy (bv->v.array, value, count * value_size); - } - - bv->type = type; - bv->size = size; - bv->count = count; -} - -void -_cogl_boxed_value_set_1f (CoglBoxedValue *bv, - float value) -{ - _cogl_boxed_value_set_x (bv, - 1, 1, COGL_BOXED_FLOAT, - sizeof (float), &value, FALSE); -} - -void -_cogl_boxed_value_set_1i (CoglBoxedValue *bv, - int value) -{ - _cogl_boxed_value_set_x (bv, - 1, 1, COGL_BOXED_INT, - sizeof (int), &value, FALSE); -} - -void -_cogl_boxed_value_set_float (CoglBoxedValue *bv, - int n_components, - int count, - const float *value) -{ - _cogl_boxed_value_set_x (bv, - n_components, count, - COGL_BOXED_FLOAT, - sizeof (float) * n_components, value, FALSE); -} - -void -_cogl_boxed_value_set_int (CoglBoxedValue *bv, - int n_components, - int count, - const int *value) -{ - _cogl_boxed_value_set_x (bv, - n_components, count, - COGL_BOXED_INT, - sizeof (int) * n_components, value, FALSE); -} - -void -_cogl_boxed_value_set_matrix (CoglBoxedValue *bv, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - _cogl_boxed_value_set_x (bv, - dimensions, count, - COGL_BOXED_MATRIX, - sizeof (float) * dimensions * dimensions, - value, - transpose); -} - -void -_cogl_boxed_value_copy (CoglBoxedValue *dst, - const CoglBoxedValue *src) -{ - *dst = *src; - - if (src->count > 1) - { - switch (src->type) - { - case COGL_BOXED_NONE: - break; - - case COGL_BOXED_INT: - dst->v.int_array = g_memdup2 (src->v.int_array, - src->size * src->count * sizeof (int)); - break; - - case COGL_BOXED_FLOAT: - dst->v.float_array = g_memdup2 (src->v.float_array, - src->size * - src->count * - sizeof (float)); - break; - - case COGL_BOXED_MATRIX: - dst->v.float_array = g_memdup2 (src->v.float_array, - src->size * src->size * - src->count * sizeof (float)); - break; - } - } -} - -void -_cogl_boxed_value_destroy (CoglBoxedValue *bv) -{ - if (bv->count > 1) - g_free (bv->v.array); -} - -void -_cogl_boxed_value_set_uniform (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value) -{ - ctx->driver_vtable->set_uniform (ctx, location, value); -} diff --git a/cogl/cogl/cogl-boxed-value.h b/cogl/cogl/cogl-boxed-value.h deleted file mode 100644 index 962c13387..000000000 --- a/cogl/cogl/cogl-boxed-value.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_BOXED_VALUE_H -#define __COGL_BOXED_VALUE_H - -#include <glib.h> - -#include "cogl-context.h" - -typedef enum -{ - COGL_BOXED_NONE, - COGL_BOXED_INT, - COGL_BOXED_FLOAT, - COGL_BOXED_MATRIX -} CoglBoxedType; - -typedef struct _CoglBoxedValue -{ - CoglBoxedType type; - int size, count; - - union { - float float_value[4]; - int int_value[4]; - float matrix[16]; - float *float_array; - int *int_array; - void *array; - } v; -} CoglBoxedValue; - -#define _cogl_boxed_value_init(bv) \ - G_STMT_START { \ - CoglBoxedValue *_bv = (bv); \ - _bv->type = COGL_BOXED_NONE; \ - _bv->count = 1; \ - } G_STMT_END - -gboolean -_cogl_boxed_value_equal (const CoglBoxedValue *bva, - const CoglBoxedValue *bvb); - -void -_cogl_boxed_value_set_1f (CoglBoxedValue *bv, - float value); - -void -_cogl_boxed_value_set_1i (CoglBoxedValue *bv, - int value); - -void -_cogl_boxed_value_set_float (CoglBoxedValue *bv, - int n_components, - int count, - const float *value); - -void -_cogl_boxed_value_set_int (CoglBoxedValue *bv, - int n_components, - int count, - const int *value); - -void -_cogl_boxed_value_set_matrix (CoglBoxedValue *bv, - int dimensions, - int count, - gboolean transpose, - const float *value); - -/* - * _cogl_boxed_value_copy: - * @dst: The destination boxed value - * @src: The source boxed value - * - * This copies @src to @dst. It is assumed that @dst is initialised. - */ -void -_cogl_boxed_value_copy (CoglBoxedValue *dst, - const CoglBoxedValue *src); - -void -_cogl_boxed_value_destroy (CoglBoxedValue *bv); - -void -_cogl_boxed_value_set_uniform (CoglContext *ctx, - int location, - const CoglBoxedValue *value); - -#endif /* __COGL_BOXED_VALUE_H */ diff --git a/cogl/cogl/cogl-buffer-private.h b/cogl/cogl/cogl-buffer-private.h deleted file mode 100644 index 1e8113838..000000000 --- a/cogl/cogl/cogl-buffer-private.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_BUFFER_PRIVATE_H__ -#define __COGL_BUFFER_PRIVATE_H__ - -#include <glib.h> - -#include "cogl-object-private.h" -#include "cogl-buffer.h" -#include "cogl-context.h" -#include "cogl-gl-header.h" - -G_BEGIN_DECLS - -typedef struct _CoglBufferVtable CoglBufferVtable; - -struct _CoglBufferVtable -{ - void * (* map_range) (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - - void (* unmap) (CoglBuffer *buffer); - - gboolean (* set_data) (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error); -}; - -typedef enum _CoglBufferFlags -{ - COGL_BUFFER_FLAG_NONE = 0, - COGL_BUFFER_FLAG_BUFFER_OBJECT = 1UL << 0, /* real openGL buffer object */ - COGL_BUFFER_FLAG_MAPPED = 1UL << 1, - COGL_BUFFER_FLAG_MAPPED_FALLBACK = 1UL << 2 -} CoglBufferFlags; - -typedef enum -{ - COGL_BUFFER_USAGE_HINT_TEXTURE, - COGL_BUFFER_USAGE_HINT_ATTRIBUTE_BUFFER, - COGL_BUFFER_USAGE_HINT_INDEX_BUFFER -} CoglBufferUsageHint; - -typedef enum -{ - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, - COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, - - COGL_BUFFER_BIND_TARGET_COUNT -} CoglBufferBindTarget; - -struct _CoglBuffer -{ - CoglObject _parent; - - CoglContext *context; - - CoglBufferVtable vtable; - - CoglBufferBindTarget last_target; - - CoglBufferFlags flags; - - GLuint gl_handle; /* OpenGL handle */ - unsigned int size; /* size of the buffer, in bytes */ - CoglBufferUsageHint usage_hint; - CoglBufferUpdateHint update_hint; - - /* points to the mapped memory when the CoglBuffer is a VBO, PBO, - * ... or points to allocated memory in the fallback paths */ - uint8_t *data; - - int immutable_ref; - - unsigned int store_created:1; -}; - -/* This is used to register a type to the list of handle types that - will be considered a texture in cogl_is_texture() */ -void -_cogl_buffer_register_buffer_type (const CoglObjectClass *klass); - -#define COGL_BUFFER_DEFINE(TypeName, type_name) \ - COGL_OBJECT_DEFINE_WITH_CODE \ - (TypeName, type_name, \ - _cogl_buffer_register_buffer_type (&_cogl_##type_name##_class)) - -void -_cogl_buffer_initialize (CoglBuffer *buffer, - CoglContext *context, - size_t size, - CoglBufferBindTarget default_target, - CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint); - -void -_cogl_buffer_fini (CoglBuffer *buffer); - -CoglBufferUsageHint -_cogl_buffer_get_usage_hint (CoglBuffer *buffer); - -CoglBuffer * -_cogl_buffer_immutable_ref (CoglBuffer *buffer); - -void -_cogl_buffer_immutable_unref (CoglBuffer *buffer); - -gboolean -_cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size, - GError **error); - -void * -_cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -/* This is a wrapper around cogl_buffer_map_range for internal use - when we want to map the buffer for write only to replace the entire - contents. If the map fails then it will fallback to writing to a - temporary buffer. When _cogl_buffer_unmap_for_fill_or_fallback is - called the temporary buffer will be copied into the array. Note - that these calls share a global array so they can not be nested. */ -void * -_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, - size_t offset, - size_t size); -COGL_EXPORT void * -_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer); - -COGL_EXPORT void -_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer); - -G_END_DECLS - -#endif /* __COGL_BUFFER_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-buffer.c b/cogl/cogl/cogl-buffer.c deleted file mode 100644 index 592605cce..000000000 --- a/cogl/cogl/cogl-buffer.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -/* For an overview of the functionality implemented here, please see - * cogl-buffer.h, which contains the gtk-doc section overview for the - * Pixel Buffers API. - */ - -#include "cogl-config.h" - -#include <stdio.h> -#include <string.h> -#include <glib.h> - -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-pixel-buffer-private.h" - -/* XXX: - * The CoglObject macros don't support any form of inheritance, so for - * now we implement the CoglObject support for the CoglBuffer - * abstract class manually. - */ - -static GSList *_cogl_buffer_types; - -void -_cogl_buffer_register_buffer_type (const CoglObjectClass *klass) -{ - _cogl_buffer_types = g_slist_prepend (_cogl_buffer_types, (void *) klass); -} - -gboolean -cogl_is_buffer (void *object) -{ - const CoglObject *obj = object; - GSList *l; - - if (object == NULL) - return FALSE; - - for (l = _cogl_buffer_types; l; l = l->next) - if (l->data == obj->klass) - return TRUE; - - return FALSE; -} - -/* - * Fallback path, buffer->data points to a malloc'ed buffer. - */ - -static void * -malloc_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - buffer->flags |= COGL_BUFFER_FLAG_MAPPED; - return buffer->data + offset; -} - -static void -malloc_unmap (CoglBuffer *buffer) -{ - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; -} - -static gboolean -malloc_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error) -{ - memcpy (buffer->data + offset, data, size); - return TRUE; -} - -void -_cogl_buffer_initialize (CoglBuffer *buffer, - CoglContext *ctx, - size_t size, - CoglBufferBindTarget default_target, - CoglBufferUsageHint usage_hint, - CoglBufferUpdateHint update_hint) -{ - gboolean use_malloc = FALSE; - - buffer->context = ctx; - buffer->flags = COGL_BUFFER_FLAG_NONE; - buffer->store_created = FALSE; - buffer->size = size; - buffer->last_target = default_target; - buffer->usage_hint = usage_hint; - buffer->update_hint = update_hint; - buffer->data = NULL; - buffer->immutable_ref = 0; - - if (default_target == COGL_BUFFER_BIND_TARGET_PIXEL_PACK || - default_target == COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK) - { - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_PBOS)) - use_malloc = TRUE; - } - - if (use_malloc) - { - buffer->vtable.map_range = malloc_map_range; - buffer->vtable.unmap = malloc_unmap; - buffer->vtable.set_data = malloc_set_data; - - buffer->data = g_malloc (size); - } - else - { - buffer->vtable.map_range = ctx->driver_vtable->buffer_map_range; - buffer->vtable.unmap = ctx->driver_vtable->buffer_unmap; - buffer->vtable.set_data = ctx->driver_vtable->buffer_set_data; - - ctx->driver_vtable->buffer_create (buffer); - - buffer->flags |= COGL_BUFFER_FLAG_BUFFER_OBJECT; - } -} - -void -_cogl_buffer_fini (CoglBuffer *buffer) -{ - g_return_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)); - g_return_if_fail (buffer->immutable_ref == 0); - - if (buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) - buffer->context->driver_vtable->buffer_destroy (buffer); - else - g_free (buffer->data); -} - -unsigned int -cogl_buffer_get_size (CoglBuffer *buffer) -{ - if (!cogl_is_buffer (buffer)) - return 0; - - return COGL_BUFFER (buffer)->size; -} - -void -cogl_buffer_set_update_hint (CoglBuffer *buffer, - CoglBufferUpdateHint hint) -{ - if (!cogl_is_buffer (buffer)) - return; - - if (G_UNLIKELY (hint > COGL_BUFFER_UPDATE_HINT_STREAM)) - hint = COGL_BUFFER_UPDATE_HINT_STATIC; - - buffer->update_hint = hint; -} - -CoglBufferUpdateHint -cogl_buffer_get_update_hint (CoglBuffer *buffer) -{ - if (!cogl_is_buffer (buffer)) - return FALSE; - - return buffer->update_hint; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of buffers has " - "undefined results\n"); - seen = TRUE; - } -} - -void * -_cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - - return cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, error); -} - -void * -cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints) -{ - GError *ignore_error = NULL; - void *ptr = - cogl_buffer_map_range (buffer, 0, buffer->size, access, hints, - &ignore_error); - g_clear_error (&ignore_error); - return ptr; -} - -void * -cogl_buffer_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - g_return_val_if_fail (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED), NULL); - - if (G_UNLIKELY (buffer->immutable_ref)) - warn_about_midscene_changes (); - - buffer->data = buffer->vtable.map_range (buffer, - offset, - size, - access, - hints, - error); - - return buffer->data; -} - -void -cogl_buffer_unmap (CoglBuffer *buffer) -{ - if (!cogl_is_buffer (buffer)) - return; - - if (!(buffer->flags & COGL_BUFFER_FLAG_MAPPED)) - return; - - buffer->vtable.unmap (buffer); -} - -void * -_cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer) -{ - return _cogl_buffer_map_range_for_fill_or_fallback (buffer, 0, buffer->size); -} - -void * -_cogl_buffer_map_range_for_fill_or_fallback (CoglBuffer *buffer, - size_t offset, - size_t size) -{ - CoglContext *ctx = buffer->context; - void *ret; - GError *ignore_error = NULL; - - g_return_val_if_fail (!ctx->buffer_map_fallback_in_use, NULL); - - ctx->buffer_map_fallback_in_use = TRUE; - - ret = cogl_buffer_map_range (buffer, - offset, - size, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - - if (ret) - return ret; - - g_error_free (ignore_error); - - /* If the map fails then we'll use a temporary buffer to fill - the data and then upload it using cogl_buffer_set_data when - the buffer is unmapped. The temporary buffer is shared to - avoid reallocating it every time */ - g_byte_array_set_size (ctx->buffer_map_fallback_array, size); - ctx->buffer_map_fallback_offset = offset; - - buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK; - - return ctx->buffer_map_fallback_array->data; -} - -void -_cogl_buffer_unmap_for_fill_or_fallback (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - g_return_if_fail (ctx->buffer_map_fallback_in_use); - - ctx->buffer_map_fallback_in_use = FALSE; - - if ((buffer->flags & COGL_BUFFER_FLAG_MAPPED_FALLBACK)) - { - /* Note: don't try to catch OOM errors here since the use cases - * we currently have for this api (the journal and path stroke - * tessellator) don't have anything particularly sensible they - * can do in response to a failure anyway so it seems better to - * simply abort instead. - * - * If we find this is a problem for real world applications - * then in the path tessellation case we could potentially add an - * explicit cogl_path_tesselate_stroke() api that can throw an - * error for the app to cache. For the journal we could - * potentially flush the journal in smaller batches so we use - * smaller buffers, though that would probably not help for - * deferred renderers. - */ - _cogl_buffer_set_data (buffer, - ctx->buffer_map_fallback_offset, - ctx->buffer_map_fallback_array->data, - ctx->buffer_map_fallback_array->len, - NULL); - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED_FALLBACK; - } - else - cogl_buffer_unmap (buffer); -} - -gboolean -_cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size, - GError **error) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), FALSE); - g_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, error); -} - -gboolean -cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size) -{ - GError *ignore_error = NULL; - gboolean status = - _cogl_buffer_set_data (buffer, offset, data, size, &ignore_error); - g_clear_error (&ignore_error); - return status; -} - -CoglBuffer * -_cogl_buffer_immutable_ref (CoglBuffer *buffer) -{ - g_return_val_if_fail (cogl_is_buffer (buffer), NULL); - - buffer->immutable_ref++; - return buffer; -} - -void -_cogl_buffer_immutable_unref (CoglBuffer *buffer) -{ - g_return_if_fail (cogl_is_buffer (buffer)); - g_return_if_fail (buffer->immutable_ref > 0); - - buffer->immutable_ref--; -} - diff --git a/cogl/cogl/cogl-buffer.h b/cogl/cogl/cogl-buffer.h deleted file mode 100644 index 4dc1f5744..000000000 --- a/cogl/cogl/cogl-buffer.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C)2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_BUFFER_H__ -#define __COGL_BUFFER_H__ - -#include <cogl/cogl-types.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-buffer - * @short_description: Common buffer functions, including data upload APIs - * @stability: unstable - * - * The CoglBuffer API provides a common interface to manipulate - * buffers that have been allocated either via cogl_pixel_buffer_new() - * or cogl_attribute_buffer_new(). The API allows you to upload data - * to these buffers and define usage hints that help Cogl manage your - * buffer optimally. - * - * Data can either be uploaded by supplying a pointer and size so Cogl - * can copy your data, or you can mmap() a CoglBuffer and then you can - * copy data to the buffer directly. - * - * One of the most common uses for CoglBuffers is to upload texture - * data asynchronously since the ability to mmap the buffers into - * the CPU makes it possible for another thread to handle the IO - * of loading an image file and unpacking it into the mapped buffer - * without blocking other Cogl operations. - */ - -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ - !defined(COGL_GIR_SCANNING) -/* For the public C api we typedef interface types as void to avoid needing - * lots of casting in code and instead we will rely on runtime type checking - * for these objects. */ -typedef void CoglBuffer; -#else -typedef struct _CoglBuffer CoglBuffer; -#define COGL_BUFFER(buffer) ((CoglBuffer *)(buffer)) -#endif - -#define COGL_BUFFER_ERROR (_cogl_buffer_error_domain ()) - -/** - * CoglBufferError: - * @COGL_BUFFER_ERROR_MAP: A buffer could not be mapped either - * because the feature isn't supported or because a system - * limitation was hit. - * - * Error enumeration for #CoglBuffer - * - * Stability: unstable - */ -typedef enum /*< prefix=COGL_BUFFER_ERROR >*/ -{ - COGL_BUFFER_ERROR_MAP -} CoglBufferError; - -uint32_t -_cogl_buffer_error_domain (void); - -/** - * cogl_is_buffer: - * @object: a buffer object - * - * Checks whether @buffer is a buffer object. - * - * Return value: %TRUE if the handle is a CoglBuffer, and %FALSE otherwise - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_buffer (void *object); - -/** - * cogl_buffer_get_size: - * @buffer: a buffer object - * - * Retrieves the size of buffer - * - * Return value: the size of the buffer in bytes - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT unsigned int -cogl_buffer_get_size (CoglBuffer *buffer); - -/** - * CoglBufferUpdateHint: - * @COGL_BUFFER_UPDATE_HINT_STATIC: the buffer will not change over time - * @COGL_BUFFER_UPDATE_HINT_DYNAMIC: the buffer will change from time to time - * @COGL_BUFFER_UPDATE_HINT_STREAM: the buffer will be used once or a couple of - * times - * - * The update hint on a buffer allows the user to give some detail on how often - * the buffer data is going to be updated. - * - * Since: 1.2 - * Stability: unstable - */ -typedef enum /*< prefix=COGL_BUFFER_UPDATE_HINT >*/ -{ - COGL_BUFFER_UPDATE_HINT_STATIC, - COGL_BUFFER_UPDATE_HINT_DYNAMIC, - COGL_BUFFER_UPDATE_HINT_STREAM -} CoglBufferUpdateHint; - -/** - * cogl_buffer_set_update_hint: - * @buffer: a buffer object - * @hint: the new hint - * - * Sets the update hint on a buffer. See #CoglBufferUpdateHint for a description - * of the available hints. - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT void -cogl_buffer_set_update_hint (CoglBuffer *buffer, - CoglBufferUpdateHint hint); - -/** - * cogl_buffer_get_update_hint: - * @buffer: a buffer object - * - * Retrieves the update hints set using cogl_buffer_set_update_hint() - * - * Return value: the #CoglBufferUpdateHint currently used by the buffer - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT CoglBufferUpdateHint -cogl_buffer_get_update_hint (CoglBuffer *buffer); - -/** - * CoglBufferAccess: - * @COGL_BUFFER_ACCESS_READ: the buffer will be read - * @COGL_BUFFER_ACCESS_WRITE: the buffer will written to - * @COGL_BUFFER_ACCESS_READ_WRITE: the buffer will be used for both reading and - * writing - * - * The access hints for cogl_buffer_set_update_hint() - * - * Since: 1.2 - * Stability: unstable - */ -typedef enum /*< prefix=COGL_BUFFER_ACCESS >*/ -{ - COGL_BUFFER_ACCESS_READ = 1 << 0, - COGL_BUFFER_ACCESS_WRITE = 1 << 1, - COGL_BUFFER_ACCESS_READ_WRITE = COGL_BUFFER_ACCESS_READ | COGL_BUFFER_ACCESS_WRITE -} CoglBufferAccess; - - -/** - * CoglBufferMapHint: - * @COGL_BUFFER_MAP_HINT_DISCARD: Tells Cogl that you plan to replace - * all the buffer's contents. When this flag is used to map a - * buffer, the entire contents of the buffer become undefined, even - * if only a subregion of the buffer is mapped. - * @COGL_BUFFER_MAP_HINT_DISCARD_RANGE: Tells Cogl that you plan to - * replace all the contents of the mapped region. The contents of - * the region specified are undefined after this flag is used to - * map a buffer. - * - * Hints to Cogl about how you are planning to modify the data once it - * is mapped. - * - * Since: 1.4 - * Stability: unstable - */ -typedef enum /*< prefix=COGL_BUFFER_MAP_HINT >*/ -{ - COGL_BUFFER_MAP_HINT_DISCARD = 1 << 0, - COGL_BUFFER_MAP_HINT_DISCARD_RANGE = 1 << 1 -} CoglBufferMapHint; - -/** - * cogl_buffer_map: - * @buffer: a buffer object - * @access: how the mapped buffer will be used by the application - * @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how - * the data will be modified once mapped. - * - * Maps the buffer into the application address space for direct - * access. This is equivalent to calling cogl_buffer_map_range() with - * zero as the offset and the size of the entire buffer as the size. - * - * It is strongly recommended that you pass - * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace - * all the buffer's data. This way if the buffer is currently being - * used by the GPU then the driver won't have to stall the CPU and - * wait for the hardware to finish because it can instead allocate a - * new buffer to map. - * - * The behaviour is undefined if you access the buffer in a way - * conflicting with the @access mask you pass. It is also an error to - * release your last reference while the buffer is mapped. - * - * Return value: (transfer none): A pointer to the mapped memory or - * %NULL is the call fails - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT void * -cogl_buffer_map (CoglBuffer *buffer, - CoglBufferAccess access, - CoglBufferMapHint hints); - -/** - * cogl_buffer_map_range: - * @buffer: a buffer object - * @offset: Offset within the buffer to start the mapping - * @size: The size of data to map - * @access: how the mapped buffer will be used by the application - * @hints: A mask of #CoglBufferMapHint<!-- -->s that tell Cogl how - * the data will be modified once mapped. - * @error: A #GError for catching exceptional errors - * - * Maps a sub-region of the buffer into the application's address space - * for direct access. - * - * It is strongly recommended that you pass - * %COGL_BUFFER_MAP_HINT_DISCARD as a hint if you are going to replace - * all the buffer's data. This way if the buffer is currently being - * used by the GPU then the driver won't have to stall the CPU and - * wait for the hardware to finish because it can instead allocate a - * new buffer to map. You can pass - * %COGL_BUFFER_MAP_HINT_DISCARD_RANGE instead if you want the - * regions outside of the mapping to be retained. - * - * The behaviour is undefined if you access the buffer in a way - * conflicting with the @access mask you pass. It is also an error to - * release your last reference while the buffer is mapped. - * - * Return value: (transfer none): A pointer to the mapped memory or - * %NULL is the call fails - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void * -cogl_buffer_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -/** - * cogl_buffer_unmap: - * @buffer: a buffer object - * - * Unmaps a buffer previously mapped by cogl_buffer_map(). - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT void -cogl_buffer_unmap (CoglBuffer *buffer); - -/** - * cogl_buffer_set_data: - * @buffer: a buffer object - * @offset: destination offset (in bytes) in the buffer - * @data: a pointer to the data to be copied into the buffer - * @size: number of bytes to copy - * - * Updates part of the buffer with new data from @data. Where to put this new - * data is controlled by @offset and @offset + @data should be less than the - * buffer size. - * - * Return value: %TRUE is the operation succeeded, %FALSE otherwise - * - * Since: 1.2 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_buffer_set_data (CoglBuffer *buffer, - size_t offset, - const void *data, - size_t size); - -G_END_DECLS - -#endif /* __COGL_BUFFER_H__ */ diff --git a/cogl/cogl/cogl-clip-stack.c b/cogl/cogl/cogl-clip-stack.c deleted file mode 100644 index 4212810ae..000000000 --- a/cogl/cogl/cogl-clip-stack.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> -#include <math.h> - -#include <glib.h> - -#include "cogl-clip-stack.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-journal-private.h" -#include "cogl-util.h" -#include "cogl-primitives-private.h" -#include "cogl-private.h" -#include "cogl-attribute-private.h" -#include "cogl-primitive-private.h" -#include "cogl1-context.h" -#include "cogl-offscreen.h" -#include "cogl-matrix-stack.h" - -static void * -_cogl_clip_stack_push_entry (CoglClipStack *clip_stack, - size_t size, - CoglClipStackType type) -{ - CoglClipStack *entry = g_malloc0 (size); - - /* The new entry starts with a ref count of 1 because the stack - holds a reference to it as it is the top entry */ - entry->ref_count = 1; - entry->type = type; - entry->parent = clip_stack; - - /* We don't need to take a reference to the parent from the entry - because the we are stealing the ref in the new stack top */ - - return entry; -} - -static void -get_transformed_corners (float x_1, - float y_1, - float x_2, - float y_2, - graphene_matrix_t *modelview, - graphene_matrix_t *projection, - const float *viewport, - float *transformed_corners) -{ - int i; - - transformed_corners[0] = x_1; - transformed_corners[1] = y_1; - transformed_corners[2] = x_2; - transformed_corners[3] = y_1; - transformed_corners[4] = x_2; - transformed_corners[5] = y_2; - transformed_corners[6] = x_1; - transformed_corners[7] = y_2; - - - /* Project the coordinates to window space coordinates */ - for (i = 0; i < 4; i++) - { - float *v = transformed_corners + i * 2; - _cogl_transform_point (modelview, projection, viewport, v, v + 1); - } -} - -/* Sets the window-space bounds of the entry based on the projected - coordinates of the given rectangle */ -static void -_cogl_clip_stack_entry_set_bounds (CoglClipStack *entry, - float *transformed_corners) -{ - float min_x = G_MAXFLOAT, min_y = G_MAXFLOAT; - float max_x = -G_MAXFLOAT, max_y = -G_MAXFLOAT; - int i; - - for (i = 0; i < 4; i++) - { - float *v = transformed_corners + i * 2; - - if (v[0] > max_x) - max_x = v[0]; - if (v[0] < min_x) - min_x = v[0]; - if (v[1] > max_y) - max_y = v[1]; - if (v[1] < min_y) - min_y = v[1]; - } - - entry->bounds_x0 = floorf (min_x); - entry->bounds_x1 = ceilf (max_x); - entry->bounds_y0 = floorf (min_y); - entry->bounds_y1 = ceilf (max_y); -} - -CoglClipStack * -_cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, - int x_offset, - int y_offset, - int width, - int height) -{ - CoglClipStack *entry; - - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackWindowRect), - COGL_CLIP_STACK_WINDOW_RECT); - - entry->bounds_x0 = x_offset; - entry->bounds_x1 = x_offset + width; - entry->bounds_y0 = y_offset; - entry->bounds_y1 = y_offset + height; - - return entry; -} - -CoglClipStack * -_cogl_clip_stack_push_rectangle (CoglClipStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport) -{ - CoglClipStackRect *entry; - graphene_matrix_t modelview; - graphene_matrix_t projection; - graphene_matrix_t modelview_projection; - - /* Corners of the given rectangle in an clockwise order: - * (0, 1) (2, 3) - * - * - * - * (6, 7) (4, 5) - */ - float rect[] = { - x_1, y_1, - x_2, y_1, - x_2, y_2, - x_1, y_2 - }; - - /* Make a new entry */ - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackRect), - COGL_CLIP_STACK_RECT); - - entry->x0 = x_1; - entry->y0 = y_1; - entry->x1 = x_2; - entry->y1 = y_2; - - entry->matrix_entry = cogl_matrix_entry_ref (modelview_entry); - - cogl_matrix_entry_get (modelview_entry, &modelview); - cogl_matrix_entry_get (projection_entry, &projection); - - graphene_matrix_multiply (&modelview, &projection, &modelview_projection); - - /* Technically we could avoid the viewport transform at this point - * if we want to make this a bit faster. */ - _cogl_transform_point (&modelview, &projection, viewport, &rect[0], &rect[1]); - _cogl_transform_point (&modelview, &projection, viewport, &rect[2], &rect[3]); - _cogl_transform_point (&modelview, &projection, viewport, &rect[4], &rect[5]); - _cogl_transform_point (&modelview, &projection, viewport, &rect[6], &rect[7]); - - /* If the fully transformed rectangle isn't still axis aligned we - * can't handle it using a scissor. - * - * We don't use an epsilon here since we only really aim to catch - * simple cases where the transform doesn't leave the rectangle screen - * aligned and don't mind some false positives. - */ - if (rect[0] != rect[6] || - rect[1] != rect[3] || - rect[2] != rect[4] || - rect[7] != rect[5]) - { - entry->can_be_scissor = FALSE; - - _cogl_clip_stack_entry_set_bounds ((CoglClipStack *) entry, - rect); - } - else - { - CoglClipStack *base_entry = (CoglClipStack *) entry; - x_1 = rect[0]; - y_1 = rect[1]; - x_2 = rect[4]; - y_2 = rect[5]; - - /* Consider that the modelview matrix may flip the rectangle - * along the x or y axis... */ -#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0) - if (x_1 > x_2) - SWAP (x_1, x_2); - if (y_1 > y_2) - SWAP (y_1, y_2); -#undef SWAP - - base_entry->bounds_x0 = COGL_UTIL_NEARBYINT (x_1); - base_entry->bounds_y0 = COGL_UTIL_NEARBYINT (y_1); - base_entry->bounds_x1 = COGL_UTIL_NEARBYINT (x_2); - base_entry->bounds_y1 = COGL_UTIL_NEARBYINT (y_2); - entry->can_be_scissor = TRUE; - } - - return (CoglClipStack *) entry; -} - -CoglClipStack * -_cogl_clip_stack_push_primitive (CoglClipStack *stack, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport) -{ - CoglClipStackPrimitive *entry; - graphene_matrix_t modelview; - graphene_matrix_t projection; - float transformed_corners[8]; - - entry = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackPrimitive), - COGL_CLIP_STACK_PRIMITIVE); - - entry->primitive = cogl_object_ref (primitive); - - entry->matrix_entry = cogl_matrix_entry_ref (modelview_entry); - - entry->bounds_x1 = bounds_x1; - entry->bounds_y1 = bounds_y1; - entry->bounds_x2 = bounds_x2; - entry->bounds_y2 = bounds_y2; - - cogl_matrix_entry_get (modelview_entry, &modelview); - cogl_matrix_entry_get (projection_entry, &projection); - - get_transformed_corners (bounds_x1, bounds_y1, bounds_x2, bounds_y2, - &modelview, - &projection, - viewport, - transformed_corners); - - /* NB: this is referring to the bounds in window coordinates as opposed - * to the bounds above in primitive local coordinates. */ - _cogl_clip_stack_entry_set_bounds ((CoglClipStack *) entry, - transformed_corners); - - return (CoglClipStack *) entry; -} - -CoglClipStack * -cogl_clip_stack_push_region (CoglClipStack *stack, - cairo_region_t *region) -{ - CoglClipStack *entry; - CoglClipStackRegion *entry_region; - cairo_rectangle_int_t bounds; - - entry_region = _cogl_clip_stack_push_entry (stack, - sizeof (CoglClipStackRegion), - COGL_CLIP_STACK_REGION); - entry = (CoglClipStack *) entry_region; - - cairo_region_get_extents (region, &bounds); - entry->bounds_x0 = bounds.x; - entry->bounds_x1 = bounds.x + bounds.width; - entry->bounds_y0 = bounds.y; - entry->bounds_y1 = bounds.y + bounds.height; - - entry_region->region = cairo_region_reference (region); - - return entry; -} - -CoglClipStack * -_cogl_clip_stack_ref (CoglClipStack *entry) -{ - /* A NULL pointer is considered a valid stack so we should accept - that as an argument */ - if (entry) - entry->ref_count++; - - return entry; -} - -void -_cogl_clip_stack_unref (CoglClipStack *entry) -{ - /* Unref all of the entries until we hit the root of the list or the - entry still has a remaining reference */ - while (entry && --entry->ref_count <= 0) - { - CoglClipStack *parent = entry->parent; - - switch (entry->type) - { - case COGL_CLIP_STACK_RECT: - { - CoglClipStackRect *rect = (CoglClipStackRect *) entry; - cogl_matrix_entry_unref (rect->matrix_entry); - g_free (entry); - break; - } - case COGL_CLIP_STACK_WINDOW_RECT: - g_free (entry); - break; - case COGL_CLIP_STACK_PRIMITIVE: - { - CoglClipStackPrimitive *primitive_entry = - (CoglClipStackPrimitive *) entry; - cogl_matrix_entry_unref (primitive_entry->matrix_entry); - cogl_object_unref (primitive_entry->primitive); - g_free (entry); - break; - } - case COGL_CLIP_STACK_REGION: - { - CoglClipStackRegion *region = (CoglClipStackRegion *) entry; - cairo_region_destroy (region->region); - g_free (entry); - break; - } - default: - g_assert_not_reached (); - } - - entry = parent; - } -} - -CoglClipStack * -_cogl_clip_stack_pop (CoglClipStack *stack) -{ - CoglClipStack *new_top; - - g_return_val_if_fail (stack != NULL, NULL); - - /* To pop we are moving the top of the stack to the old top's parent - node. The stack always needs to have a reference to the top entry - so we must take a reference to the new top. The stack would have - previously had a reference to the old top so we need to decrease - the ref count on that. We need to ref the new head first in case - this stack was the only thing referencing the old top. In that - case the call to _cogl_clip_stack_entry_unref will unref the - parent. */ - new_top = stack->parent; - - _cogl_clip_stack_ref (new_top); - - _cogl_clip_stack_unref (stack); - - return new_top; -} - -void -_cogl_clip_stack_get_bounds (CoglClipStack *stack, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1) -{ - CoglClipStack *entry; - - *scissor_x0 = 0; - *scissor_y0 = 0; - *scissor_x1 = G_MAXINT; - *scissor_y1 = G_MAXINT; - - for (entry = stack; entry; entry = entry->parent) - { - /* Get the intersection of the current scissor and the bounding - box of this clip */ - _cogl_util_scissor_intersect (entry->bounds_x0, - entry->bounds_y0, - entry->bounds_x1, - entry->bounds_y1, - scissor_x0, - scissor_y0, - scissor_x1, - scissor_y1); - } -} - -void -_cogl_clip_stack_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - ctx->driver_vtable->clip_stack_flush (stack, framebuffer); -} diff --git a/cogl/cogl/cogl-clip-stack.h b/cogl/cogl/cogl-clip-stack.h deleted file mode 100644 index 2efaa2777..000000000 --- a/cogl/cogl/cogl-clip-stack.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_CLIP_STACK_H -#define __COGL_CLIP_STACK_H - -#include "cogl-primitive.h" -#include "cogl-framebuffer.h" -#include "cogl-matrix-stack.h" - -/* The clip stack works like a GSList where only a pointer to the top - of the stack is stored. The empty clip stack is represented simply - by the NULL pointer. When an entry is added to or removed from the - stack the new top of the stack is returned. When an entry is pushed - a new clip stack entry is created which effectively takes ownership - of the reference on the old entry. Therefore unrefing the top entry - effectively loses ownership of all entries in the stack */ - -typedef struct _CoglClipStack CoglClipStack; -typedef struct _CoglClipStackRect CoglClipStackRect; -typedef struct _CoglClipStackWindowRect CoglClipStackWindowRect; -typedef struct _CoglClipStackPrimitive CoglClipStackPrimitive; -typedef struct _CoglClipStackRegion CoglClipStackRegion; - -typedef enum - { - COGL_CLIP_STACK_RECT, - COGL_CLIP_STACK_WINDOW_RECT, - COGL_CLIP_STACK_PRIMITIVE, - COGL_CLIP_STACK_REGION, - } CoglClipStackType; - -/* A clip stack consists a list of entries. Each entry has a reference - * count and a link to its parent node. The child takes a reference on - * the parent and the CoglClipStack holds a reference to the top of - * the stack. There are no links back from the parent to the - * children. This allows stacks that have common ancestry to share the - * entries. - * - * For example, the following sequence of operations would generate - * the tree below: - * - * CoglClipStack *stack_a = NULL; - * stack_a = _cogl_clip_stack_push_rectangle (stack_a, ...); - * stack_a = _cogl_clip_stack_push_rectangle (stack_a, ...); - * stack_a = _cogl_clip_stack_push_primitive (stack_a, ...); - * CoglClipStack *stack_b = NULL; - * stack_b = cogl_clip_stack_push_window_rectangle (stack_b, ...); - * - * stack_a - * \ holds a ref to - * +-----------+ - * | prim node | - * |ref count 1| - * +-----------+ - * \ - * +-----------+ +-----------+ - * both tops hold | rect node | | rect node | - * a ref to the |ref count 2|--|ref count 1| - * same rect node +-----------+ +-----------+ - * / - * +-----------+ - * | win. rect | - * |ref count 1| - * +-----------+ - * / holds a ref to - * stack_b - * - */ - -struct _CoglClipStack -{ - /* This will be null if there is no parent. If it is not null then - this node must be holding a reference to the parent */ - CoglClipStack *parent; - - CoglClipStackType type; - - /* All clip entries have a window-space bounding box which we can - use to calculate a scissor. The scissor limits the clip so that - we don't need to do a full stencil clear if the stencil buffer is - needed. This is stored in Cogl's coordinate space (ie, 0,0 is the - top left) */ - int bounds_x0; - int bounds_y0; - int bounds_x1; - int bounds_y1; - - unsigned int ref_count; -}; - -struct _CoglClipStackRect -{ - CoglClipStack _parent_data; - - /* The rectangle for this clip */ - float x0; - float y0; - float x1; - float y1; - - /* The matrix that was current when the clip was set */ - CoglMatrixEntry *matrix_entry; - - /* If this is true then the clip for this rectangle is entirely - described by the scissor bounds. This implies that the rectangle - is screen aligned and we don't need to use the stencil buffer to - set the clip. We keep the entry as a rect entry rather than a - window rect entry so that it will be easier to detect if the - modelview matrix is that same as when a rectangle is added to the - journal. In that case we can use the original clip coordinates - and modify the rectangle instead. */ - gboolean can_be_scissor; -}; - -struct _CoglClipStackWindowRect -{ - CoglClipStack _parent_data; - - /* The window rect clip doesn't need any specific data because it - just adds to the scissor clip */ -}; - -struct _CoglClipStackPrimitive -{ - CoglClipStack _parent_data; - - /* The matrix that was current when the clip was set */ - CoglMatrixEntry *matrix_entry; - - CoglPrimitive *primitive; - - float bounds_x1; - float bounds_y1; - float bounds_x2; - float bounds_y2; -}; - -struct _CoglClipStackRegion -{ - CoglClipStack _parent_data; - - cairo_region_t *region; -}; - -CoglClipStack * -_cogl_clip_stack_push_window_rectangle (CoglClipStack *stack, - int x_offset, - int y_offset, - int width, - int height); - -COGL_EXPORT CoglClipStack * -_cogl_clip_stack_push_rectangle (CoglClipStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport); - -COGL_EXPORT CoglClipStack * -_cogl_clip_stack_push_primitive (CoglClipStack *stack, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - CoglMatrixEntry *modelview_entry, - CoglMatrixEntry *projection_entry, - const float *viewport); -CoglClipStack * -cogl_clip_stack_push_region (CoglClipStack *stack, - cairo_region_t *region); - -CoglClipStack * -_cogl_clip_stack_pop (CoglClipStack *stack); - -void -_cogl_clip_stack_get_bounds (CoglClipStack *stack, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1); - -void -_cogl_clip_stack_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer); - -CoglClipStack * -_cogl_clip_stack_ref (CoglClipStack *stack); - -void -_cogl_clip_stack_unref (CoglClipStack *stack); - -#endif /* __COGL_CLIP_STACK_H */ diff --git a/cogl/cogl/cogl-closure-list-private.h b/cogl/cogl/cogl-closure-list-private.h deleted file mode 100644 index f4b829ba7..000000000 --- a/cogl/cogl/cogl-closure-list-private.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef _COGL_CLOSURE_LIST_PRIVATE_H_ -#define _COGL_CLOSURE_LIST_PRIVATE_H_ - -#include "cogl-object.h" -#include "cogl-list.h" - -/* - * This implements a list of callbacks that can be used a bit like - * signals in GObject, but that don't have any marshalling overhead. - * - * The idea is that any Cogl code that wants to provide a callback - * point will provide api to add a callback for that particular point. - * The function can take a function pointer with the correct - * signature. Internally the Cogl code can use _cogl_closure_list_add, - * _cogl_closure_disconnect and _cogl_closure_list_disconnect_all - * - * In the future we could consider exposing the CoglClosure type which - * would allow applications to use _cogl_closure_disconnect() directly - * so we don't need to expose new disconnect apis for each callback - * point. - */ - -typedef struct _CoglClosure -{ - CoglList link; - - void *function; - void *user_data; - CoglUserDataDestroyCallback destroy_cb; -} CoglClosure; - -/* - * _cogl_closure_disconnect: - * @closure: A closure connected to a Cogl closure list - * - * Removes the given closure from the callback list it is connected to - * and destroys it. If the closure was created with a destroy function - * then it will be invoked. */ -COGL_EXPORT void -_cogl_closure_disconnect (CoglClosure *closure); - -void -_cogl_closure_list_disconnect_all (CoglList *list); - -CoglClosure * -_cogl_closure_list_add (CoglList *list, - void *function, - void *user_data, - CoglUserDataDestroyCallback destroy_cb); - -/* - * _cogl_closure_list_invoke: - * @list: A pointer to a CoglList containing CoglClosures - * @cb_type: The name of a typedef for the closure callback function signature - * @...: The the arguments to pass to the callback - * - * A convenience macro to invoke a closure list with a variable number - * of arguments that will be passed to the closure callback functions. - * - * Note that the arguments will be evaluated multiple times so it is - * not safe to pass expressions that have side-effects. - * - * Note also that this function ignores the return value from the - * callbacks. If you want to handle the return value you should - * manually iterate the list and invoke the callbacks yourself. - */ -#define _cogl_closure_list_invoke(list, cb_type, ...) \ - G_STMT_START { \ - CoglClosure *_c, *_tmp; \ - \ - _cogl_list_for_each_safe (_c, _tmp, (list), link) \ - { \ - cb_type _cb = _c->function; \ - _cb (__VA_ARGS__, _c->user_data); \ - } \ - } G_STMT_END - -#define _cogl_closure_list_invoke_no_args(list) \ - G_STMT_START { \ - CoglClosure *_c, *_tmp; \ - \ - _cogl_list_for_each_safe (_c, _tmp, (list), link) \ - { \ - void (*_cb)(void *) = _c->function; \ - _cb (_c->user_data); \ - } \ - } G_STMT_END - -#endif /* _COGL_CLOSURE_LIST_PRIVATE_H_ */ diff --git a/cogl/cogl/cogl-closure-list.c b/cogl/cogl/cogl-closure-list.c deleted file mode 100644 index 1f4efdc68..000000000 --- a/cogl/cogl/cogl-closure-list.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include <glib.h> - -#include "cogl-closure-list-private.h" - -void -_cogl_closure_disconnect (CoglClosure *closure) -{ - _cogl_list_remove (&closure->link); - - if (closure->destroy_cb) - closure->destroy_cb (closure->user_data); - - g_free (closure); -} - -void -_cogl_closure_list_disconnect_all (CoglList *list) -{ - CoglClosure *closure, *next; - - _cogl_list_for_each_safe (closure, next, list, link) - _cogl_closure_disconnect (closure); -} - -CoglClosure * -_cogl_closure_list_add (CoglList *list, - void *function, - void *user_data, - CoglUserDataDestroyCallback destroy_cb) -{ - CoglClosure *closure = g_new0 (CoglClosure, 1); - - closure->function = function; - closure->user_data = user_data; - closure->destroy_cb = destroy_cb; - - _cogl_list_insert (list, &closure->link); - - return closure; -} diff --git a/cogl/cogl/cogl-color-private.h b/cogl/cogl/cogl-color-private.h deleted file mode 100644 index bb1a58e25..000000000 --- a/cogl/cogl/cogl-color-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_COLOR_PRIVATE_PRIVATE_H -#define __COGL_COLOR_PRIVATE_PRIVATE_H - -#include "cogl-color.h" - -#include <glib.h> - -/* cogl-pipeline.c wants to be able to hash CoglColor data so it needs - * the exact data size to be able to avoid reading the padding bytes. - */ -#define _COGL_COLOR_DATA_SIZE 4 - -void -_cogl_color_get_rgba_4ubv (const CoglColor *color, - uint8_t *dest); - -#endif /* __COGL_COLOR_PRIVATE_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-color.c b/cogl/cogl/cogl-color.c deleted file mode 100644 index 16f471c0f..000000000 --- a/cogl/cogl/cogl-color.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-util.h" -#include "cogl-color.h" -#include "cogl-color-private.h" -#include "cogl-gtype-private.h" - -COGL_GTYPE_DEFINE_BOXED (Color, color, cogl_color_copy, cogl_color_free); - -CoglColor * -cogl_color_new (void) -{ - return g_new0 (CoglColor, 1); -} - -CoglColor * -cogl_color_copy (const CoglColor *color) -{ - if (G_LIKELY (color)) - return g_memdup2 (color, sizeof (CoglColor)); - - return NULL; -} - -void -cogl_color_free (CoglColor *color) -{ - if (G_LIKELY (color)) - g_free (color); -} - -void -cogl_color_init_from_4ub (CoglColor *color, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha) -{ - g_return_if_fail (color != NULL); - - color->red = red; - color->green = green; - color->blue = blue; - color->alpha = alpha; -} - -void -cogl_color_init_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha) -{ - g_return_if_fail (color != NULL); - - color->red = (red * 255); - color->green = (green * 255); - color->blue = (blue * 255); - color->alpha = (alpha * 255); -} - -void -cogl_color_init_from_4fv (CoglColor *color, - const float *color_array) -{ - g_return_if_fail (color != NULL); - - color->red = (color_array[0] * 255); - color->green = (color_array[1] * 255); - color->blue = (color_array[2] * 255); - color->alpha = (color_array[3] * 255); -} - -unsigned char -cogl_color_get_red_byte (const CoglColor *color) -{ - return color->red; -} - -float -cogl_color_get_red_float (const CoglColor *color) -{ - return (float) color->red / 255.0; -} - -float -cogl_color_get_red (const CoglColor *color) -{ - return ((float) color->red / 255.0); -} - -unsigned char -cogl_color_get_green_byte (const CoglColor *color) -{ - return color->green; -} - -float -cogl_color_get_green_float (const CoglColor *color) -{ - return (float) color->green / 255.0; -} - -float -cogl_color_get_green (const CoglColor *color) -{ - return ((float) color->green / 255.0); -} - -unsigned char -cogl_color_get_blue_byte (const CoglColor *color) -{ - return color->blue; -} - -float -cogl_color_get_blue_float (const CoglColor *color) -{ - return (float) color->blue / 255.0; -} - -float -cogl_color_get_blue (const CoglColor *color) -{ - return ((float) color->blue / 255.0); -} - -unsigned char -cogl_color_get_alpha_byte (const CoglColor *color) -{ - return color->alpha; -} - -float -cogl_color_get_alpha_float (const CoglColor *color) -{ - return (float) color->alpha / 255.0; -} - -float -cogl_color_get_alpha (const CoglColor *color) -{ - return ((float) color->alpha / 255.0); -} - -void -cogl_color_set_red_byte (CoglColor *color, - unsigned char red) -{ - color->red = red; -} - -void -cogl_color_set_red_float (CoglColor *color, - float red) -{ - color->red = red * 255.0; -} - -void -cogl_color_set_red (CoglColor *color, - float red) -{ - color->red = red * 255.0; -} - -void -cogl_color_set_green_byte (CoglColor *color, - unsigned char green) -{ - color->green = green; -} - -void -cogl_color_set_green_float (CoglColor *color, - float green) -{ - color->green = green * 255.0; -} - -void -cogl_color_set_green (CoglColor *color, - float green) -{ - color->green = green * 255.0; -} - -void -cogl_color_set_blue_byte (CoglColor *color, - unsigned char blue) -{ - color->blue = blue; -} - -void -cogl_color_set_blue_float (CoglColor *color, - float blue) -{ - color->blue = blue * 255.0; -} - -void -cogl_color_set_blue (CoglColor *color, - float blue) -{ - color->blue = blue * 255.0; -} - -void -cogl_color_set_alpha_byte (CoglColor *color, - unsigned char alpha) -{ - color->alpha = alpha; -} - -void -cogl_color_set_alpha_float (CoglColor *color, - float alpha) -{ - color->alpha = alpha * 255.0; -} - -void -cogl_color_set_alpha (CoglColor *color, - float alpha) -{ - color->alpha = alpha * 255.0; -} - -void -cogl_color_premultiply (CoglColor *color) -{ - color->red = (color->red * color->alpha + 128) / 255; - color->green = (color->green * color->alpha + 128) / 255; - color->blue = (color->blue * color->alpha + 128) / 255; -} - -void -cogl_color_unpremultiply (CoglColor *color) -{ - if (color->alpha != 0) - { - color->red = (color->red * 255) / color->alpha; - color->green = (color->green * 255) / color->alpha; - color->blue = (color->blue * 255) / color->alpha; - } -} - -gboolean -cogl_color_equal (const void *v1, const void *v2) -{ - const uint32_t *c1 = v1, *c2 = v2; - - g_return_val_if_fail (v1 != NULL, FALSE); - g_return_val_if_fail (v2 != NULL, FALSE); - - /* XXX: We don't compare the padding */ - return *c1 == *c2 ? TRUE : FALSE; -} - -void -_cogl_color_get_rgba_4ubv (const CoglColor *color, - uint8_t *dest) -{ - memcpy (dest, color, 4); -} - -void -cogl_color_to_hsl (const CoglColor *color, - float *hue, - float *saturation, - float *luminance) -{ - float red, green, blue; - float min, max, delta; - float h, l, s; - - red = color->red / 255.0; - green = color->green / 255.0; - blue = color->blue / 255.0; - - if (red > green) - { - if (red > blue) - max = red; - else - max = blue; - - if (green < blue) - min = green; - else - min = blue; - } - else - { - if (green > blue) - max = green; - else - max = blue; - - if (red < blue) - min = red; - else - min = blue; - } - - l = (max + min) / 2; - s = 0; - h = 0; - - if (max != min) - { - if (l <= 0.5) - s = (max - min) / (max + min); - else - s = (max - min) / (2.0 - max - min); - - delta = max - min; - - if (red == max) - h = (green - blue) / delta; - else if (green == max) - h = 2.0 + (blue - red) / delta; - else if (blue == max) - h = 4.0 + (red - green) / delta; - - h *= 60; - - if (h < 0) - h += 360.0; - } - - if (hue) - *hue = h; - - if (luminance) - *luminance = l; - - if (saturation) - *saturation = s; -} - -void -cogl_color_init_from_hsl (CoglColor *color, - float hue, - float saturation, - float luminance) -{ - float tmp1, tmp2; - float tmp3[3]; - float clr[3]; - int i; - - hue /= 360.0; - - if (saturation == 0) - { - cogl_color_init_from_4f (color, luminance, luminance, luminance, 1.0f); - return; - } - - if (luminance <= 0.5) - tmp2 = luminance * (1.0 + saturation); - else - tmp2 = luminance + saturation - (luminance * saturation); - - tmp1 = 2.0 * luminance - tmp2; - - tmp3[0] = hue + 1.0 / 3.0; - tmp3[1] = hue; - tmp3[2] = hue - 1.0 / 3.0; - - for (i = 0; i < 3; i++) - { - if (tmp3[i] < 0) - tmp3[i] += 1.0; - - if (tmp3[i] > 1) - tmp3[i] -= 1.0; - - if (6.0 * tmp3[i] < 1.0) - clr[i] = tmp1 + (tmp2 - tmp1) * tmp3[i] * 6.0; - else if (2.0 * tmp3[i] < 1.0) - clr[i] = tmp2; - else if (3.0 * tmp3[i] < 2.0) - clr[i] = (tmp1 + (tmp2 - tmp1) * ((2.0 / 3.0) - tmp3[i]) * 6.0); - else - clr[i] = tmp1; - } - - cogl_color_init_from_4f (color, clr[0], clr[1], clr[2], 1.0f); -} diff --git a/cogl/cogl/cogl-color.h b/cogl/cogl/cogl-color.h deleted file mode 100644 index 0defb733c..000000000 --- a/cogl/cogl/cogl-color.h +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_COLOR_H__ -#define __COGL_COLOR_H__ - -/** - * SECTION:cogl-color - * @short_description: A generic color definition - * - * #CoglColor is a simple structure holding the definition of a color such - * that it can be efficiently used by GL - * - * Since: 1.0 - */ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-macros.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * cogl_color_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_color_get_gtype (void); - -/** - * cogl_color_new: - * - * Creates a new (empty) color - * - * Return value: a newly-allocated #CoglColor. Use cogl_color_free() - * to free the allocated resources - * - * Since: 1.0 - */ -COGL_EXPORT CoglColor * -cogl_color_new (void); - -/** - * cogl_color_copy: - * @color: the color to copy - * - * Creates a copy of @color - * - * Return value: a newly-allocated #CoglColor. Use cogl_color_free() - * to free the allocate resources - * - * Since: 1.0 - */ -COGL_EXPORT CoglColor * -cogl_color_copy (const CoglColor *color); - -/** - * cogl_color_free: - * @color: the color to free - * - * Frees the resources allocated by cogl_color_new() and cogl_color_copy() - * - * Since: 1.0 - */ -COGL_EXPORT void -cogl_color_free (CoglColor *color); - -/** - * cogl_color_init_from_4ub: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and 255 - * @green: value of the green channel, between 0 and 255 - * @blue: value of the blue channel, between 0 and 255 - * @alpha: value of the alpha channel, between 0 and 255 - * - * Sets the values of the passed channels into a #CoglColor. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_init_from_4ub (CoglColor *color, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha); - -/** - * cogl_color_init_from_4f: - * @color: A pointer to a #CoglColor to initialize - * @red: value of the red channel, between 0 and 1.0 - * @green: value of the green channel, between 0 and 1.0 - * @blue: value of the blue channel, between 0 and 1.0 - * @alpha: value of the alpha channel, between 0 and 1.0 - * - * Sets the values of the passed channels into a #CoglColor - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_init_from_4f (CoglColor *color, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_color_init_from_4fv: - * @color: A pointer to a #CoglColor to initialize - * @color_array: a pointer to an array of 4 float color components - * - * Sets the values of the passed channels into a #CoglColor - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_init_from_4fv (CoglColor *color, - const float *color_array); - -/** - * cogl_color_get_red_byte: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a byte value - * between 0 and 255 - * - * Return value: the red channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT unsigned char -cogl_color_get_red_byte (const CoglColor *color); - -/** - * cogl_color_get_green_byte: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a byte value - * between 0 and 255 - * - * Return value: the green channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT unsigned char -cogl_color_get_green_byte (const CoglColor *color); - -/** - * cogl_color_get_blue_byte: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a byte value - * between 0 and 255 - * - * Return value: the blue channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT unsigned char -cogl_color_get_blue_byte (const CoglColor *color); - -/** - * cogl_color_get_alpha_byte: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a byte value - * between 0 and 255 - * - * Return value: the alpha channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT unsigned char -cogl_color_get_alpha_byte (const CoglColor *color); - -/** - * cogl_color_get_red_float: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the red channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_red_float (const CoglColor *color); - -/** - * cogl_color_get_green_float: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the green channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_green_float (const CoglColor *color); - -/** - * cogl_color_get_blue_float: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the blue channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_blue_float (const CoglColor *color); - -/** - * cogl_color_get_alpha_float: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a floating point - * value between 0.0 and 1.0 - * - * Return value: the alpha channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_alpha_float (const CoglColor *color); - -/** - * cogl_color_get_red: - * @color: a #CoglColor - * - * Retrieves the red channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the red channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_red (const CoglColor *color); - -/** - * cogl_color_get_green: - * @color: a #CoglColor - * - * Retrieves the green channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the green channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_green (const CoglColor *color); - -/** - * cogl_color_get_blue: - * @color: a #CoglColor - * - * Retrieves the blue channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the blue channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_blue (const CoglColor *color); - -/** - * cogl_color_get_alpha: - * @color: a #CoglColor - * - * Retrieves the alpha channel of @color as a fixed point - * value between 0 and 1.0. - * - * Return value: the alpha channel of the passed color - * - * Since: 1.0 - */ -COGL_EXPORT float -cogl_color_get_alpha (const CoglColor *color); - -/** - * cogl_color_set_red_byte: - * @color: a #CoglColor - * @red: a byte value between 0 and 255 - * - * Sets the red channel of @color to @red. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_red_byte (CoglColor *color, - unsigned char red); - -/** - * cogl_color_set_green_byte: - * @color: a #CoglColor - * @green: a byte value between 0 and 255 - * - * Sets the green channel of @color to @green. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_green_byte (CoglColor *color, - unsigned char green); - -/** - * cogl_color_set_blue_byte: - * @color: a #CoglColor - * @blue: a byte value between 0 and 255 - * - * Sets the blue channel of @color to @blue. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_blue_byte (CoglColor *color, - unsigned char blue); - -/** - * cogl_color_set_alpha_byte: - * @color: a #CoglColor - * @alpha: a byte value between 0 and 255 - * - * Sets the alpha channel of @color to @alpha. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_alpha_byte (CoglColor *color, - unsigned char alpha); - -/** - * cogl_color_set_red_float: - * @color: a #CoglColor - * @red: a float value between 0.0f and 1.0f - * - * Sets the red channel of @color to @red. - * - * since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_red_float (CoglColor *color, - float red); - -/** - * cogl_color_set_green_float: - * @color: a #CoglColor - * @green: a float value between 0.0f and 1.0f - * - * Sets the green channel of @color to @green. - * - * since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_green_float (CoglColor *color, - float green); - -/** - * cogl_color_set_blue_float: - * @color: a #CoglColor - * @blue: a float value between 0.0f and 1.0f - * - * Sets the blue channel of @color to @blue. - * - * since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_blue_float (CoglColor *color, - float blue); - -/** - * cogl_color_set_alpha_float: - * @color: a #CoglColor - * @alpha: a float value between 0.0f and 1.0f - * - * Sets the alpha channel of @color to @alpha. - * - * since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_alpha_float (CoglColor *color, - float alpha); - -/** - * cogl_color_set_red: - * @color: a #CoglColor - * @red: a float value between 0.0f and 1.0f - * - * Sets the red channel of @color to @red. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_red (CoglColor *color, - float red); - -/** - * cogl_color_set_green: - * @color: a #CoglColor - * @green: a float value between 0.0f and 1.0f - * - * Sets the green channel of @color to @green. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_green (CoglColor *color, - float green); - -/** - * cogl_color_set_blue: - * @color: a #CoglColor - * @blue: a float value between 0.0f and 1.0f - * - * Sets the blue channel of @color to @blue. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_blue (CoglColor *color, - float blue); - -/** - * cogl_color_set_alpha: - * @color: a #CoglColor - * @alpha: a float value between 0.0f and 1.0f - * - * Sets the alpha channel of @color to @alpha. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_set_alpha (CoglColor *color, - float alpha); - -/** - * cogl_color_premultiply: - * @color: the color to premultiply - * - * Converts a non-premultiplied color to a pre-multiplied color. For - * example, semi-transparent red is (1.0, 0, 0, 0.5) when non-premultiplied - * and (0.5, 0, 0, 0.5) when premultiplied. - * - * Since: 1.0 - */ -COGL_EXPORT void -cogl_color_premultiply (CoglColor *color); - -/** - * cogl_color_unpremultiply: - * @color: the color to unpremultiply - * - * Converts a pre-multiplied color to a non-premultiplied color. For - * example, semi-transparent red is (0.5, 0, 0, 0.5) when premultiplied - * and (1.0, 0, 0, 0.5) when non-premultiplied. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_color_unpremultiply (CoglColor *color); - -/** - * cogl_color_equal: - * @v1: a #CoglColor - * @v2: a #CoglColor - * - * Compares two #CoglColor<!-- -->s and checks if they are the same. - * - * This function can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using #CoglColor<!-- -->s as keys in a #GHashTable. - * - * Return value: %TRUE if the two colors are the same. - * - * Since: 1.0 - */ -COGL_EXPORT gboolean -cogl_color_equal (const void *v1, const void *v2); - -/** - * cogl_color_to_hsl: - * @color: a #CoglColor - * @hue: (out): return location for the hue value or %NULL - * @saturation: (out): return location for the saturation value or %NULL - * @luminance: (out): return location for the luminance value or %NULL - * - * Converts @color to the HLS format. - * - * The @hue value is in the 0 .. 360 range. The @luminance and - * @saturation values are in the 0 .. 1 range. - * - * Since: 1.16 - */ -COGL_EXPORT void -cogl_color_to_hsl (const CoglColor *color, - float *hue, - float *saturation, - float *luminance); - -/** - * cogl_color_init_from_hsl: - * @color: (out): return location for a #CoglColor - * @hue: hue value, in the 0 .. 360 range - * @saturation: saturation value, in the 0 .. 1 range - * @luminance: luminance value, in the 0 .. 1 range - * - * Converts a color expressed in HLS (hue, luminance and saturation) - * values into a #CoglColor. - * - * Since: 1.16 - */ -COGL_EXPORT void -cogl_color_init_from_hsl (CoglColor *color, - float hue, - float saturation, - float luminance); - -G_END_DECLS - -#endif /* __COGL_COLOR_H__ */ diff --git a/cogl/cogl/cogl-context-private.h b/cogl/cogl/cogl-context-private.h deleted file mode 100644 index 5856f76e9..000000000 --- a/cogl/cogl/cogl-context-private.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_CONTEXT_PRIVATE_H -#define __COGL_CONTEXT_PRIVATE_H - -#include "cogl-context.h" -#include "cogl-flags.h" - -#include "cogl-display-private.h" -#include "cogl-clip-stack.h" -#include "cogl-matrix-stack.h" -#include "cogl-pipeline-private.h" -#include "cogl-buffer-private.h" -#include "cogl-bitmask.h" -#include "cogl-atlas.h" -#include "cogl-driver.h" -#include "cogl-texture-driver.h" -#include "cogl-pipeline-cache.h" -#include "cogl-texture-2d.h" -#include "cogl-sampler-cache-private.h" -#include "cogl-gl-header.h" -#include "cogl-framebuffer-private.h" -#include "cogl-offscreen-private.h" -#include "cogl-onscreen-private.h" -#include "cogl-fence-private.h" -#include "cogl-poll-private.h" -#include "cogl-private.h" -#include "winsys/cogl-winsys-private.h" - -typedef struct -{ - GLfloat v[3]; - GLfloat t[2]; - GLubyte c[4]; -} CoglTextureGLVertex; - -struct _CoglTimestampQuery -{ - unsigned int id; -}; - -struct _CoglContext -{ - CoglObject _parent; - - CoglDisplay *display; - - CoglDriver driver; - - /* vtables for the driver functions */ - const CoglDriverVtable *driver_vtable; - const CoglTextureDriver *texture_driver; - - void *driver_context; - - int glsl_major; - int glsl_minor; - - /* This is the GLSL version that we will claim that snippets are - * written against using the #version pragma. This will be the - * largest version that is less than or equal to the version - * provided by the driver without massively altering the syntax. Eg, - * we wouldn't use version 1.3 even if it is available because that - * removes the ‘attribute’ and ‘varying’ keywords. */ - int glsl_version_to_use; - - /* Features cache */ - unsigned long features[COGL_FLAGS_N_LONGS_FOR_SIZE (_COGL_N_FEATURE_IDS)]; - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)]; - - CoglPipeline *default_pipeline; - CoglPipelineLayer *default_layer_0; - CoglPipelineLayer *default_layer_n; - CoglPipelineLayer *dummy_layer_dependant; - - GHashTable *attribute_name_states_hash; - GArray *attribute_name_index_map; - int n_attribute_names; - - CoglBitmask enabled_custom_attributes; - - /* These are temporary bitmasks that are used when disabling - * builtin and custom attribute arrays. They are here just - * to avoid allocating new ones each time */ - CoglBitmask enable_custom_attributes_tmp; - CoglBitmask changed_bits_tmp; - - gboolean legacy_backface_culling_enabled; - - /* A few handy matrix constants */ - graphene_matrix_t identity_matrix; - graphene_matrix_t y_flip_matrix; - - /* The matrix stack entries that should be flushed during the next - * pipeline state flush */ - CoglMatrixEntry *current_projection_entry; - CoglMatrixEntry *current_modelview_entry; - - CoglMatrixEntry identity_entry; - - /* Only used for comparing other pipelines when reading pixels. */ - CoglPipeline *opaque_color_pipeline; - - GString *codegen_header_buffer; - GString *codegen_source_buffer; - GString *codegen_boilerplate_buffer; - - CoglPipelineCache *pipeline_cache; - - /* Textures */ - CoglTexture2D *default_gl_texture_2d_tex; - - /* Central list of all framebuffers so all journals can be flushed - * at any time. */ - GList *framebuffers; - - /* Global journal buffers */ - GArray *journal_flush_attributes_array; - GArray *journal_clip_bounds; - - /* Some simple caching, to minimize state changes... */ - CoglPipeline *current_pipeline; - unsigned long current_pipeline_changes_since_flush; - gboolean current_pipeline_with_color_attrib; - gboolean current_pipeline_unknown_color_alpha; - unsigned long current_pipeline_age; - - gboolean gl_blend_enable_cache; - - gboolean depth_test_enabled_cache; - CoglDepthTestFunction depth_test_function_cache; - gboolean depth_writing_enabled_cache; - float depth_range_near_cache; - float depth_range_far_cache; - - gboolean legacy_depth_test_enabled; - - CoglBuffer *current_buffer[COGL_BUFFER_BIND_TARGET_COUNT]; - - /* Framebuffers */ - unsigned long current_draw_buffer_state_flushed; - unsigned long current_draw_buffer_changes; - CoglFramebuffer *current_draw_buffer; - CoglFramebuffer *current_read_buffer; - - gboolean have_last_offscreen_allocate_flags; - CoglOffscreenAllocateFlags last_offscreen_allocate_flags; - - GHashTable *swap_callback_closures; - int next_swap_callback_id; - - CoglList onscreen_events_queue; - CoglList onscreen_dirty_queue; - CoglClosure *onscreen_dispatch_idle; - - /* This becomes TRUE the first time the context is bound to an - * onscreen buffer. This is used by cogl-framebuffer-gl to determine - * when to initialise the glDrawBuffer state */ - gboolean was_bound_to_onscreen; - - /* Primitives */ - CoglPipeline *stencil_pipeline; - - CoglIndices *rectangle_byte_indices; - CoglIndices *rectangle_short_indices; - int rectangle_short_indices_len; - - CoglPipeline *blit_texture_pipeline; - - GSList *atlases; - GHookList atlas_reorganize_callbacks; - - /* This debugging variable is used to pick a colour for visually - displaying the quad batches. It needs to be global so that it can - be reset by cogl_clear. It needs to be reset to increase the - chances of getting the same colour during an animation */ - uint8_t journal_rectangles_color; - - /* Cached values for GL_MAX_TEXTURE_[IMAGE_]UNITS to avoid calling - glGetInteger too often */ - GLint max_texture_units; - GLint max_texture_image_units; - GLint max_activateable_texture_units; - - /* Fragment processing programs */ - GLuint current_gl_program; - - gboolean current_gl_dither_enabled; - GLenum current_gl_draw_buffer; - - /* Clipping */ - /* TRUE if we have a valid clipping stack flushed. In that case - current_clip_stack will describe what the current state is. If - this is FALSE then the current clip stack is completely unknown - so it will need to be reflushed. In that case current_clip_stack - doesn't need to be a valid pointer. We can't just use NULL in - current_clip_stack to mark a dirty state because NULL is a valid - stack (meaning no clipping) */ - gboolean current_clip_stack_valid; - /* The clip state that was flushed. This isn't intended to be used - as a stack to push and pop new entries. Instead the current stack - that the user wants is part of the framebuffer state. This is - just used to record the flush state so we can avoid flushing the - same state multiple times. When the clip state is flushed this - will hold a reference */ - CoglClipStack *current_clip_stack; - - /* This is used as a temporary buffer to fill a CoglBuffer when - cogl_buffer_map fails and we only want to map to fill it with new - data */ - GByteArray *buffer_map_fallback_array; - gboolean buffer_map_fallback_in_use; - size_t buffer_map_fallback_offset; - - CoglSamplerCache *sampler_cache; - - unsigned long winsys_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - void *winsys; - - /* Array of names of uniforms. These are used like quarks to give a - unique number to each uniform name except that we ensure that - they increase sequentially so that we can use the id as an index - into a bitfield representing the uniforms that a pipeline - overrides from its parent. */ - GPtrArray *uniform_names; - /* A hash table to quickly get an index given an existing name. The - name strings are owned by the uniform_names array. The values are - the uniform location cast to a pointer. */ - GHashTable *uniform_name_hash; - int n_uniform_names; - - CoglPollSource *fences_poll_source; - CoglList fences; - - GHashTable *named_pipelines; - - /* This defines a list of function pointers that Cogl uses from - either GL or GLES. All functions are accessed indirectly through - these pointers rather than linking to them directly */ -#ifndef APIENTRY -#define APIENTRY -#endif - -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - extension_suffixes, extension_names) -#define COGL_EXT_FUNCTION(ret, name, args) \ - ret (APIENTRY * name) args; -#define COGL_EXT_END() - -#include "gl-prototypes/cogl-all-functions.h" - -#undef COGL_EXT_BEGIN -#undef COGL_EXT_FUNCTION -#undef COGL_EXT_END -}; - -COGL_EXPORT CoglContext * -_cogl_context_get_default (void); - -const CoglWinsysVtable * -_cogl_context_get_winsys (CoglContext *context); - -/* Query the GL extensions and lookup the corresponding function - * pointers. Theoretically the list of extensions can change for - * different GL contexts so it is the winsys backend's responsibility - * to know when to re-query the GL extensions. The backend should also - * check whether the GL context is supported by Cogl. If not it should - * return FALSE and set @error */ -gboolean -_cogl_context_update_features (CoglContext *context, - GError **error); - -/* Obtains the context and returns retval if NULL */ -#define _COGL_GET_CONTEXT(ctxvar, retval) \ -CoglContext *ctxvar = _cogl_context_get_default (); \ -if (ctxvar == NULL) return retval; - -#define NO_RETVAL - -void -_cogl_context_set_current_projection_entry (CoglContext *context, - CoglMatrixEntry *entry); - -void -_cogl_context_set_current_modelview_entry (CoglContext *context, - CoglMatrixEntry *entry); - -#endif /* __COGL_CONTEXT_PRIVATE_H */ diff --git a/cogl/cogl/cogl-context.c b/cogl/cogl/cogl-context.c deleted file mode 100644 index 89019e908..000000000 --- a/cogl/cogl/cogl-context.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-mutter.h" -#include "cogl-object.h" -#include "cogl-private.h" -#include "cogl-profile.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-journal-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-private.h" -#include "cogl-attribute-private.h" -#include "cogl1-context.h" -#include "cogl-gtype-private.h" -#include "winsys/cogl-winsys-private.h" - -#include <string.h> -#include <stdlib.h> - -static void _cogl_context_free (CoglContext *context); - -COGL_OBJECT_DEFINE (Context, context); -COGL_GTYPE_DEFINE_CLASS (Context, context); - -extern void -_cogl_create_context_driver (CoglContext *context); - -static CoglContext *_cogl_context = NULL; - -static void -_cogl_init_feature_overrides (CoglContext *ctx) -{ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_PBOS))) - COGL_FLAGS_SET (ctx->private_features, COGL_PRIVATE_FEATURE_PBOS, FALSE); -} - -const CoglWinsysVtable * -_cogl_context_get_winsys (CoglContext *context) -{ - return context->display->renderer->winsys_vtable; -} - -static const CoglDriverVtable * -_cogl_context_get_driver (CoglContext *context) -{ - return context->driver_vtable; -} - -/* For reference: There was some deliberation over whether to have a - * constructor that could throw an exception but looking at standard - * practices with several high level OO languages including python, C++, - * C# Java and Ruby they all support exceptions in constructors and the - * general consensus appears to be that throwing an exception is neater - * than successfully constructing with an internal error status that - * would then have to be explicitly checked via some form of ::is_ok() - * method. - */ -CoglContext * -cogl_context_new (CoglDisplay *display, - GError **error) -{ - CoglContext *context; - uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff }; - const CoglWinsysVtable *winsys; - int i; - - _cogl_init (); - -#ifdef COGL_ENABLE_PROFILE - /* We need to be absolutely sure that uprof has been initialized - * before calling _cogl_uprof_init. uprof_init (NULL, NULL) - * will be a NOP if it has been initialized but it will also - * mean subsequent parsing of the UProf GOptionGroup will have no - * affect. - * - * Sadly GOptionGroup based library initialization is extremely - * fragile by design because GOptionGroups have no notion of - * dependencies and so the order things are initialized isn't - * currently under tight control. - */ - uprof_init (NULL, NULL); - _cogl_uprof_init (); -#endif - - /* Allocate context memory */ - context = g_malloc0 (sizeof (CoglContext)); - - /* Convert the context into an object immediately in case any of the - code below wants to verify that the context pointer is a valid - object */ - _cogl_context_object_new (context); - - /* XXX: Gross hack! - * Currently everything in Cogl just assumes there is a default - * context which it can access via _COGL_GET_CONTEXT() including - * code used to construct a CoglContext. Until all of that code - * has been updated to take an explicit context argument we have - * to immediately make our pointer the default context. - */ - _cogl_context = context; - - /* Init default values */ - memset (context->features, 0, sizeof (context->features)); - memset (context->private_features, 0, sizeof (context->private_features)); - memset (context->winsys_features, 0, sizeof (context->winsys_features)); - - if (!display) - { - CoglRenderer *renderer = cogl_renderer_new (); - if (!cogl_renderer_connect (renderer, error)) - { - g_free (context); - return NULL; - } - - display = cogl_display_new (renderer, NULL); - cogl_object_unref(renderer); - } - else - cogl_object_ref (display); - - if (!cogl_display_setup (display, error)) - { - cogl_object_unref (display); - g_free (context); - return NULL; - } - - context->display = display; - - /* This is duplicated data, but it's much more convenient to have - the driver attached to the context and the value is accessed a - lot throughout Cogl */ - context->driver = display->renderer->driver; - - /* Again this is duplicated data, but it convenient to be able - * access these from the context. */ - context->driver_vtable = display->renderer->driver_vtable; - context->texture_driver = display->renderer->texture_driver; - - for (i = 0; i < G_N_ELEMENTS (context->private_features); i++) - context->private_features[i] |= display->renderer->private_features[i]; - - winsys = _cogl_context_get_winsys (context); - if (!winsys->context_init (context, error)) - { - cogl_object_unref (display); - g_free (context); - return NULL; - } - - if (!context->driver_vtable->context_init (context)) - { - cogl_object_unref (display); - g_free (context); - return NULL; - } - - context->attribute_name_states_hash = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - context->attribute_name_index_map = NULL; - context->n_attribute_names = 0; - - /* The "cogl_color_in" attribute needs a deterministic name_index - * so we make sure it's the first attribute name we register */ - _cogl_attribute_register_attribute_name (context, "cogl_color_in"); - - - context->uniform_names = - g_ptr_array_new_with_free_func ((GDestroyNotify) g_free); - context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal); - context->n_uniform_names = 0; - - /* Initialise the driver specific state */ - _cogl_init_feature_overrides (context); - - context->sampler_cache = _cogl_sampler_cache_new (context); - - _cogl_pipeline_init_default_pipeline (); - _cogl_pipeline_init_default_layers (); - _cogl_pipeline_init_state_hash_functions (); - _cogl_pipeline_init_layer_state_hash_functions (); - - context->current_clip_stack_valid = FALSE; - context->current_clip_stack = NULL; - - context->legacy_backface_culling_enabled = FALSE; - - graphene_matrix_init_identity (&context->identity_matrix); - graphene_matrix_init_identity (&context->y_flip_matrix); - graphene_matrix_scale (&context->y_flip_matrix, 1, -1, 1); - - context->opaque_color_pipeline = cogl_pipeline_new (context); - - context->codegen_header_buffer = g_string_new (""); - context->codegen_source_buffer = g_string_new (""); - context->codegen_boilerplate_buffer = g_string_new (""); - - context->default_gl_texture_2d_tex = NULL; - - context->framebuffers = NULL; - context->current_draw_buffer = NULL; - context->current_read_buffer = NULL; - context->current_draw_buffer_state_flushed = 0; - context->current_draw_buffer_changes = COGL_FRAMEBUFFER_STATE_ALL; - - context->swap_callback_closures = - g_hash_table_new (g_direct_hash, g_direct_equal); - - _cogl_list_init (&context->onscreen_events_queue); - _cogl_list_init (&context->onscreen_dirty_queue); - - context->journal_flush_attributes_array = - g_array_new (TRUE, FALSE, sizeof (CoglAttribute *)); - context->journal_clip_bounds = NULL; - - context->current_pipeline = NULL; - context->current_pipeline_changes_since_flush = 0; - context->current_pipeline_with_color_attrib = FALSE; - - _cogl_bitmask_init (&context->enabled_custom_attributes); - _cogl_bitmask_init (&context->enable_custom_attributes_tmp); - _cogl_bitmask_init (&context->changed_bits_tmp); - - context->max_texture_units = -1; - context->max_activateable_texture_units = -1; - - context->current_gl_program = 0; - - context->current_gl_dither_enabled = TRUE; - - context->gl_blend_enable_cache = FALSE; - - context->depth_test_enabled_cache = FALSE; - context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS; - context->depth_writing_enabled_cache = TRUE; - context->depth_range_near_cache = 0; - context->depth_range_far_cache = 1; - - context->legacy_depth_test_enabled = FALSE; - - context->pipeline_cache = _cogl_pipeline_cache_new (); - - for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++) - context->current_buffer[i] = NULL; - - context->stencil_pipeline = cogl_pipeline_new (context); - - context->rectangle_byte_indices = NULL; - context->rectangle_short_indices = NULL; - context->rectangle_short_indices_len = 0; - - context->blit_texture_pipeline = NULL; - - context->current_modelview_entry = NULL; - context->current_projection_entry = NULL; - _cogl_matrix_entry_identity_init (&context->identity_entry); - - /* Create default textures used for fall backs */ - context->default_gl_texture_2d_tex = - cogl_texture_2d_new_from_data (context, - 1, 1, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - 0, /* rowstride */ - white_pixel, - NULL); /* abort on error */ - - context->atlases = NULL; - g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook)); - - context->buffer_map_fallback_array = g_byte_array_new (); - context->buffer_map_fallback_in_use = FALSE; - - _cogl_list_init (&context->fences); - - context->named_pipelines = - g_hash_table_new_full (NULL, NULL, NULL, cogl_object_unref); - - return context; -} - -static void -_cogl_context_free (CoglContext *context) -{ - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - const CoglDriverVtable *driver = _cogl_context_get_driver (context); - - winsys->context_deinit (context); - - if (context->default_gl_texture_2d_tex) - cogl_object_unref (context->default_gl_texture_2d_tex); - - if (context->opaque_color_pipeline) - cogl_object_unref (context->opaque_color_pipeline); - - if (context->blit_texture_pipeline) - cogl_object_unref (context->blit_texture_pipeline); - - if (context->swap_callback_closures) - g_hash_table_destroy (context->swap_callback_closures); - - if (context->journal_flush_attributes_array) - g_array_free (context->journal_flush_attributes_array, TRUE); - if (context->journal_clip_bounds) - g_array_free (context->journal_clip_bounds, TRUE); - - if (context->rectangle_byte_indices) - cogl_object_unref (context->rectangle_byte_indices); - if (context->rectangle_short_indices) - cogl_object_unref (context->rectangle_short_indices); - - if (context->default_pipeline) - cogl_object_unref (context->default_pipeline); - - if (context->dummy_layer_dependant) - cogl_object_unref (context->dummy_layer_dependant); - if (context->default_layer_n) - cogl_object_unref (context->default_layer_n); - if (context->default_layer_0) - cogl_object_unref (context->default_layer_0); - - if (context->current_clip_stack_valid) - _cogl_clip_stack_unref (context->current_clip_stack); - - g_slist_free (context->atlases); - g_hook_list_clear (&context->atlas_reorganize_callbacks); - - _cogl_bitmask_destroy (&context->enabled_custom_attributes); - _cogl_bitmask_destroy (&context->enable_custom_attributes_tmp); - _cogl_bitmask_destroy (&context->changed_bits_tmp); - - if (context->current_modelview_entry) - cogl_matrix_entry_unref (context->current_modelview_entry); - if (context->current_projection_entry) - cogl_matrix_entry_unref (context->current_projection_entry); - - _cogl_pipeline_cache_free (context->pipeline_cache); - - _cogl_sampler_cache_free (context->sampler_cache); - - g_ptr_array_free (context->uniform_names, TRUE); - g_hash_table_destroy (context->uniform_name_hash); - - g_hash_table_destroy (context->attribute_name_states_hash); - g_array_free (context->attribute_name_index_map, TRUE); - - g_byte_array_free (context->buffer_map_fallback_array, TRUE); - - driver->context_deinit (context); - - cogl_object_unref (context->display); - - g_hash_table_remove_all (context->named_pipelines); - g_hash_table_destroy (context->named_pipelines); - - g_free (context); -} - -CoglContext * -_cogl_context_get_default (void) -{ - GError *error = NULL; - /* Create if doesn't exist yet */ - if (_cogl_context == NULL) - { - _cogl_context = cogl_context_new (NULL, &error); - if (!_cogl_context) - { - g_warning ("Failed to create default context: %s", - error->message); - g_error_free (error); - } - } - - return _cogl_context; -} - -CoglDisplay * -cogl_context_get_display (CoglContext *context) -{ - return context->display; -} - -CoglRenderer * -cogl_context_get_renderer (CoglContext *context) -{ - return context->display->renderer; -} - -gboolean -_cogl_context_update_features (CoglContext *context, - GError **error) -{ - return context->driver_vtable->update_features (context, error); -} - -void -_cogl_context_set_current_projection_entry (CoglContext *context, - CoglMatrixEntry *entry) -{ - cogl_matrix_entry_ref (entry); - if (context->current_projection_entry) - cogl_matrix_entry_unref (context->current_projection_entry); - context->current_projection_entry = entry; -} - -void -_cogl_context_set_current_modelview_entry (CoglContext *context, - CoglMatrixEntry *entry) -{ - cogl_matrix_entry_ref (entry); - if (context->current_modelview_entry) - cogl_matrix_entry_unref (context->current_modelview_entry); - context->current_modelview_entry = entry; -} - -CoglGraphicsResetStatus -cogl_get_graphics_reset_status (CoglContext *context) -{ - return context->driver_vtable->get_graphics_reset_status (context); -} - -gboolean -cogl_context_is_hardware_accelerated (CoglContext *context) -{ - return context->driver_vtable->is_hardware_accelerated (context); -} - -gboolean -cogl_context_format_supports_upload (CoglContext *ctx, - CoglPixelFormat format) -{ - return ctx->texture_driver->format_supports_upload (ctx, format); -} - -void -cogl_context_set_named_pipeline (CoglContext *context, - CoglPipelineKey *key, - CoglPipeline *pipeline) -{ - if (pipeline) - { - g_debug ("Adding named pipeline %s", *key); - g_hash_table_insert (context->named_pipelines, (gpointer) key, pipeline); - } - else - { - g_debug ("Removing named pipeline %s", *key); - g_hash_table_remove (context->named_pipelines, (gpointer) key); - } -} - -CoglPipeline * -cogl_context_get_named_pipeline (CoglContext *context, - CoglPipelineKey *key) -{ - return g_hash_table_lookup (context->named_pipelines, key); -} - -void -cogl_context_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query) -{ - context->driver_vtable->free_timestamp_query (context, query); -} - -int64_t -cogl_context_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query) -{ - return context->driver_vtable->timestamp_query_get_time_ns (context, query); -} - -int64_t -cogl_context_get_gpu_time_ns (CoglContext *context) -{ - g_return_val_if_fail (cogl_has_feature (context, - COGL_FEATURE_ID_GET_GPU_TIME), - 0); - - return context->driver_vtable->get_gpu_time_ns (context); -} diff --git a/cogl/cogl/cogl-context.h b/cogl/cogl/cogl-context.h deleted file mode 100644 index 38ac11be8..000000000 --- a/cogl/cogl/cogl-context.h +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_CONTEXT_H__ -#define __COGL_CONTEXT_H__ - -/* We forward declare the CoglContext type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglContext CoglContext; -typedef struct _CoglTimestampQuery CoglTimestampQuery; - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-display.h> -#include <cogl/cogl-pipeline.h> -#include <cogl/cogl-primitive.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-context - * @short_description: The top level application context. - * - * A #CoglContext is the top most sandbox of Cogl state for an - * application or toolkit. Its main purpose is to act as a sandbox - * for the memory management of state objects. Normally an application - * will only create a single context since there is no way to share - * resources between contexts. - * - * For those familiar with OpenGL or perhaps Cairo it should be - * understood that unlike these APIs a Cogl context isn't a rendering - * context as such. In other words Cogl doesn't aim to provide a state - * machine style model for configuring rendering parameters. Most - * rendering state in Cogl is directly associated with user managed - * objects called pipelines and geometry is drawn with a specific - * pipeline object to a framebuffer object and those 3 things fully - * define the state for drawing. This is an important part of Cogl's - * design since it helps you write orthogonal rendering components - * that can all access the same GPU without having to worry about - * what state other components have left you with. - * - * <note><para>Cogl does not maintain internal references to the context for - * resources that depend on the context so applications. This is to - * help applications control the lifetime a context without us needing to - * introduce special api to handle the breakup of internal circular - * references due to internal resources and caches associated with the - * context. - * - * One a context has been destroyed then all directly or indirectly - * dependent resources will be in an inconsistent state and should not - * be manipulated or queried in any way. - * - * For applications that rely on the operating system to clean up - * resources this policy shouldn't affect them, but for applications - * that need to carefully destroy and re-create Cogl contexts multiple - * times throughout their lifetime (such as Android applications) they - * should be careful to destroy all context dependent resources, such as - * framebuffers or textures etc before unrefing and destroying the - * context.</para></note> - */ - -#define COGL_CONTEXT(OBJECT) ((CoglContext *)OBJECT) - -/** - * cogl_context_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_context_get_gtype (void); - -/** - * cogl_context_new: (constructor) (skip) - * @display: (allow-none): A #CoglDisplay pointer - * @error: A GError return location. - * - * Creates a new #CoglContext which acts as an application sandbox - * for any state objects that are allocated. - * - * Return value: (transfer full): A newly allocated #CoglContext - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT CoglContext * -cogl_context_new (CoglDisplay *display, - GError **error); - -/** - * cogl_context_get_display: (skip) - * @context: A #CoglContext pointer - * - * Retrieves the #CoglDisplay that is internally associated with the - * given @context. This will return the same #CoglDisplay that was - * passed to cogl_context_new() or if %NULL was passed to - * cogl_context_new() then this function returns a pointer to the - * display that was automatically setup internally. - * - * Return value: (transfer none): The #CoglDisplay associated with the - * given @context. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT CoglDisplay * -cogl_context_get_display (CoglContext *context); - -/** - * cogl_context_get_renderer: (skip) - * @context: A #CoglContext pointer - * - * Retrieves the #CoglRenderer that is internally associated with the - * given @context. This will return the same #CoglRenderer that was - * passed to cogl_display_new() or if %NULL was passed to - * cogl_display_new() or cogl_context_new() then this function returns - * a pointer to the renderer that was automatically connected - * internally. - * - * Return value: (transfer none): The #CoglRenderer associated with the - * given @context. - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT CoglRenderer * -cogl_context_get_renderer (CoglContext *context); - -/** - * cogl_is_context: - * @object: An object or %NULL - * - * Gets whether the given object references an existing context object. - * - * Return value: %TRUE if the @object references a #CoglContext, - * %FALSE otherwise - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_context (void *object); - -/* XXX: not guarded by the EXPERIMENTAL_API defines to avoid - * upsetting glib-mkenums, but this can still be considered implicitly - * experimental since it's only useable with experimental API... */ -/** - * CoglFeatureID: - * @COGL_FEATURE_ID_TEXTURE_RG: Support for - * %COGL_TEXTURE_COMPONENTS_RG as the internal components of a - * texture. - * @COGL_FEATURE_ID_UNSIGNED_INT_INDICES: Set if - * %COGL_INDICES_TYPE_UNSIGNED_INT is supported in - * cogl_indices_new(). - * @COGL_FEATURE_ID_MAP_BUFFER_FOR_READ: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including read support. - * @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is - * supported with CoglBufferAccess including write support. - * @COGL_FEATURE_ID_BUFFER_AGE: Available if the age of #CoglOnscreen back - * buffers are tracked and so cogl_onscreen_get_buffer_age() can be - * expected to return age values other than 0. - * @COGL_FEATURE_ID_BLIT_FRAMEBUFFER: Whether blitting using - * cogl_blit_framebuffer() is supported. - * - * All the capabilities that can vary between different GPUs supported - * by Cogl. Applications that depend on any of these features should explicitly - * check for them using cogl_has_feature() or cogl_has_features(). - * - * Since: 1.10 - */ -typedef enum _CoglFeatureID -{ - COGL_FEATURE_ID_UNSIGNED_INT_INDICES, - COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, - COGL_FEATURE_ID_FENCE, - COGL_FEATURE_ID_TEXTURE_RG, - COGL_FEATURE_ID_BUFFER_AGE, - COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL, - COGL_FEATURE_ID_BLIT_FRAMEBUFFER, - COGL_FEATURE_ID_TIMESTAMP_QUERY, - COGL_FEATURE_ID_GET_GPU_TIME, - - /*< private >*/ - _COGL_N_FEATURE_IDS /*< skip >*/ -} CoglFeatureID; - - -/** - * cogl_has_feature: - * @context: A #CoglContext pointer - * @feature: A #CoglFeatureID - * - * Checks if a given @feature is currently available - * - * Cogl does not aim to be a lowest common denominator API, it aims to - * expose all the interesting features of GPUs to application which - * means applications have some responsibility to explicitly check - * that certain features are available before depending on them. - * - * Returns: %TRUE if the @feature is currently supported or %FALSE if - * not. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_has_feature (CoglContext *context, CoglFeatureID feature); - -/** - * cogl_has_features: - * @context: A #CoglContext pointer - * @...: A 0 terminated list of CoglFeatureID<!-- -->s - * - * Checks if a list of features are all currently available. - * - * This checks all of the listed features using cogl_has_feature() and - * returns %TRUE if all the features are available or %FALSE - * otherwise. - * - * Return value: %TRUE if all the features are available, %FALSE - * otherwise. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_has_features (CoglContext *context, ...); - -/** - * CoglFeatureCallback: - * @feature: A single feature currently supported by Cogl - * @user_data: A private pointer passed to cogl_foreach_feature(). - * - * A callback used with cogl_foreach_feature() for enumerating all - * context level features supported by Cogl. - * - * Since: 0.10 - * Stability: unstable - */ -typedef void (*CoglFeatureCallback) (CoglFeatureID feature, void *user_data); - -/** - * cogl_foreach_feature: - * @context: A #CoglContext pointer - * @callback: (scope call): A #CoglFeatureCallback called for each - * supported feature - * @user_data: (closure): Private data to pass to the callback - * - * Iterates through all the context level features currently supported - * for a given @context and for each feature @callback is called. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_foreach_feature (CoglContext *context, - CoglFeatureCallback callback, - void *user_data); - -/** - * CoglGraphicsResetStatus: - * @COGL_GRAPHICS_RESET_STATUS_NO_ERROR: - * @COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET: - * @COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET: - * @COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET: - * @COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET: - * - * All the error values that might be returned by - * cogl_get_graphics_reset_status(). Each value's meaning corresponds - * to the similarly named value defined in the ARB_robustness and - * NV_robustness_video_memory_purge extensions. - */ -typedef enum _CoglGraphicsResetStatus -{ - COGL_GRAPHICS_RESET_STATUS_NO_ERROR, - COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET, - COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET, - COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET, - COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET, -} CoglGraphicsResetStatus; - -/** - * cogl_get_graphics_reset_status: - * @context: a #CoglContext pointer - * - * Returns the graphics reset status as reported by - * GetGraphicsResetStatusARB defined in the ARB_robustness extension. - * - * Note that Cogl doesn't normally enable the ARB_robustness - * extension in which case this will only ever return - * #COGL_GRAPHICS_RESET_STATUS_NO_ERROR. - * - * Applications must explicitly use a backend specific method to - * request that errors get reported such as X11's - * cogl_xlib_renderer_request_reset_on_video_memory_purge(). - * - * Return value: a #CoglGraphicsResetStatus - */ -COGL_EXPORT CoglGraphicsResetStatus -cogl_get_graphics_reset_status (CoglContext *context); - -/** - * cogl_context_is_hardware_accelerated: - * @context: a #CoglContext pointer - * - * Returns: %TRUE if the @context is hardware accelerated, or %FALSE if - * not. - */ -COGL_EXPORT gboolean -cogl_context_is_hardware_accelerated (CoglContext *context); - -typedef const char * const CoglPipelineKey; - -/** - * cogl_context_set_named_pipeline: - * @context: a #CoglContext pointer - * @key: a #CoglPipelineKey pointer - * @pipeline: (nullable): a #CoglPipeline to associate with the @context and - * @key - * - * Associate a #CoglPipeline with a @context and @key. This will not take a new - * reference to the @pipeline, but will unref all associated pipelines when - * the @context gets destroyed. Similarly, if a pipeline gets overwritten, - * it will get unreffed as well. - */ -COGL_EXPORT void -cogl_context_set_named_pipeline (CoglContext *context, - CoglPipelineKey *key, - CoglPipeline *pipeline); - -/** - * cogl_context_get_named_pipeline: - * @context: a #CoglContext pointer - * @key: a #CoglPipelineKey pointer - * - * Return value: (transfer none): The #CoglPipeline associated with the - * given @context and @key, or %NULL if no such #CoglPipeline - * was found. - */ -COGL_EXPORT CoglPipeline * -cogl_context_get_named_pipeline (CoglContext *context, - CoglPipelineKey *key); - -COGL_EXPORT void -cogl_context_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query); - -COGL_EXPORT int64_t -cogl_context_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query); - -/** - * cogl_context_get_gpu_time_ns: - * @context: a #CoglContext pointer - * - * This function should only be called if the COGL_FEATURE_ID_GET_GPU_TIME - * feature is advertised. - * - * Return value: Current GPU time in nanoseconds - */ -COGL_EXPORT int64_t -cogl_context_get_gpu_time_ns (CoglContext *context); - -G_END_DECLS - -#endif /* __COGL_CONTEXT_H__ */ - diff --git a/cogl/cogl/cogl-debug-options.h b/cogl/cogl/cogl-debug-options.h deleted file mode 100644 index e6b1ca46d..000000000 --- a/cogl/cogl/cogl-debug-options.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -OPT (OBJECT, - N_("Cogl Tracing"), - "ref-counts", - N_("CoglObject references"), - N_("Debug ref counting issues for CoglObjects")) -OPT (SLICING, - N_("Cogl Tracing"), - "slicing", - N_("Trace Texture Slicing"), - N_("debug the creation of texture slices")) -OPT (ATLAS, - N_("Cogl Tracing"), - "atlas", - N_("Trace Atlas Textures"), - N_("Debug texture atlas management")) -OPT (BLEND_STRINGS, - N_("Cogl Tracing"), - "blend-strings", - N_("Trace Blend Strings"), - N_("Debug CoglBlendString parsing")) -OPT (JOURNAL, - N_("Cogl Tracing"), - "journal", - N_("Trace Journal"), - N_("View all the geometry passing through the journal")) -OPT (BATCHING, - N_("Cogl Tracing"), - "batching", - N_("Trace Batching"), - N_("Show how geometry is being batched in the journal")) -OPT (MATRICES, - N_("Cogl Tracing"), - "matrices", - N_("Trace matrices"), - N_("Trace all matrix manipulation")) -/* XXX we should replace the "draw" option its very hand wavy... */ -OPT (DRAW, - N_("Cogl Tracing"), - "draw", - N_("Trace Misc Drawing"), - N_("Trace some misc drawing operations")) -OPT (PANGO, - N_("Cogl Tracing"), - "pango", - N_("Trace Pango Renderer"), - N_("Trace the Cogl Pango renderer")) -OPT (TEXTURE_PIXMAP, - N_("Cogl Tracing"), - "texture-pixmap", - N_("Trace CoglTexturePixmap backend"), - N_("Trace the Cogl texture pixmap backend")) -OPT (RECTANGLES, - N_("Visualize"), - "rectangles", - N_("Outline rectangles"), - N_("Add wire outlines for all rectangular geometry")) -OPT (WIREFRAME, - N_("Visualize"), - "wireframe", - N_("Show wireframes"), - N_("Add wire outlines for all geometry")) -OPT (DISABLE_BATCHING, - N_("Root Cause"), - "disable-batching", - N_("Disable Journal batching"), - N_("Disable batching of geometry in the Cogl Journal.")) -OPT (DISABLE_PBOS, - N_("Root Cause"), - "disable-pbos", - N_("Disable GL Pixel Buffers"), - N_("Disable use of OpenGL pixel buffer objects")) -OPT (DISABLE_SOFTWARE_TRANSFORM, - N_("Root Cause"), - "disable-software-transform", - N_("Disable software rect transform"), - N_("Use the GPU to transform rectangular geometry")) -OPT (DUMP_ATLAS_IMAGE, - N_("Cogl Specialist"), - "dump-atlas-image", - N_("Dump atlas images"), - N_("Dump texture atlas changes to an image file")) -OPT (DISABLE_ATLAS, - N_("Root Cause"), - "disable-atlas", - N_("Disable texture atlasing"), - N_("Disable use of texture atlasing")) -OPT (DISABLE_SHARED_ATLAS, - N_("Root Cause"), - "disable-shared-atlas", - N_("Disable sharing the texture atlas between text and images"), - N_("When this is set the glyph cache will always use a separate texture " - "for its atlas. Otherwise it will try to share the atlas with images.")) -OPT (DISABLE_TEXTURING, - N_("Root Cause"), - "disable-texturing", - N_("Disable texturing"), - N_("Disable texturing any primitives")) -OPT (DISABLE_BLENDING, - N_("Root Cause"), - "disable-blending", - N_("Disable blending"), - N_("Disable use of blending")) -OPT (DISABLE_SOFTWARE_CLIP, - N_("Root Cause"), - "disable-software-clip", - N_("Disable software clipping"), - N_("Disables Cogl's attempts to clip some rectangles in software.")) -OPT (SHOW_SOURCE, - N_("Cogl Tracing"), - "show-source", - N_("Show source"), - N_("Show generated GLSL source code")) -OPT (OPENGL, - N_("Cogl Tracing"), - "opengl", - N_("Trace some OpenGL"), - N_("Traces some select OpenGL calls")) -OPT (OFFSCREEN, - N_("Cogl Tracing"), - "offscreen", - N_("Trace offscreen support"), - N_("Debug offscreen support")) -OPT (DISABLE_BLENDING, - N_("Root Cause"), - "disable-program-caches", - N_("Disable program caches"), - N_("Disable fallback caches for glsl programs")) -OPT (DISABLE_FAST_READ_PIXEL, - N_("Root Cause"), - "disable-fast-read-pixel", - N_("Disable read pixel optimization"), - N_("Disable optimization for reading 1px for simple " - "scenes of opaque rectangles")) -OPT (CLIPPING, - N_("Cogl Tracing"), - "clipping", - N_("Trace clipping"), - N_("Logs information about how Cogl is implementing clipping")) -OPT (PERFORMANCE, - N_("Cogl Tracing"), - "performance", - N_("Trace performance concerns"), - N_("Tries to highlight sub-optimal Cogl usage.")) -OPT (SYNC_PRIMITIVE, - N_("Root Cause"), - "sync-primitive", - N_("Render primitives synchronously"), - N_("Call glFinish after rendering each primitive, so profilers can see " - "the call stack of what's incurring most of the render time.")) -OPT (SYNC_FRAME, - N_("Root Cause"), - "sync-frame", - N_("Render frames synchronously"), - N_("Call glFinish after rendering each frame, so profilers can measure " - "the total render time (as a portion of the stage update time) more " - "accurately.")) -OPT (TEXTURES, - N_("Cogl Tracing"), - "textures", - N_("Debug texture management"), - N_("Logs information about texture management")) -OPT (STENCILLING, - N_("Root Cause"), - "stencilling", - N_("Stencil every clip entry"), - N_("Disables optimizations that usually avoid stencilling when it's not " - "needed. This exercises more of the stencilling logic than usual.")) diff --git a/cogl/cogl/cogl-debug.c b/cogl/cogl/cogl-debug.c deleted file mode 100644 index 056d92ec3..000000000 --- a/cogl/cogl/cogl-debug.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <stdlib.h> - -#include "cogl-i18n-private.h" -#include "cogl-private.h" -#include "cogl-debug.h" -#include "cogl1-context.h" - -/* XXX: If you add a debug option, please also add an option - * definition to cogl-debug-options.h. This will enable us - for - * example - to emit a "help" description for the option. - */ - -/* NB: Only these options get enabled if COGL_DEBUG=all is - * used since they don't affect the behaviour of Cogl they - * simply print out verbose information */ -static const GDebugKey cogl_log_debug_keys[] = { - { "object", COGL_DEBUG_OBJECT }, - { "slicing", COGL_DEBUG_SLICING }, - { "atlas", COGL_DEBUG_ATLAS }, - { "blend-strings", COGL_DEBUG_BLEND_STRINGS }, - { "journal", COGL_DEBUG_JOURNAL }, - { "batching", COGL_DEBUG_BATCHING }, - { "matrices", COGL_DEBUG_MATRICES }, - { "draw", COGL_DEBUG_DRAW }, - { "opengl", COGL_DEBUG_OPENGL }, - { "pango", COGL_DEBUG_PANGO }, - { "show-source", COGL_DEBUG_SHOW_SOURCE}, - { "framebuffer", COGL_DEBUG_FRAMEBUFFER }, - { "offscreen", COGL_DEBUG_OFFSCREEN }, - { "texture-pixmap", COGL_DEBUG_TEXTURE_PIXMAP }, - { "bitmap", COGL_DEBUG_BITMAP }, - { "clipping", COGL_DEBUG_CLIPPING }, - { "winsys", COGL_DEBUG_WINSYS }, - { "performance", COGL_DEBUG_PERFORMANCE }, - { "textures", COGL_DEBUG_TEXTURES }, -}; -static const int n_cogl_log_debug_keys = - G_N_ELEMENTS (cogl_log_debug_keys); - -static const GDebugKey cogl_behavioural_debug_keys[] = { - { "rectangles", COGL_DEBUG_RECTANGLES }, - { "disable-batching", COGL_DEBUG_DISABLE_BATCHING }, - { "disable-pbos", COGL_DEBUG_DISABLE_PBOS }, - { "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM }, - { "dump-atlas-image", COGL_DEBUG_DUMP_ATLAS_IMAGE }, - { "disable-atlas", COGL_DEBUG_DISABLE_ATLAS }, - { "disable-shared-atlas", COGL_DEBUG_DISABLE_SHARED_ATLAS }, - { "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING}, - { "disable-blending", COGL_DEBUG_DISABLE_BLENDING}, - { "wireframe", COGL_DEBUG_WIREFRAME}, - { "disable-software-clip", COGL_DEBUG_DISABLE_SOFTWARE_CLIP}, - { "disable-program-caches", COGL_DEBUG_DISABLE_PROGRAM_CACHES}, - { "disable-fast-read-pixel", COGL_DEBUG_DISABLE_FAST_READ_PIXEL}, - { "sync-primitive", COGL_DEBUG_SYNC_PRIMITIVE }, - { "sync-frame", COGL_DEBUG_SYNC_FRAME}, - { "stencilling", COGL_DEBUG_STENCILLING }, -}; -static const int n_cogl_behavioural_debug_keys = - G_N_ELEMENTS (cogl_behavioural_debug_keys); - -unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; -GHashTable *_cogl_debug_instances; - -static void -_cogl_parse_debug_string_for_keys (const char *value, - gboolean enable, - const GDebugKey *keys, - unsigned int nkeys) -{ - int long_num, key_num; - - /* g_parse_debug_string expects the value field in GDebugKey to be a - mask in an unsigned int but the flags are stored in an array of - multiple longs so we need to build a separate array for each - possible unsigned int */ - - for (long_num = 0; long_num < COGL_DEBUG_N_LONGS; long_num++) - { - int int_num; - - for (int_num = 0; - int_num < sizeof (unsigned long) / sizeof (unsigned int); - int_num++) - { - GDebugKey keys_for_int[sizeof (unsigned int) * 8]; - int nkeys_for_int = 0; - - for (key_num = 0; key_num < nkeys; key_num++) - { - int long_index = COGL_FLAGS_GET_INDEX (keys[key_num].value); - int int_index = (keys[key_num].value % - (sizeof (unsigned long) * 8) / - (sizeof (unsigned int) * 8)); - - if (long_index == long_num && int_index == int_num) - { - keys_for_int[nkeys_for_int] = keys[key_num]; - keys_for_int[nkeys_for_int].value = - COGL_FLAGS_GET_MASK (keys[key_num].value) >> - (int_num * sizeof (unsigned int) * 8); - nkeys_for_int++; - } - } - - if (nkeys_for_int > 0) - { - unsigned long mask = - ((unsigned long) g_parse_debug_string (value, - keys_for_int, - nkeys_for_int)) << - (int_num * sizeof (unsigned int) * 8); - - if (enable) - _cogl_debug_flags[long_num] |= mask; - else - _cogl_debug_flags[long_num] &= ~mask; - } - } - } -} - -void -_cogl_parse_debug_string (const char *value, - gboolean enable, - gboolean ignore_help) -{ - if (ignore_help && strcmp (value, "help") == 0) - return; - - /* We don't want to let g_parse_debug_string handle "all" because - * literally enabling all the debug options wouldn't be useful to - * anyone; instead the all option enables all non behavioural - * options. - */ - if (strcmp (value, "all") == 0 || - strcmp (value, "verbose") == 0) - { - int i; - for (i = 0; i < n_cogl_log_debug_keys; i++) - if (enable) - COGL_DEBUG_SET_FLAG (cogl_log_debug_keys[i].value); - else - COGL_DEBUG_CLEAR_FLAG (cogl_log_debug_keys[i].value); - } - else if (g_ascii_strcasecmp (value, "help") == 0) - { - g_printerr ("\n\n%28s\n", _("Supported debug values:")); -#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - g_printerr ("%28s %s\n", NAME ":", DESCRIPTION); -#include "cogl-debug-options.h" - g_printerr ("\n%28s\n", _("Special debug values:")); - OPT (IGNORED, "ignored", "all", "ignored", \ - N_("Enables all non-behavioural debug options")); - OPT (IGNORED, "ignored", "verbose", "ignored", \ - N_("Enables all non-behavioural debug options")); -#undef OPT - - g_printerr ("\n" - "%28s\n" - " COGL_DISABLE_GL_EXTENSIONS: %s\n" - " COGL_OVERRIDE_GL_VERSION: %s\n", - _("Additional environment variables:"), - _("Comma-separated list of GL extensions to pretend are " - "disabled"), - _("Override the GL version that Cogl will assume the driver " - "supports")); - exit (1); - } - else - { - _cogl_parse_debug_string_for_keys (value, - enable, - cogl_log_debug_keys, - n_cogl_log_debug_keys); - _cogl_parse_debug_string_for_keys (value, - enable, - cogl_behavioural_debug_keys, - n_cogl_behavioural_debug_keys); - } -} - -#ifdef COGL_ENABLE_DEBUG -static gboolean -cogl_arg_debug_cb (const char *key, - const char *value, - void *user_data) -{ - _cogl_parse_debug_string (value, - TRUE /* enable the flags */, - FALSE /* don't ignore help */); - return TRUE; -} - -static gboolean -cogl_arg_no_debug_cb (const char *key, - const char *value, - void *user_data) -{ - _cogl_parse_debug_string (value, - FALSE, /* disable the flags */ - TRUE /* ignore help */); - return TRUE; -} -#endif /* COGL_ENABLE_DEBUG */ - -static GOptionEntry cogl_args[] = { -#ifdef COGL_ENABLE_DEBUG - { "cogl-debug", 0, 0, G_OPTION_ARG_CALLBACK, cogl_arg_debug_cb, - N_("Cogl debugging flags to set"), "FLAGS" }, - { "cogl-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, cogl_arg_no_debug_cb, - N_("Cogl debugging flags to unset"), "FLAGS" }, -#endif /* COGL_ENABLE_DEBUG */ - { NULL, }, -}; - -void -_cogl_debug_check_environment (void) -{ - const char *env_string; - - env_string = g_getenv ("COGL_DEBUG"); - if (env_string != NULL) - { - _cogl_parse_debug_string (env_string, - TRUE /* enable the flags */, - FALSE /* don't ignore help */); - env_string = NULL; - } - - env_string = g_getenv ("COGL_NO_DEBUG"); - if (env_string != NULL) - { - _cogl_parse_debug_string (env_string, - FALSE /* disable the flags */, - FALSE /* don't ignore help */); - env_string = NULL; - } -} - -static gboolean -pre_parse_hook (GOptionContext *context, - GOptionGroup *group, - void *data, - GError **error) -{ - _cogl_init (); - - return TRUE; -} - -/* XXX: GOption based library initialization is not reliable because the - * GOption API has no way to represent dependencies between libraries. - */ -GOptionGroup * -cogl_get_option_group (void) -{ - GOptionGroup *group; - - group = g_option_group_new ("cogl", - _("Cogl Options"), - _("Show Cogl options"), - NULL, NULL); - - g_option_group_set_parse_hooks (group, pre_parse_hook, NULL); - g_option_group_add_entries (group, cogl_args); - - return group; -} diff --git a/cogl/cogl/cogl-debug.h b/cogl/cogl/cogl-debug.h deleted file mode 100644 index d818437f6..000000000 --- a/cogl/cogl/cogl-debug.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_DEBUG_H__ -#define __COGL_DEBUG_H__ - -#include "cogl-profile.h" -#include "cogl-flags.h" -#include "cogl-util.h" - -#include <glib.h> - -G_BEGIN_DECLS - -typedef enum -{ - COGL_DEBUG_SLICING, - COGL_DEBUG_FRAMEBUFFER, - COGL_DEBUG_OFFSCREEN, - COGL_DEBUG_DRAW, - COGL_DEBUG_PANGO, - COGL_DEBUG_RECTANGLES, - COGL_DEBUG_OBJECT, - COGL_DEBUG_BLEND_STRINGS, - COGL_DEBUG_DISABLE_BATCHING, - COGL_DEBUG_DISABLE_PBOS, - COGL_DEBUG_JOURNAL, - COGL_DEBUG_BATCHING, - COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM, - COGL_DEBUG_MATRICES, - COGL_DEBUG_ATLAS, - COGL_DEBUG_DUMP_ATLAS_IMAGE, - COGL_DEBUG_DISABLE_ATLAS, - COGL_DEBUG_DISABLE_SHARED_ATLAS, - COGL_DEBUG_OPENGL, - COGL_DEBUG_DISABLE_TEXTURING, - COGL_DEBUG_SHOW_SOURCE, - COGL_DEBUG_DISABLE_BLENDING, - COGL_DEBUG_TEXTURE_PIXMAP, - COGL_DEBUG_BITMAP, - COGL_DEBUG_WIREFRAME, - COGL_DEBUG_DISABLE_SOFTWARE_CLIP, - COGL_DEBUG_DISABLE_PROGRAM_CACHES, - COGL_DEBUG_DISABLE_FAST_READ_PIXEL, - COGL_DEBUG_CLIPPING, - COGL_DEBUG_WINSYS, - COGL_DEBUG_PERFORMANCE, - COGL_DEBUG_SYNC_PRIMITIVE, - COGL_DEBUG_SYNC_FRAME, - COGL_DEBUG_TEXTURES, - COGL_DEBUG_STENCILLING, - - COGL_DEBUG_N_FLAGS -} CoglDebugFlags; - -COGL_EXPORT -GHashTable *_cogl_debug_instances; -#define COGL_DEBUG_N_LONGS COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_DEBUG_N_FLAGS) - -COGL_EXPORT -unsigned long _cogl_debug_flags[COGL_DEBUG_N_LONGS]; - -#define COGL_DEBUG_ENABLED(flag) \ - COGL_FLAGS_GET (_cogl_debug_flags, flag) - -#define COGL_DEBUG_SET_FLAG(flag) \ - COGL_FLAGS_SET (_cogl_debug_flags, flag, TRUE) - -#define COGL_DEBUG_CLEAR_FLAG(flag) \ - COGL_FLAGS_SET (_cogl_debug_flags, flag, FALSE) - -#ifdef __GNUC__ -#define COGL_NOTE(type,x,a...) G_STMT_START { \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type))) { \ - _cogl_profile_trace_message ("[" #type "] " G_STRLOC ": " x, ##a); \ - } } G_STMT_END - -#else -#define COGL_NOTE(type,...) G_STMT_START { \ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_##type))) { \ - char *_fmt = g_strdup_printf (__VA_ARGS__); \ - _cogl_profile_trace_message ("[" #type "] " G_STRLOC ": %s", _fmt);\ - g_free (_fmt); \ - } } G_STMT_END - -#endif /* __GNUC__ */ - -void -_cogl_debug_check_environment (void); - -void -_cogl_parse_debug_string (const char *value, - gboolean enable, - gboolean ignore_help); - -G_END_DECLS - -#endif /* __COGL_DEBUG_H__ */ - diff --git a/cogl/cogl/cogl-defines.h.in b/cogl/cogl/cogl-defines.h.in deleted file mode 100644 index a438a9622..000000000 --- a/cogl/cogl/cogl-defines.h.in +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_DEFINES_H__ -#define __COGL_DEFINES_H__ - -@COGL_DEFINES@ - -#endif diff --git a/cogl/cogl/cogl-defines.h.meson b/cogl/cogl/cogl-defines.h.meson deleted file mode 100644 index 4c9535239..000000000 --- a/cogl/cogl/cogl-defines.h.meson +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include <poll.h> - -#define COGL_SYSDEF_POLLIN POLLIN -#define COGL_SYSDEF_POLLPRI POLLPRI -#define COGL_SYSDEF_POLLOUT POLLOUT -#define COGL_SYSDEF_POLLERR POLLERR -#define COGL_SYSDEF_POLLHUP POLLHUP -#define COGL_SYSDEF_POLLNVAL POLLNVAL - -#mesondefine COGL_HAS_GL -#mesondefine CLUTTER_COGL_HAS_GL -#mesondefine COGL_HAS_GLX_SUPPORT -#mesondefine COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT -#mesondefine COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT -#mesondefine COGL_HAS_EGL_SUPPORT -#mesondefine COGL_HAS_X11 -#mesondefine COGL_HAS_X11_SUPPORT -#mesondefine COGL_HAS_XLIB -#mesondefine COGL_HAS_XLIB_SUPPORT - -#mesondefine COGL_HAS_TRACING diff --git a/cogl/cogl/cogl-depth-state-private.h b/cogl/cogl/cogl-depth-state-private.h deleted file mode 100644 index 6c14bb9f2..000000000 --- a/cogl/cogl/cogl-depth-state-private.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_DEPTH_STATE_PRIVATE_H -#define __COGL_DEPTH_STATE_PRIVATE_H - - -#define COGL_DEPTH_STATE_MAGIC 0xDEADBEEF - -#endif /* __COGL_DEPTH_STATE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-depth-state.c b/cogl/cogl/cogl-depth-state.c deleted file mode 100644 index a8b141d49..000000000 --- a/cogl/cogl/cogl-depth-state.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-depth-state-private.h" -#include "cogl-depth-state.h" - -void -cogl_depth_state_init (CoglDepthState *state) -{ - state->magic = COGL_DEPTH_STATE_MAGIC; - - /* The same as the GL defaults */ - state->test_enabled = FALSE; - state->write_enabled = TRUE; - state->test_function = COGL_DEPTH_TEST_FUNCTION_LESS; - state->range_near = 0; - state->range_far = 1; -} - -void -cogl_depth_state_set_test_enabled (CoglDepthState *state, - gboolean enabled) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->test_enabled = enabled; -} - -gboolean -cogl_depth_state_get_test_enabled (CoglDepthState *state) -{ - g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - return state->test_enabled; -} - -void -cogl_depth_state_set_write_enabled (CoglDepthState *state, - gboolean enabled) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->write_enabled = enabled; -} - -gboolean -cogl_depth_state_get_write_enabled (CoglDepthState *state) -{ - g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - return state->write_enabled; -} - -void -cogl_depth_state_set_test_function (CoglDepthState *state, - CoglDepthTestFunction function) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->test_function = function; -} - -CoglDepthTestFunction -cogl_depth_state_get_test_function (CoglDepthState *state) -{ - g_return_val_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); - return state->test_function; -} - -void -cogl_depth_state_set_range (CoglDepthState *state, - float near, - float far) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - state->range_near = near; - state->range_far = far; -} - -void -cogl_depth_state_get_range (CoglDepthState *state, - float *near_out, - float *far_out) -{ - g_return_if_fail (state->magic == COGL_DEPTH_STATE_MAGIC); - *near_out = state->range_near; - *far_out = state->range_far; -} diff --git a/cogl/cogl/cogl-depth-state.h b/cogl/cogl/cogl-depth-state.h deleted file mode 100644 index b3b240526..000000000 --- a/cogl/cogl/cogl-depth-state.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_DEPTH_STATE_H__ -#define __COGL_DEPTH_STATE_H__ - -G_BEGIN_DECLS - -/** - * SECTION:cogl-depth-state - * @short_description: Functions for describing the depth testing - * state of your GPU. - */ - -/** - * CoglDepthState: - * - * Since: 2.0 - */ -typedef struct { - /*< private >*/ - uint32_t COGL_PRIVATE (magic); - - gboolean COGL_PRIVATE (test_enabled); - CoglDepthTestFunction COGL_PRIVATE (test_function); - gboolean COGL_PRIVATE (write_enabled); - float COGL_PRIVATE (range_near); - float COGL_PRIVATE (range_far); - - uint32_t COGL_PRIVATE (padding0); - uint32_t COGL_PRIVATE (padding1); - uint32_t COGL_PRIVATE (padding2); - uint32_t COGL_PRIVATE (padding3); - uint32_t COGL_PRIVATE (padding4); - uint32_t COGL_PRIVATE (padding5); - uint32_t COGL_PRIVATE (padding6); - uint32_t COGL_PRIVATE (padding7); - uint32_t COGL_PRIVATE (padding8); - uint32_t COGL_PRIVATE (padding9); -} CoglDepthState; - -/** - * cogl_depth_state_init: - * @state: A #CoglDepthState struct - * - * Initializes the members of @state to their default values. - * - * You should never pass an un initialized #CoglDepthState structure - * to cogl_pipeline_set_depth_state(). - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_depth_state_init (CoglDepthState *state); - -/** - * cogl_depth_state_set_test_enabled: - * @state: A #CoglDepthState struct - * @enable: The enable state you want - * - * Enables or disables depth testing according to the value of - * @enable. - * - * If depth testing is enable then the #CoglDepthTestFunction set - * using cogl_depth_state_set_test_function() us used to evaluate - * the depth value of incoming fragments against the corresponding - * value stored in the current depth buffer, and if the test passes - * then the fragments depth value is used to update the depth buffer. - * (unless you have disabled depth writing via - * cogl_depth_state_set_write_enabled()) - * - * By default depth testing is disabled. - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state() - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_depth_state_set_test_enabled (CoglDepthState *state, - gboolean enable); - -/** - * cogl_depth_state_get_test_enabled: - * @state: A #CoglDepthState struct - * - * Gets the current depth test enabled state as previously set by - * cogl_depth_state_set_test_enabled(). - * - * Returns: The pipeline's current depth test enabled state. - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_depth_state_get_test_enabled (CoglDepthState *state); - -/** - * cogl_depth_state_set_write_enabled: - * @state: A #CoglDepthState struct - * @enable: The enable state you want - * - * Enables or disables depth buffer writing according to the value of - * @enable. Normally when depth testing is enabled and the comparison - * between a fragment's depth value and the corresponding depth buffer - * value passes then the fragment's depth is written to the depth - * buffer unless writing is disabled here. - * - * By default depth writing is enabled - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state() - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_depth_state_set_write_enabled (CoglDepthState *state, - gboolean enable); - -/** - * cogl_depth_state_get_write_enabled: - * @state: A #CoglDepthState struct - * - * Gets the depth writing enable state as set by the corresponding - * cogl_depth_state_set_write_enabled(). - * - * Returns: The current depth writing enable state - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_depth_state_get_write_enabled (CoglDepthState *state); - -/** - * cogl_depth_state_set_test_function: - * @state: A #CoglDepthState struct - * @function: The #CoglDepthTestFunction to set - * - * Sets the #CoglDepthTestFunction used to compare the depth value of - * an incoming fragment against the corresponding value in the current - * depth buffer. - * - * By default the depth test function is %COGL_DEPTH_TEST_FUNCTION_LESS - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state() - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_depth_state_set_test_function (CoglDepthState *state, - CoglDepthTestFunction function); - -/** - * cogl_depth_state_get_test_function: - * @state: A #CoglDepthState struct - * - * Gets the current depth test enable state as previously set via - * cogl_depth_state_set_test_enabled(). - * - * Returns: The current depth test enable state. - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT CoglDepthTestFunction -cogl_depth_state_get_test_function (CoglDepthState *state); - -/** - * cogl_depth_state_set_range: - * @state: A #CoglDepthState object - * @near_val: The near component of the desired depth range which will be - * clamped to the range [0, 1] - * @far_val: The far component of the desired depth range which will be - * clamped to the range [0, 1] - * - * Sets the range to map depth values in normalized device coordinates - * to before writing out to a depth buffer. - * - * After your geometry has be transformed, clipped and had perspective - * division applied placing it in normalized device - * coordinates all depth values between the near and far z clipping - * planes are in the range -1 to 1. Before writing any depth value to - * the depth buffer though the value is mapped into the range [0, 1]. - * - * With this function you can change the range which depth values are - * mapped too although the range must still lye within the range [0, - * 1]. - * - * By default normalized device coordinate depth values are mapped to - * the full range of depth buffer values, [0, 1]. - * - * NB: this won't directly affect the state of the GPU. You have - * to then set the state on a #CoglPipeline using - * cogl_pipeline_set_depth_state(). - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_depth_state_set_range (CoglDepthState *state, - float near_val, - float far_val); - -/** - * cogl_depth_state_get_range: - * @state: A #CoglDepthState object - * @near_val: A pointer to store the near component of the depth range - * @far_val: A pointer to store the far component of the depth range - * - * Gets the current range to which normalized depth values are mapped - * before writing to the depth buffer. This corresponds to the range - * set with cogl_depth_state_set_range(). - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_depth_state_get_range (CoglDepthState *state, - float *near_val, - float *far_val); - -G_END_DECLS - -#endif /* __COGL_DEPTH_STATE_H__ */ diff --git a/cogl/cogl/cogl-display-private.h b/cogl/cogl/cogl-display-private.h deleted file mode 100644 index e20036345..000000000 --- a/cogl/cogl/cogl-display-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_DISPLAY_PRIVATE_H -#define __COGL_DISPLAY_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-display.h" -#include "cogl-renderer.h" -#include "cogl-onscreen-template.h" - -struct _CoglDisplay -{ - CoglObject _parent; - - gboolean setup; - CoglRenderer *renderer; - CoglOnscreenTemplate *onscreen_template; - - void *winsys; -}; - -#endif /* __COGL_DISPLAY_PRIVATE_H */ diff --git a/cogl/cogl/cogl-display.c b/cogl/cogl/cogl-display.c deleted file mode 100644 index 64e9df809..000000000 --- a/cogl/cogl/cogl-display.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-private.h" -#include "cogl-object.h" - -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-gtype-private.h" -#include "winsys/cogl-winsys-private.h" - -static void _cogl_display_free (CoglDisplay *display); - -COGL_OBJECT_DEFINE (Display, display); -COGL_GTYPE_DEFINE_CLASS (Display, display); - -static const CoglWinsysVtable * -_cogl_display_get_winsys (CoglDisplay *display) -{ - return display->renderer->winsys_vtable; -} - -static void -_cogl_display_free (CoglDisplay *display) -{ - const CoglWinsysVtable *winsys; - - if (display->setup) - { - winsys = _cogl_display_get_winsys (display); - winsys->display_destroy (display); - display->setup = FALSE; - } - - if (display->renderer) - { - cogl_object_unref (display->renderer); - display->renderer = NULL; - } - - if (display->onscreen_template) - { - cogl_object_unref (display->onscreen_template); - display->onscreen_template = NULL; - } - - g_free (display); -} - -CoglDisplay * -cogl_display_new (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template) -{ - CoglDisplay *display = g_new0 (CoglDisplay, 1); - GError *error = NULL; - - _cogl_init (); - - display->renderer = renderer; - if (renderer) - cogl_object_ref (renderer); - else - display->renderer = cogl_renderer_new (); - - if (!cogl_renderer_connect (display->renderer, &error)) - g_error ("Failed to connect to renderer: %s\n", error->message); - - display->setup = FALSE; - - display = _cogl_display_object_new (display); - - cogl_display_set_onscreen_template (display, onscreen_template); - - return display; -} - -CoglRenderer * -cogl_display_get_renderer (CoglDisplay *display) -{ - return display->renderer; -} - -void -cogl_display_set_onscreen_template (CoglDisplay *display, - CoglOnscreenTemplate *onscreen_template) -{ - g_return_if_fail (display->setup == FALSE); - - if (onscreen_template) - cogl_object_ref (onscreen_template); - - if (display->onscreen_template) - cogl_object_unref (display->onscreen_template); - - display->onscreen_template = onscreen_template; - - /* NB: we want to maintain the invariable that there is always an - * onscreen template associated with a CoglDisplay... */ - if (!onscreen_template) - display->onscreen_template = cogl_onscreen_template_new (NULL); -} - -gboolean -cogl_display_setup (CoglDisplay *display, - GError **error) -{ - const CoglWinsysVtable *winsys; - - if (display->setup) - return TRUE; - - winsys = _cogl_display_get_winsys (display); - if (!winsys->display_setup (display, error)) - return FALSE; - - display->setup = TRUE; - - return TRUE; -} diff --git a/cogl/cogl/cogl-display.h b/cogl/cogl/cogl-display.h deleted file mode 100644 index 098e436ae..000000000 --- a/cogl/cogl/cogl-display.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_DISPLAY_H__ -#define __COGL_DISPLAY_H__ - -#include <cogl/cogl-renderer.h> -#include <cogl/cogl-onscreen-template.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-display - * @short_description: Common aspects of a display pipeline - * - * The basic intention for this object is to let the application - * configure common display preferences before creating a context, and - * there are a few different aspects to this... - * - * Firstly there are options directly relating to the physical display - * pipeline that is currently being used including the digital to - * analogue conversion hardware and the screens the user sees. - * - * Another aspect is that display options may constrain or affect how - * onscreen framebuffers should later be configured. The original - * rationale for the display object in fact was to let us handle GLX - * and EGLs requirements that framebuffers must be "compatible" with - * the config associated with the current context meaning we have to - * force the user to describe how they would like to create their - * onscreen windows before we can choose a suitable fbconfig and - * create a GLContext. - */ - -typedef struct _CoglDisplay CoglDisplay; - -#define COGL_DISPLAY(OBJECT) ((CoglDisplay *)OBJECT) - -/** - * cogl_display_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_display_get_gtype (void); - -/** - * cogl_display_new: - * @renderer: A #CoglRenderer - * @onscreen_template: A #CoglOnscreenTemplate - * - * Explicitly allocates a new #CoglDisplay object to encapsulate the - * common state of the display pipeline that applies to the whole - * application. - * - * <note>Many applications don't need to explicitly use - * cogl_display_new() and can just jump straight to cogl_context_new() - * and pass a %NULL display argument so Cogl will automatically - * connect and setup a renderer and display.</note> - * - * A @display can only be made for a specific choice of renderer which - * is why this takes the @renderer argument. - * - * A common use for explicitly allocating a display object is to - * define a template for allocating onscreen framebuffers which is - * what the @onscreen_template argument is for, or alternatively - * you can use cogl_display_set_onscreen_template(). - * - * When a display is first allocated via cogl_display_new() it is in a - * mutable configuration mode. It's designed this way so we can - * extend the apis available for configuring a display without - * requiring huge numbers of constructor arguments. - * - * When you have finished configuring a display object you can - * optionally call cogl_display_setup() to explicitly apply the - * configuration and check for errors. Alternaitvely you can pass the - * display to cogl_context_new() and Cogl will implicitly apply your - * configuration but if there are errors then the application will - * abort with a message. For simple applications with no fallback - * options then relying on the implicit setup can be fine. - * - * Return value: (transfer full): A newly allocated #CoglDisplay - * object in a mutable configuration mode. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglDisplay * -cogl_display_new (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template); - -/** - * cogl_display_get_renderer: - * @display: a #CoglDisplay - * - * Queries the #CoglRenderer associated with the given @display. - * - * Return value: (transfer none): The associated #CoglRenderer - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglRenderer * -cogl_display_get_renderer (CoglDisplay *display); - -/** - * cogl_display_set_onscreen_template: - * @display: a #CoglDisplay - * @onscreen_template: A template for creating #CoglOnscreen framebuffers - * - * Specifies a template for creating #CoglOnscreen framebuffers. - * - * Depending on the system, the constraints for creating #CoglOnscreen - * framebuffers need to be known before setting up a #CoglDisplay because the - * final setup of the display may constrain how onscreen framebuffers may be - * allocated. If Cogl knows how an application wants to allocate onscreen - * framebuffers then it can try to make sure to setup the display accordingly. - * - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT void -cogl_display_set_onscreen_template (CoglDisplay *display, - CoglOnscreenTemplate *onscreen_template); - -/** - * cogl_display_setup: - * @display: a #CoglDisplay - * @error: return location for a #GError - * - * Explicitly sets up the given @display object. Use of this api is - * optional since Cogl will internally setup the display if not done - * explicitly. - * - * When a display is first allocated via cogl_display_new() it is in a - * mutable configuration mode. This allows us to extend the apis - * available for configuring a display without requiring huge numbers - * of constructor arguments. - * - * Its possible to request a configuration that might not be - * supportable on the current system and so this api provides a means - * to apply the configuration explicitly but if it fails then an - * exception will be returned so you can handle the error gracefully - * and perhaps fall back to an alternative configuration. - * - * If you instead rely on Cogl implicitly calling cogl_display_setup() - * for you then if there is an error with the configuration you won't - * get an opportunity to handle that and the application may abort - * with a message. For simple applications that don't have any - * fallback options this behaviour may be fine. - * - * Return value: Returns %TRUE if there was no error, else it returns - * %FALSE and returns an exception via @error. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_display_setup (CoglDisplay *display, - GError **error); - -/** - * cogl_is_display: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglDisplay. - * - * Return value: %TRUE if the object references a #CoglDisplay - * and %FALSE otherwise. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_display (void *object); - -G_END_DECLS - -#endif /* __COGL_DISPLAY_H__ */ - diff --git a/cogl/cogl/cogl-dma-buf-handle.c b/cogl/cogl/cogl-dma-buf-handle.c deleted file mode 100644 index 5b18f1030..000000000 --- a/cogl/cogl/cogl-dma-buf-handle.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2020 Endless, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Georges Basile Stavracas Neto <georges.stavracas@gmail.com> - */ - -#include "cogl-config.h" - -#include "cogl-dma-buf-handle.h" -#include "cogl-object.h" - -#include <errno.h> -#include <gio/gio.h> -#include <linux/dma-buf.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <unistd.h> - -struct _CoglDmaBufHandle -{ - CoglFramebuffer *framebuffer; - int dmabuf_fd; - int width; - int height; - int stride; - int offset; - int bpp; - gpointer user_data; - GDestroyNotify destroy_func; -}; - -CoglDmaBufHandle * -cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, - int dmabuf_fd, - int width, - int height, - int stride, - int offset, - int bpp, - gpointer user_data, - GDestroyNotify destroy_func) -{ - CoglDmaBufHandle *dmabuf_handle; - - g_assert (framebuffer); - g_assert (dmabuf_fd != -1); - - dmabuf_handle = g_new0 (CoglDmaBufHandle, 1); - dmabuf_handle->framebuffer = g_object_ref (framebuffer); - dmabuf_handle->dmabuf_fd = dmabuf_fd; - dmabuf_handle->user_data = user_data; - dmabuf_handle->destroy_func = destroy_func; - - dmabuf_handle->width = width; - dmabuf_handle->height = height; - dmabuf_handle->stride = stride; - dmabuf_handle->offset = offset; - dmabuf_handle->bpp = bpp; - - return dmabuf_handle; -} - -void -cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle) -{ - g_return_if_fail (dmabuf_handle != NULL); - - g_clear_object (&dmabuf_handle->framebuffer); - - if (dmabuf_handle->destroy_func) - g_clear_pointer (&dmabuf_handle->user_data, dmabuf_handle->destroy_func); - - if (dmabuf_handle->dmabuf_fd != -1) - close (dmabuf_handle->dmabuf_fd); - - g_free (dmabuf_handle); -} - -static gboolean -sync_read (CoglDmaBufHandle *dmabuf_handle, - uint64_t start_or_end, - GError **error) -{ - struct dma_buf_sync sync = { 0 }; - - sync.flags = start_or_end | DMA_BUF_SYNC_READ; - - while (TRUE) - { - int ret; - - ret = ioctl (dmabuf_handle->dmabuf_fd, DMA_BUF_IOCTL_SYNC, &sync); - if (ret == -1 && errno == EINTR) - { - continue; - } - else if (ret == -1) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "ioctl: %s", g_strerror (errno)); - return FALSE; - } - else - { - break; - } - } - - return TRUE; -} - -gboolean -cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle *dmabuf_handle, - GError **error) -{ - return sync_read (dmabuf_handle, DMA_BUF_SYNC_START, error); -} - -gboolean -cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle *dmabuf_handle, - GError **error) -{ - return sync_read (dmabuf_handle, DMA_BUF_SYNC_END, error); -} - -gpointer -cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle, - GError **error) -{ - size_t size; - gpointer data; - - size = dmabuf_handle->height * dmabuf_handle->stride; - - data = mmap (NULL, size, PROT_READ, MAP_PRIVATE, - dmabuf_handle->dmabuf_fd, - dmabuf_handle->offset); - if (data == MAP_FAILED) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "mmap failed: %s", g_strerror (errno)); - return NULL; - } - - return data; -} - -gboolean -cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle, - gpointer data, - GError **error) -{ - size_t size; - - size = dmabuf_handle->height * dmabuf_handle->stride; - if (munmap (data, size) != 0) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "munmap failed: %s", g_strerror (errno)); - return FALSE; - } - - return TRUE; -} - -CoglFramebuffer * -cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->framebuffer; -} - -int -cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->dmabuf_fd; -} - -int -cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->width; -} - -int -cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->height; -} - -int -cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->stride; -} - -int -cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->offset; -} - -int -cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle) -{ - return dmabuf_handle->bpp; -} diff --git a/cogl/cogl/cogl-dma-buf-handle.h b/cogl/cogl/cogl-dma-buf-handle.h deleted file mode 100644 index c505ff76c..000000000 --- a/cogl/cogl/cogl-dma-buf-handle.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2020 Endless, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Georges Basile Stavracas Neto <georges.stavracas@gmail.com> - */ - - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_DMA_BUF_HANDLE_H__ -#define __COGL_DMA_BUF_HANDLE_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-framebuffer.h> - -/** - * cogl_dma_buf_handle_new: (skip) - */ -COGL_EXPORT CoglDmaBufHandle * -cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, - int dmabuf_fd, - int width, - int height, - int stride, - int offset, - int bpp, - gpointer user_data, - GDestroyNotify destroy_func); - -/** - * cogl_dma_buf_handle_free: (skip) - * - * Releases @dmabuf_handle; it is a programming error to release - * an already released handle. - */ -COGL_EXPORT void -cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle); - -COGL_EXPORT gboolean -cogl_dma_buf_handle_sync_read_start (CoglDmaBufHandle *dmabuf_handle, - GError **error); - -COGL_EXPORT gboolean -cogl_dma_buf_handle_sync_read_end (CoglDmaBufHandle *dmabuf_handle, - GError **error); - -COGL_EXPORT gpointer -cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle, - GError **error); - -COGL_EXPORT gboolean -cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle, - gpointer data, - GError **error); - -/** - * cogl_dma_buf_handle_get_framebuffer: (skip) - * - * Retrieves the #CoglFramebuffer, backed by an exported DMABuf buffer, - * of @dmabuf_handle. - * - * Returns: (transfer none): a #CoglFramebuffer - */ -COGL_EXPORT CoglFramebuffer * -cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dma_buf_handle_get_fd: (skip) - * - * Retrieves the file descriptor of @dmabuf_handle. - * - * Returns: a valid file descriptor - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_width: (skip) - * - * Returns: the buffer width - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_width (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_height: (skip) - * - * Returns: the buffer height - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_stride: (skip) - * - * Returns: the buffer stride - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_offset: (skip) - * - * Returns: the buffer offset - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle); - -/** - * cogl_dmabuf_handle_get_bpp: (skip) - * - * Returns: the number of bytes per pixel - */ -COGL_EXPORT int -cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle); - -#endif /* __COGL_DMA_BUF_HANDLE_H__ */ diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h deleted file mode 100644 index aeabfe0e7..000000000 --- a/cogl/cogl/cogl-driver.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_DRIVER_H -#define __COGL_DRIVER_H - -#include "cogl-context.h" -#include "cogl-offscreen-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-attribute-private.h" -#include "cogl-sampler-cache-private.h" - -typedef struct _CoglDriverVtable CoglDriverVtable; - -struct _CoglDriverVtable -{ - gboolean - (* context_init) (CoglContext *context); - - void - (* context_deinit) (CoglContext *context); - - gboolean - (* is_hardware_accelerated) (CoglContext *context); - - CoglGraphicsResetStatus - (* get_graphics_reset_status) (CoglContext *context); - - /* TODO: factor this out since this is OpenGL specific and - * so can be ignored by non-OpenGL drivers. */ - gboolean - (* pixel_format_from_gl_internal) (CoglContext *context, - GLenum gl_int_format, - CoglPixelFormat *out_format); - - /* TODO: factor this out since this is OpenGL specific and - * so can be ignored by non-OpenGL drivers. */ - CoglPixelFormat - (* pixel_format_to_gl) (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype); - - gboolean - (* update_features) (CoglContext *context, - GError **error); - - CoglFramebufferDriver * - (* create_framebuffer_driver) (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); - - void - (* flush_framebuffer_state) (CoglContext *context, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state); - - /* Destroys any driver specific resources associated with the given - * 2D texture. */ - void - (* texture_2d_free) (CoglTexture2D *tex_2d); - - /* Returns TRUE if the driver can support creating a 2D texture with - * the given geometry and specified internal format. - */ - gboolean - (* texture_2d_can_create) (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format); - - /* Initializes driver private state before allocating any specific - * storage for a 2D texture, where base texture and texture 2D - * members will already be initialized before passing control to - * the driver. - */ - void - (* texture_2d_init) (CoglTexture2D *tex_2d); - - /* Allocates (uninitialized) storage for the given texture according - * to the configured size and format of the texture */ - gboolean - (* texture_2d_allocate) (CoglTexture *tex, - GError **error); - - /* Initialize the specified region of storage of the given texture - * with the contents of the specified framebuffer region - */ - void - (* texture_2d_copy_from_framebuffer) (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - - /* If the given texture has a corresponding OpenGL texture handle - * then return that. - * - * This is optional - */ - unsigned int - (* texture_2d_get_gl_handle) (CoglTexture2D *tex_2d); - - /* Update all mipmap levels > 0 */ - void - (* texture_2d_generate_mipmap) (CoglTexture2D *tex_2d); - - /* Initialize the specified region of storage of the given texture - * with the contents of the specified bitmap region - * - * Since this may need to create the underlying storage first - * it may throw a NO_MEMORY error. - */ - gboolean - (* texture_2d_copy_from_bitmap) (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error); - - gboolean - (* texture_2d_is_get_data_supported) (CoglTexture2D *tex_2d); - - /* Reads back the full contents of the given texture and write it to - * @data in the given @format and with the given @rowstride. - * - * This is optional - */ - void - (* texture_2d_get_data) (CoglTexture2D *tex_2d, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - - /* Prepares for drawing by flushing the journal, framebuffer state, - * pipeline state and attribute state. - */ - void - (* flush_attributes_state) (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layer_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); - - /* Flushes the clip stack to the GPU using a combination of the - * stencil buffer, scissor and clip plane state. - */ - void - (* clip_stack_flush) (CoglClipStack *stack, CoglFramebuffer *framebuffer); - - /* Enables the driver to create some meta data to represent a buffer - * but with no corresponding storage allocated yet. - */ - void - (* buffer_create) (CoglBuffer *buffer); - - void - (* buffer_destroy) (CoglBuffer *buffer); - - /* Maps a buffer into the CPU */ - void * - (* buffer_map_range) (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - - /* Unmaps a buffer */ - void - (* buffer_unmap) (CoglBuffer *buffer); - - /* Uploads data to the buffer without needing to map it necessarily - */ - gboolean - (* buffer_set_data) (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error); - - void - (*sampler_init) (CoglContext *context, - CoglSamplerCacheEntry *entry); - - void - (*sampler_free) (CoglContext *context, - CoglSamplerCacheEntry *entry); - - void - (* set_uniform) (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value); - - CoglTimestampQuery * - (* create_timestamp_query) (CoglContext *context); - - void - (* free_timestamp_query) (CoglContext *context, - CoglTimestampQuery *query); - - int64_t - (* timestamp_query_get_time_ns) (CoglContext *context, - CoglTimestampQuery *query); - - int64_t - (* get_gpu_time_ns) (CoglContext *context); -}; - -#define COGL_DRIVER_ERROR (_cogl_driver_error_quark ()) - -typedef enum /*< prefix=COGL_DRIVER_ERROR >*/ -{ - COGL_DRIVER_ERROR_UNKNOWN_VERSION, - COGL_DRIVER_ERROR_INVALID_VERSION, - COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, - COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY -} CoglDriverError; - -uint32_t -_cogl_driver_error_quark (void); - -#endif /* __COGL_DRIVER_H */ - diff --git a/cogl/cogl/cogl-egl-defines.h.in b/cogl/cogl/cogl-egl-defines.h.in deleted file mode 100644 index 648a62ddf..000000000 --- a/cogl/cogl/cogl-egl-defines.h.in +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_EGL_DEFINES_H__ -#define __COGL_EGL_DEFINES_H__ - -#ifdef COGL_HAS_EGL_SUPPORT - -@COGL_EGL_INCLUDES@ - -#endif /* COGL_HAS_EGL_SUPPORT */ - -#endif diff --git a/cogl/cogl/cogl-egl-private.h b/cogl/cogl/cogl-egl-private.h deleted file mode 100644 index 0af8518f1..000000000 --- a/cogl/cogl/cogl-egl-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_EGL_PRIVATE_H__ -#define __COGL_EGL_PRIVATE_H__ - -#include "cogl-egl-defines.h" - -#if defined(GL_OES_EGL_image) && !defined(GLeglImageOES) -#define GLeglImageOES void * -#endif - -#endif /* __COGL_EGL_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-egl.h b/cogl/cogl/cogl-egl.h deleted file mode 100644 index 07dac799b..000000000 --- a/cogl/cogl/cogl-egl.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_EGL_H__ -#define __COGL_EGL_H__ - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_EGL_H_INSIDE__ */ -#ifndef __COGL_EGL_H_INSIDE__ -#define __COGL_EGL_H_INSIDE__ -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_EGL__ -#endif - -#endif /* COGL_COMPILATION */ - - -#include <cogl/cogl-egl-defines.h> -#include <cogl/cogl-types.h> - -G_BEGIN_DECLS - -/** - * cogl_egl_context_get_egl_display: - * @context: A #CoglContext pointer - * - * If you have done a runtime check to determine that Cogl is using - * EGL internally then this API can be used to retrieve the EGLDisplay - * handle that was setup internally. The result is undefined if Cogl - * is not using EGL. - * - * Note: The current window system backend can be checked using - * cogl_renderer_get_winsys_id(). - * - * Return value: The internally setup EGLDisplay handle. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT EGLDisplay -cogl_egl_context_get_egl_display (CoglContext *context); - -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_EGL__ -#undef __COGL_H_INSIDE__ -#undef __COGL_EGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_EGL__ -#endif - -#endif /* __COGL_EGL_H__ */ diff --git a/cogl/cogl/cogl-feature-private.c b/cogl/cogl/cogl-feature-private.c deleted file mode 100644 index 3b2a9be98..000000000 --- a/cogl/cogl/cogl-feature-private.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-context-private.h" - -#include "cogl-feature-private.h" -#include "cogl-renderer-private.h" -#include "cogl-private.h" - -gboolean -_cogl_feature_check (CoglRenderer *renderer, - const char *driver_prefix, - const CoglFeatureData *data, - int gl_major, - int gl_minor, - CoglDriver driver, - char * const *extensions, - void *function_table) - -{ - const char *suffix = NULL; - int func_num; - CoglExtGlesAvailability gles_availability = 0; - gboolean in_core; - - switch (driver) - { - case COGL_DRIVER_GLES2: - gles_availability = COGL_EXT_IN_GLES2; - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0)) - gles_availability |= COGL_EXT_IN_GLES3; - break; - case COGL_DRIVER_ANY: - g_assert_not_reached (); - case COGL_DRIVER_NOP: - case COGL_DRIVER_GL: - case COGL_DRIVER_GL3: - break; - } - - /* First check whether the functions should be directly provided by - GL */ - if (((driver == COGL_DRIVER_GL || - driver == COGL_DRIVER_GL3) && - COGL_CHECK_GL_VERSION (gl_major, gl_minor, - data->min_gl_major, data->min_gl_minor)) || - (data->gles_availability & gles_availability)) - { - suffix = ""; - in_core = TRUE; - } - else - { - /* Otherwise try all of the extensions */ - const char *namespace, *namespace_suffix; - unsigned int namespace_len; - - for (namespace = data->namespaces; - *namespace; - namespace += strlen (namespace) + 1) - { - const char *extension; - GString *full_extension_name = g_string_new (""); - - /* If the namespace part contains a ':' then the suffix for - the function names is different from the name space */ - if ((namespace_suffix = strchr (namespace, ':'))) - { - namespace_len = namespace_suffix - namespace; - namespace_suffix++; - } - else - { - namespace_len = strlen (namespace); - namespace_suffix = namespace; - } - - for (extension = data->extension_names; - *extension; - extension += strlen (extension) + 1) - { - g_string_assign (full_extension_name, driver_prefix); - g_string_append_c (full_extension_name, '_'); - g_string_append_len (full_extension_name, - namespace, namespace_len); - g_string_append_c (full_extension_name, '_'); - g_string_append (full_extension_name, extension); - if (_cogl_check_extension (full_extension_name->str, - extensions)) - break; - } - - g_string_free (full_extension_name, TRUE); - - /* If we found an extension with this namespace then use it - as the suffix */ - if (*extension) - { - suffix = namespace_suffix; - break; - } - } - - in_core = FALSE; - } - - /* If we couldn't find anything that provides the functions then - give up */ - if (suffix == NULL) - goto error; - - /* Try to get all of the entry points */ - for (func_num = 0; data->functions[func_num].name; func_num++) - { - void *func; - char *full_function_name; - - full_function_name = g_strconcat (data->functions[func_num].name, - suffix, NULL); - func = _cogl_renderer_get_proc_address (renderer, - full_function_name, - in_core); - g_free (full_function_name); - - if (func == NULL) - goto error; - - /* Set the function pointer in the context */ - *(void **) ((uint8_t *) function_table + - data->functions[func_num].pointer_offset) = func; - } - - return TRUE; - - /* If the extension isn't found or one of the functions wasn't found - * then set all of the functions pointers to NULL so Cogl can safely - * do feature testing by just looking at the function pointers */ -error: - for (func_num = 0; data->functions[func_num].name; func_num++) - *(void **) ((uint8_t *) function_table + - data->functions[func_num].pointer_offset) = NULL; - - return FALSE; -} - -/* Define a set of arrays containing the functions required from GL - for each feature */ -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - namespaces, extension_names) \ - static const CoglFeatureFunction cogl_ext_ ## name ## _funcs[] = { -#define COGL_EXT_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglContext, name) }, -#define COGL_EXT_END() \ - { NULL, 0 }, \ - }; -#include "gl-prototypes/cogl-all-functions.h" - -/* Define an array of features */ -#undef COGL_EXT_BEGIN -#define COGL_EXT_BEGIN(name, \ - min_gl_major, min_gl_minor, \ - gles_availability, \ - namespaces, extension_names) \ - { min_gl_major, min_gl_minor, gles_availability, namespaces, \ - extension_names, 0, 0, \ - cogl_ext_ ## name ## _funcs }, -#undef COGL_EXT_FUNCTION -#define COGL_EXT_FUNCTION(ret, name, args) -#undef COGL_EXT_END -#define COGL_EXT_END() - -static const CoglFeatureData -cogl_feature_ext_functions_data[] = - { -#include "gl-prototypes/cogl-all-functions.h" - }; - -void -_cogl_feature_check_ext_functions (CoglContext *context, - int gl_major, - int gl_minor, - char * const *gl_extensions) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (cogl_feature_ext_functions_data); i++) - _cogl_feature_check (context->display->renderer, - "GL", cogl_feature_ext_functions_data + i, - gl_major, gl_minor, context->driver, - gl_extensions, - context); -} diff --git a/cogl/cogl/cogl-feature-private.h b/cogl/cogl/cogl-feature-private.h deleted file mode 100644 index 35ec08953..000000000 --- a/cogl/cogl/cogl-feature-private.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_FEATURE_PRIVATE_H -#define __COGL_FEATURE_PRIVATE_H - -#include <glib.h> - -#include "cogl-context.h" -#include "cogl-renderer.h" - -#define COGL_CHECK_GL_VERSION(driver_major, driver_minor, \ - target_major, target_minor) \ - ((driver_major) > (target_major) || \ - ((driver_major) == (target_major) && (driver_minor) >= (target_minor))) - -typedef enum -{ - COGL_EXT_IN_GL = (1 << 0), - COGL_EXT_IN_GLES2 = (1 << 1), - COGL_EXT_IN_GLES3 = (1 << 2) -} CoglExtGlesAvailability; - -typedef struct _CoglFeatureFunction CoglFeatureFunction; - -struct _CoglFeatureFunction -{ - /* The name of the function without the "EXT" or "ARB" suffix */ - const char *name; - /* The offset in the context of where to store the function pointer */ - unsigned int pointer_offset; -}; - -typedef struct _CoglFeatureData CoglFeatureData; - -struct _CoglFeatureData -{ - /* A minimum GL version which the functions should be defined in - without needing an extension. Set to 255,255 if it's only - provided in an extension */ - int min_gl_major, min_gl_minor; - /* Flags specifying which versions of GLES the feature is available - in core in */ - CoglExtGlesAvailability gles_availability; - /* \0 separated list of namespaces to try. Eg "EXT\0ARB\0" */ - const char *namespaces; - /* \0 separated list of required extension names without the GL_EXT - or GL_ARB prefix. Any of the extensions must be available for the - feature to be considered available. If the suffix for an - extension is different from the namespace, you can specify it - with a ':' after the namespace */ - const char *extension_names; - /* A set of private feature flags to enable if the extension is - * available */ - int feature_flags_private; - /* An optional corresponding winsys feature. */ - CoglWinsysFeature winsys_feature; - /* A list of functions required for this feature. Terminated with a - NULL name */ - const CoglFeatureFunction *functions; -}; - -gboolean -_cogl_feature_check (CoglRenderer *renderer, - const char *driver_prefix, - const CoglFeatureData *data, - int gl_major, - int gl_minor, - CoglDriver driver, - char * const *extensions, - void *function_table); - -void -_cogl_feature_check_ext_functions (CoglContext *context, - int gl_major, - int gl_minor, - char * const *gl_extensions); - -#endif /* __COGL_FEATURE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-fence-private.h b/cogl/cogl/cogl-fence-private.h deleted file mode 100644 index d2fe839f3..000000000 --- a/cogl/cogl/cogl-fence-private.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_FENCE_PRIVATE_H__ -#define __COGL_FENCE_PRIVATE_H__ - -#include "cogl-fence.h" -#include "cogl-list.h" -#include "winsys/cogl-winsys-private.h" - -typedef enum -{ - FENCE_TYPE_PENDING, -#ifdef GL_ARB_sync - FENCE_TYPE_GL_ARB, -#endif - FENCE_TYPE_WINSYS, - FENCE_TYPE_ERROR -} CoglFenceType; - -struct _CoglFenceClosure -{ - CoglList link; - CoglFramebuffer *framebuffer; - - CoglFenceType type; - void *fence_obj; - - CoglFenceCallback callback; - void *user_data; -}; - -void -_cogl_fence_submit (CoglFenceClosure *fence); - -void -_cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer); - -#endif /* __COGL_FENCE_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-fence.c b/cogl/cogl/cogl-fence.c deleted file mode 100644 index b2fcd148a..000000000 --- a/cogl/cogl/cogl-fence.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "cogl-fence.h" -#include "cogl-fence-private.h" -#include "cogl-context-private.h" -#include "winsys/cogl-winsys-private.h" - -#define FENCE_CHECK_TIMEOUT 5000 /* microseconds */ - -void * -cogl_fence_closure_get_user_data (CoglFenceClosure *closure) -{ - return closure->user_data; -} - -static void -_cogl_fence_check (CoglFenceClosure *fence) -{ - CoglContext *context = cogl_framebuffer_get_context (fence->framebuffer); - - if (fence->type == FENCE_TYPE_WINSYS) - { - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - gboolean ret; - - ret = winsys->fence_is_complete (context, fence->fence_obj); - if (!ret) - return; - } -#ifdef GL_ARB_sync - else if (fence->type == FENCE_TYPE_GL_ARB) - { - GLenum arb; - - arb = context->glClientWaitSync (fence->fence_obj, - GL_SYNC_FLUSH_COMMANDS_BIT, - 0); - if (arb != GL_ALREADY_SIGNALED && arb != GL_CONDITION_SATISFIED) - return; - } -#endif - - fence->callback (NULL, /* dummy CoglFence object */ - fence->user_data); - cogl_framebuffer_cancel_fence_callback (fence->framebuffer, fence); -} - -static void -_cogl_fence_poll_dispatch (void *source, int revents) -{ - CoglContext *context = source; - CoglFenceClosure *fence, *tmp; - - _cogl_list_for_each_safe (fence, tmp, &context->fences, link) - _cogl_fence_check (fence); -} - -static int64_t -_cogl_fence_poll_prepare (void *source) -{ - CoglContext *context = source; - GList *l; - - /* If there are any pending fences in any of the journals then we - * need to flush the journal otherwise the fence will never be - * hit and the main loop might block forever */ - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer); - - if (!_cogl_list_empty (&journal->pending_fences)) - _cogl_framebuffer_flush_journal (framebuffer); - } - - if (!_cogl_list_empty (&context->fences)) - return FENCE_CHECK_TIMEOUT; - else - return -1; -} - -void -_cogl_fence_submit (CoglFenceClosure *fence) -{ - CoglContext *context = cogl_framebuffer_get_context (fence->framebuffer); - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - fence->type = FENCE_TYPE_ERROR; - - if (winsys->fence_add) - { - fence->fence_obj = winsys->fence_add (context); - if (fence->fence_obj) - { - fence->type = FENCE_TYPE_WINSYS; - goto done; - } - } - -#ifdef GL_ARB_sync - if (context->glFenceSync) - { - fence->fence_obj = context->glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, - 0); - if (fence->fence_obj) - { - fence->type = FENCE_TYPE_GL_ARB; - goto done; - } - } -#endif - - done: - _cogl_list_insert (context->fences.prev, &fence->link); - - if (!context->fences_poll_source) - { - context->fences_poll_source = - _cogl_poll_renderer_add_source (context->display->renderer, - _cogl_fence_poll_prepare, - _cogl_fence_poll_dispatch, - context); - } -} - -CoglFenceClosure * -cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceCallback callback, - void *user_data) -{ - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer); - CoglFenceClosure *fence; - - if (!COGL_FLAGS_GET (context->features, COGL_FEATURE_ID_FENCE)) - return NULL; - - fence = g_new0 (CoglFenceClosure, 1); - fence->framebuffer = framebuffer; - fence->callback = callback; - fence->user_data = user_data; - fence->fence_obj = NULL; - - if (journal->entries->len) - { - _cogl_list_insert (journal->pending_fences.prev, &fence->link); - fence->type = FENCE_TYPE_PENDING; - } - else - _cogl_fence_submit (fence); - - return fence; -} - -void -cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceClosure *fence) -{ - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - - if (fence->type == FENCE_TYPE_PENDING) - { - _cogl_list_remove (&fence->link); - } - else - { - _cogl_list_remove (&fence->link); - - if (fence->type == FENCE_TYPE_WINSYS) - { - const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context); - - winsys->fence_destroy (context, fence->fence_obj); - } -#ifdef GL_ARB_sync - else if (fence->type == FENCE_TYPE_GL_ARB) - { - context->glDeleteSync (fence->fence_obj); - } -#endif - } - - g_free (fence); -} - -void -_cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer) -{ - CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglFenceClosure *fence, *tmp; - - while (!_cogl_list_empty (&journal->pending_fences)) - { - fence = _cogl_container_of (journal->pending_fences.next, - CoglFenceClosure, - link); - cogl_framebuffer_cancel_fence_callback (framebuffer, fence); - } - - _cogl_list_for_each_safe (fence, tmp, &context->fences, link) - { - if (fence->framebuffer == framebuffer) - cogl_framebuffer_cancel_fence_callback (framebuffer, fence); - } -} diff --git a/cogl/cogl/cogl-fence.h b/cogl/cogl/cogl-fence.h deleted file mode 100644 index 22cb88e1f..000000000 --- a/cogl/cogl/cogl-fence.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_FENCE_H__ -#define __COGL_FENCE_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-framebuffer.h> - -/** - * SECTION:cogl-fence - * @short_description: Functions for notification of command completion - * - * Cogl allows notification of GPU command completion; users may mark - * points in the GPU command stream and receive notification when the GPU - * has executed to that point. - */ - -/** - * CoglFence: - * - * An opaque object representing a fence. This type is currently - * unused but in the future may be used to pass extra information - * about the fence completion. - * - * Since: 2.0 - * Stability: Unstable - */ -typedef struct _CoglFence CoglFence; - -/** - * CoglFenceCallback: - * @fence: Unused. In the future this parameter may be used to pass - * extra information about the fence completion but for now it - * should be ignored. - * @user_data: The private data passed to cogl_framebuffer_add_fence_callback() - * - * The callback prototype used with - * cogl_framebuffer_add_fence_callback() for notification of GPU - * command completion. - * - * Since: 2.0 - * Stability: Unstable - */ -typedef void (* CoglFenceCallback) (CoglFence *fence, - void *user_data); - -/** - * CoglFenceClosure: - * - * An opaque type representing one future callback to be made when the - * GPU command stream has passed a certain point. - * - * Since: 2.0 - * Stability: Unstable - */ -typedef struct _CoglFenceClosure CoglFenceClosure; - -/** - * cogl_frame_closure_get_user_data: - * @closure: A #CoglFenceClosure returned from cogl_framebuffer_add_fence() - * - * Returns the user_data submitted to cogl_framebuffer_add_fence() which - * returned a given #CoglFenceClosure. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void * -cogl_fence_closure_get_user_data (CoglFenceClosure *closure); - -/** - * cogl_framebuffer_add_fence_callback: - * @framebuffer: The #CoglFramebuffer the commands have been submitted to - * @callback: (scope notified): A #CoglFenceCallback to be called when - * all commands submitted to Cogl have been executed - * @user_data: (closure): Private data that will be passed to the callback - * - * Calls the provided callback when all previously-submitted commands have - * been executed by the GPU. - * - * Returns non-NULL if the fence succeeded, or %NULL if it was unable to - * be inserted and the callback will never be called. The user does not - * need to free the closure; it will be freed automatically when the - * callback is called, or cancelled. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT CoglFenceClosure * -cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceCallback callback, - void *user_data); - -/** - * cogl_framebuffer_cancel_fence_callback: - * @framebuffer: The #CoglFramebuffer the commands were submitted to - * @closure: The #CoglFenceClosure returned from - * cogl_framebuffer_add_fence_callback() - * - * Removes a fence previously submitted with - * cogl_framebuffer_add_fence_callback(); the callback will not be - * called. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer, - CoglFenceClosure *closure); - -#endif /* __COGL_FENCE_H__ */ diff --git a/cogl/cogl/cogl-flags.h b/cogl/cogl/cogl-flags.h deleted file mode 100644 index 773818dcb..000000000 --- a/cogl/cogl/cogl-flags.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#ifndef __COGL_FLAGS_H -#define __COGL_FLAGS_H - -#include <glib.h> - -#include "cogl-util.h" - -G_BEGIN_DECLS - -/* These are macros used to implement a fixed-size array of bits. This - should be used instead of CoglBitmask when the maximum bit number - that will be set is known at compile time, for example when setting - for recording a set of known available features */ - -/* The bits are stored in an array of unsigned longs. To use these - macros, you would typically have an enum defining the available - bits with an extra last enum to define the maximum value. Then to - store the flags you would declare an array of unsigned longs sized - using COGL_FLAGS_N_LONGS_FOR_SIZE, eg: - - typedef enum { FEATURE_A, FEATURE_B, FEATURE_C, N_FEATURES } Features; - - unsigned long feature_flags[COGL_FLAGS_N_LONGS_FOR_SIZE (N_FEATURES)]; -*/ - -#define COGL_FLAGS_N_LONGS_FOR_SIZE(size) \ - (((size) + \ - (sizeof (unsigned long) * 8 - 1)) \ - / (sizeof (unsigned long) * 8)) - -/* @flag is expected to be constant so these should result in a - constant expression. This means that setting a flag is equivalent - to just setting in a bit in a global variable at a known - location */ -#define COGL_FLAGS_GET_INDEX(flag) \ - ((flag) / (sizeof (unsigned long) * 8)) -#define COGL_FLAGS_GET_MASK(flag) \ - (1UL << ((unsigned long) (flag) & \ - (sizeof (unsigned long) * 8 - 1))) - -#define COGL_FLAGS_GET(array, flag) \ - (!!((array)[COGL_FLAGS_GET_INDEX (flag)] & \ - COGL_FLAGS_GET_MASK (flag))) - -/* The expectation here is that @value will be constant so the if - statement will be optimised out */ -#define COGL_FLAGS_SET(array, flag, value) \ - G_STMT_START { \ - if (value) \ - ((array)[COGL_FLAGS_GET_INDEX (flag)] |= \ - COGL_FLAGS_GET_MASK (flag)); \ - else \ - ((array)[COGL_FLAGS_GET_INDEX (flag)] &= \ - ~COGL_FLAGS_GET_MASK (flag)); \ - } G_STMT_END - -/* Macros to help iterate an array of flags. It should be used like - * this: - * - * int n_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (...); - * unsigned long flags[n_longs]; - * int bit_num; - * - * COGL_FLAGS_FOREACH_START (flags, n_longs, bit_num) - * { - * do_something_with_the_bit (bit_num); - * } - * COGL_FLAGS_FOREACH_END; - */ -#define COGL_FLAGS_FOREACH_START(array, n_longs, bit) \ - G_STMT_START { \ - const unsigned long *_p = (array); \ - int _n_longs = (n_longs); \ - int _i; \ - \ - for (_i = 0; _i < _n_longs; _i++) \ - { \ - unsigned long _mask = *(_p++); \ - \ - (bit) = _i * sizeof (unsigned long) * 8 - 1; \ - \ - while (_mask) \ - { \ - int _next_bit = _cogl_util_ffsl (_mask); \ - (bit) += _next_bit; \ - /* This odd two-part shift is to avoid */ \ - /* shifting by sizeof (long)*8 which has */ \ - /* undefined results according to the */ \ - /* C spec (and seems to be a no-op in */ \ - /* practice) */ \ - _mask = (_mask >> (_next_bit - 1)) >> 1; \ - -#define COGL_FLAGS_FOREACH_END \ - } } } G_STMT_END - -G_END_DECLS - -#endif /* __COGL_FLAGS_H */ - diff --git a/cogl/cogl/cogl-frame-info-private.h b/cogl/cogl/cogl-frame-info-private.h deleted file mode 100644 index 2a59288d1..000000000 --- a/cogl/cogl/cogl-frame-info-private.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_FRAME_INFO_PRIVATE_H -#define __COGL_FRAME_INFO_PRIVATE_H - -#include "cogl-frame-info.h" -#include "cogl-object-private.h" -#include "cogl-context.h" - -typedef enum _CoglFrameInfoFlag -{ - COGL_FRAME_INFO_FLAG_NONE = 0, - COGL_FRAME_INFO_FLAG_SYMBOLIC = 1 << 0, - /* presentation_time timestamp was provided by the hardware */ - COGL_FRAME_INFO_FLAG_HW_CLOCK = 1 << 1, - /* - * The presentation of this frame was done zero-copy. This means the buffer - * from the client was given to display hardware as is, without copying it. - * Compositing with OpenGL counts as copying, even if textured directly from - * the client buffer. Possible zero-copy cases include direct scanout of a - * fullscreen surface and a surface on a hardware overlay. - */ - COGL_FRAME_INFO_FLAG_ZERO_COPY = 1 << 2, - /* - * The presentation was synchronized to the "vertical retrace" by the display - * hardware such that tearing does not happen. Relying on user space - * scheduling is not acceptable for this flag. If presentation is done by a - * copy to the active frontbuffer, then it must guarantee that tearing cannot - * happen. - */ - COGL_FRAME_INFO_FLAG_VSYNC = 1 << 3, -} CoglFrameInfoFlag; - -struct _CoglFrameInfo -{ - CoglObject _parent; - - CoglContext *context; - - int64_t frame_counter; - int64_t presentation_time_us; /* CLOCK_MONOTONIC */ - float refresh_rate; - - int64_t global_frame_counter; - - CoglFrameInfoFlag flags; - - unsigned int sequence; - - CoglTimestampQuery *timestamp_query; - int64_t gpu_time_before_buffer_swap_ns; - int64_t cpu_time_before_buffer_swap_us; -}; - -COGL_EXPORT -CoglFrameInfo *cogl_frame_info_new (CoglContext *context, - int64_t global_frame_counter); - -#endif /* __COGL_FRAME_INFO_PRIVATE_H */ diff --git a/cogl/cogl/cogl-frame-info.c b/cogl/cogl/cogl-frame-info.c deleted file mode 100644 index adaf2bad9..000000000 --- a/cogl/cogl/cogl-frame-info.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-frame-info-private.h" -#include "cogl-gtype-private.h" -#include "cogl-context-private.h" - -static void _cogl_frame_info_free (CoglFrameInfo *info); - -COGL_OBJECT_DEFINE (FrameInfo, frame_info); -COGL_GTYPE_DEFINE_CLASS (FrameInfo, frame_info); - -CoglFrameInfo * -cogl_frame_info_new (CoglContext *context, - int64_t global_frame_counter) -{ - CoglFrameInfo *info; - - info = g_new0 (CoglFrameInfo, 1); - info->context = context; - info->global_frame_counter = global_frame_counter; - - return _cogl_frame_info_object_new (info); -} - -static void -_cogl_frame_info_free (CoglFrameInfo *info) -{ - if (info->timestamp_query) - cogl_context_free_timestamp_query (info->context, info->timestamp_query); - - g_free (info); -} - -int64_t -cogl_frame_info_get_frame_counter (CoglFrameInfo *info) -{ - return info->frame_counter; -} - -int64_t -cogl_frame_info_get_presentation_time_us (CoglFrameInfo *info) -{ - g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); - - return info->presentation_time_us; -} - -float -cogl_frame_info_get_refresh_rate (CoglFrameInfo *info) -{ - g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); - - return info->refresh_rate; -} - -int64_t -cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info) -{ - return info->global_frame_counter; -} - -gboolean -cogl_frame_info_get_is_symbolic (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC); -} - -gboolean -cogl_frame_info_is_hw_clock (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_HW_CLOCK); -} - -gboolean -cogl_frame_info_is_zero_copy (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_ZERO_COPY); -} - -gboolean -cogl_frame_info_is_vsync (CoglFrameInfo *info) -{ - return !!(info->flags & COGL_FRAME_INFO_FLAG_VSYNC); -} - -unsigned int -cogl_frame_info_get_sequence (CoglFrameInfo *info) -{ - g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC)); - - return info->sequence; -} - -int64_t -cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info) -{ - int64_t gpu_time_rendering_done_ns; - - if (!info->timestamp_query || - info->gpu_time_before_buffer_swap_ns == 0) - return 0; - - gpu_time_rendering_done_ns = - cogl_context_timestamp_query_get_time_ns (info->context, - info->timestamp_query); - - return gpu_time_rendering_done_ns - info->gpu_time_before_buffer_swap_ns; -} - -int64_t -cogl_frame_info_get_time_before_buffer_swap_us (CoglFrameInfo *info) -{ - return info->cpu_time_before_buffer_swap_us; -} diff --git a/cogl/cogl/cogl-frame-info.h b/cogl/cogl/cogl-frame-info.h deleted file mode 100644 index c0ff12bc1..000000000 --- a/cogl/cogl/cogl-frame-info.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Owen Taylor <otaylor@redhat.com> - */ -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_FRAME_INFO_H -#define __COGL_FRAME_INFO_H - -#include <cogl/cogl-types.h> -#include <cogl/cogl-output.h> - -#include <glib-object.h> -#include <glib.h> - -G_BEGIN_DECLS - -/** - * CoglFrameInfo: - * - * Frame information. - */ -typedef struct _CoglFrameInfo CoglFrameInfo; -#define COGL_FRAME_INFO(X) ((CoglFrameInfo *)(X)) - -/** - * cogl_frame_info_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_frame_info_get_gtype (void); - -/** - * cogl_is_frame_info: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglFrameInfo. - * - * Return value: %TRUE if the object references a #CoglFrameInfo - * and %FALSE otherwise. - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_frame_info (void *object); - -/** - * cogl_frame_info_get_frame_counter: - * @info: a #CoglFrameInfo object - * - * Gets the frame counter for the #CoglOnscreen that corresponds - * to this frame. - * - * Return value: The frame counter value - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT -int64_t cogl_frame_info_get_frame_counter (CoglFrameInfo *info); - -/** - * cogl_frame_info_get_presentation_time_us: - * @info: a #CoglFrameInfo object - * - * Gets the presentation time for the frame. This is the time at which - * the frame became visible to the user. - * - * The presentation time measured in microseconds, is based on - * CLOCK_MONOTONIC. - * - * <note>Some buggy Mesa drivers up to 9.0.1 may - * incorrectly report non-monotonic timestamps.</note> - * - * Return value: the presentation time for the frame - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT -int64_t cogl_frame_info_get_presentation_time_us (CoglFrameInfo *info); - -/** - * cogl_frame_info_get_refresh_rate: - * @info: a #CoglFrameInfo object - * - * Gets the refresh rate in Hertz for the output that the frame was on - * at the time the frame was presented. - * - * <note>Some platforms can't associate a #CoglOutput with a - * #CoglFrameInfo object but are able to report a refresh rate via - * this api. Therefore if you need this information then this api is - * more reliable than using cogl_frame_info_get_output() followed by - * cogl_output_get_refresh_rate().</note> - * - * Return value: the refresh rate in Hertz - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT -float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info); - -/** - * cogl_frame_info_get_global_frame_counter: (skip) - */ -COGL_EXPORT -int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_get_is_symbolic (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_is_hw_clock (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_is_zero_copy (CoglFrameInfo *info); - -COGL_EXPORT -gboolean cogl_frame_info_is_vsync (CoglFrameInfo *info); - -COGL_EXPORT -unsigned int cogl_frame_info_get_sequence (CoglFrameInfo *info); - -COGL_EXPORT -int64_t cogl_frame_info_get_rendering_duration_ns (CoglFrameInfo *info); - -COGL_EXPORT -int64_t cogl_frame_info_get_time_before_buffer_swap_us (CoglFrameInfo *info); - -G_END_DECLS - -#endif /* __COGL_FRAME_INFO_H */ diff --git a/cogl/cogl/cogl-framebuffer-driver.c b/cogl/cogl/cogl-framebuffer-driver.c deleted file mode 100644 index bd99a795d..000000000 --- a/cogl/cogl/cogl-framebuffer-driver.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "cogl-framebuffer-driver.h" - -enum -{ - PROP_0, - - PROP_FRAMEBUFFER, - - N_PROPS -}; - -static GParamSpec *obj_props[N_PROPS]; - -typedef struct _CoglFramebufferDriverPrivate -{ - CoglFramebuffer *framebuffer; -} CoglFramebufferDriverPrivate; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebufferDriver, - cogl_framebuffer_driver, - G_TYPE_OBJECT) - -CoglFramebuffer * -cogl_framebuffer_driver_get_framebuffer (CoglFramebufferDriver *driver) -{ - CoglFramebufferDriverPrivate *priv = - cogl_framebuffer_driver_get_instance_private (driver); - - return priv->framebuffer; -} - -void -cogl_framebuffer_driver_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->query_bits (driver, bits); -} - -void -cogl_framebuffer_driver_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->clear (driver, - buffers, - red, - green, - blue, - alpha); -} - -void -cogl_framebuffer_driver_finish (CoglFramebufferDriver *driver) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->finish (driver); -} - -void -cogl_framebuffer_driver_flush (CoglFramebufferDriver *driver) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->flush (driver); -} - -void -cogl_framebuffer_driver_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->discard_buffers (driver, buffers); -} - -void -cogl_framebuffer_driver_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver)->draw_attributes (driver, - pipeline, - mode, - first_vertex, - n_vertices, - attributes, - n_attributes, - flags); -} - -void -cogl_framebuffer_driver_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebufferDriverClass *klass = - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver); - - klass->draw_indexed_attributes (driver, - pipeline, - mode, - first_vertex, - n_vertices, - indices, - attributes, - n_attributes, - flags); -} - -gboolean -cogl_framebuffer_driver_read_pixels_into_bitmap (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - CoglFramebufferDriverClass *klass = - COGL_FRAMEBUFFER_DRIVER_GET_CLASS (driver); - - return klass->read_pixels_into_bitmap (driver, x, y, source, bitmap, error); -} - -static void -cogl_framebuffer_driver_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (object); - CoglFramebufferDriverPrivate *priv = - cogl_framebuffer_driver_get_instance_private (driver); - - switch (prop_id) - { - case PROP_FRAMEBUFFER: - g_value_set_object (value, priv->framebuffer); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_driver_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (object); - CoglFramebufferDriverPrivate *priv = - cogl_framebuffer_driver_get_instance_private (driver); - - switch (prop_id) - { - case PROP_FRAMEBUFFER: - priv->framebuffer = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_driver_init (CoglFramebufferDriver *driver) -{ -} - -static void -cogl_framebuffer_driver_class_init (CoglFramebufferDriverClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = cogl_framebuffer_driver_get_property; - object_class->set_property = cogl_framebuffer_driver_set_property; - - obj_props[PROP_FRAMEBUFFER] = - g_param_spec_object ("framebuffer", - "framebuffer", - "CoglFramebuffer", - COGL_TYPE_FRAMEBUFFER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - g_object_class_install_properties (object_class, N_PROPS, obj_props); -} diff --git a/cogl/cogl/cogl-framebuffer-driver.h b/cogl/cogl/cogl-framebuffer-driver.h deleted file mode 100644 index d8815234b..000000000 --- a/cogl/cogl/cogl-framebuffer-driver.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef COGL_FRAMEBUFFER_DRIVER_H -#define COGL_FRAMEBUFFER_DRIVER_H - -#include "cogl-attribute-private.h" -#include "cogl-framebuffer.h" - -typedef struct _CoglFramebufferBits CoglFramebufferBits; - -#define COGL_TYPE_FRAMEBUFFER_DRIVER (cogl_framebuffer_driver_get_type ()) -G_DECLARE_DERIVABLE_TYPE (CoglFramebufferDriver, - cogl_framebuffer_driver, - COGL, FRAMEBUFFER_DRIVER, - GObject) - -struct _CoglFramebufferDriverClass -{ - GObjectClass parent_cleass; - - void (* query_bits) (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits); - - void (* clear) (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - - void (* finish) (CoglFramebufferDriver *driver); - - void (* flush) (CoglFramebufferDriver *driver); - - void (* discard_buffers) (CoglFramebufferDriver *driver, - unsigned long buffers); - - void (* draw_attributes) (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - - void (* draw_indexed_attributes) (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - - gboolean (* read_pixels_into_bitmap) (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error); -}; - -CoglFramebuffer * -cogl_framebuffer_driver_get_framebuffer (CoglFramebufferDriver *driver); - -void -cogl_framebuffer_driver_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits); - -void -cogl_framebuffer_driver_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -void -cogl_framebuffer_driver_finish (CoglFramebufferDriver *driver); - -void -cogl_framebuffer_driver_flush (CoglFramebufferDriver *driver); - -void -cogl_framebuffer_driver_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers); - -void -cogl_framebuffer_driver_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - -void -cogl_framebuffer_driver_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - -gboolean -cogl_framebuffer_driver_read_pixels_into_bitmap (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error); - -#endif /* COGL_FRAMEBUFFER_DRIVER_H */ diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h deleted file mode 100644 index 523647819..000000000 --- a/cogl/cogl/cogl-framebuffer-private.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_FRAMEBUFFER_PRIVATE_H -#define __COGL_FRAMEBUFFER_PRIVATE_H - -#include "cogl-framebuffer-driver.h" -#include "cogl-object-private.h" -#include "cogl-matrix-stack-private.h" -#include "cogl-journal-private.h" -#include "winsys/cogl-winsys-private.h" -#include "cogl-attribute-private.h" -#include "cogl-clip-stack.h" - -typedef enum -{ - COGL_FRAMEBUFFER_DRIVER_TYPE_FBO, - COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, -} CoglFramebufferDriverType; - -struct _CoglFramebufferDriverConfig -{ - CoglFramebufferDriverType type; - - gboolean disable_depth_and_stencil; -}; - -typedef struct -{ - CoglSwapChain *swap_chain; - gboolean need_stencil; - int samples_per_pixel; - gboolean stereo_enabled; -} CoglFramebufferConfig; - -/* XXX: The order of these indices determines the order they are - * flushed. - * - * Flushing clip state may trash the modelview and projection matrices - * so we must do it before flushing the matrices. - */ -typedef enum _CoglFramebufferStateIndex -{ - COGL_FRAMEBUFFER_STATE_INDEX_BIND = 0, - COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT = 1, - COGL_FRAMEBUFFER_STATE_INDEX_CLIP = 2, - COGL_FRAMEBUFFER_STATE_INDEX_DITHER = 3, - COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW = 4, - COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5, - COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 6, - COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 7, - COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE = 8, - COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9 -} CoglFramebufferStateIndex; - -typedef enum _CoglFramebufferState -{ - COGL_FRAMEBUFFER_STATE_BIND = 1<<0, - COGL_FRAMEBUFFER_STATE_VIEWPORT = 1<<1, - COGL_FRAMEBUFFER_STATE_CLIP = 1<<2, - COGL_FRAMEBUFFER_STATE_DITHER = 1<<3, - COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4, - COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5, - COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<6, - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<7, - COGL_FRAMEBUFFER_STATE_STEREO_MODE = 1<<8 -} CoglFramebufferState; - -#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1) - -/* Private flags that can internally be added to CoglReadPixelsFlags */ -typedef enum -{ - /* If this is set then the data will not be flipped to compensate - for GL's upside-down coordinate system but instead will be left - in whatever order GL gives us (which will depend on whether the - framebuffer is offscreen or not) */ - COGL_READ_PIXELS_NO_FLIP = 1L << 30 -} CoglPrivateReadPixelsFlags; - -typedef struct _CoglFramebufferBits -{ - int red; - int blue; - int green; - int alpha; - int depth; - int stencil; -} CoglFramebufferBits; - -gboolean -cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer); - -void -cogl_framebuffer_init_config (CoglFramebuffer *framebuffer, - const CoglFramebufferConfig *config); - -const CoglFramebufferConfig * -cogl_framebuffer_get_config (CoglFramebuffer *framebuffer); - -void -cogl_framebuffer_update_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel); - -void -cogl_framebuffer_update_size (CoglFramebuffer *framebuffer, - int width, - int height); - -/* XXX: For a public api we might instead want a way to explicitly - * set the _premult status of a framebuffer or what components we - * care about instead of exposing the CoglPixelFormat - * internal_format. - * - * The current use case for this api is where we create an offscreen - * framebuffer for a shared atlas texture that has a format of - * RGBA_8888 disregarding the premultiplied alpha status for - * individual atlased textures or whether the alpha component is being - * discarded. We want to overried the internal_format that will be - * derived from the texture. - */ -void -_cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer, - CoglPixelFormat internal_format); - -CoglPixelFormat -cogl_framebuffer_get_internal_format (CoglFramebuffer *framebuffer); - -void _cogl_framebuffer_free (CoglFramebuffer *framebuffer); - -const CoglWinsysVtable * -_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -void -_cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer); - -void -cogl_framebuffer_set_depth_buffer_clear_needed (CoglFramebuffer *framebuffer); - -/* - * _cogl_framebuffer_get_clip_stack: - * @framebuffer: A #CoglFramebuffer - * - * Gets a pointer to the current clip stack. A reference is not taken on the - * stack so if you want to keep it you should call - * _cogl_clip_stack_ref(). - * - * Return value: a pointer to the @framebuffer clip stack. - */ -CoglClipStack * -_cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer); - -COGL_EXPORT CoglMatrixStack * -_cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer); - -COGL_EXPORT CoglMatrixStack * -_cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer, - CoglFramebuffer *dependency); - -void -_cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer); - -void -cogl_context_flush_framebuffer_state (CoglContext *context, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state); - -CoglFramebuffer * -_cogl_get_read_framebuffer (void); - -GSList * -_cogl_create_framebuffer_stack (void); - -void -_cogl_free_framebuffer_stack (GSList *stack); - -void -_cogl_framebuffer_save_clip_stack (CoglFramebuffer *framebuffer); - -void -_cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer); - -/* This can be called directly by the CoglJournal to draw attributes - * skipping the implicit journal flush, the framebuffer flush and - * pipeline validation. */ -void -_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - -void -_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags); - -void -cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport); - -void -cogl_framebuffer_get_viewport4f (CoglFramebuffer *framebuffer, - float *viewport_x, - float *viewport_y, - float *viewport_width, - float *viewport_height); - -unsigned long -_cogl_framebuffer_compare (CoglFramebuffer *a, - CoglFramebuffer *b, - unsigned long state); - -static inline CoglMatrixEntry * -_cogl_framebuffer_get_modelview_entry (CoglFramebuffer *framebuffer) -{ - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - return modelview_stack->last_entry; -} - -static inline CoglMatrixEntry * -_cogl_framebuffer_get_projection_entry (CoglFramebuffer *framebuffer) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - return projection_stack->last_entry; -} - -gboolean -_cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error); - -/* - * _cogl_framebuffer_get_stencil_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of stencil bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT int -_cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer); - -CoglJournal * -cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer); - -CoglFramebufferDriver * -cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_is_y_flipped: - * @framebuffer: a #CoglFramebuffer - * - * Returns %TRUE if the Y coordinate 0 means the bottom of the framebuffer, and - * %FALSE if the Y coordinate means the top. - */ -gboolean -cogl_framebuffer_is_y_flipped (CoglFramebuffer *framebuffer); - -#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c deleted file mode 100644 index 525b24293..000000000 --- a/cogl/cogl/cogl-framebuffer.c +++ /dev/null @@ -1,2683 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-debug.h" -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-object-private.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-clip-stack.h" -#include "cogl-journal-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-primitive-private.h" -#include "cogl-offscreen.h" -#include "cogl1-context.h" -#include "cogl-private.h" -#include "cogl-primitives-private.h" -#include "cogl-gtype-private.h" -#include "winsys/cogl-winsys-private.h" - -enum -{ - PROP_0, - - PROP_CONTEXT, - PROP_DRIVER_CONFIG, - PROP_WIDTH, - PROP_HEIGHT, - - N_PROPS -}; - -static GParamSpec *obj_props[N_PROPS]; - -enum -{ - DESTROY, - - N_SIGNALS -}; - -static guint signals[N_SIGNALS]; - -#ifdef COGL_ENABLE_DEBUG -static CoglUserDataKey wire_pipeline_key; -#endif - -typedef struct _CoglFramebufferPrivate -{ - CoglContext *context; - - /* The user configuration before allocation... */ - CoglFramebufferConfig config; - - CoglFramebufferDriverConfig driver_config; - CoglFramebufferDriver *driver; - - int width; - int height; - /* Format of the pixels in the framebuffer (including the expected - premult state) */ - CoglPixelFormat internal_format; - gboolean allocated; - - CoglMatrixStack *modelview_stack; - CoglMatrixStack *projection_stack; - float viewport_x; - float viewport_y; - float viewport_width; - float viewport_height; - int viewport_age; - int viewport_age_for_scissor_workaround; - - CoglClipStack *clip_stack; - - gboolean dither_enabled; - gboolean depth_writing_enabled; - CoglStereoMode stereo_mode; - - /* We journal the textured rectangles we want to submit to OpenGL so - * we have an opportunity to batch them together into less draw - * calls. */ - CoglJournal *journal; - - /* The scene of a given framebuffer may depend on images in other - * framebuffers... */ - GList *deps; - - /* As part of an optimization for reading-back single pixels from a - * framebuffer in some simple cases where the geometry is still - * available in the journal we need to track the bounds of the last - * region cleared, its color and we need to track when something - * does in fact draw to that region so it is no longer clear. - */ - float clear_color_red; - float clear_color_green; - float clear_color_blue; - float clear_color_alpha; - int clear_clip_x0; - int clear_clip_y0; - int clear_clip_x1; - int clear_clip_y1; - gboolean clear_clip_dirty; - - int samples_per_pixel; - - /* Whether the depth buffer was enabled for this framebuffer, - * usually means it needs to be cleared before being reused next. - */ - gboolean depth_buffer_clear_needed; -} CoglFramebufferPrivate; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer, - G_TYPE_OBJECT) - -uint32_t -cogl_framebuffer_error_quark (void) -{ - return g_quark_from_static_string ("cogl-framebuffer-error-quark"); -} - -gboolean -cogl_is_framebuffer (void *object) -{ - return COGL_IS_FRAMEBUFFER (object); -} - -static void -cogl_framebuffer_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - switch (prop_id) - { - case PROP_CONTEXT: - g_value_set_boxed (value, priv->context); - break; - case PROP_DRIVER_CONFIG: - g_value_set_pointer (value, &priv->driver_config); - break; - case PROP_WIDTH: - g_value_set_int (value, priv->width); - break; - case PROP_HEIGHT: - g_value_set_int (value, priv->height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglFramebufferDriverConfig *driver_config; - - switch (prop_id) - { - case PROP_CONTEXT: - priv->context = g_value_get_boxed (value); - break; - case PROP_DRIVER_CONFIG: - driver_config = g_value_get_pointer (value); - if (driver_config) - priv->driver_config = *driver_config; - break; - case PROP_WIDTH: - priv->width = g_value_get_int (value); - break; - case PROP_HEIGHT: - priv->height = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -cogl_framebuffer_constructed (GObject *object) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_assert (priv->context); - - priv->internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - priv->viewport_x = 0; - priv->viewport_y = 0; - priv->viewport_width = priv->width; - priv->viewport_height = priv->height; - priv->viewport_age = 0; - priv->viewport_age_for_scissor_workaround = -1; - priv->dither_enabled = TRUE; - priv->depth_writing_enabled = TRUE; - priv->depth_buffer_clear_needed = TRUE; - - priv->modelview_stack = cogl_matrix_stack_new (priv->context); - priv->projection_stack = cogl_matrix_stack_new (priv->context); - - priv->samples_per_pixel = 0; - - priv->clip_stack = NULL; - - priv->journal = _cogl_journal_new (framebuffer); - - /* Ensure we know the framebuffer->clear_color* members can't be - * referenced for our fast-path read-pixel optimization (see - * _cogl_journal_try_read_pixel()) until some region of the - * framebuffer is initialized. - */ - priv->clear_clip_dirty = TRUE; - - /* XXX: We have to maintain a central list of all framebuffers - * because at times we need to be able to flush all known journals. - * - * Examples where we need to flush all journals are: - * - because journal entries can reference OpenGL texture - * coordinates that may not survive texture-atlas reorganization - * so we need the ability to flush those entries. - * - because although we generally advise against modifying - * pipelines after construction we have to handle that possibility - * and since pipelines may be referenced in journal entries we - * need to be able to flush them before allowing the pipelines to - * be changed. - * - * Note we don't maintain a list of journals and associate - * framebuffers with journals by e.g. having a journal->framebuffer - * reference since that would introduce a circular reference. - * - * Note: As a future change to try and remove the need to index all - * journals it might be possible to defer resolving of OpenGL - * texture coordinates for rectangle primitives until we come to - * flush a journal. This would mean for instance that a single - * rectangle entry in a journal could later be expanded into - * multiple quad primitives to handle sliced textures but would mean - * we don't have to worry about retaining references to OpenGL - * texture coordinates that may later become invalid. - */ - priv->context->framebuffers = g_list_prepend (priv->context->framebuffers, - framebuffer); -} - -void -_cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer, - CoglPixelFormat internal_format) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->internal_format = internal_format; -} - -CoglPixelFormat -cogl_framebuffer_get_internal_format (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->internal_format; -} - -const CoglFramebufferConfig * -cogl_framebuffer_get_config (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return &priv->config; -} - -void -cogl_framebuffer_init_config (CoglFramebuffer *framebuffer, - const CoglFramebufferConfig *config) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->config = *config; - cogl_object_ref (priv->config.swap_chain); -} - -static void -cogl_framebuffer_dispose (GObject *object) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglContext *ctx = priv->context; - - if (priv->journal) - { - _cogl_journal_flush (priv->journal); - - g_signal_emit (framebuffer, signals[DESTROY], 0); - - _cogl_fence_cancel_fences_for_framebuffer (framebuffer); - } - - g_clear_pointer (&priv->clip_stack, _cogl_clip_stack_unref); - cogl_clear_object (&priv->modelview_stack); - cogl_clear_object (&priv->projection_stack); - cogl_clear_object (&priv->journal); - - ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer); - - if (ctx->current_draw_buffer == framebuffer) - ctx->current_draw_buffer = NULL; - if (ctx->current_read_buffer == framebuffer) - ctx->current_read_buffer = NULL; - - g_clear_object (&priv->driver); -} - -static void -cogl_framebuffer_init (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->width = -1; - priv->height = -1; -} - -static void -cogl_framebuffer_class_init (CoglFramebufferClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = cogl_framebuffer_dispose; - object_class->constructed = cogl_framebuffer_constructed; - object_class->get_property = cogl_framebuffer_get_property; - object_class->set_property = cogl_framebuffer_set_property; - - obj_props[PROP_CONTEXT] = - g_param_spec_boxed ("context", - "context", - "CoglContext", - COGL_TYPE_HANDLE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_DRIVER_CONFIG] = - g_param_spec_pointer ("driver-config", - "driver-config", - "CoglFramebufferDriverConfig", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_WIDTH] = - g_param_spec_int ("width", - "width", - "framebuffer width", - -1, INT_MAX, -1, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_HEIGHT] = - g_param_spec_int ("height", - "height", - "framebuffer height", - -1, INT_MAX, -1, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, N_PROPS, obj_props); - - signals[DESTROY] = - g_signal_new (I_("destroy"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, - 0); -} - -const CoglWinsysVtable * -_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->context->display->renderer->winsys_vtable; -} - -/* This version of cogl_clear can be used internally as an alternative - * to avoid flushing the journal or the framebuffer state. This is - * needed when doing operations that may be called while flushing - * the journal */ -void -_cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (!buffers) - { - static gboolean shown = FALSE; - - if (!shown) - { - g_warning ("You should specify at least one auxiliary buffer " - "when calling cogl_framebuffer_clear"); - } - - return; - } - - cogl_framebuffer_driver_clear (priv->driver, - buffers, - red, - green, - blue, - alpha); -} - -void -_cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clear_clip_dirty = TRUE; -} - -void -cogl_framebuffer_set_depth_buffer_clear_needed (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->depth_buffer_clear_needed = TRUE; -} - -void -cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); - gboolean had_depth_and_color_buffer_bits; - int scissor_x0; - int scissor_y0; - int scissor_x1; - int scissor_y1; - - had_depth_and_color_buffer_bits = - (buffers & COGL_BUFFER_BIT_DEPTH) && - (buffers & COGL_BUFFER_BIT_COLOR); - - if (!priv->depth_buffer_clear_needed && - (buffers & COGL_BUFFER_BIT_DEPTH)) - buffers &= ~(COGL_BUFFER_BIT_DEPTH); - - if (buffers == 0) - return; - - _cogl_clip_stack_get_bounds (clip_stack, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - - /* NB: the previous clear could have had an arbitrary clip. - * NB: everything for the last frame might still be in the journal - * but we can't assume anything about how each entry was - * clipped. - * NB: Clutter will scissor its pick renders which would mean all - * journal entries have a common ClipStack entry, but without - * a layering violation Cogl has to explicitly walk the journal - * entries to determine if this is the case. - * NB: We have a software only read-pixel optimization in the - * journal that determines the color at a given framebuffer - * coordinate for simple scenes without rendering with the GPU. - * When Clutter is hitting this fast-path we can expect to - * receive calls to clear the framebuffer with an un-flushed - * journal. - * NB: To fully support software based picking for Clutter we - * need to be able to reliably detect when the contents of a - * journal can be discarded and when we can skip the call to - * glClear because it matches the previous clear request. - */ - - /* Note: we don't check for the stencil buffer being cleared here - * since there isn't any public cogl api to manipulate the stencil - * buffer. - * - * Note: we check for an exact clip match here because - * 1) a smaller clip could mean existing journal entries may - * need to contribute to regions outside the new clear-clip - * 2) a larger clip would mean we need to issue a real - * glClear and we only care about cases avoiding a - * glClear. - * - * Note: Comparing without an epsilon is considered - * appropriate here. - */ - if (had_depth_and_color_buffer_bits && - !priv->clear_clip_dirty && - priv->clear_color_red == red && - priv->clear_color_green == green && - priv->clear_color_blue == blue && - priv->clear_color_alpha == alpha && - scissor_x0 == priv->clear_clip_x0 && - scissor_y0 == priv->clear_clip_y0 && - scissor_x1 == priv->clear_clip_x1 && - scissor_y1 == priv->clear_clip_y1) - { - /* NB: We only have to consider the clip state of journal - * entries if the current clear is clipped since otherwise we - * know every pixel of the framebuffer is affected by the clear - * and so all journal entries become redundant and can simply be - * discarded. - */ - if (clip_stack) - { - /* - * Note: the function for checking the journal entries is - * quite strict. It avoids detailed checking of all entry - * clip_stacks by only checking the details of the first - * entry and then it only verifies that the remaining - * entries share the same clip_stack ancestry. This means - * it's possible for some false negatives here but that will - * just result in us falling back to a real clear. - */ - if (_cogl_journal_all_entries_within_bounds (priv->journal, - scissor_x0, scissor_y0, - scissor_x1, scissor_y1)) - { - _cogl_journal_discard (priv->journal); - goto cleared; - } - } - else - { - _cogl_journal_discard (priv->journal); - goto cleared; - } - } - - COGL_NOTE (DRAW, "Clear begin"); - - _cogl_framebuffer_flush_journal (framebuffer); - - /* NB: cogl_context_flush_framebuffer_state may disrupt various state (such - * as the pipeline state) when flushing the clip stack, so should - * always be done first when preparing to draw. */ - cogl_context_flush_framebuffer_state (context, - framebuffer, framebuffer, - COGL_FRAMEBUFFER_STATE_ALL); - - _cogl_framebuffer_clear_without_flush4f (framebuffer, buffers, - red, green, blue, alpha); - - /* This is a debugging variable used to visually display the quad - * batches from the journal. It is reset here to increase the - * chances of getting the same colours for each frame during an - * animation */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES)) && - buffers & COGL_BUFFER_BIT_COLOR) - { - priv->context->journal_rectangles_color = 1; - } - - COGL_NOTE (DRAW, "Clear end"); - -cleared: - - _cogl_framebuffer_mark_clear_clip_dirty (framebuffer); - - if (buffers & COGL_BUFFER_BIT_DEPTH) - priv->depth_buffer_clear_needed = FALSE; - - if (had_depth_and_color_buffer_bits) - { - /* For our fast-path for reading back a single pixel of simple - * scenes where the whole frame is in the journal we need to - * track the cleared color of the framebuffer in case the point - * read doesn't intersect any of the journal rectangles. */ - priv->clear_clip_dirty = FALSE; - priv->clear_color_red = red; - priv->clear_color_green = green; - priv->clear_color_blue = blue; - priv->clear_color_alpha = alpha; - - /* NB: A clear may be scissored so we need to track the extents - * that the clear is applicable too... */ - _cogl_clip_stack_get_bounds (clip_stack, - &priv->clear_clip_x0, - &priv->clear_clip_y0, - &priv->clear_clip_x1, - &priv->clear_clip_y1); - } -} - -/* Note: the 'buffers' and 'color' arguments were switched around on - * purpose compared to the original cogl_clear API since it was odd - * that you would be expected to specify a color before even - * necessarily choosing to clear the color buffer. - */ -void -cogl_framebuffer_clear (CoglFramebuffer *framebuffer, - unsigned long buffers, - const CoglColor *color) -{ - cogl_framebuffer_clear4f (framebuffer, buffers, - cogl_color_get_red_float (color), - cogl_color_get_green_float (color), - cogl_color_get_blue_float (color), - cogl_color_get_alpha_float (color)); -} - -/* We will lazily allocate framebuffers if necessary when querying - * their size/viewport but note we need to be careful in the case of - * onscreen framebuffers that are instantiated with an initial request - * size that we don't trigger an allocation when this is queried since - * that would lead to a recursion when the winsys backend queries this - * requested size during allocation. */ -static void -ensure_size_initialized (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - /* In the case of offscreen framebuffers backed by a texture then - * until that texture has been allocated we might not know the size - * of the framebuffer */ - if (priv->width < 0) - { - /* Currently we assume the size is always initialized for - * onscreen framebuffers. */ - g_return_if_fail (COGL_IS_OFFSCREEN (framebuffer)); - - /* We also assume the size would have been initialized if the - * framebuffer were allocated. */ - g_return_if_fail (!priv->allocated); - - cogl_framebuffer_allocate (framebuffer, NULL); - } -} - -void -cogl_framebuffer_update_size (CoglFramebuffer *framebuffer, - int width, - int height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->width = width; - priv->height = height; - - cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height); -} - -int -cogl_framebuffer_get_width (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->width; -} - -int -cogl_framebuffer_get_height (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->height; -} - -CoglClipStack * -_cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->clip_stack; -} - -void -cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->viewport_x == viewport[0] && - priv->viewport_y == viewport[1] && - priv->viewport_width == viewport[2] && - priv->viewport_height == viewport[3]) - return; - - priv->viewport_x = viewport[0]; - priv->viewport_y = viewport[1]; - priv->viewport_width = viewport[2]; - priv->viewport_height = viewport[3]; - priv->viewport_age++; -} - -void -cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, - float x, - float y, - float width, - float height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (width > 0 && height > 0); - - if (priv->viewport_x == x && - priv->viewport_y == y && - priv->viewport_width == width && - priv->viewport_height == height) - return; - - priv->viewport_x = x; - priv->viewport_y = y; - priv->viewport_width = width; - priv->viewport_height = height; -} - -float -cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->viewport_x; -} - -float -cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->viewport_y; -} - -float -cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->viewport_width; -} - -float -cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - return priv->viewport_height; -} - -void -cogl_framebuffer_get_viewport4f (CoglFramebuffer *framebuffer, - float *viewport_x, - float *viewport_y, - float *viewport_width, - float *viewport_height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - ensure_size_initialized (framebuffer); - - *viewport_x = priv->viewport_x; - *viewport_y = priv->viewport_y; - *viewport_width = priv->viewport_width; - *viewport_height = priv->viewport_height; -} - -void -cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport) -{ - cogl_framebuffer_get_viewport4f (framebuffer, - &viewport[0], - &viewport[1], - &viewport[2], - &viewport[3]); -} - -CoglMatrixStack * -_cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->modelview_stack; -} - -CoglMatrixStack * -_cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->projection_stack; -} - -void -_cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer, - CoglFramebuffer *dependency) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - GList *l; - - for (l = priv->deps; l; l = l->next) - { - CoglFramebuffer *existing_dep = l->data; - if (existing_dep == dependency) - return; - } - - /* TODO: generalize the primed-array type structure we e.g. use for - * cogl_object_set_user_data or for pipeline children as a way to - * avoid quite a lot of mid-scene micro allocations here... */ - priv->deps = - g_list_prepend (priv->deps, g_object_ref (dependency)); -} - -void -_cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - _cogl_journal_flush (priv->journal); -} - -void -_cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_list_foreach (priv->deps, (GFunc) _cogl_framebuffer_flush_journal, NULL); - g_list_free_full (priv->deps, g_object_unref); - priv->deps = NULL; -} - -gboolean -cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->allocated; -} - -static gboolean -cogl_framebuffer_init_driver (CoglFramebuffer *framebuffer, - GError **error) - -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - const CoglDriverVtable *driver_vtable = priv->context->driver_vtable; - CoglFramebufferDriver *driver; - - driver = driver_vtable->create_framebuffer_driver (priv->context, - framebuffer, - &priv->driver_config, - error); - if (!driver) - return FALSE; - - priv->driver = driver; - return TRUE; -} - -gboolean -cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglFramebufferClass *klass = COGL_FRAMEBUFFER_GET_CLASS (framebuffer); - - if (priv->allocated) - return TRUE; - - if (!klass->allocate (framebuffer, error)) - return FALSE; - - if (!cogl_framebuffer_init_driver (framebuffer, error)) - return FALSE; - - priv->allocated = TRUE; - - return TRUE; -} - -static unsigned long -_cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - if (priv_a->viewport_x != priv_b->viewport_x || - priv_a->viewport_y != priv_b->viewport_y || - priv_a->viewport_width != priv_b->viewport_width || - priv_a->viewport_height != priv_b->viewport_height || - /* NB: we render upside down to offscreen framebuffers and that - * can affect how we setup the GL viewport... */ - G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) - return COGL_FRAMEBUFFER_STATE_VIEWPORT; - else - return 0; -} - -static unsigned long -_cogl_framebuffer_compare_clip_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - if (priv_a->clip_stack != priv_b->clip_stack) - return COGL_FRAMEBUFFER_STATE_CLIP; - else - return 0; -} - -static unsigned long -_cogl_framebuffer_compare_dither_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - return priv_a->dither_enabled != priv_b->dither_enabled ? - COGL_FRAMEBUFFER_STATE_DITHER : 0; -} - -static unsigned long -_cogl_framebuffer_compare_modelview_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - /* We always want to flush the modelview state. All this does is set - the current modelview stack on the context to the framebuffer's - stack. */ - return COGL_FRAMEBUFFER_STATE_MODELVIEW; -} - -static unsigned long -_cogl_framebuffer_compare_projection_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - /* We always want to flush the projection state. All this does is - set the current projection stack on the context to the - framebuffer's stack. */ - return COGL_FRAMEBUFFER_STATE_PROJECTION; -} - -static unsigned long -_cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b)) - return COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING; - else - return 0; -} - -static unsigned long -_cogl_framebuffer_compare_depth_write_state (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - return priv_a->depth_writing_enabled != priv_b->depth_writing_enabled ? - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE : 0; -} - -static unsigned long -_cogl_framebuffer_compare_stereo_mode (CoglFramebuffer *a, - CoglFramebuffer *b) -{ - CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a); - CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b); - - return priv_a->stereo_mode != priv_b->stereo_mode ? - COGL_FRAMEBUFFER_STATE_STEREO_MODE : 0; -} - -unsigned long -_cogl_framebuffer_compare (CoglFramebuffer *a, - CoglFramebuffer *b, - unsigned long state) -{ - unsigned long differences = 0; - int bit; - - if (state & COGL_FRAMEBUFFER_STATE_BIND) - { - differences |= COGL_FRAMEBUFFER_STATE_BIND; - state &= ~COGL_FRAMEBUFFER_STATE_BIND; - } - - COGL_FLAGS_FOREACH_START (&state, 1, bit) - { - /* XXX: We considered having an array of callbacks for each state index - * that we'd call here but decided that this way the compiler is more - * likely going to be able to in-line the comparison functions and use - * the index to jump straight to the required code. */ - switch (bit) - { - case COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT: - differences |= - _cogl_framebuffer_compare_viewport_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_CLIP: - differences |= _cogl_framebuffer_compare_clip_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DITHER: - differences |= _cogl_framebuffer_compare_dither_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW: - differences |= - _cogl_framebuffer_compare_modelview_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION: - differences |= - _cogl_framebuffer_compare_projection_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: - differences |= - _cogl_framebuffer_compare_front_face_winding_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE: - differences |= - _cogl_framebuffer_compare_depth_write_state (a, b); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE: - differences |= - _cogl_framebuffer_compare_stereo_mode (a, b); - break; - default: - g_warn_if_reached (); - } - } - COGL_FLAGS_FOREACH_END; - - return differences; -} - -void -cogl_context_flush_framebuffer_state (CoglContext *ctx, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state) -{ - ctx->driver_vtable->flush_framebuffer_state (ctx, - draw_buffer, - read_buffer, - state); -} - -static void -cogl_framebuffer_query_bits (CoglFramebuffer *framebuffer, - CoglFramebufferBits *bits) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (priv->driver); - - cogl_framebuffer_driver_query_bits (priv->driver, bits); -} - -int -cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.red; -} - -int -cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.green; -} - -int -cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.blue; -} - -int -cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.alpha; -} - -int -cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.depth; -} - -int -_cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer) -{ - CoglFramebufferBits bits; - - cogl_framebuffer_query_bits (framebuffer, &bits); - - return bits.stencil; -} - -gboolean -cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->config.stereo_enabled; -} - -CoglStereoMode -cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->stereo_mode; -} - -void -cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer, - CoglStereoMode stereo_mode) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->stereo_mode == stereo_mode) - return; - - /* Stereo mode changes don't go through the journal */ - _cogl_framebuffer_flush_journal (framebuffer); - - priv->stereo_mode = stereo_mode; - - if (priv->context->current_draw_buffer == framebuffer) - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_STEREO_MODE; -} - -gboolean -cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->depth_writing_enabled; -} - -void -cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, - gboolean depth_write_enabled) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->depth_writing_enabled == depth_write_enabled) - return; - - /* XXX: Currently depth write changes don't go through the journal */ - _cogl_framebuffer_flush_journal (framebuffer); - - priv->depth_writing_enabled = depth_write_enabled; - - if (priv->context->current_draw_buffer == framebuffer) - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_DEPTH_WRITE; -} - -gboolean -cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->dither_enabled; -} - -void -cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, - gboolean dither_enabled) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->dither_enabled == dither_enabled) - return; - - priv->dither_enabled = dither_enabled; -} - -int -cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - if (priv->allocated) - return priv->samples_per_pixel; - else - return priv->config.samples_per_pixel; -} - -void -cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (!priv->allocated); - - priv->config.samples_per_pixel = samples_per_pixel; -} - -void -cogl_framebuffer_update_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->samples_per_pixel = samples_per_pixel; -} - -void -cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - cogl_framebuffer_resolve_samples_region (framebuffer, - 0, 0, - priv->width, - priv->height); - - /* TODO: Make this happen implicitly when the resolve texture next gets used - * as a source, either via cogl_texture_get_data(), via cogl_read_pixels() or - * if used as a source for rendering. We would also implicitly resolve if - * necessary before freeing a CoglFramebuffer. - * - * This API should still be kept but it is optional, only necessary - * if the user wants to explicitly control when the resolve happens e.g. - * to ensure it's done in advance of it being used as a source. - * - * Every texture should have a CoglFramebuffer *needs_resolve member - * internally. When the texture gets validated before being used as a source - * we should first check the needs_resolve pointer and if set we'll - * automatically call cogl_framebuffer_resolve_samples (). - * - * Calling cogl_framebuffer_resolve_samples() or - * cogl_framebuffer_resolve_samples_region() should reset the textures - * needs_resolve pointer to NULL. - * - * Rendering anything to a framebuffer will cause the corresponding - * texture's ->needs_resolve pointer to be set. - * - * XXX: Note: we only need to address this TODO item when adding support for - * EXT_framebuffer_multisample because currently we only support hardware - * that resolves implicitly anyway. - */ -} - -void -cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height) -{ - /* NOP for now since we don't support EXT_framebuffer_multisample yet which - * requires an explicit resolve. */ -} - -CoglContext * -cogl_framebuffer_get_context (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_val_if_fail (framebuffer != NULL, NULL); - - return priv->context; -} - -CoglJournal * -cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->journal; -} - -static gboolean -_cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - gboolean found_intersection; - CoglPixelFormat format; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_FAST_READ_PIXEL))) - return FALSE; - - if (source != COGL_READ_PIXELS_COLOR_BUFFER) - return FALSE; - - format = cogl_bitmap_get_format (bitmap); - - if (format != COGL_PIXEL_FORMAT_RGBA_8888_PRE && - format != COGL_PIXEL_FORMAT_RGBA_8888) - return FALSE; - - if (!_cogl_journal_try_read_pixel (priv->journal, - x, y, bitmap, - &found_intersection)) - return FALSE; - - /* If we can't determine the color from the primitives in the - * journal then see if we can use the last recorded clear color - */ - - /* If _cogl_journal_try_read_pixel() failed even though there was an - * intersection of the given point with a primitive in the journal - * then we can't fallback to the framebuffer's last clear color... - * */ - if (found_intersection) - return TRUE; - - /* If the framebuffer has been rendered too since it was last - * cleared then we can't return the last known clear color. */ - if (priv->clear_clip_dirty) - return FALSE; - - if (x >= priv->clear_clip_x0 && - x < priv->clear_clip_x1 && - y >= priv->clear_clip_y0 && - y < priv->clear_clip_y1) - { - uint8_t *pixel; - GError *ignore_error = NULL; - - /* we currently only care about cases where the premultiplied or - * unpremultipled colors are equivalent... */ - if (priv->clear_color_alpha != 1.0) - return FALSE; - - pixel = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - if (pixel == NULL) - { - g_error_free (ignore_error); - return FALSE; - } - - pixel[0] = priv->clear_color_red * 255.0; - pixel[1] = priv->clear_color_green * 255.0; - pixel[2] = priv->clear_color_blue * 255.0; - pixel[3] = priv->clear_color_alpha * 255.0; - - _cogl_bitmap_unmap (bitmap); - - return TRUE; - } - - return FALSE; -} - -gboolean -_cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - int width; - int height; - - g_return_val_if_fail (source & COGL_READ_PIXELS_COLOR_BUFFER, FALSE); - g_return_val_if_fail (cogl_is_framebuffer (framebuffer), FALSE); - - if (!cogl_framebuffer_allocate (framebuffer, error)) - return FALSE; - - width = cogl_bitmap_get_width (bitmap); - height = cogl_bitmap_get_height (bitmap); - - if (width == 1 && height == 1 && !priv->clear_clip_dirty) - { - /* If everything drawn so far for this frame is still in the - * Journal then if all of the rectangles only have a flat - * opaque color we have a fast-path for reading a single pixel - * that avoids the relatively high cost of flushing primitives - * to be drawn on the GPU (considering how simple the geometry - * is in this case) and then blocking on the long GPU pipelines - * for the result. - */ - if (_cogl_framebuffer_try_fast_read_pixel (framebuffer, - x, y, source, bitmap)) - return TRUE; - } - - /* make sure any batched primitives get emitted to the driver - * before issuing our read pixels... - */ - _cogl_framebuffer_flush_journal (framebuffer); - - return cogl_framebuffer_driver_read_pixels_into_bitmap (priv->driver, - x, y, - source, - bitmap, - error); -} - -gboolean -cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap) -{ - GError *ignore_error = NULL; - gboolean status = - _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, source, bitmap, - &ignore_error); - g_clear_error (&ignore_error); - return status; -} - -gboolean -cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height, - CoglPixelFormat format, - uint8_t *pixels) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - int bpp; - CoglBitmap *bitmap; - gboolean ret; - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - bitmap = cogl_bitmap_new_for_data (priv->context, - width, height, - format, - bpp * width, /* rowstride */ - pixels); - - /* Note: we don't try and catch errors here since we created the - * bitmap storage up-front and can assume we won't hit an - * out-of-memory error which should be the only exception - * this api throws. - */ - ret = _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap, - NULL); - cogl_object_unref (bitmap); - - return ret; -} - -gboolean -cogl_framebuffer_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return COGL_FRAMEBUFFER_GET_CLASS (framebuffer)->is_y_flipped (framebuffer); -} - -gboolean -cogl_blit_framebuffer (CoglFramebuffer *framebuffer, - CoglFramebuffer *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglFramebufferPrivate *dst_priv = - cogl_framebuffer_get_instance_private (dst); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - int src_x1, src_y1, src_x2, src_y2; - int dst_x1, dst_y1, dst_x2, dst_y2; - - if (!cogl_has_feature (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER)) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Cogl BLIT_FRAMEBUFFER is not supported by the system."); - return FALSE; - } - - /* The buffers must use the same premult convention */ - if ((priv->internal_format & COGL_PREMULT_BIT) != - (dst_priv->internal_format & COGL_PREMULT_BIT)) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "cogl_blit_framebuffer premult mismatch."); - return FALSE; - } - - /* Make sure any batched primitives get submitted to the driver - * before blitting - */ - _cogl_framebuffer_flush_journal (framebuffer); - - /* Make sure the current framebuffers are bound. We explicitly avoid - flushing the clip state so we can bind our own empty state */ - cogl_context_flush_framebuffer_state (ctx, - dst, - framebuffer, - (COGL_FRAMEBUFFER_STATE_ALL & - ~COGL_FRAMEBUFFER_STATE_CLIP)); - - /* Flush any empty clip stack because glBlitFramebuffer is affected - by the scissor and we want to hide this feature for the Cogl API - because it's not obvious to an app how the clip state will affect - the scissor */ - _cogl_clip_stack_flush (NULL, dst); - - /* XXX: Because we are manually flushing clip state here we need to - * make sure that the clip state gets updated the next time we flush - * framebuffer state by marking the current framebuffer's clip state - * as changed */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - /* Offscreens we do the normal way, onscreens need an y-flip. Even if - * we consider offscreens to be rendered upside-down, the offscreen - * orientation is in this function's API. */ - if (cogl_framebuffer_is_y_flipped (framebuffer)) - { - src_x1 = src_x; - src_y1 = src_y; - src_x2 = src_x + width; - src_y2 = src_y + height; - } - else - { - src_x1 = src_x; - src_y1 = cogl_framebuffer_get_height (framebuffer) - src_y; - src_x2 = src_x + width; - src_y2 = src_y1 - height; - } - - if (cogl_framebuffer_is_y_flipped (dst)) - { - dst_x1 = dst_x; - dst_y1 = dst_y; - dst_x2 = dst_x + width; - dst_y2 = dst_y + height; - } - else - { - dst_x1 = dst_x; - dst_y1 = cogl_framebuffer_get_height (dst) - dst_y; - dst_x2 = dst_x + width; - dst_y2 = dst_y1 - height; - } - - ctx->glBlitFramebuffer (src_x1, src_y1, src_x2, src_y2, - dst_x1, dst_y1, dst_x2, dst_y2, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - return TRUE; -} - -void -cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, - unsigned long buffers) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - g_return_if_fail (buffers & COGL_BUFFER_BIT_COLOR); - - cogl_framebuffer_driver_discard_buffers (priv->driver, buffers); -} - -void -cogl_framebuffer_finish (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_framebuffer_driver_finish (priv->driver); -} - -void -cogl_framebuffer_flush (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_framebuffer_driver_flush (priv->driver); -} - -void -cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_push (modelview_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_pop (modelview_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_load_identity (modelview_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_scale (CoglFramebuffer *framebuffer, - float x, - float y, - float z) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_scale (modelview_stack, x, y, z); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_translate (CoglFramebuffer *framebuffer, - float x, - float y, - float z) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_translate (modelview_stack, x, y, z); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, - float angle, - float x, - float y, - float z) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_rotate (modelview_stack, angle, x, y, z); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, - const graphene_euler_t *euler) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_rotate_euler (modelview_stack, euler); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_transform (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_multiply (modelview_stack, matrix); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_perspective (CoglFramebuffer *framebuffer, - float fov_y, - float aspect, - float z_near, - float z_far) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - float ymax = z_near * tanf (fov_y * G_PI / 360.0); - - cogl_framebuffer_frustum (framebuffer, - -ymax * aspect, /* left */ - ymax * aspect, /* right */ - -ymax, /* bottom */ - ymax, /* top */ - z_near, - z_far); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_frustum (CoglFramebuffer *framebuffer, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - /* XXX: The projection matrix isn't currently tracked in the journal - * so we need to flush all journaled primitives first... */ - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_matrix_stack_load_identity (projection_stack); - - cogl_matrix_stack_frustum (projection_stack, - left, - right, - bottom, - top, - z_near, - z_far); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - graphene_matrix_t ortho; - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - /* XXX: The projection matrix isn't currently tracked in the journal - * so we need to flush all journaled primitives first... */ - _cogl_framebuffer_flush_journal (framebuffer); - - graphene_matrix_init_ortho (&ortho, x_1, x_2, y_2, y_1, near, far); - cogl_matrix_stack_set (projection_stack, &ortho); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix) -{ - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - - cogl_matrix_entry_get (modelview_entry, matrix); -} - -void -cogl_framebuffer_set_modelview_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - cogl_matrix_stack_set (modelview_stack, matrix); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_MODELVIEW; - } -} - -void -cogl_framebuffer_get_projection_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix) -{ - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - - cogl_matrix_entry_get (projection_entry, matrix); -} - -void -cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - - /* XXX: The projection matrix isn't currently tracked in the journal - * so we need to flush all journaled primitives first... */ - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_matrix_stack_set (projection_stack, matrix); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_PROJECTION; - } -} - -void -cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clip_stack = - _cogl_clip_stack_push_window_rectangle (priv->clip_stack, - x, y, width, height); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - /* XXX: It would be nicer if we stored the private viewport as a - * vec4 so we could avoid this redundant copy. */ - float viewport[] = { - priv->viewport_x, - priv->viewport_y, - priv->viewport_width, - priv->viewport_height - }; - - priv->clip_stack = - _cogl_clip_stack_push_rectangle (priv->clip_stack, - x_1, y_1, x_2, y_2, - modelview_entry, - projection_entry, - viewport); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - /* XXX: It would be nicer if we stored the private viewport as a - * vec4 so we could avoid this redundant copy. */ - float viewport[] = { - priv->viewport_x, - priv->viewport_y, - priv->viewport_width, - priv->viewport_height - }; - - priv->clip_stack = - _cogl_clip_stack_push_primitive (priv->clip_stack, - primitive, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2, - modelview_entry, - projection_entry, - viewport); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, - cairo_region_t *region) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clip_stack = - cogl_clip_stack_push_region (priv->clip_stack, - region); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -void -cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - priv->clip_stack = _cogl_clip_stack_pop (priv->clip_stack); - - if (priv->context->current_draw_buffer == framebuffer) - { - priv->context->current_draw_buffer_changes |= - COGL_FRAMEBUFFER_STATE_CLIP; - } -} - -#ifdef COGL_ENABLE_DEBUG -static int -get_index (void *indices, - CoglIndicesType type, - int _index) -{ - if (!indices) - return _index; - - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return ((uint8_t *)indices)[_index]; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return ((uint16_t *)indices)[_index]; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return ((uint32_t *)indices)[_index]; - } - - g_return_val_if_reached (0); -} - -static void -add_line (uint32_t *line_indices, - int base, - void *user_indices, - CoglIndicesType user_indices_type, - int index0, - int index1, - int *pos) -{ - index0 = get_index (user_indices, user_indices_type, index0); - index1 = get_index (user_indices, user_indices_type, index1); - - line_indices[(*pos)++] = base + index0; - line_indices[(*pos)++] = base + index1; -} - -static int -get_line_count (CoglVerticesMode mode, int n_vertices) -{ - if (mode == COGL_VERTICES_MODE_TRIANGLES && - (n_vertices % 3) == 0) - { - return n_vertices; - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN && - n_vertices >= 3) - { - return 2 * n_vertices - 3; - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP && - n_vertices >= 3) - { - return 2 * n_vertices - 3; - } - /* In the journal we are a bit sneaky and actually use GL_QUADS - * which isn't actually a valid CoglVerticesMode! */ -#ifdef HAVE_COGL_GL - else if (mode == GL_QUADS && (n_vertices % 4) == 0) - { - return n_vertices; - } -#endif - - g_return_val_if_reached (0); -} - -static CoglIndices * -get_wire_line_indices (CoglContext *ctx, - CoglVerticesMode mode, - int first_vertex, - int n_vertices_in, - CoglIndices *user_indices, - int *n_indices) -{ - int n_lines; - uint32_t *line_indices; - CoglIndexBuffer *index_buffer; - void *indices; - CoglIndicesType indices_type; - int base = first_vertex; - int pos; - int i; - CoglIndices *ret; - - if (user_indices) - { - index_buffer = cogl_indices_get_buffer (user_indices); - indices = _cogl_buffer_map (COGL_BUFFER (index_buffer), - COGL_BUFFER_ACCESS_READ, 0, - NULL); - indices_type = cogl_indices_get_type (user_indices); - } - else - { - index_buffer = NULL; - indices = NULL; - indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE; - } - - n_lines = get_line_count (mode, n_vertices_in); - - /* Note: we are using COGL_INDICES_TYPE_UNSIGNED_INT so 4 bytes per index. */ - line_indices = g_malloc (4 * n_lines * 2); - - pos = 0; - - if (mode == COGL_VERTICES_MODE_TRIANGLES && - (n_vertices_in % 3) == 0) - { - for (i = 0; i < n_vertices_in; i += 3) - { - add_line (line_indices, base, indices, indices_type, i, i+1, &pos); - add_line (line_indices, base, indices, indices_type, i+1, i+2, &pos); - add_line (line_indices, base, indices, indices_type, i+2, i, &pos); - } - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN && - n_vertices_in >= 3) - { - add_line (line_indices, base, indices, indices_type, 0, 1, &pos); - add_line (line_indices, base, indices, indices_type, 1, 2, &pos); - add_line (line_indices, base, indices, indices_type, 0, 2, &pos); - - for (i = 3; i < n_vertices_in; i++) - { - add_line (line_indices, base, indices, indices_type, i - 1, i, &pos); - add_line (line_indices, base, indices, indices_type, 0, i, &pos); - } - } - else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP && - n_vertices_in >= 3) - { - add_line (line_indices, base, indices, indices_type, 0, 1, &pos); - add_line (line_indices, base, indices, indices_type, 1, 2, &pos); - add_line (line_indices, base, indices, indices_type, 0, 2, &pos); - - for (i = 3; i < n_vertices_in; i++) - { - add_line (line_indices, base, indices, indices_type, i - 1, i, &pos); - add_line (line_indices, base, indices, indices_type, i - 2, i, &pos); - } - } - /* In the journal we are a bit sneaky and actually use GL_QUADS - * which isn't actually a valid CoglVerticesMode! */ -#ifdef HAVE_COGL_GL - else if (mode == GL_QUADS && (n_vertices_in % 4) == 0) - { - for (i = 0; i < n_vertices_in; i += 4) - { - add_line (line_indices, - base, indices, indices_type, i, i + 1, &pos); - add_line (line_indices, - base, indices, indices_type, i + 1, i + 2, &pos); - add_line (line_indices, - base, indices, indices_type, i + 2, i + 3, &pos); - add_line (line_indices, - base, indices, indices_type, i + 3, i, &pos); - } - } -#endif - - if (user_indices) - cogl_buffer_unmap (COGL_BUFFER (index_buffer)); - - *n_indices = n_lines * 2; - - ret = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_INT, - line_indices, - *n_indices); - - g_free (line_indices); - - return ret; -} - -static void -pipeline_destroyed_cb (CoglPipeline *weak_pipeline, void *user_data) -{ - CoglPipeline *original_pipeline = user_data; - - /* XXX: I think we probably need to provide a custom unref function for - * CoglPipeline because it's possible that we will reach this callback - * because original_pipeline is being freed which means cogl_object_unref - * will have already freed any associated user data. - * - * Setting more user data here will *probably* succeed but that may allocate - * a new user-data array which could be leaked. - * - * Potentially we could have a _cogl_object_free_user_data function so - * that a custom unref function could be written that can destroy weak - * pipeline children before removing user data. - */ - cogl_object_set_user_data (COGL_OBJECT (original_pipeline), - &wire_pipeline_key, NULL, NULL); - - cogl_object_unref (weak_pipeline); -} - -static void -draw_wireframe (CoglContext *ctx, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglIndices *indices, - CoglDrawFlags flags) -{ - CoglIndices *wire_indices; - CoglPipeline *wire_pipeline; - int n_indices; - - wire_indices = get_wire_line_indices (ctx, - mode, - first_vertex, - n_vertices, - indices, - &n_indices); - - wire_pipeline = cogl_object_get_user_data (COGL_OBJECT (pipeline), - &wire_pipeline_key); - - if (!wire_pipeline) - { - static CoglSnippet *snippet = NULL; - - wire_pipeline = - _cogl_pipeline_weak_copy (pipeline, pipeline_destroyed_cb, NULL); - - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &wire_pipeline_key, wire_pipeline, - NULL); - - /* If we have glsl then the pipeline may have an associated - * vertex program and since we'd like to see the results of the - * vertex program in the wireframe we just add a final clobber - * of the wire color leaving the rest of the state untouched. */ - - /* The snippet is cached so that it will reuse the program - * from the pipeline cache if possible */ - if (snippet == NULL) - { - snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - NULL, - NULL); - cogl_snippet_set_replace (snippet, - "cogl_color_out = " - "vec4 (0.0, 1.0, 0.0, 1.0);\n"); - } - - cogl_pipeline_add_snippet (wire_pipeline, snippet); - } - - /* temporarily disable the wireframe to avoid recursion! */ - flags |= COGL_DRAW_SKIP_DEBUG_WIREFRAME; - _cogl_framebuffer_draw_indexed_attributes ( - framebuffer, - wire_pipeline, - COGL_VERTICES_MODE_LINES, - 0, - n_indices, - wire_indices, - attributes, - n_attributes, - flags); - COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME); - - cogl_object_unref (wire_indices); -} -#endif - -/* This can be called directly by the CoglJournal to draw attributes - * skipping the implicit journal flush, the framebuffer flush and - * pipeline validation. */ -void -_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME) && - (flags & COGL_DRAW_SKIP_DEBUG_WIREFRAME) == 0) && - mode != COGL_VERTICES_MODE_LINES && - mode != COGL_VERTICES_MODE_LINE_LOOP && - mode != COGL_VERTICES_MODE_LINE_STRIP) - draw_wireframe (priv->context, - framebuffer, pipeline, - mode, first_vertex, n_vertices, - attributes, n_attributes, NULL, - flags); - else -#endif - { - cogl_framebuffer_driver_draw_attributes (priv->driver, - pipeline, - mode, - first_vertex, - n_vertices, - attributes, - n_attributes, - flags); - } -} - -void -_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME) && - (flags & COGL_DRAW_SKIP_DEBUG_WIREFRAME) == 0) && - mode != COGL_VERTICES_MODE_LINES && - mode != COGL_VERTICES_MODE_LINE_LOOP && - mode != COGL_VERTICES_MODE_LINE_STRIP) - draw_wireframe (priv->context, - framebuffer, pipeline, - mode, first_vertex, n_vertices, - attributes, n_attributes, indices, - flags); - else -#endif - { - cogl_framebuffer_driver_draw_indexed_attributes (priv->driver, - pipeline, - mode, - first_vertex, - n_vertices, - indices, - attributes, - n_attributes, - flags); - } -} - -void -cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglPrimitive *primitive) -{ - _cogl_primitive_draw (primitive, framebuffer, pipeline, 0); -} - -void -cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * _CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rect.position = position; - rect.tex_coords = NULL; - rect.tex_coords_len = 0; - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - &rect, - 1); -} - -void -cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - float s_1, - float t_1, - float s_2, - float t_2) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - const float tex_coords[4] = {s_1, t_1, s_2, t_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rect.position = position; - rect.tex_coords = tex_coords; - rect.tex_coords_len = 4; - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - &rect, - 1); -} - -void -cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - const float *tex_coords, - int tex_coords_len) -{ - const float position[4] = {x_1, y_1, x_2, y_2}; - CoglMultiTexturedRect rect; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rect.position = position; - rect.tex_coords = tex_coords; - rect.tex_coords_len = tex_coords_len; - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - &rect, - 1); -} - -void -cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles) -{ - CoglMultiTexturedRect *rects; - int i; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rects = g_alloca (n_rectangles * sizeof (CoglMultiTexturedRect)); - - for (i = 0; i < n_rectangles; i++) - { - rects[i].position = &coordinates[i * 4]; - rects[i].tex_coords = NULL; - rects[i].tex_coords_len = 0; - } - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - rects, - n_rectangles); -} - -void -cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles) -{ - CoglMultiTexturedRect *rects; - int i; - - /* XXX: All the _*_rectangle* APIs normalize their input into an array of - * _CoglMultiTexturedRect rectangles and pass these on to our work horse; - * _cogl_framebuffer_draw_multitextured_rectangles. - */ - - rects = g_alloca (n_rectangles * sizeof (CoglMultiTexturedRect)); - - for (i = 0; i < n_rectangles; i++) - { - rects[i].position = &coordinates[i * 8]; - rects[i].tex_coords = &coordinates[i * 8 + 4]; - rects[i].tex_coords_len = 4; - } - - _cogl_framebuffer_draw_multitextured_rectangles (framebuffer, - pipeline, - rects, - n_rectangles); -} - -CoglFramebufferDriver * -cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - - return priv->driver; -} - -CoglTimestampQuery * -cogl_framebuffer_create_timestamp_query (CoglFramebuffer *framebuffer) -{ - CoglFramebufferPrivate *priv = - cogl_framebuffer_get_instance_private (framebuffer); - const CoglDriverVtable *driver_vtable = priv->context->driver_vtable; - - g_return_val_if_fail (cogl_has_feature (priv->context, - COGL_FEATURE_ID_TIMESTAMP_QUERY), - NULL); - - /* The timestamp query completes upon completion of all previously submitted - * GL commands. So make sure those commands are indeed submitted by flushing - * the journal. - */ - _cogl_framebuffer_flush_journal (framebuffer); - - cogl_context_flush_framebuffer_state (priv->context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - return driver_vtable->create_timestamp_query (priv->context); -} diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h deleted file mode 100644 index 571b48998..000000000 --- a/cogl/cogl/cogl-framebuffer.h +++ /dev/null @@ -1,1582 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2011 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_FRAMEBUFFER_H -#define __COGL_FRAMEBUFFER_H - - -#include <cogl/cogl-pipeline.h> -#include <cogl/cogl-indices.h> -#include <cogl/cogl-bitmap.h> -#include <cogl/cogl-texture.h> -#include <glib-object.h> -#include <cairo.h> - -#include <graphene.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-framebuffer - * @short_description: A common interface for manipulating framebuffers - * - * Framebuffers are a collection of buffers that can be rendered too. - * A framebuffer may be comprised of one or more color buffers, an - * optional depth buffer and an optional stencil buffer. Other - * configuration parameters are associated with framebuffers too such - * as whether the framebuffer supports multi-sampling (an anti-aliasing - * technique) or dithering. - * - * There are two kinds of framebuffer in Cogl, #CoglOnscreen - * framebuffers and #CoglOffscreen framebuffers. As the names imply - * offscreen framebuffers are for rendering something offscreen - * (perhaps to a texture which is bound as one of the color buffers). - * The exact semantics of onscreen framebuffers depends on the window - * system backend that you are using, but typically you can expect - * rendering to a #CoglOnscreen framebuffer will be immediately - * visible to the user. - * - * If you want to create a new framebuffer then you should start by - * looking at the #CoglOnscreen and #CoglOffscreen constructor - * functions, such as cogl_offscreen_new_with_texture() or - * cogl_onscreen_new(). The #CoglFramebuffer interface deals with - * all aspects that are common between those two types of framebuffer. - * - * Setup of a new CoglFramebuffer happens in two stages. There is a - * configuration stage where you specify all the options and ancillary - * buffers you want associated with your framebuffer and then when you - * are happy with the configuration you can "allocate" the framebuffer - * using cogl_framebuffer_allocate(). Technically explicitly calling - * cogl_framebuffer_allocate() is optional for convenience and the - * framebuffer will automatically be allocated when you first try to - * draw to it, but if you do the allocation manually then you can - * also catch any possible errors that may arise from your - * configuration. - */ - -typedef struct _CoglFramebufferDriverConfig CoglFramebufferDriverConfig; - -#define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ()) -COGL_EXPORT -G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer, - COGL, FRAMEBUFFER, GObject) - -struct _CoglFramebufferClass -{ - /*< private >*/ - GObjectClass parent_class; - - gboolean (* allocate) (CoglFramebuffer *framebuffer, - GError **error); - gboolean (* is_y_flipped) (CoglFramebuffer *framebuffer); -}; - -/** - * cogl_framebuffer_allocate: - * @framebuffer: A #CoglFramebuffer - * @error: A pointer to a #GError for returning exceptions. - * - * Explicitly allocates a configured #CoglFramebuffer allowing developers to - * check and handle any errors that might arise from an unsupported - * configuration so that fallback configurations may be tried. - * - * <note>Many applications don't support any fallback options at least when - * they are initially developed and in that case the don't need to use this API - * since Cogl will automatically allocate a framebuffer when it first gets - * used. The disadvantage of relying on automatic allocation is that the - * program will abort with an error message if there is an error during - * automatic allocation.</note> - * - * Return value: %TRUE if there were no error allocating the framebuffer, else %FALSE. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, - GError **error); - -/** - * cogl_framebuffer_get_width: - * @framebuffer: A #CoglFramebuffer - * - * Queries the current width of the given @framebuffer. - * - * Return value: The width of @framebuffer. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_width (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_height: - * @framebuffer: A #CoglFramebuffer - * - * Queries the current height of the given @framebuffer. - * - * Return value: The height of @framebuffer. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_height (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_viewport: - * @framebuffer: A #CoglFramebuffer - * @x: The top-left x coordinate of the viewport origin (only integers - * supported currently) - * @y: The top-left y coordinate of the viewport origin (only integers - * supported currently) - * @width: The width of the viewport (only integers supported currently) - * @height: The height of the viewport (only integers supported currently) - * - * Defines a scale and offset for everything rendered relative to the - * top-left of the destination framebuffer. - * - * By default the viewport has an origin of (0,0) and width and height - * that match the framebuffer's size. Assuming a default projection and - * modelview matrix then you could translate the contents of a window - * down and right by leaving the viewport size unchanged by moving the - * offset to (10,10). The viewport coordinates are measured in pixels. - * If you left the x and y origin as (0,0) you could scale the windows - * contents down by specify and width and height that's half the real - * size of the framebuffer. - * - * <note>Although the function takes floating point arguments, existing - * drivers only allow the use of integer values. In the future floating - * point values will be exposed via a checkable feature.</note> - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer, - float x, - float y, - float width, - float height); - -/** - * cogl_framebuffer_get_viewport_x: - * @framebuffer: A #CoglFramebuffer - * - * Queries the x coordinate of the viewport origin as set using cogl_framebuffer_set_viewport() - * or the default value which is 0. - * - * Return value: The x coordinate of the viewport origin. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport_y: - * @framebuffer: A #CoglFramebuffer - * - * Queries the y coordinate of the viewport origin as set using cogl_framebuffer_set_viewport() - * or the default value which is 0. - * - * Return value: The y coordinate of the viewport origin. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport_width: - * @framebuffer: A #CoglFramebuffer - * - * Queries the width of the viewport as set using cogl_framebuffer_set_viewport() - * or the default value which is the width of the framebuffer. - * - * Return value: The width of the viewport. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport_height: - * @framebuffer: A #CoglFramebuffer - * - * Queries the height of the viewport as set using cogl_framebuffer_set_viewport() - * or the default value which is the height of the framebuffer. - * - * Return value: The height of the viewport. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT float -cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_viewport4fv: - * @framebuffer: A #CoglFramebuffer - * @viewport: (out caller-allocates) (array fixed-size=4): A pointer to an - * array of 4 floats to receive the (x, y, width, height) - * components of the current viewport. - * - * Queries the x, y, width and height components of the current viewport as set - * using cogl_framebuffer_set_viewport() or the default values which are 0, 0, - * framebuffer_width and framebuffer_height. The values are written into the - * given @viewport array. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer, - float *viewport); - -/** - * cogl_framebuffer_push_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * - * Copies the current model-view matrix onto the matrix stack. The matrix - * can later be restored with cogl_framebuffer_pop_matrix(). - * - * Since: 1.10 - */ -COGL_EXPORT void -cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_pop_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * - * Restores the model-view matrix on the top of the matrix stack. - * - * Since: 1.10 - */ -COGL_EXPORT void -cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_identity_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * - * Resets the current model-view matrix to the identity matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_scale: - * @framebuffer: A #CoglFramebuffer pointer - * @x: Amount to scale along the x-axis - * @y: Amount to scale along the y-axis - * @z: Amount to scale along the z-axis - * - * Multiplies the current model-view matrix by one that scales the x, - * y and z axes by the given values. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_scale (CoglFramebuffer *framebuffer, - float x, - float y, - float z); - -/** - * cogl_framebuffer_translate: - * @framebuffer: A #CoglFramebuffer pointer - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current model-view matrix by one that translates the - * model along all three axes according to the given values. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_translate (CoglFramebuffer *framebuffer, - float x, - float y, - float z); - -/** - * cogl_framebuffer_rotate: - * @framebuffer: A #CoglFramebuffer pointer - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Multiplies the current model-view matrix by one that rotates the - * model around the axis-vector specified by @x, @y and @z. The - * rotation follows the right-hand thumb rule so for example rotating - * by 10 degrees about the axis-vector (0, 0, 1) causes a small - * counter-clockwise rotation. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, - float angle, - float x, - float y, - float z); - -/** - * cogl_framebuffer_rotate_euler: - * @framebuffer: A #CoglFramebuffer pointer - * @euler: A #graphene_euler_t - * - * Multiplies the current model-view matrix by one that rotates - * according to the rotation described by @euler. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, - const graphene_euler_t *euler); - -/** - * cogl_framebuffer_transform: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: the matrix to multiply with the current model-view - * - * Multiplies the current model-view matrix by the given matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_transform (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_get_modelview_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: (out): return location for the model-view matrix - * - * Stores the current model-view matrix in @matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_get_modelview_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_set_modelview_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: the new model-view matrix - * - * Sets @matrix as the new model-view matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_modelview_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_perspective: - * @framebuffer: A #CoglFramebuffer pointer - * @fov_y: Vertical field of view angle in degrees. - * @aspect: The (width over height) aspect ratio for display - * @z_near: The distance to the near clipping plane (Must be positive, - * and must not be 0) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current projection matrix with a perspective matrix - * based on the provided values. - * - * <note>You should be careful not to have to great a @z_far / @z_near - * ratio since that will reduce the effectiveness of depth testing - * since there won't be enough precision to identify the depth of - * objects near to each other.</note> - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_perspective (CoglFramebuffer *framebuffer, - float fov_y, - float aspect, - float z_near, - float z_far); - -/** - * cogl_framebuffer_frustum: - * @framebuffer: A #CoglFramebuffer pointer - * @left: X position of the left clipping plane where it - * intersects the near clipping plane - * @right: X position of the right clipping plane where it - * intersects the near clipping plane - * @bottom: Y position of the bottom clipping plane where it - * intersects the near clipping plane - * @top: Y position of the top clipping plane where it intersects - * the near clipping plane - * @z_near: The distance to the near clipping plane (Must be positive) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current projection matrix with a perspective matrix - * for a given viewing frustum defined by 4 side clip planes that - * all cross through the origin and 2 near and far clip planes. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_frustum (CoglFramebuffer *framebuffer, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_framebuffer_orthographic: - * @framebuffer: A #CoglFramebuffer pointer - * @x_1: The x coordinate for the first vertical clipping plane - * @y_1: The y coordinate for the first horizontal clipping plane - * @x_2: The x coordinate for the second vertical clipping plane - * @y_2: The y coordinate for the second horizontal clipping plane - * @near: The <emphasis>distance</emphasis> to the near clipping - * plane (will be <emphasis>negative</emphasis> if the plane is - * behind the viewer) - * @far: The <emphasis>distance</emphasis> to the far clipping - * plane (will be <emphasis>negative</emphasis> if the plane is - * behind the viewer) - * - * Replaces the current projection matrix with an orthographic projection - * matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far); - -/** - * cogl_framebuffer_get_projection_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: (out): return location for the projection matrix - * - * Stores the current projection matrix in @matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_get_projection_matrix (CoglFramebuffer *framebuffer, - graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_set_projection_matrix: - * @framebuffer: A #CoglFramebuffer pointer - * @matrix: the new projection matrix - * - * Sets @matrix as the new projection matrix. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_projection_matrix (CoglFramebuffer *framebuffer, - const graphene_matrix_t *matrix); - -/** - * cogl_framebuffer_push_scissor_clip: - * @framebuffer: A #CoglFramebuffer pointer - * @x: left edge of the clip rectangle in window coordinates - * @y: top edge of the clip rectangle in window coordinates - * @width: width of the clip rectangle - * @height: height of the clip rectangle - * - * Specifies a rectangular clipping area for all subsequent drawing - * operations. Any drawing commands that extend outside the rectangle - * will be clipped so that only the portion inside the rectangle will - * be displayed. The rectangle dimensions are not transformed by the - * current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_framebuffer_pop_clip(). - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height); - -/** - * cogl_framebuffer_push_rectangle_clip: - * @framebuffer: A #CoglFramebuffer pointer - * @x_1: x coordinate for top left corner of the clip rectangle - * @y_1: y coordinate for top left corner of the clip rectangle - * @x_2: x coordinate for bottom right corner of the clip rectangle - * @y_2: y coordinate for bottom right corner of the clip rectangle - * - * Specifies a modelview transformed rectangular clipping area for all - * subsequent drawing operations. Any drawing commands that extend - * outside the rectangle will be clipped so that only the portion - * inside the rectangle will be displayed. The rectangle dimensions - * are transformed by the current model-view matrix. - * - * The rectangle is intersected with the current clip region. To undo - * the effect of this function, call cogl_framebuffer_pop_clip(). - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer, - float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_framebuffer_push_primitive_clip: (skip) - * @framebuffer: A #CoglFramebuffer pointer - * @primitive: A #CoglPrimitive describing a flat 2D shape - * @bounds_x1: x coordinate for the top-left corner of the primitives - * bounds - * @bounds_y1: y coordinate for the top-left corner of the primitives - * bounds - * @bounds_x2: x coordinate for the bottom-right corner of the - * primitives bounds. - * @bounds_y2: y coordinate for the bottom-right corner of the - * primitives bounds. - * - * Sets a new clipping area using a 2D shaped described with a - * #CoglPrimitive. The shape must not contain self overlapping - * geometry and must lie on a single 2D plane. A bounding box of the - * 2D shape in local coordinates (the same coordinates used to - * describe the shape) must be given. It is acceptable for the bounds - * to be larger than the true bounds but behaviour is undefined if the - * bounds are smaller than the true bounds. - * - * The primitive is transformed by the current model-view matrix and - * the silhouette is intersected with the previous clipping area. To - * restore the previous clipping area, call - * cogl_framebuffer_pop_clip(). - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2); - -COGL_EXPORT void -cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer, - cairo_region_t *region); - -/** - * cogl_framebuffer_pop_clip: - * @framebuffer: A #CoglFramebuffer pointer - * - * Reverts the clipping region to the state before the last call to - * cogl_framebuffer_push_scissor_clip(), cogl_framebuffer_push_rectangle_clip() - * cogl_framebuffer_push_path_clip(), or cogl_framebuffer_push_primitive_clip(). - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_red_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of red bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_green_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of green bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_blue_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of blue bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_alpha_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of alpha bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_depth_bits: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves the number of depth bits of @framebuffer - * - * Return value: the number of bits - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer); - -/* - * cogl_framebuffer_get_is_stereo: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Retrieves whether @framebuffer has separate left and right - * buffers for use with stereo drawing. See - * cogl_framebuffer_set_stereo_mode(). - * - * Return value: %TRUE if @framebuffer has separate left and - * right buffers. - * - * Since: 1.20 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_get_dither_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Returns whether dithering has been requested for the given @framebuffer. - * See cogl_framebuffer_set_dither_enabled() for more details about dithering. - * - * <note>This may return %TRUE even when the underlying @framebuffer - * display pipeline does not support dithering. This value only represents - * the user's request for dithering.</note> - * - * Return value: %TRUE if dithering has been requested or %FALSE if not. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_dither_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * @dither_enabled: %TRUE to enable dithering or %FALSE to disable - * - * Enables or disabled dithering if supported by the hardware. - * - * Dithering is a hardware dependent technique to increase the visible - * color resolution beyond what the underlying hardware supports by playing - * tricks with the colors placed into the framebuffer to give the illusion - * of other colors. (For example this can be compared to half-toning used - * by some news papers to show varying levels of grey even though their may - * only be black and white are available). - * - * If the current display pipeline for @framebuffer does not support dithering - * then this has no affect. - * - * Dithering is enabled by default. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer, - gboolean dither_enabled); - -/** - * cogl_framebuffer_get_depth_write_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Queries whether depth buffer writing is enabled for @framebuffer. This - * can be controlled via cogl_framebuffer_set_depth_write_enabled(). - * - * Return value: %TRUE if depth writing is enabled or %FALSE if not. - * Since: 1.18 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_depth_write_enabled: - * @framebuffer: a pointer to a #CoglFramebuffer - * @depth_write_enabled: %TRUE to enable depth writing or %FALSE to disable - * - * Enables or disables depth buffer writing when rendering to @framebuffer. - * If depth writing is enabled for both the framebuffer and the rendering - * pipeline, and the framebuffer has an associated depth buffer, depth - * information will be written to this buffer during rendering. - * - * Depth buffer writing is enabled by default. - * - * Since: 1.18 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer, - gboolean depth_write_enabled); - -/** - * cogl_framebuffer_get_stereo_mode: - * @framebuffer: a pointer to a #CoglFramebuffer - * - * Gets the current #CoglStereoMode, which defines which stereo buffers - * should be drawn to. See cogl_framebuffer_set_stereo_mode(). - * - * Returns: A #CoglStereoMode - * Since: 1.20 - * Stability: unstable - */ -COGL_EXPORT CoglStereoMode -cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_set_stereo_mode: - * @framebuffer: a pointer to a #CoglFramebuffer - * @stereo_mode: A #CoglStereoMode specifying which stereo buffers - * should be drawn tow. - * - * Sets which stereo buffers should be drawn to. The default - * is %COGL_STEREO_BOTH, which means that both the left and - * right buffers will be affected by drawing. For this to have - * an effect, the display system must support stereo drawables, - * and the framebuffer must have been created with stereo - * enabled. (See cogl_onscreen_template_set_stereo_enabled(), - * cogl_framebuffer_get_is_stereo().) - * - * Since: 1.20 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer, - CoglStereoMode stereo_mode); - -/** - * cogl_framebuffer_set_samples_per_pixel: - * @framebuffer: A #CoglFramebuffer framebuffer - * @samples_per_pixel: The minimum number of samples per pixel - * - * Requires that when rendering to @framebuffer then @n point samples - * should be made per pixel which will all contribute to the final - * resolved color for that pixel. The idea is that the hardware aims - * to get quality similar to what you would get if you rendered - * everything twice as big (for 4 samples per pixel) and then scaled - * that image back down with filtering. It can effectively remove the - * jagged edges of polygons and should be more efficient than if you - * were to manually render at a higher resolution and downscale - * because the hardware is often able to take some shortcuts. For - * example the GPU may only calculate a single texture sample for all - * points of a single pixel, and for tile based architectures all the - * extra sample data (such as depth and stencil samples) may be - * handled on-chip and so avoid increased demand on system memory - * bandwidth. - * - * By default this value is usually set to 0 and that is referred to - * as "single-sample" rendering. A value of 1 or greater is referred - * to as "multisample" rendering. - * - * <note>There are some semantic differences between single-sample - * rendering and multisampling with just 1 point sample such as it - * being redundant to use the cogl_framebuffer_resolve_samples() and - * cogl_framebuffer_resolve_samples_region() apis with single-sample - * rendering.</note> - * - * <note>It's recommended that - * cogl_framebuffer_resolve_samples_region() be explicitly used at the - * end of rendering to a point sample buffer to minimize the number of - * samples that get resolved. By default Cogl will implicitly resolve - * all framebuffer samples but if only a small region of a - * framebuffer has changed this can lead to redundant work being - * done.</note> - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer, - int samples_per_pixel); - -/** - * cogl_framebuffer_get_samples_per_pixel: - * @framebuffer: A #CoglFramebuffer framebuffer - * - * Gets the number of points that are sampled per-pixel when - * rasterizing geometry. Usually by default this will return 0 which - * means that single-sample not multisample rendering has been chosen. - * When using a GPU supporting multisample rendering it's possible to - * increase the number of samples per pixel using - * cogl_framebuffer_set_samples_per_pixel(). - * - * Calling cogl_framebuffer_get_samples_per_pixel() before the - * framebuffer has been allocated will simply return the value set - * using cogl_framebuffer_set_samples_per_pixel(). After the - * framebuffer has been allocated the value will reflect the actual - * number of samples that will be made by the GPU. - * - * Returns: The number of point samples made per pixel when - * rasterizing geometry or 0 if single-sample rendering - * has been chosen. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT int -cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer); - - -/** - * cogl_framebuffer_resolve_samples: - * @framebuffer: A #CoglFramebuffer framebuffer - * - * When point sample rendering (also known as multisample rendering) - * has been enabled via cogl_framebuffer_set_samples_per_pixel() - * then you can optionally call this function (or - * cogl_framebuffer_resolve_samples_region()) to explicitly resolve - * the point samples into values for the final color buffer. - * - * Some GPUs will implicitly resolve the point samples during - * rendering and so this function is effectively a nop, but with other - * architectures it is desirable to defer the resolve step until the - * end of the frame. - * - * Since Cogl will automatically ensure samples are resolved if the - * target color buffer is used as a source this API only needs to be - * used if explicit control is desired - perhaps because you want to - * ensure that the resolve is completed in advance to avoid later - * having to wait for the resolve to complete. - * - * If you are performing incremental updates to a framebuffer you - * should consider using cogl_framebuffer_resolve_samples_region() - * instead to avoid resolving redundant pixels. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_resolve_samples_region: - * @framebuffer: A #CoglFramebuffer framebuffer - * @x: top-left x coordinate of region to resolve - * @y: top-left y coordinate of region to resolve - * @width: width of region to resolve - * @height: height of region to resolve - * - * When point sample rendering (also known as multisample rendering) - * has been enabled via cogl_framebuffer_set_samples_per_pixel() - * then you can optionally call this function (or - * cogl_framebuffer_resolve_samples()) to explicitly resolve the point - * samples into values for the final color buffer. - * - * Some GPUs will implicitly resolve the point samples during - * rendering and so this function is effectively a nop, but with other - * architectures it is desirable to defer the resolve step until the - * end of the frame. - * - * Use of this API is recommended if incremental, small updates to - * a framebuffer are being made because by default Cogl will - * implicitly resolve all the point samples of the framebuffer which - * can result in redundant work if only a small number of samples have - * changed. - * - * Because some GPUs implicitly resolve point samples this function - * only guarantees that at-least the region specified will be resolved - * and if you have rendered to a larger region then it's possible that - * other samples may be implicitly resolved. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height); - -/** - * cogl_framebuffer_get_context: - * @framebuffer: A #CoglFramebuffer - * - * Can be used to query the #CoglContext a given @framebuffer was - * instantiated within. This is the #CoglContext that was passed to - * cogl_onscreen_new() for example. - * - * Return value: (transfer none): The #CoglContext that the given - * @framebuffer was instantiated within. - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT CoglContext * -cogl_framebuffer_get_context (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_clear: - * @framebuffer: A #CoglFramebuffer - * @buffers: A mask of #CoglBufferBit<!-- -->'s identifying which auxiliary - * buffers to clear - * @color: The color to clear the color buffer too if specified in - * @buffers. - * - * Clears all the auxiliary buffers identified in the @buffers mask, and if - * that includes the color buffer then the specified @color is used. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_clear (CoglFramebuffer *framebuffer, - unsigned long buffers, - const CoglColor *color); - -/** - * cogl_framebuffer_clear4f: - * @framebuffer: A #CoglFramebuffer - * @buffers: A mask of #CoglBufferBit<!-- -->'s identifying which auxiliary - * buffers to clear - * @red: The red component of color to clear the color buffer too if - * specified in @buffers. - * @green: The green component of color to clear the color buffer too if - * specified in @buffers. - * @blue: The blue component of color to clear the color buffer too if - * specified in @buffers. - * @alpha: The alpha component of color to clear the color buffer too if - * specified in @buffers. - * - * Clears all the auxiliary buffers identified in the @buffers mask, and if - * that includes the color buffer then the specified @color is used. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer, - unsigned long buffers, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_framebuffer_draw_primitive: (skip) - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @primitive: A #CoglPrimitive geometry object - * - * Draws the given @primitive geometry to the specified destination - * @framebuffer using the graphics processing state described by @pipeline. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D are associated with layers of the given - * @pipeline. - * - * <note>This api doesn't support any of the legacy global state options such - * as cogl_set_depth_test_enabled() or - * cogl_set_backface_culling_enabled().</note> - * - * Stability: unstable - * Since: 1.10 - * Deprecated: 1.16: Use #CoglPrimitive<!-- -->s and - * cogl_primitive_draw() instead - */ -COGL_DEPRECATED_FOR (cogl_primitive_draw) -COGL_EXPORT void -cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglPrimitive *primitive); - -/** - * cogl_framebuffer_draw_rectangle: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @x_1: X coordinate of the top-left corner - * @y_1: Y coordinate of the top-left corner - * @x_2: X coordinate of the bottom-right corner - * @y_2: Y coordinate of the bottom-right corner - * - * Draws a rectangle to @framebuffer with the given @pipeline state - * and with the top left corner positioned at (@x_1, @y_1) and the - * bottom right corner positioned at (@x_2, @y_2). - * - * <note>The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix.</note> - * - * <note>If you want to describe a rectangle with a texture mapped on - * it then you can use - * cogl_framebuffer_draw_textured_rectangle().</note> - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_draw_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2); - -/** - * cogl_framebuffer_draw_textured_rectangle: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @x_1: x coordinate upper left on screen. - * @y_1: y coordinate upper left on screen. - * @x_2: x coordinate lower right on screen. - * @y_2: y coordinate lower right on screen. - * @s_1: S texture coordinate of the top-left coorner - * @t_1: T texture coordinate of the top-left coorner - * @s_2: S texture coordinate of the bottom-right coorner - * @t_2: T texture coordinate of the bottom-right coorner - * - * Draws a textured rectangle to @framebuffer using the given - * @pipeline state with the top left corner positioned at (@x_1, @y_1) - * and the bottom right corner positioned at (@x_2, @y_2). The top - * left corner will have texture coordinates of (@s_1, @t_1) and the - * bottom right corner will have texture coordinates of (@s_2, @t_2). - * - * <note>The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix.</note> - * - * This is a high level drawing api that can handle any kind of - * #CoglMetaTexture texture such as #CoglTexture2DSliced textures - * which may internally be comprised of multiple low-level textures. - * This is unlike low-level drawing apis such as cogl_primitive_draw() - * which only support low level texture types that are directly - * supported by GPUs such as #CoglTexture2D. - * - * <note>The given texture coordinates will only be used for the first - * texture layer of the pipeline and if your pipeline has more than - * one layer then all other layers will have default texture - * coordinates of @s_1=0.0 @t_1=0.0 @s_2=1.0 @t_2=1.0 </note> - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in @s_1=0, @t_1=0, @s_2=1, @t_2=1. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_draw_textured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - float s_1, - float t_1, - float s_2, - float t_2); - -/** - * cogl_framebuffer_draw_multitextured_rectangle: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @x_1: x coordinate upper left on screen. - * @y_1: y coordinate upper left on screen. - * @x_2: x coordinate lower right on screen. - * @y_2: y coordinate lower right on screen. - * @tex_coords: (in) (array) (transfer none): An array containing groups of - * 4 float values: [s_1, t_1, s_2, t_2] that are interpreted as two texture - * coordinates; one for the top left texel, and one for the bottom right - * texel. Each value should be between 0.0 and 1.0, where the coordinate - * (0.0, 0.0) represents the top left of the texture, and (1.0, 1.0) the - * bottom right. - * @tex_coords_len: The length of the @tex_coords array. (For one layer - * and one group of texture coordinates, this would be 4) - * - * Draws a textured rectangle to @framebuffer with the given @pipeline - * state with the top left corner positioned at (@x_1, @y_1) and the - * bottom right corner positioned at (@x_2, @y_2). As a pipeline may - * contain multiple texture layers this interface lets you supply - * texture coordinates for each layer of the pipeline. - * - * <note>The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix.</note> - * - * This is a high level drawing api that can handle any kind of - * #CoglMetaTexture texture for the first layer such as - * #CoglTexture2DSliced textures which may internally be comprised of - * multiple low-level textures. This is unlike low-level drawing apis - * such as cogl_primitive_draw() which only support low level texture - * types that are directly supported by GPUs such as #CoglTexture2D. - * - * <note>This api can not currently handle multiple high-level meta - * texture layers. The first layer may be a high level meta texture - * such as #CoglTexture2DSliced but all other layers much be low - * level textures such as #CoglTexture2D. - * - * The top left texture coordinate for layer 0 of any pipeline will be - * (tex_coords[0], tex_coords[1]) and the bottom right coordinate will - * be (tex_coords[2], tex_coords[3]). The coordinates for layer 1 - * would be (tex_coords[4], tex_coords[5]) (tex_coords[6], - * tex_coords[7]) and so on... - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1, - * tex_coords[3]=1. - * - * The first pair of coordinates are for the first layer (with the - * smallest layer index) and if you supply less texture coordinates - * than there are layers in the current source material then default - * texture coordinates (0.0, 0.0, 1.0, 1.0) are generated. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_draw_multitextured_rectangle (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2, - const float *tex_coords, - int tex_coords_len); - -/** - * cogl_framebuffer_draw_rectangles: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @coordinates: (in) (array) (transfer none): an array of coordinates - * containing groups of 4 float values: [x_1, y_1, x_2, y_2] that are - * interpreted as two position coordinates; one for the top left of - * the rectangle (x1, y1), and one for the bottom right of the - * rectangle (x2, y2). - * @n_rectangles: number of rectangles defined in @coordinates. - * - * Draws a series of rectangles to @framebuffer with the given - * @pipeline state in the same way that - * cogl_framebuffer_draw_rectangle() does. - * - * The top left corner of the first rectangle is positioned at - * (coordinates[0], coordinates[1]) and the bottom right corner is - * positioned at (coordinates[2], coordinates[3]). The positions for - * the second rectangle are (coordinates[4], coordinates[5]) and - * (coordinates[6], coordinates[7]) and so on... - * - * <note>The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix.</note> - * - * As a general rule for better performance its recommended to use - * this this API instead of calling - * cogl_framebuffer_draw_textured_rectangle() separately for multiple - * rectangles if all of the rectangles will be drawn together with the - * same @pipeline state. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_draw_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles); - -/** - * cogl_framebuffer_draw_textured_rectangles: - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * @coordinates: (in) (array) (transfer none): an array containing - * groups of 8 float values: [x_1, y_1, x_2, y_2, s_1, t_1, s_2, t_2] - * that have the same meaning as the arguments for - * cogl_framebuffer_draw_textured_rectangle(). - * @n_rectangles: number of rectangles to @coordinates to draw - * - * Draws a series of rectangles to @framebuffer with the given - * @pipeline state in the same way that - * cogl_framebuffer_draw_textured_rectangle() does. - * - * <note>The position is the position before the rectangle has been - * transformed by the model-view matrix and the projection - * matrix.</note> - * - * This is a high level drawing api that can handle any kind of - * #CoglMetaTexture texture such as #CoglTexture2DSliced textures - * which may internally be comprised of multiple low-level textures. - * This is unlike low-level drawing apis such as cogl_primitive_draw() - * which only support low level texture types that are directly - * supported by GPUs such as #CoglTexture2D. - * - * The top left corner of the first rectangle is positioned at - * (coordinates[0], coordinates[1]) and the bottom right corner is - * positioned at (coordinates[2], coordinates[3]). The top left - * texture coordinate is (coordinates[4], coordinates[5]) and the - * bottom right texture coordinate is (coordinates[6], - * coordinates[7]). The coordinates for subsequent rectangles - * are defined similarly by the subsequent coordinates. - * - * As a general rule for better performance its recommended to use - * this this API instead of calling - * cogl_framebuffer_draw_textured_rectangle() separately for multiple - * rectangles if all of the rectangles will be drawn together with the - * same @pipeline state. - * - * The given texture coordinates should always be normalized such that - * (0, 0) corresponds to the top left and (1, 1) corresponds to the - * bottom right. To map an entire texture across the rectangle pass - * in tex_coords[0]=0, tex_coords[1]=0, tex_coords[2]=1, - * tex_coords[3]=1. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *coordinates, - unsigned int n_rectangles); - -/* XXX: Should we take an n_buffers + buffer id array instead of using - * the CoglBufferBits type which doesn't seem future proof? */ -/** - * cogl_framebuffer_discard_buffers: - * @framebuffer: A #CoglFramebuffer - * @buffers: A #CoglBufferBit mask of which ancillary buffers you want - * to discard. - * - * Declares that the specified @buffers no longer need to be referenced - * by any further rendering commands. This can be an important - * optimization to avoid subsequent frames of rendering depending on - * the results of a previous frame. - * - * For example; some tile-based rendering GPUs are able to avoid allocating and - * accessing system memory for the depth and stencil buffer so long as these - * buffers are not required as input for subsequent frames and that can save a - * significant amount of memory bandwidth used to save and restore their - * contents to system memory between frames. - * - * It is currently considered an error to try and explicitly discard the color - * buffer by passing %COGL_BUFFER_BIT_COLOR. This is because the color buffer is - * already implicitly discard when you finish rendering to a #CoglOnscreen - * framebuffer, and it's not meaningful to try and discard the color buffer of - * a #CoglOffscreen framebuffer since they are single-buffered. - * - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, - unsigned long buffers); - -/** - * cogl_framebuffer_finish: - * @framebuffer: A #CoglFramebuffer pointer - * - * This blocks the CPU until all pending rendering associated with the - * specified framebuffer has completed. It's very rare that developers should - * ever need this level of synchronization with the GPU and should never be - * used unless you clearly understand why you need to explicitly force - * synchronization. - * - * One example might be for benchmarking purposes to be sure timing - * measurements reflect the time that the GPU is busy for not just the time it - * takes to queue rendering commands. - * - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT void -cogl_framebuffer_finish (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_read_pixels_into_bitmap: - * @framebuffer: A #CoglFramebuffer - * @x: The x position to read from - * @y: The y position to read from - * @source: Identifies which auxiliary buffer you want to read - * (only COGL_READ_PIXELS_COLOR_BUFFER supported currently) - * @bitmap: The bitmap to store the results in. - * - * This reads a rectangle of pixels from the given framebuffer where - * position (0, 0) is the top left. The pixel at (x, y) is the first - * read, and a rectangle of pixels with the same size as the bitmap is - * read right and downwards from that point. - * - * Currently Cogl assumes that the framebuffer is in a premultiplied - * format so if the format of @bitmap is non-premultiplied it will - * convert it. To read the pixel values without any conversion you - * should either specify a format that doesn't use an alpha channel or - * use one of the formats ending in PRE. - * - * Return value: %TRUE if the read succeeded or %FALSE otherwise. The - * function is only likely to fail if the bitmap points to a pixel - * buffer and it could not be mapped. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap); - -/** - * cogl_framebuffer_read_pixels: - * @framebuffer: A #CoglFramebuffer - * @x: The x position to read from - * @y: The y position to read from - * @width: The width of the region of rectangles to read - * @height: The height of the region of rectangles to read - * @format: The pixel format to store the data in - * @pixels: The address of the buffer to store the data in - * - * This is a convenience wrapper around - * cogl_framebuffer_read_pixels_into_bitmap() which allocates a - * temporary #CoglBitmap to read pixel data directly into the given - * buffer. The rowstride of the buffer is assumed to be the width of - * the region times the bytes per pixel of the format. The source for - * the data is always taken from the color buffer. If you want to use - * any other rowstride or source, please use the - * cogl_framebuffer_read_pixels_into_bitmap() function directly. - * - * The implementation of the function looks like this: - * - * |[ - * bitmap = cogl_bitmap_new_for_data (context, - * width, height, - * format, - * /<!-- -->* rowstride *<!-- -->/ - * bpp * width, - * pixels); - * cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - * x, y, - * COGL_READ_PIXELS_COLOR_BUFFER, - * bitmap); - * cogl_object_unref (bitmap); - * ]| - * - * Return value: %TRUE if the read succeeded or %FALSE otherwise. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, - int x, - int y, - int width, - int height, - CoglPixelFormat format, - uint8_t *pixels); - -COGL_EXPORT uint32_t -cogl_framebuffer_error_quark (void); - -/** - * COGL_FRAMEBUFFER_ERROR: - * - * An error domain for reporting #CoglFramebuffer exceptions - */ -#define COGL_FRAMEBUFFER_ERROR (cogl_framebuffer_error_quark ()) - -typedef enum /*< prefix=COGL_FRAMEBUFFER_ERROR >*/ -{ - COGL_FRAMEBUFFER_ERROR_ALLOCATE -} CoglFramebufferError; - -/** - * cogl_is_framebuffer: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglFramebuffer. - * - * Return value: %TRUE if the object references a #CoglFramebuffer - * and %FALSE otherwise. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_framebuffer (void *object); - -/** - * cogl_blit_framebuffer: - * @framebuffer: The source #CoglFramebuffer - * @dst: The destination #CoglFramebuffer - * @src_x: Source x position - * @src_y: Source y position - * @dst_x: Destination x position - * @dst_y: Destination y position - * @width: Width of region to copy - * @height: Height of region to copy - * @error: optional error object - * - * @return FALSE for an immediately detected error, TRUE otherwise. - * - * This blits a region of the color buffer of the source buffer - * to the destination buffer. This function should only be - * called if the COGL_FEATURE_ID_BLIT_FRAMEBUFFER feature is - * advertised. - * - * The source and destination rectangles are defined in offscreen - * framebuffer orientation. When copying between an offscreen and - * onscreen framebuffers, the image is y-flipped accordingly. - * - * The two buffers must have the same value types (e.g. floating-point, - * unsigned int, signed int, or fixed-point), but color formats do not - * need to match. This limitation comes from OpenGL ES 3.0 definition - * of glBlitFramebuffer. - * - * Note that this function differs a lot from the glBlitFramebuffer - * function provided by the GL_EXT_framebuffer_blit extension. Notably - * it doesn't support having different sizes for the source and - * destination rectangle. This doesn't seem - * like a particularly useful feature. If the application wanted to - * scale the results it may make more sense to draw a primitive - * instead. - * - * The GL function is documented to be affected by the scissor. This - * function therefore ensure that an empty clip stack is flushed - * before performing the blit which means the scissor is effectively - * ignored. - * - * The function also doesn't support specifying the buffers to copy - * and instead only the color buffer is copied. When copying the depth - * or stencil buffers the extension on GLES2.0 only supports copying - * the full buffer which would be awkward to document with this - * API. If we wanted to support that feature it may be better to have - * a separate function to copy the entire buffer for a given mask. - * - * The @c error argument is optional, it can be NULL. If it is not NULL - * and this function returns FALSE, an error object with a code from - * COGL_SYSTEM_ERROR will be created. - */ -COGL_EXPORT gboolean -cogl_blit_framebuffer (CoglFramebuffer *framebuffer, - CoglFramebuffer *dst, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - GError **error); - -/** - * cogl_framebuffer_flush: - * @framebuffer: A #CoglFramebuffer pointer - * - * Flushes @framebuffer to ensure the current batch of commands is - * submitted to the GPU. - * - * Unlike cogl_framebuffer_finish(), this does not block the CPU. - */ -COGL_EXPORT void -cogl_framebuffer_flush (CoglFramebuffer *framebuffer); - -/** - * cogl_framebuffer_create_timestamp_query: (skip) - * - * Creates a query for the GPU timestamp that will complete upon completion of - * all previously submitted GL commands related to this framebuffer. E.g. when - * the rendering is finished on this framebuffer. - * - * This function should only be called if the COGL_FEATURE_ID_TIMESTAMP_QUERY - * feature is advertised. - */ -COGL_EXPORT CoglTimestampQuery * -cogl_framebuffer_create_timestamp_query (CoglFramebuffer *framebuffer); - -G_END_DECLS - -#endif /* __COGL_FRAMEBUFFER_H */ diff --git a/cogl/cogl/cogl-gl-header.h.in b/cogl/cogl/cogl-gl-header.h.in deleted file mode 100644 index a6659e92f..000000000 --- a/cogl/cogl/cogl-gl-header.h.in +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(COGL_COMPILATION) && !defined(COGL_ENABLE_MUTTER_API) -#error "cogl-gl-header.h should only be included when compiling Cogl" -#endif - -#ifndef __COGL_GL_HEADER_H__ -#define __COGL_GL_HEADER_H__ - -#include "cogl-defines.h" - -@COGL_GL_HEADER_INCLUDES@ - -#ifndef GL_OES_EGL_image -#define GLeglImageOES void * -#endif - -#endif /* __COGL_GL_HEADER_H__ */ diff --git a/cogl/cogl/cogl-glib-source.c b/cogl/cogl/cogl-glib-source.c deleted file mode 100644 index aa86c828d..000000000 --- a/cogl/cogl/cogl-glib-source.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-glib-source.h" -#include "cogl-poll.h" - -typedef struct _CoglGLibSource -{ - GSource source; - - CoglRenderer *renderer; - - GArray *poll_fds; - int poll_fds_age; - - int64_t expiration_time; -} CoglGLibSource; - -static gboolean -cogl_glib_source_prepare (GSource *source, int *timeout) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - CoglPollFD *poll_fds; - int n_poll_fds; - int64_t cogl_timeout; - int age; - int i; - - age = cogl_poll_renderer_get_info (cogl_source->renderer, - &poll_fds, - &n_poll_fds, - &cogl_timeout); - - /* We have to be careful not to call g_source_add/remove_poll unless - * the FDs have changed because it will cause the main loop to - * immediately wake up. If we call it every time the source is - * prepared it will effectively never go idle. */ - if (age != cogl_source->poll_fds_age) - { - /* Remove any existing polls before adding the new ones */ - for (i = 0; i < cogl_source->poll_fds->len; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - g_source_remove_poll (source, poll_fd); - } - - g_array_set_size (cogl_source->poll_fds, n_poll_fds); - - for (i = 0; i < n_poll_fds; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - poll_fd->fd = poll_fds[i].fd; - g_source_add_poll (source, poll_fd); - } - } - - cogl_source->poll_fds_age = age; - - /* Update the events */ - for (i = 0; i < n_poll_fds; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - poll_fd->events = poll_fds[i].events; - poll_fd->revents = 0; - } - - if (cogl_timeout == -1) - { - *timeout = -1; - cogl_source->expiration_time = -1; - } - else - { - /* Round up to ensure that we don't try again too early */ - *timeout = (cogl_timeout + 999) / 1000; - cogl_source->expiration_time = (g_source_get_time (source) + - cogl_timeout); - } - - return *timeout == 0; -} - -static gboolean -cogl_glib_source_check (GSource *source) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - int i; - - if (cogl_source->expiration_time >= 0 && - g_source_get_time (source) >= cogl_source->expiration_time) - return TRUE; - - for (i = 0; i < cogl_source->poll_fds->len; i++) - { - GPollFD *poll_fd = &g_array_index (cogl_source->poll_fds, GPollFD, i); - if (poll_fd->revents != 0) - return TRUE; - } - - return FALSE; -} - -static gboolean -cogl_glib_source_dispatch (GSource *source, - GSourceFunc callback, - void *user_data) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - CoglPollFD *poll_fds = - (CoglPollFD *) &g_array_index (cogl_source->poll_fds, GPollFD, 0); - - cogl_poll_renderer_dispatch (cogl_source->renderer, - poll_fds, - cogl_source->poll_fds->len); - - return TRUE; -} - -static void -cogl_glib_source_finalize (GSource *source) -{ - CoglGLibSource *cogl_source = (CoglGLibSource *) source; - - g_array_free (cogl_source->poll_fds, TRUE); -} - -static GSourceFuncs -cogl_glib_source_funcs = - { - cogl_glib_source_prepare, - cogl_glib_source_check, - cogl_glib_source_dispatch, - cogl_glib_source_finalize - }; - -GSource * -cogl_glib_renderer_source_new (CoglRenderer *renderer, - int priority) -{ - GSource *source; - CoglGLibSource *cogl_source; - - source = g_source_new (&cogl_glib_source_funcs, - sizeof (CoglGLibSource)); - cogl_source = (CoglGLibSource *) source; - - cogl_source->renderer = renderer; - cogl_source->poll_fds = g_array_new (FALSE, FALSE, sizeof (GPollFD)); - - if (priority != G_PRIORITY_DEFAULT) - g_source_set_priority (source, priority); - - return source; -} - -GSource * -cogl_glib_source_new (CoglContext *context, - int priority) -{ - return cogl_glib_renderer_source_new (cogl_context_get_renderer (context), - priority); -} - - diff --git a/cogl/cogl/cogl-glib-source.h b/cogl/cogl/cogl-glib-source.h deleted file mode 100644 index cf192e3d7..000000000 --- a/cogl/cogl/cogl-glib-source.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_GSOURCE_H__ -#define __COGL_GSOURCE_H__ - -#include <glib.h> -#include <cogl/cogl-context.h> - -G_BEGIN_DECLS - -/** - * cogl_glib_source_new: - * @context: A #CoglContext - * @priority: The priority of the #GSource - * - * Creates a #GSource which handles Cogl's internal system event - * processing. This can be used as a convenience instead of - * cogl_poll_renderer_get_info() and cogl_poll_renderer_dispatch() in - * applications that are already using the GLib main loop. After this - * is called the #GSource should be attached to the main loop using - * g_source_attach(). - * - * Applications that manually connect to a #CoglRenderer before they - * create a #CoglContext should instead use - * cogl_glib_renderer_source_new() so that events may be dispatched - * before a context has been created. In that case you don't need to - * use this api in addition later, it is simply enough to use - * cogl_glib_renderer_source_new() instead. - * - * <note>This api is actually just a thin convenience wrapper around - * cogl_glib_renderer_source_new()</note> - * - * Return value: a new #GSource - * - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT GSource * -cogl_glib_source_new (CoglContext *context, - int priority); - -/** - * cogl_glib_renderer_source_new: - * @renderer: A #CoglRenderer - * @priority: The priority of the #GSource - * - * Creates a #GSource which handles Cogl's internal system event - * processing. This can be used as a convenience instead of - * cogl_poll_renderer_get_info() and cogl_poll_renderer_dispatch() in - * applications that are already using the GLib main loop. After this - * is called the #GSource should be attached to the main loop using - * g_source_attach(). - * - * Return value: a new #GSource - * - * Stability: unstable - * Since: 1.16 - */ -COGL_EXPORT GSource * -cogl_glib_renderer_source_new (CoglRenderer *renderer, - int priority); - -G_END_DECLS - -#endif /* __COGL_GSOURCE_H__ */ diff --git a/cogl/cogl/cogl-glsl-shader-boilerplate.h b/cogl/cogl/cogl-glsl-shader-boilerplate.h deleted file mode 100644 index 6d882dad2..000000000 --- a/cogl/cogl/cogl-glsl-shader-boilerplate.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_SHADER_BOILERPLATE_H -#define __COGL_SHADER_BOILERPLATE_H - -#define _COGL_COMMON_SHADER_BOILERPLATE \ - "#define COGL_VERSION 100\n" \ - "\n" \ - "uniform mat4 cogl_modelview_matrix;\n" \ - "uniform mat4 cogl_modelview_projection_matrix;\n" \ - "uniform mat4 cogl_projection_matrix;\n" - -/* This declares all of the variables that we might need. This is - * working on the assumption that the compiler will optimise them out - * if they are not actually used. The GLSL spec at least implies that - * this will happen for varyings but it doesn't explicitly so for - * attributes */ -#define _COGL_VERTEX_SHADER_BOILERPLATE \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "#define cogl_color_out _cogl_color\n" \ - "varying vec4 _cogl_color;\n" \ - "#define cogl_tex_coord_out _cogl_tex_coord\n" \ - "#define cogl_position_out gl_Position\n" \ - "#define cogl_point_size_out gl_PointSize\n" \ - "\n" \ - "attribute vec4 cogl_color_in;\n" \ - "attribute vec4 cogl_position_in;\n" \ - "#define cogl_tex_coord_in cogl_tex_coord0_in;\n" \ - "attribute vec3 cogl_normal_in;\n" - -#define _COGL_FRAGMENT_SHADER_BOILERPLATE \ - "#ifdef GL_ES\n" \ - "precision highp float;\n" \ - "#endif\n" \ - _COGL_COMMON_SHADER_BOILERPLATE \ - "\n" \ - "varying vec4 _cogl_color;\n" \ - "\n" \ - "#define cogl_color_in _cogl_color\n" \ - "#define cogl_tex_coord_in _cogl_tex_coord\n" \ - "\n" \ - "#define cogl_color_out gl_FragColor\n" \ - "#define cogl_depth_out gl_FragDepth\n" \ - "\n" \ - "#define cogl_front_facing gl_FrontFacing\n" \ - "\n" \ - "#define cogl_point_coord gl_PointCoord\n" -#if 0 - /* GLSL 1.2 has a bottom left origin, though later versions - * allow use of an origin_upper_left keyword which would be - * more appropriate for Cogl. */ - "#define coglFragCoord gl_FragCoord\n" -#endif - -#endif /* __COGL_SHADER_BOILERPLATE_H */ - diff --git a/cogl/cogl/cogl-graphene.c b/cogl/cogl/cogl-graphene.c deleted file mode 100644 index 38631db8c..000000000 --- a/cogl/cogl/cogl-graphene.c +++ /dev/null @@ -1,284 +0,0 @@ -/* cogl-graphene.c - * - * Copyright 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#include "cogl/cogl-graphene.h" - -typedef struct _Point2f -{ - float x; - float y; -} Point2f; - -typedef struct _Point3f -{ - float x; - float y; - float z; -} Point3f; - -typedef struct _Point4f -{ - float x; - float y; - float z; - float w; -} Point4f; - -static void -init_matrix_rows (const graphene_matrix_t *matrix, - unsigned int n_rows, - graphene_vec4_t *rows) -{ - graphene_matrix_t m; - unsigned int i; - - graphene_matrix_transpose (matrix, &m); - - for (i = 0; i < n_rows; i++) - graphene_matrix_get_row (&m, i, &rows[i]); -} - -static void -transform_points_f2 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[3]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point2f p = *(Point2f *)((uint8_t *)points_in + i * stride_in); - Point3f *o = (Point3f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, 0.f, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - } -} - -static void -project_points_f2 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[4]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point2f p = *(Point2f *)((uint8_t *)points_in + i * stride_in); - Point4f *o = (Point4f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, 0.f, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - o->w = graphene_vec4_dot (&rows[3], &point); - } -} - -static void -transform_points_f3 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[3]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point3f p = *(Point3f *)((uint8_t *)points_in + i * stride_in); - Point3f *o = (Point3f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, p.z, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - } -} - -static void -project_points_f3 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[4]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point3f p = *(Point3f *)((uint8_t *)points_in + i * stride_in); - Point4f *o = (Point4f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, p.z, 1.f); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - o->w = graphene_vec4_dot (&rows[3], &point); - } -} - -static void -project_points_f4 (const graphene_matrix_t *matrix, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - graphene_vec4_t rows[4]; - int i; - - init_matrix_rows (matrix, G_N_ELEMENTS (rows), rows); - - for (i = 0; i < n_points; i++) - { - Point4f p = *(Point4f *)((uint8_t *)points_in + i * stride_in); - Point4f *o = (Point4f *)((uint8_t *)points_out + i * stride_out); - graphene_vec4_t point; - - graphene_vec4_init (&point, p.x, p.y, p.z, p.w); - - o->x = graphene_vec4_dot (&rows[0], &point); - o->y = graphene_vec4_dot (&rows[1], &point); - o->z = graphene_vec4_dot (&rows[2], &point); - o->w = graphene_vec4_dot (&rows[3], &point); - } -} - -void -cogl_graphene_matrix_project_point (const graphene_matrix_t *matrix, - float *x, - float *y, - float *z, - float *w) -{ - graphene_vec4_t p; - - graphene_vec4_init (&p, *x, *y, *z, *w); - graphene_matrix_transform_vec4 (matrix, &p, &p); - - *x = graphene_vec4_get_x (&p); - *y = graphene_vec4_get_y (&p); - *z = graphene_vec4_get_z (&p); - *w = graphene_vec4_get_w (&p); -} - -void -cogl_graphene_matrix_transform_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - /* The results of transforming always have three components... */ - g_return_if_fail (stride_out >= sizeof (Point3f)); - - if (n_components == 2) - { - transform_points_f2 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } - else - { - g_return_if_fail (n_components == 3); - - transform_points_f3 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } -} - -void -cogl_graphene_matrix_project_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points) -{ - if (n_components == 2) - { - project_points_f2 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } - else if (n_components == 3) - { - project_points_f3 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } - else - { - g_return_if_fail (n_components == 4); - - project_points_f4 (matrix, - stride_in, points_in, - stride_out, points_out, - n_points); - } -} diff --git a/cogl/cogl/cogl-graphene.h b/cogl/cogl/cogl-graphene.h deleted file mode 100644 index cd0d2971e..000000000 --- a/cogl/cogl/cogl-graphene.h +++ /dev/null @@ -1,176 +0,0 @@ -/* cogl-graphene.h - * - * Copyright 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#ifndef COGL_GRAPHENE_H -#define COGL_GRAPHENE_H - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-macros.h> -#include <cogl/cogl-types.h> - -#include <glib.h> - -#include <graphene.h> - -G_BEGIN_DECLS - - -/** - * cogl_graphene_matrix_project_point: - * @matrix: A 4x4 transformation matrix - * @x: (inout): The X component of your points position - * @y: (inout): The Y component of your points position - * @z: (inout): The Z component of your points position - * @w: (inout): The W component of your points position - * - * Transforms a point whose position is given and returned as four float - * components. - */ -COGL_EXPORT void -cogl_graphene_matrix_project_point (const graphene_matrix_t *matrix, - float *x, - float *y, - float *z, - float *w); - -/** - * cogl_graphene_matrix_transform_points: - * @matrix: A transformation matrix - * @n_components: The number of position components for each input point. - * (either 2 or 3) - * @stride_in: The stride in bytes between input points. - * @points_in: A pointer to the first component of the first input point. - * @stride_out: The stride in bytes between output points. - * @points_out: A pointer to the first component of the first output point. - * @n_points: The number of points to transform. - * - * Transforms an array of input points and writes the result to - * another array of output points. The input points can either have 2 - * or 3 components each. The output points always have 3 components. - * The output array can simply point to the input array to do the - * transform in-place. - * - * If you need to transform 4 component points see - * cogl_graphene_matrix_project_points(). - * - * Here's an example with differing input/output strides: - * |[ - * typedef struct { - * float x,y; - * uint8_t r,g,b,a; - * float s,t,p; - * } MyInVertex; - * typedef struct { - * uint8_t r,g,b,a; - * float x,y,z; - * } MyOutVertex; - * MyInVertex vertices[N_VERTICES]; - * MyOutVertex results[N_VERTICES]; - * graphene_matrix_t matrix; - * - * my_load_vertices (vertices); - * my_get_matrix (&matrix); - * - * cogl_graphene_matrix_transform_points (&matrix, - * 2, - * sizeof (MyInVertex), - * &vertices[0].x, - * sizeof (MyOutVertex), - * &results[0].x, - * N_VERTICES); - * ]| - * - * Stability: unstable - */ -COGL_EXPORT void -cogl_graphene_matrix_transform_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points); - -/** - * cogl_graphene_matrix_project_points: - * @matrix: A projection matrix - * @n_components: The number of position components for each input point. - * (either 2, 3 or 4) - * @stride_in: The stride in bytes between input points. - * @points_in: A pointer to the first component of the first input point. - * @stride_out: The stride in bytes between output points. - * @points_out: A pointer to the first component of the first output point. - * @n_points: The number of points to transform. - * - * Projects an array of input points and writes the result to another - * array of output points. The input points can either have 2, 3 or 4 - * components each. The output points always have 4 components (known - * as homogeneous coordinates). The output array can simply point to - * the input array to do the transform in-place. - * - * Here's an example with differing input/output strides: - * |[ - * typedef struct { - * float x,y; - * uint8_t r,g,b,a; - * float s,t,p; - * } MyInVertex; - * typedef struct { - * uint8_t r,g,b,a; - * float x,y,z; - * } MyOutVertex; - * MyInVertex vertices[N_VERTICES]; - * MyOutVertex results[N_VERTICES]; - * graphene_matrix_t matrix; - * - * my_load_vertices (vertices); - * my_get_matrix (&matrix); - * - * cogl_graphene_matrix_project_points (&matrix, - * 2, - * sizeof (MyInVertex), - * &vertices[0].x, - * sizeof (MyOutVertex), - * &results[0].x, - * N_VERTICES); - * ]| - * - * Stability: unstable - */ -COGL_EXPORT void -cogl_graphene_matrix_project_points (const graphene_matrix_t *matrix, - int n_components, - size_t stride_in, - const void *points_in, - size_t stride_out, - void *points_out, - int n_points); - -G_END_DECLS - -#endif /* COGL_GRAPHENE_H */ diff --git a/cogl/cogl/cogl-gtype-private.h b/cogl/cogl/cogl-gtype-private.h deleted file mode 100644 index 1926f3f62..000000000 --- a/cogl/cogl/cogl-gtype-private.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_GTYPE_PRIVATE_H__ -#define __COGL_GTYPE_PRIVATE_H__ - -#include "cogl-config.h" - -#include <glib.h> -#include <glib-object.h> - -#include "cogl-object-private.h" - -/* Move this to public headers? */ -typedef struct _CoglGtypeObject CoglGtypeObject; -typedef struct _CoglGtypeClass CoglGtypeClass; - -struct _CoglGtypeObject -{ - GTypeInstance parent_instance; - - guint dummy; -}; - -struct _CoglGtypeClass -{ - GTypeClass base_class; - - guint dummy; -}; - -#define I_(str) (g_intern_static_string ((str))) - -/**/ - -#define COGL_GTYPE_DEFINE_BOXED(Name,underscore_name,copy_func,free_func) \ -GType \ -cogl_##underscore_name##_get_gtype (void) \ -{ \ - static size_t g_type_id = 0; \ - if (g_once_init_enter (&g_type_id)) \ - { \ - GType type = \ - g_boxed_type_register_static (g_intern_static_string (I_("Cogl" # Name)), \ - (GBoxedCopyFunc)copy_func, \ - (GBoxedFreeFunc)free_func); \ - g_once_init_leave (&g_type_id, type); \ - } \ - return g_type_id; \ -} - -#define COGL_GTYPE_IMPLEMENT_INTERFACE(name) { \ - const GInterfaceInfo g_implement_interface_info = { \ - (GInterfaceInitFunc) _cogl_gtype_dummy_iface_init, NULL, NULL \ - }; \ - g_type_add_interface_static (fundamental_type_id, \ - cogl_##name##_get_gtype(), \ - &g_implement_interface_info); \ - } - -#define _COGL_GTYPE_DEFINE_BASE_CLASS_BEGIN(Name,name) \ -GType \ -cogl_##name##_get_gtype (void) \ -{ \ - static size_t g_type_id = 0; \ - if (g_once_init_enter (&g_type_id)) \ - { \ - static const GTypeFundamentalInfo finfo = { \ - (G_TYPE_FLAG_CLASSED | \ - G_TYPE_FLAG_INSTANTIATABLE | \ - G_TYPE_FLAG_DERIVABLE | \ - G_TYPE_FLAG_DEEP_DERIVABLE), \ - }; \ - static const GTypeValueTable value_table = { \ - _cogl_gtype_object_init_value, \ - _cogl_gtype_object_free_value, \ - _cogl_gtype_object_copy_value, \ - _cogl_gtype_object_peek_pointer, \ - "p", \ - _cogl_gtype_object_collect_value, \ - "p", \ - _cogl_gtype_object_lcopy_value, \ - }; \ - const GTypeInfo node_info = { \ - sizeof (CoglObjectClass), \ - (GBaseInitFunc) _cogl_gtype_object_class_base_init, \ - (GBaseFinalizeFunc) _cogl_gtype_object_class_base_finalize, \ - (GClassInitFunc) _cogl_gtype_object_class_init, \ - (GClassFinalizeFunc) NULL, \ - NULL, \ - sizeof (CoglObject), \ - 0, \ - (GInstanceInitFunc) _cogl_gtype_object_init, \ - &value_table, \ - }; \ - GType fundamental_type_id = \ - g_type_register_fundamental (g_type_fundamental_next (), \ - I_("Cogl" # Name), \ - &node_info, &finfo, \ - G_TYPE_FLAG_ABSTRACT); \ - g_once_init_leave (&g_type_id, \ - fundamental_type_id); - -#define _COGL_GTYPE_DEFINE_BASE_CLASS_END() \ - } \ - return g_type_id; \ - } - -#define COGL_GTYPE_DEFINE_BASE_CLASS(Name,name,...) \ - _COGL_GTYPE_DEFINE_BASE_CLASS_BEGIN(Name,name) \ - {__VA_ARGS__;} \ - _COGL_GTYPE_DEFINE_BASE_CLASS_END() - -#define _COGL_GTYPE_DEFINE_INTERFACE_EXTENDED_BEGIN(Name,name) \ - \ - static void name##_default_init (Name##Interface *klass); \ - GType \ - name##_get_gtype (void) \ - { \ - static size_t g_type_id = 0; \ - if (g_once_init_enter (&g_type_id)) \ - { \ - GType fundamental_type_id = \ - g_type_register_static_simple (G_TYPE_INTERFACE, \ - g_intern_static_string (#Name), \ - sizeof (Name##Interface), \ - (GClassInitFunc)name##_default_init, \ - 0, \ - (GInstanceInitFunc)NULL, \ - (GTypeFlags) 0); \ - g_type_interface_add_prerequisite (fundamental_type_id, \ - cogl_object_get_gtype()); \ - { /* custom code follows */ - -#define _COGL_GTYPE_DEFINE_INTERFACE_EXTENDED_END() \ - /* following custom code */ \ - } \ - g_once_init_leave (&g_type_id, \ - fundamental_type_id); \ - } \ - return g_type_id; \ - } /* closes name##_get_type() */ - - -#define COGL_GTYPE_DEFINE_INTERFACE(Name,name) \ - typedef struct _Cogl##Name##Iface Cogl##Name##Iface; \ - typedef Cogl##Name##Iface Cogl##Name##Interface; \ - struct _Cogl##Name##Iface \ - { \ - /*< private >*/ \ - GTypeInterface g_iface; \ - }; \ - _COGL_GTYPE_DEFINE_INTERFACE_EXTENDED_BEGIN (Cogl##Name, cogl_##name) \ - _COGL_GTYPE_DEFINE_INTERFACE_EXTENDED_END () \ - static void \ - cogl_##name##_default_init (Cogl##Name##Interface *iface) \ - { \ - } - -#define _COGL_GTYPE_DEFINE_TYPE_EXTENDED_BEGIN(Name,name,parent,flags) \ - \ - static void name##_init (Name *self); \ - static void name##_class_init (Name##Class *klass); \ - static gpointer name##_parent_class = NULL; \ - static gint Name##_private_offset; \ - \ - static void \ - name##_class_intern_init (gpointer klass) \ - { \ - name##_parent_class = g_type_class_peek_parent (klass); \ - name##_class_init ((Name##Class*) klass); \ - } \ - \ - static inline gpointer \ - name##_get_instance_private (Name *self) \ - { \ - return (G_STRUCT_MEMBER_P (self, Name ##_private_offset)); \ - } \ - \ - GType \ - name##_get_gtype (void) \ - { \ - static size_t g_type_id = 0; \ - if (g_once_init_enter (&g_type_id)) \ - { \ - GType fundamental_type_id = \ - g_type_register_static_simple (parent, \ - g_intern_static_string (#Name), \ - sizeof (Name##Class), \ - (GClassInitFunc) name##_class_intern_init, \ - sizeof (Name), \ - (GInstanceInitFunc) name##_init, \ - (GTypeFlags) flags); \ - { /* custom code follows */ - -#define _COGL_GTYPE_DEFINE_TYPE_EXTENDED_END() \ - /* following custom code */ \ - } \ - g_once_init_leave (&g_type_id, \ - fundamental_type_id); \ - } \ - return g_type_id; \ - } /* closes name##_get_type() */ - - -#define COGL_GTYPE_DEFINE_CLASS(Name,name,...) \ - typedef struct _Cogl##Name##Class Cogl##Name##Class; \ - struct _Cogl##Name##Class { \ - CoglObjectClass parent_class; \ - }; \ - _COGL_GTYPE_DEFINE_TYPE_EXTENDED_BEGIN(Cogl##Name, \ - cogl_##name, \ - cogl_object_get_gtype(), \ - 0) \ - {__VA_ARGS__;} \ - _COGL_GTYPE_DEFINE_TYPE_EXTENDED_END() \ - static void \ - cogl_##name##_init (Cogl##Name *instance) \ - { \ - } \ - static void \ - cogl_##name##_class_init (Cogl##Name##Class *klass) \ - { \ - } - -void _cogl_gtype_object_init_value (GValue *value); -void _cogl_gtype_object_free_value (GValue *value); -void _cogl_gtype_object_copy_value (const GValue *src, - GValue *dst); -gpointer _cogl_gtype_object_peek_pointer (const GValue *value); -gchar *_cogl_gtype_object_collect_value (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags); -gchar *_cogl_gtype_object_lcopy_value (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags); - -void _cogl_gtype_object_class_base_init (CoglObjectClass *klass); -void _cogl_gtype_object_class_base_finalize (CoglObjectClass *klass); -void _cogl_gtype_object_class_init (CoglObjectClass *klass); -void _cogl_gtype_object_init (CoglObject *object); - -COGL_EXPORT -void cogl_object_value_set_object (GValue *value, - gpointer object); -COGL_EXPORT -gpointer cogl_object_value_get_object (const GValue *value); - -void _cogl_gtype_dummy_iface_init (gpointer iface); - -#endif /* __COGL_GTYPE_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-gtype.c b/cogl/cogl/cogl-gtype.c deleted file mode 100644 index 314d8e41f..000000000 --- a/cogl/cogl/cogl-gtype.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "cogl-gtype-private.h" - -#include <gobject/gvaluecollector.h> - -void -_cogl_gtype_object_init_value (GValue *value) -{ - value->data[0].v_pointer = NULL; -} - -void -_cogl_gtype_object_free_value (GValue *value) -{ - if (value->data[0].v_pointer != NULL) - cogl_object_unref (value->data[0].v_pointer); -} - -void -_cogl_gtype_object_copy_value (const GValue *src, - GValue *dst) -{ - if (src->data[0].v_pointer != NULL) - dst->data[0].v_pointer = cogl_object_ref (src->data[0].v_pointer); - else - dst->data[0].v_pointer = NULL; -} - -gpointer -_cogl_gtype_object_peek_pointer (const GValue *value) -{ - return value->data[0].v_pointer; -} - -gchar * -_cogl_gtype_object_collect_value (GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - CoglObject *object; - - object = collect_values[0].v_pointer; - - if (object == NULL) - { - value->data[0].v_pointer = NULL; - return NULL; - } - - if (object->klass == NULL) - return g_strconcat ("invalid unclassed CoglObject pointer for " - "value type '", - G_VALUE_TYPE_NAME (value), - "'", - NULL); - - value->data[0].v_pointer = cogl_object_ref (object); - - return NULL; -} - -gchar * -_cogl_gtype_object_lcopy_value (const GValue *value, - guint n_collect_values, - GTypeCValue *collect_values, - guint collect_flags) -{ - CoglObject **object_p = collect_values[0].v_pointer; - - if (object_p == NULL) - return g_strconcat ("value location for '", - G_VALUE_TYPE_NAME (value), - "' passed as NULL", - NULL); - - if (value->data[0].v_pointer == NULL) - *object_p = NULL; - else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) - *object_p = value->data[0].v_pointer; - else - *object_p = cogl_object_ref (value->data[0].v_pointer); - - return NULL; -} - -void -_cogl_gtype_object_class_base_init (CoglObjectClass *klass) -{ -} - -void -_cogl_gtype_object_class_base_finalize (CoglObjectClass *klass) -{ -} - -void -_cogl_gtype_object_class_init (CoglObjectClass *klass) -{ -} - -void -_cogl_gtype_object_init (CoglObject *object) -{ -} - -void -_cogl_gtype_dummy_iface_init (gpointer iface) -{ -} - -/** - * cogl_object_value_set_object: - * @value: a #GValue initialized with %COGL_GTYPE_TYPE_OBJECT - * @object: (type Cogl.GtypeObject) (allow-none): a #CoglGtypeObject, or %NULL - * - * Sets the contents of a #GValue initialized with %COGL_GTYPE_TYPE_OBJECT. - * - */ -void -cogl_object_value_set_object (GValue *value, - gpointer object) -{ - CoglObject *old_object; - - old_object = value->data[0].v_pointer; - - if (object != NULL) - { - /* take over ownership */ - value->data[0].v_pointer = object; - } - else - value->data[0].v_pointer = NULL; - - if (old_object != NULL) - cogl_object_unref (old_object); -} - -/** - * cogl_object_value_get_object: - * @value: a #GValue initialized with %COGL_GTYPE_TYPE_OBJECT - * - * Retrieves a pointer to the #CoglGtypeObject contained inside - * the passed #GValue. - * - * Return value: (transfer none) (type Cogl.GtypeObject): a pointer to - * a #CoglGtypeObject, or %NULL - */ -gpointer -cogl_object_value_get_object (const GValue *value) -{ - return value->data[0].v_pointer; -} diff --git a/cogl/cogl/cogl-i18n-private.h b/cogl/cogl/cogl-i18n-private.h deleted file mode 100644 index 94202f791..000000000 --- a/cogl/cogl/cogl-i18n-private.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef _COGL_I18N_PRIVATE_H_ -#define _COGL_I18N_PRIVATE_H_ - -#include <string.h> - -#define _(X) X -#define N_(X) X - -#endif /* _COGL_I18N_PRIVATE_H_ */ diff --git a/cogl/cogl/cogl-index-buffer-private.h b/cogl/cogl/cogl-index-buffer-private.h deleted file mode 100644 index d9596cd83..000000000 --- a/cogl/cogl/cogl-index-buffer-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_INDEX_BUFFER_PRIVATE_H -#define __COGL_INDEX_BUFFER_PRIVATE_H - -#include "cogl-buffer-private.h" - -struct _CoglIndexBuffer -{ - CoglBuffer _parent; -}; - -#endif /* __COGL_INDEX_BUFFER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-index-buffer.c b/cogl/cogl/cogl-index-buffer.c deleted file mode 100644 index 2050db3c9..000000000 --- a/cogl/cogl/cogl-index-buffer.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-object-private.h" -#include "cogl-indices.h" -#include "cogl-indices-private.h" -#include "cogl-context-private.h" -#include "cogl-gtype-private.h" - -static void _cogl_index_buffer_free (CoglIndexBuffer *indices); - -COGL_BUFFER_DEFINE (IndexBuffer, index_buffer); -COGL_GTYPE_DEFINE_CLASS (IndexBuffer, index_buffer); - -/* XXX: Unlike the wiki design this just takes a size. A single - * indices buffer should be able to contain multiple ranges of indices - * which the wiki design doesn't currently consider. */ -CoglIndexBuffer * -cogl_index_buffer_new (CoglContext *context, size_t bytes) -{ - CoglIndexBuffer *indices = g_new0 (CoglIndexBuffer, 1); - - /* parent's constructor */ - _cogl_buffer_initialize (COGL_BUFFER (indices), - context, - bytes, - COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, - COGL_BUFFER_USAGE_HINT_INDEX_BUFFER, - COGL_BUFFER_UPDATE_HINT_STATIC); - - return _cogl_index_buffer_object_new (indices); -} - -static void -_cogl_index_buffer_free (CoglIndexBuffer *indices) -{ - /* parent's destructor */ - _cogl_buffer_fini (COGL_BUFFER (indices)); - - g_free (indices); -} - -/* XXX: do we want a convenience function like this as an alternative - * to using cogl_buffer_set_data? The advantage of this is that we can - * track meta data such as the indices type and max_index_value for a - * range as part of the indices buffer. If we just leave people to use - * cogl_buffer_set_data then we either need a way to specify the type - * and max index value at draw time or we'll want a separate way to - * declare the type and max value for a range after uploading the - * data. - * - * XXX: I think in the end it'll be that CoglIndices are to - * CoglIndexBuffers as CoglAttributes are to CoglAttributeBuffers. I.e - * a CoglIndexBuffer is a lite subclass of CoglBuffer that simply - * implies that the buffer will later be bound as indices but doesn't - * track more detailed meta data. CoglIndices build on a - * CoglIndexBuffer and define the type and max_index_value for some - * sub-range of a CoglIndexBuffer. - */ -#if 0 -void -cogl_index_buffer_set_data (CoglIndexBuffer *indices, - CoglIndicesType type, - int max_index_value, - size_t write_offset, - void *user_indices, - int n_indices) -{ - GList *l; - - for (l = indices->ranges; l; l = l->next) - { - - } - cogl_buffer_set -} -#endif - diff --git a/cogl/cogl/cogl-index-buffer.h b/cogl/cogl/cogl-index-buffer.h deleted file mode 100644 index bf9bf1e99..000000000 --- a/cogl/cogl/cogl-index-buffer.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_INDEX_BUFFER_H__ -#define __COGL_INDEX_BUFFER_H__ - -#include <cogl/cogl-context.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-index-buffer - * @short_description: Functions for creating and manipulating vertex - * indices. - * - * FIXME - */ - -#define COGL_INDEX_BUFFER(buffer) ((CoglIndexBuffer*) buffer) - -typedef struct _CoglIndexBuffer CoglIndexBuffer; - -/** - * cogl_index_buffer_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT GType cogl_index_buffer_get_gtype (void); - -/** - * cogl_index_buffer_new: - * @context: A #CoglContext - * @bytes: The number of bytes to allocate for vertex attribute data. - * - * Declares a new #CoglIndexBuffer of @size bytes to contain vertex - * indices. Once declared, data can be set using - * cogl_buffer_set_data() or by mapping it into the application's - * address space using cogl_buffer_map(). - * - * Return value: (transfer full): A newly allocated #CoglIndexBuffer - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT CoglIndexBuffer * -cogl_index_buffer_new (CoglContext *context, - size_t bytes); - -/** - * cogl_is_index_buffer: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglIndexBuffer. - * - * Returns: %TRUE if the @object references a #CoglIndexBuffer, - * %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_index_buffer (void *object); - -G_END_DECLS - -#endif /* __COGL_INDEX_BUFFER_H__ */ - diff --git a/cogl/cogl/cogl-indices-private.h b/cogl/cogl/cogl-indices-private.h deleted file mode 100644 index 3d5891687..000000000 --- a/cogl/cogl/cogl-indices-private.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_INDICES_PRIVATE_H -#define __COGL_INDICES_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-index-buffer-private.h" -#include "cogl-types.h" - -struct _CoglIndices -{ - CoglObject _parent; - - CoglIndexBuffer *buffer; - size_t offset; - - CoglIndicesType type; - - int immutable_ref; -}; - -CoglIndices * -_cogl_indices_immutable_ref (CoglIndices *indices); - -void -_cogl_indices_immutable_unref (CoglIndices *indices); - -#endif /* __COGL_INDICES_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-indices.c b/cogl/cogl/cogl-indices.c deleted file mode 100644 index 7613c587f..000000000 --- a/cogl/cogl/cogl-indices.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-object-private.h" -#include "cogl-context-private.h" -#include "cogl-indices.h" -#include "cogl-indices-private.h" -#include "cogl-index-buffer.h" -#include "cogl-gtype-private.h" - -#include <stdarg.h> - -static void _cogl_indices_free (CoglIndices *indices); - -COGL_OBJECT_DEFINE (Indices, indices); -COGL_GTYPE_DEFINE_CLASS (Indices, indices); - -static size_t -sizeof_indices_type (CoglIndicesType type) -{ - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return 4; - } - g_return_val_if_reached (0); -} - -CoglIndices * -cogl_indices_new_for_buffer (CoglIndicesType type, - CoglIndexBuffer *buffer, - size_t offset) -{ - CoglIndices *indices = g_new0 (CoglIndices, 1); - - indices->buffer = cogl_object_ref (buffer); - indices->offset = offset; - - indices->type = type; - - indices->immutable_ref = 0; - - return _cogl_indices_object_new (indices); -} - -CoglIndices * -cogl_indices_new (CoglContext *context, - CoglIndicesType type, - const void *indices_data, - int n_indices) -{ - size_t buffer_bytes = sizeof_indices_type (type) * n_indices; - CoglIndexBuffer *index_buffer = cogl_index_buffer_new (context, buffer_bytes); - CoglBuffer *buffer = COGL_BUFFER (index_buffer); - CoglIndices *indices; - GError *ignore_error = NULL; - - _cogl_buffer_set_data (buffer, - 0, - indices_data, - buffer_bytes, - &ignore_error); - if (ignore_error) - { - g_error_free (ignore_error); - cogl_object_unref (index_buffer); - return NULL; - } - - indices = cogl_indices_new_for_buffer (type, index_buffer, 0); - cogl_object_unref (index_buffer); - - return indices; -} - -CoglIndexBuffer * -cogl_indices_get_buffer (CoglIndices *indices) -{ - return indices->buffer; -} - -CoglIndicesType -cogl_indices_get_type (CoglIndices *indices) -{ - g_return_val_if_fail (cogl_is_indices (indices), - COGL_INDICES_TYPE_UNSIGNED_BYTE); - return indices->type; -} - -size_t -cogl_indices_get_offset (CoglIndices *indices) -{ - g_return_val_if_fail (cogl_is_indices (indices), 0); - - return indices->offset; -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of indices has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_indices_set_offset (CoglIndices *indices, - size_t offset) -{ - g_return_if_fail (cogl_is_indices (indices)); - - if (G_UNLIKELY (indices->immutable_ref)) - warn_about_midscene_changes (); - - indices->offset = offset; -} - -static void -_cogl_indices_free (CoglIndices *indices) -{ - cogl_object_unref (indices->buffer); - g_free (indices); -} - -CoglIndices * -_cogl_indices_immutable_ref (CoglIndices *indices) -{ - g_return_val_if_fail (cogl_is_indices (indices), NULL); - - indices->immutable_ref++; - _cogl_buffer_immutable_ref (COGL_BUFFER (indices->buffer)); - return indices; -} - -void -_cogl_indices_immutable_unref (CoglIndices *indices) -{ - g_return_if_fail (cogl_is_indices (indices)); - g_return_if_fail (indices->immutable_ref > 0); - - indices->immutable_ref--; - _cogl_buffer_immutable_unref (COGL_BUFFER (indices->buffer)); -} - -CoglIndices * -cogl_get_rectangle_indices (CoglContext *ctx, int n_rectangles) -{ - int n_indices = n_rectangles * 6; - - /* Check if the largest index required will fit in a byte array... */ - if (n_indices <= 256 / 4 * 6) - { - /* Generate the byte array if we haven't already */ - if (ctx->rectangle_byte_indices == NULL) - { - uint8_t *byte_array = g_malloc (256 / 4 * 6 * sizeof (uint8_t)); - uint8_t *p = byte_array; - int i, vert_num = 0; - - for (i = 0; i < 256 / 4; i++) - { - *(p++) = vert_num + 0; - *(p++) = vert_num + 1; - *(p++) = vert_num + 2; - *(p++) = vert_num + 0; - *(p++) = vert_num + 2; - *(p++) = vert_num + 3; - vert_num += 4; - } - - ctx->rectangle_byte_indices - = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_BYTE, - byte_array, - 256 / 4 * 6); - - g_free (byte_array); - } - - return ctx->rectangle_byte_indices; - } - else - { - if (ctx->rectangle_short_indices_len < n_indices) - { - uint16_t *short_array; - uint16_t *p; - int i, vert_num = 0; - - if (ctx->rectangle_short_indices != NULL) - cogl_object_unref (ctx->rectangle_short_indices); - /* Pick a power of two >= MAX (512, n_indices) */ - if (ctx->rectangle_short_indices_len == 0) - ctx->rectangle_short_indices_len = 512; - while (ctx->rectangle_short_indices_len < n_indices) - ctx->rectangle_short_indices_len *= 2; - - /* Over-allocate to generate a whole number of quads */ - p = short_array = g_malloc ((ctx->rectangle_short_indices_len - + 5) / 6 * 6 - * sizeof (uint16_t)); - - /* Fill in the complete quads */ - for (i = 0; i < ctx->rectangle_short_indices_len; i += 6) - { - *(p++) = vert_num + 0; - *(p++) = vert_num + 1; - *(p++) = vert_num + 2; - *(p++) = vert_num + 0; - *(p++) = vert_num + 2; - *(p++) = vert_num + 3; - vert_num += 4; - } - - ctx->rectangle_short_indices - = cogl_indices_new (ctx, - COGL_INDICES_TYPE_UNSIGNED_SHORT, - short_array, - ctx->rectangle_short_indices_len); - - g_free (short_array); - } - - return ctx->rectangle_short_indices; - } -} - diff --git a/cogl/cogl/cogl-indices.h b/cogl/cogl/cogl-indices.h deleted file mode 100644 index 9c9c44d30..000000000 --- a/cogl/cogl/cogl-indices.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_INDICES_H__ -#define __COGL_INDICES_H__ - -/* We forward declare the CoglIndices type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglIndices CoglIndices; - -#include <cogl/cogl-index-buffer.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-indices - * @short_description: Describe vertex indices stored in a #CoglIndexBuffer. - * - * Indices allow you to avoid duplicating vertices in your vertex data - * by virtualizing your data and instead providing a sequence of index - * values that tell the GPU which data should be used for each vertex. - * - * If the GPU is given a sequence of indices it doesn't simply walk - * through each vertex of your data in order it will instead walk - * through the indices which can provide random access to the - * underlying data. - * - * Since it's very common to have duplicate vertices when describing a - * shape as a list of triangles it can often be a significant space - * saving to describe geometry using indices. Reducing the size of - * your models can make it cheaper to map them into the GPU by - * reducing the demand on memory bandwidth and may help to make better - * use of your GPUs internal vertex caching. - * - * For example, to describe a quadrilateral as 2 triangles for the GPU - * you could either provide data with 6 vertices or instead with - * indices you can provide vertex data for just 4 vertices and an - * index buffer that specifies the 6 vertices by indexing the shared - * vertices multiple times. - * - * |[ - * CoglVertexP2 quad_vertices[] = { - * {x0, y0}, //0 = top left - * {x1, y1}, //1 = bottom left - * {x2, y2}, //2 = bottom right - * {x3, y3}, //3 = top right - * }; - * //tell the gpu how to interpret the quad as 2 triangles... - * unsigned char indices[] = {0, 1, 2, 0, 2, 3}; - * ]| - * - * Even in the above illustration we see a saving of 10bytes for one - * quad compared to having data for 6 vertices and no indices but if - * you need to draw 100s or 1000s of quads then its really quite - * significant. - * - * Something else to consider is that often indices can be defined - * once and remain static while the vertex data may change for - * animations perhaps. That means you may be able to ignore the - * negligible cost of mapping your indices into the GPU if they don't - * ever change. - * - * The above illustration is actually a good example of static indices - * because it's really common that developers have quad mesh data that - * they need to display and we know exactly what that indices array - * needs to look like depending on the number of quads that need to be - * drawn. It doesn't matter how the quads might be animated and - * changed the indices will remain the same. Cogl even has a utility - * (cogl_get_rectangle_indices()) to get access to re-useable indices - * for drawing quads as above. - */ - -/** - * cogl_indices_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_indices_get_gtype (void); - -COGL_EXPORT CoglIndices * -cogl_indices_new (CoglContext *context, - CoglIndicesType type, - const void *indices_data, - int n_indices); - -COGL_EXPORT CoglIndices * -cogl_indices_new_for_buffer (CoglIndicesType type, - CoglIndexBuffer *buffer, - size_t offset); - -COGL_EXPORT CoglIndexBuffer * -cogl_indices_get_buffer (CoglIndices *indices); - -COGL_EXPORT CoglIndicesType -cogl_indices_get_type (CoglIndices *indices); - -COGL_EXPORT size_t -cogl_indices_get_offset (CoglIndices *indices); - -COGL_EXPORT void -cogl_indices_set_offset (CoglIndices *indices, - size_t offset); - -COGL_EXPORT CoglIndices * -cogl_get_rectangle_indices (CoglContext *context, int n_rectangles); - -/** - * cogl_is_indices: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglIndices. - * - * Return value: %TRUE if the object references a #CoglIndices - * and %FALSE otherwise. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_indices (void *object); - -G_END_DECLS - -#endif /* __COGL_INDICES_H__ */ - diff --git a/cogl/cogl/cogl-journal-private.h b/cogl/cogl/cogl-journal-private.h deleted file mode 100644 index d38c3df1a..000000000 --- a/cogl/cogl/cogl-journal-private.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_JOURNAL_PRIVATE_H -#define __COGL_JOURNAL_PRIVATE_H - -#include "cogl-texture.h" -#include "cogl-object-private.h" -#include "cogl-clip-stack.h" -#include "cogl-fence-private.h" - -#define COGL_JOURNAL_VBO_POOL_SIZE 8 - -typedef struct _CoglJournal -{ - CoglObject _parent; - - /* A pointer the framebuffer that is using this journal. This is - only valid when the journal is not empty. It *does* take a - reference on the framebuffer. Although this creates a circular - reference, the framebuffer has special code to handle the case - where the journal is the only thing holding a reference and it - will cause the journal to flush */ - CoglFramebuffer *framebuffer; - - GArray *entries; - GArray *vertices; - size_t needed_vbo_len; - - /* A pool of attribute buffers is used so that we can avoid repeatedly - reallocating buffers. Only one of these buffers at a time will be - used by Cogl but we keep more than one alive anyway in case the - GL driver is internally using the buffer and it would have to - allocate a new one when we start writing to it */ - CoglAttributeBuffer *vbo_pool[COGL_JOURNAL_VBO_POOL_SIZE]; - /* The next vbo to use from the pool. We just cycle through them in - order */ - unsigned int next_vbo_in_pool; - - int fast_read_pixel_count; - - CoglList pending_fences; - -} CoglJournal; - -/* To improve batching of geometry when submitting vertices to OpenGL we - * log the texture rectangles we want to draw to a journal, so when we - * later flush the journal we aim to batch data, and gl draw calls. */ -typedef struct _CoglJournalEntry -{ - CoglPipeline *pipeline; - CoglMatrixEntry *modelview_entry; - CoglClipStack *clip_stack; - float viewport[4]; - gboolean dither_enabled; - /* Offset into ctx->logged_vertices */ - size_t array_offset; - int n_layers; -} CoglJournalEntry; - -CoglJournal * -_cogl_journal_new (CoglFramebuffer *framebuffer); - -void -_cogl_journal_log_quad (CoglJournal *journal, - const float *position, - CoglPipeline *pipeline, - int n_layers, - CoglTexture *layer0_override_texture, - const float *tex_coords, - unsigned int tex_coords_len); - -void -_cogl_journal_flush (CoglJournal *journal); - -void -_cogl_journal_discard (CoglJournal *journal); - -gboolean -_cogl_journal_all_entries_within_bounds (CoglJournal *journal, - float clip_x0, - float clip_y0, - float clip_x1, - float clip_y1); - -gboolean -_cogl_journal_try_read_pixel (CoglJournal *journal, - int x, - int y, - CoglBitmap *bitmap, - gboolean *found_intersection); - -gboolean -_cogl_is_journal (void *object); - -#endif /* __COGL_JOURNAL_PRIVATE_H */ diff --git a/cogl/cogl/cogl-journal.c b/cogl/cogl/cogl-journal.c deleted file mode 100644 index 26edb4ebf..000000000 --- a/cogl/cogl/cogl-journal.c +++ /dev/null @@ -1,1916 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-context-private.h" -#include "cogl-graphene.h" -#include "cogl-journal-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-profile.h" -#include "cogl-attribute-private.h" -#include "cogl-point-in-poly-private.h" -#include "cogl-private.h" -#include "cogl1-context.h" - -#include <string.h> -#include <gmodule.h> -#include <math.h> - -/* XXX NB: - * The data logged in logged_vertices is formatted as follows: - * - * Per entry: - * 4 RGBA GLubytes for the color - * 2 floats for the top left position - * 2 * n_layers floats for the top left texture coordinates - * 2 floats for the bottom right position - * 2 * n_layers floats for the bottom right texture coordinates - */ -#define GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS(N_LAYERS) \ - (N_LAYERS * 2 + 2) - -/* XXX NB: - * Once in the vertex array, the journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 GLfloats per position (3 when doing software transforms) - * 4 RGBA GLubytes, - * 2 GLfloats per tex coord * n_layers - * - * Where n_layers corresponds to the number of pipeline layers enabled - * - * To avoid frequent changes in the stride of our vertex data we always pad - * n_layers to be >= 2 - * - * There will be four vertices per quad in the vertex array - * - * When we are transforming quads in software we need to also track the z - * coordinate of transformed vertices. - * - * So for a given number of layers this gets the stride in 32bit words: - */ -#define SW_TRANSFORM (!(COGL_DEBUG_ENABLED \ - (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) -#define POS_STRIDE (SW_TRANSFORM ? 3 : 2) /* number of 32bit words */ -#define N_POS_COMPONENTS POS_STRIDE -#define COLOR_STRIDE 1 /* number of 32bit words */ -#define TEX_STRIDE 2 /* number of 32bit words */ -#define MIN_LAYER_PADING 2 -#define GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS(N_LAYERS) \ - (POS_STRIDE + COLOR_STRIDE + \ - TEX_STRIDE * (N_LAYERS < MIN_LAYER_PADING ? MIN_LAYER_PADING : N_LAYERS)) - -/* If a batch is longer than this threshold then we'll assume it's not - worth doing software clipping and it's cheaper to program the GPU - to do the clip */ -#define COGL_JOURNAL_HARDWARE_CLIP_THRESHOLD 8 - -typedef struct _CoglJournalFlushState -{ - CoglContext *ctx; - - CoglJournal *journal; - - CoglAttributeBuffer *attribute_buffer; - GArray *attributes; - int current_attribute; - - size_t stride; - size_t array_offset; - GLuint current_vertex; - - CoglIndices *indices; - size_t indices_type_size; - - CoglPipeline *pipeline; -} CoglJournalFlushState; - -typedef void (*CoglJournalBatchCallback) (CoglJournalEntry *start, - int n_entries, - void *data); -typedef gboolean (*CoglJournalBatchTest) (CoglJournalEntry *entry0, - CoglJournalEntry *entry1); - -static void _cogl_journal_free (CoglJournal *journal); - -COGL_OBJECT_INTERNAL_DEFINE (Journal, journal); - -static void -_cogl_journal_free (CoglJournal *journal) -{ - int i; - - if (journal->entries) - g_array_free (journal->entries, TRUE); - if (journal->vertices) - g_array_free (journal->vertices, TRUE); - - for (i = 0; i < COGL_JOURNAL_VBO_POOL_SIZE; i++) - if (journal->vbo_pool[i]) - cogl_object_unref (journal->vbo_pool[i]); - - g_free (journal); -} - -CoglJournal * -_cogl_journal_new (CoglFramebuffer *framebuffer) -{ - CoglJournal *journal = g_new0 (CoglJournal, 1); - - journal->framebuffer = framebuffer; - journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry)); - journal->vertices = g_array_new (FALSE, FALSE, sizeof (float)); - - _cogl_list_init (&journal->pending_fences); - - return _cogl_journal_object_new (journal); -} - -static void -_cogl_journal_dump_logged_quad (uint8_t *data, int n_layers) -{ - size_t stride = GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (n_layers); - int i; - - g_print ("n_layers = %d; rgba=0x%02X%02X%02X%02X\n", - n_layers, data[0], data[1], data[2], data[3]); - - data += 4; - - for (i = 0; i < 2; i++) - { - float *v = (float *)data + (i * stride); - int j; - - g_print ("v%d: x = %f, y = %f", i, v[0], v[1]); - - for (j = 0; j < n_layers; j++) - { - float *t = v + 2 + TEX_STRIDE * j; - g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]); - } - g_print ("\n"); - } -} - -static void -_cogl_journal_dump_quad_vertices (uint8_t *data, int n_layers) -{ - size_t stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers); - int i; - - g_print ("n_layers = %d; stride = %d; pos stride = %d; color stride = %d; " - "tex stride = %d; stride in bytes = %d\n", - n_layers, (int)stride, POS_STRIDE, COLOR_STRIDE, - TEX_STRIDE, (int)stride * 4); - - for (i = 0; i < 4; i++) - { - float *v = (float *)data + (i * stride); - uint8_t *c = data + (POS_STRIDE * 4) + (i * stride * 4); - int j; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - g_print ("v%d: x = %f, y = %f, rgba=0x%02X%02X%02X%02X", - i, v[0], v[1], c[0], c[1], c[2], c[3]); - else - g_print ("v%d: x = %f, y = %f, z = %f, rgba=0x%02X%02X%02X%02X", - i, v[0], v[1], v[2], c[0], c[1], c[2], c[3]); - for (j = 0; j < n_layers; j++) - { - float *t = v + POS_STRIDE + COLOR_STRIDE + TEX_STRIDE * j; - g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]); - } - g_print ("\n"); - } -} - -static void -_cogl_journal_dump_quad_batch (uint8_t *data, int n_layers, int n_quads) -{ - size_t byte_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4; - int i; - - g_print ("_cogl_journal_dump_quad_batch: n_layers = %d, n_quads = %d\n", - n_layers, n_quads); - for (i = 0; i < n_quads; i++) - _cogl_journal_dump_quad_vertices (data + byte_stride * 2 * i, n_layers); -} - -static void -batch_and_call (CoglJournalEntry *entries, - int n_entries, - CoglJournalBatchTest can_batch_callback, - CoglJournalBatchCallback batch_callback, - void *data) -{ - int i; - int batch_len = 1; - CoglJournalEntry *batch_start = entries; - - if (n_entries < 1) - return; - - for (i = 1; i < n_entries; i++) - { - CoglJournalEntry *entry0 = &entries[i - 1]; - CoglJournalEntry *entry1 = entry0 + 1; - - if (can_batch_callback (entry0, entry1)) - { - batch_len++; - continue; - } - - batch_callback (batch_start, batch_len, data); - - batch_start = entry1; - batch_len = 1; - } - - /* The last batch... */ - batch_callback (batch_start, batch_len, data); -} - -static void -_cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglContext *ctx = state->ctx; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglAttribute **attributes; - CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); - - COGL_STATIC_TIMER (time_flush_modelview_and_entries, - "flush: pipeline+entries", /* parent */ - "flush: modelview+entries", - "The time spent flushing modelview + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_modelview_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: modelview batch len = %d\n", batch_len); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - _cogl_context_set_current_modelview_entry (ctx, - batch_start->modelview_entry); - - attributes = (CoglAttribute **)state->attributes->data; - - if (!_cogl_pipeline_get_real_blend_enabled (state->pipeline)) - draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE; - - if (batch_len > 1) - { - CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES; - int first_vertex = state->current_vertex * 6 / 4; - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - state->pipeline, - mode, - first_vertex, - batch_len * 6, - state->indices, - attributes, - state->attributes->len, - draw_flags); - } - else - { - _cogl_framebuffer_draw_attributes (framebuffer, - state->pipeline, - COGL_VERTICES_MODE_TRIANGLE_FAN, - state->current_vertex, 4, - attributes, - state->attributes->len, - draw_flags); - } - - /* DEBUGGING CODE XXX: This path will cause all rectangles to be - * drawn with a coloured outline. Each batch will be rendered with - * the same color. This may e.g. help with debugging texture slicing - * issues, visually seeing what is batched and debugging blending - * issues, plus it looks quite cool. - */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES))) - { - static CoglPipeline *outline = NULL; - uint8_t color_intensity; - int i; - CoglAttribute *loop_attributes[1]; - - if (outline == NULL) - outline = cogl_pipeline_new (ctx); - - /* The least significant three bits represent the three - components so that the order of colours goes red, green, - yellow, blue, magenta, cyan. Black and white are skipped. The - next two bits give four scales of intensity for those colours - in the order 0xff, 0xcc, 0x99, and 0x66. This gives a total - of 24 colours. If there are more than 24 batches on the stage - then it will wrap around */ - color_intensity = 0xff - 0x33 * (ctx->journal_rectangles_color >> 3); - cogl_pipeline_set_color4ub (outline, - (ctx->journal_rectangles_color & 1) ? - color_intensity : 0, - (ctx->journal_rectangles_color & 2) ? - color_intensity : 0, - (ctx->journal_rectangles_color & 4) ? - color_intensity : 0, - 0xff); - - loop_attributes[0] = attributes[0]; /* we just want the position */ - for (i = 0; i < batch_len; i++) - _cogl_framebuffer_draw_attributes (framebuffer, - outline, - COGL_VERTICES_MODE_LINE_LOOP, - 4 * i + state->current_vertex, 4, - loop_attributes, - 1, - draw_flags); - - /* Go to the next color */ - do - ctx->journal_rectangles_color = ((ctx->journal_rectangles_color + 1) & - ((1 << 5) - 1)); - /* We don't want to use black or white */ - while ((ctx->journal_rectangles_color & 0x07) == 0 - || (ctx->journal_rectangles_color & 0x07) == 0x07); - } - - state->current_vertex += (4 * batch_len); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_modelview_and_entries); -} - -static gboolean -compare_entry_modelviews (CoglJournalEntry *entry0, - CoglJournalEntry *entry1) -{ - /* Batch together quads with the same model view matrix */ - return entry0->modelview_entry == entry1->modelview_entry; -} - -/* At this point we have a run of quads that we know have compatible - * pipelines, but they may not all have the same modelview matrix */ -static void -_cogl_journal_flush_pipeline_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - COGL_STATIC_TIMER (time_flush_pipeline_entries, - "flush: texcoords+pipeline+entries", /* parent */ - "flush: pipeline+entries", - "The time spent flushing pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: pipeline batch len = %d\n", batch_len); - - state->pipeline = batch_start->pipeline; - - /* If we haven't transformed the quads in software then we need to also break - * up batches according to changes in the modelview matrix... */ - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - batch_and_call (batch_start, - batch_len, - compare_entry_modelviews, - _cogl_journal_flush_modelview_and_entries, - data); - } - else - _cogl_journal_flush_modelview_and_entries (batch_start, batch_len, data); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_pipeline_entries); -} - -static gboolean -compare_entry_pipelines (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - /* batch rectangles using compatible pipelines */ - - if (_cogl_pipeline_equal (entry0->pipeline, - entry1->pipeline, - (COGL_PIPELINE_STATE_ALL & - ~COGL_PIPELINE_STATE_COLOR), - COGL_PIPELINE_LAYER_STATE_ALL, - 0)) - return TRUE; - else - return FALSE; -} - -typedef struct _CreateAttributeState -{ - int current; - CoglJournalFlushState *flush_state; -} CreateAttributeState; - -static gboolean -create_attribute_cb (CoglPipeline *pipeline, - int layer_number, - void *user_data) -{ - CreateAttributeState *state = user_data; - CoglJournalFlushState *flush_state = state->flush_state; - CoglAttribute **attribute_entry = - &g_array_index (flush_state->attributes, - CoglAttribute *, - state->current + 2); - const char *names[] = { - "cogl_tex_coord0_in", - "cogl_tex_coord1_in", - "cogl_tex_coord2_in", - "cogl_tex_coord3_in", - "cogl_tex_coord4_in", - "cogl_tex_coord5_in", - "cogl_tex_coord6_in", - "cogl_tex_coord7_in" - }; - char *name; - - /* XXX NB: - * Our journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 floats per position (3 when doing software transforms) - * 4 RGBA bytes, - * 2 floats per tex coord * n_layers - * (though n_layers may be padded; see definition of - * GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details) - */ - name = layer_number < 8 ? (char *)names[layer_number] : - g_strdup_printf ("cogl_tex_coord%d_in", layer_number); - - /* XXX: it may be worth having some form of static initializer for - * attributes... */ - *attribute_entry = - cogl_attribute_new (flush_state->attribute_buffer, - name, - flush_state->stride, - flush_state->array_offset + - (POS_STRIDE + COLOR_STRIDE) * 4 + - TEX_STRIDE * 4 * state->current, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - if (layer_number >= 8) - g_free (name); - - state->current++; - - return TRUE; -} - -/* Since the stride may not reflect the number of texture layers in use - * (due to padding) we deal with texture coordinate offsets separately - * from vertex and color offsets... */ -static void -_cogl_journal_flush_texcoord_vbo_offsets_and_entries ( - CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CreateAttributeState create_attrib_state; - int i; - COGL_STATIC_TIMER (time_flush_texcoord_pipeline_entries, - "flush: vbo+texcoords+pipeline+entries", /* parent */ - "flush: texcoords+pipeline+entries", - "The time spent flushing texcoord offsets + pipeline " - "+ entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); - - /* NB: attributes 0 and 1 are position and color */ - - for (i = 2; i < state->attributes->len; i++) - cogl_object_unref (g_array_index (state->attributes, CoglAttribute *, i)); - - g_array_set_size (state->attributes, batch_start->n_layers + 2); - - create_attrib_state.current = 0; - create_attrib_state.flush_state = state; - - cogl_pipeline_foreach_layer (batch_start->pipeline, - create_attribute_cb, - &create_attrib_state); - - batch_and_call (batch_start, - batch_len, - compare_entry_pipelines, - _cogl_journal_flush_pipeline_and_entries, - data); - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_texcoord_pipeline_entries); -} - -static gboolean -compare_entry_layer_numbers (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - if (_cogl_pipeline_layer_numbers_equal (entry0->pipeline, entry1->pipeline)) - return TRUE; - else - return FALSE; -} - -/* At this point we know the stride has changed from the previous batch - * of journal entries */ -static void -_cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - size_t stride; - int i; - CoglAttribute **attribute_entry; - COGL_STATIC_TIMER (time_flush_vbo_texcoord_pipeline_entries, - "flush: clip+vbo+texcoords+pipeline+entries", /* parent */ - "flush: vbo+texcoords+pipeline+entries", - "The time spent flushing vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, - time_flush_vbo_texcoord_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: vbo offset batch len = %d\n", batch_len); - - /* XXX NB: - * Our journal's vertex data is arranged as follows: - * 4 vertices per quad: - * 2 or 3 GLfloats per position (3 when doing software transforms) - * 4 RGBA GLubytes, - * 2 GLfloats per tex coord * n_layers - * (though n_layers may be padded; see definition of - * GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details) - */ - stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (batch_start->n_layers); - stride *= sizeof (float); - state->stride = stride; - - for (i = 0; i < state->attributes->len; i++) - cogl_object_unref (g_array_index (state->attributes, CoglAttribute *, i)); - - g_array_set_size (state->attributes, 2); - - attribute_entry = &g_array_index (state->attributes, CoglAttribute *, 0); - *attribute_entry = cogl_attribute_new (state->attribute_buffer, - "cogl_position_in", - stride, - state->array_offset, - N_POS_COMPONENTS, - COGL_ATTRIBUTE_TYPE_FLOAT); - - attribute_entry = &g_array_index (state->attributes, CoglAttribute *, 1); - *attribute_entry = - cogl_attribute_new (state->attribute_buffer, - "cogl_color_in", - stride, - state->array_offset + (POS_STRIDE * 4), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - state->indices = cogl_get_rectangle_indices (ctx, batch_len); - - /* We only create new Attributes when the stride within the - * AttributeBuffer changes. (due to a change in the number of pipeline - * layers) While the stride remains constant we walk forward through - * the above AttributeBuffer using a vertex offset passed to - * cogl_draw_attributes - */ - state->current_vertex = 0; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL)) && - cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) - { - uint8_t *verts; - - /* Mapping a buffer for read is probably a really bad thing to - do but this will only happen during debugging so it probably - doesn't matter */ - verts = ((uint8_t *)_cogl_buffer_map (COGL_BUFFER (state->attribute_buffer), - COGL_BUFFER_ACCESS_READ, 0, - NULL) + - state->array_offset); - - _cogl_journal_dump_quad_batch (verts, - batch_start->n_layers, - batch_len); - - cogl_buffer_unmap (COGL_BUFFER (state->attribute_buffer)); - } - - batch_and_call (batch_start, - batch_len, - compare_entry_layer_numbers, - _cogl_journal_flush_texcoord_vbo_offsets_and_entries, - data); - - /* progress forward through the VBO containing all our vertices */ - state->array_offset += (stride * 4 * batch_len); - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - g_print ("new vbo offset = %lu\n", (unsigned long)state->array_offset); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_flush_vbo_texcoord_pipeline_entries); -} - -static gboolean -compare_entry_strides (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - /* Currently the only thing that affects the stride for our vertex arrays - * is the number of pipeline layers. We need to update our VBO offsets - * whenever the stride changes. */ - /* TODO: We should be padding the n_layers == 1 case as if it were - * n_layers == 2 so we can reduce the need to split batches. */ - if (entry0->n_layers == entry1->n_layers || - (entry0->n_layers <= MIN_LAYER_PADING && - entry1->n_layers <= MIN_LAYER_PADING)) - return TRUE; - else - return FALSE; -} - -/* At this point we know the batch has a unique clip stack */ -static void -_cogl_journal_flush_clip_stacks_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixStack *projection_stack; - - COGL_STATIC_TIMER (time_flush_clip_stack_pipeline_entries, - "Journal Flush", /* parent */ - "flush: clip+vbo+texcoords+pipeline+entries", - "The time spent flushing clip + vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, - time_flush_clip_stack_pipeline_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: clip stack batch len = %d\n", batch_len); - - _cogl_clip_stack_flush (batch_start->clip_stack, framebuffer); - - /* XXX: Because we are manually flushing clip state here we need to - * make sure that the clip state gets updated the next time we flush - * framebuffer state by marking the current framebuffer's clip state - * as changed. */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - /* If we have transformed all our quads at log time then we ensure - * no further model transform is applied by loading the identity - * matrix here. We need to do this after flushing the clip stack - * because the clip stack flushing code can modify the current - * modelview matrix entry */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM)))) - _cogl_context_set_current_modelview_entry (ctx, &ctx->identity_entry); - - /* Setting up the clip state can sometimes also update the current - * projection matrix entry so we should update it again. This will have - * no affect if the clip code didn't modify the projection */ - projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - _cogl_context_set_current_projection_entry (ctx, - projection_stack->last_entry); - - batch_and_call (batch_start, - batch_len, - compare_entry_strides, - _cogl_journal_flush_vbo_offsets_and_entries, /* callback */ - data); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_flush_clip_stack_pipeline_entries); -} - -typedef struct -{ - float x_1, y_1; - float x_2, y_2; -} ClipBounds; - -static gboolean -can_software_clip_entry (CoglJournalEntry *journal_entry, - CoglJournalEntry *prev_journal_entry, - CoglClipStack *clip_stack, - ClipBounds *clip_bounds_out) -{ - CoglPipeline *pipeline = journal_entry->pipeline; - CoglClipStack *clip_entry; - int layer_num; - - clip_bounds_out->x_1 = -G_MAXFLOAT; - clip_bounds_out->y_1 = -G_MAXFLOAT; - clip_bounds_out->x_2 = G_MAXFLOAT; - clip_bounds_out->y_2 = G_MAXFLOAT; - - /* Check the pipeline is usable. We can short-cut here for - entries using the same pipeline as the previous entry */ - if (prev_journal_entry == NULL || pipeline != prev_journal_entry->pipeline) - { - /* If the pipeline has a user program then we can't reliably modify - the texture coordinates */ - if (cogl_pipeline_get_user_program (pipeline)) - return FALSE; - - /* If any of the pipeline layers have a texture matrix then we can't - reliably modify the texture coordinates */ - for (layer_num = cogl_pipeline_get_n_layers (pipeline) - 1; - layer_num >= 0; - layer_num--) - if (_cogl_pipeline_layer_has_user_matrix (pipeline, layer_num)) - return FALSE; - } - - /* Now we need to verify that each clip entry's matrix is just a - translation of the journal entry's modelview matrix. We can - also work out the bounds of the clip in modelview space using - this translation */ - for (clip_entry = clip_stack; clip_entry; clip_entry = clip_entry->parent) - { - float rect_x1, rect_y1, rect_x2, rect_y2; - CoglClipStackRect *clip_rect; - float tx, ty, tz; - CoglMatrixEntry *modelview_entry; - - clip_rect = (CoglClipStackRect *) clip_entry; - - modelview_entry = journal_entry->modelview_entry; - if (!cogl_matrix_entry_calculate_translation (clip_rect->matrix_entry, - modelview_entry, - &tx, &ty, &tz)) - return FALSE; - - if (clip_rect->x0 < clip_rect->x1) - { - rect_x1 = clip_rect->x0; - rect_x2 = clip_rect->x1; - } - else - { - rect_x1 = clip_rect->x1; - rect_x2 = clip_rect->x0; - } - if (clip_rect->y0 < clip_rect->y1) - { - rect_y1 = clip_rect->y0; - rect_y2 = clip_rect->y1; - } - else - { - rect_y1 = clip_rect->y1; - rect_y2 = clip_rect->y0; - } - - clip_bounds_out->x_1 = MAX (clip_bounds_out->x_1, rect_x1 - tx); - clip_bounds_out->y_1 = MAX (clip_bounds_out->y_1, rect_y1 - ty); - clip_bounds_out->x_2 = MIN (clip_bounds_out->x_2, rect_x2 - tx); - clip_bounds_out->y_2 = MIN (clip_bounds_out->y_2, rect_y2 - ty); - } - - if (clip_bounds_out->x_2 <= clip_bounds_out->x_1 || - clip_bounds_out->y_2 <= clip_bounds_out->y_1) - memset (clip_bounds_out, 0, sizeof (ClipBounds)); - - return TRUE; -} - -static void -software_clip_entry (CoglJournalEntry *journal_entry, - float *verts, - ClipBounds *clip_bounds) -{ - size_t stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (journal_entry->n_layers); - float rx1, ry1, rx2, ry2; - float vx1, vy1, vx2, vy2; - int layer_num; - - /* Remove the clip on the entry */ - _cogl_clip_stack_unref (journal_entry->clip_stack); - journal_entry->clip_stack = NULL; - - vx1 = verts[0]; - vy1 = verts[1]; - vx2 = verts[stride]; - vy2 = verts[stride + 1]; - - if (vx1 < vx2) - { - rx1 = vx1; - rx2 = vx2; - } - else - { - rx1 = vx2; - rx2 = vx1; - } - if (vy1 < vy2) - { - ry1 = vy1; - ry2 = vy2; - } - else - { - ry1 = vy2; - ry2 = vy1; - } - - rx1 = CLAMP (rx1, clip_bounds->x_1, clip_bounds->x_2); - ry1 = CLAMP (ry1, clip_bounds->y_1, clip_bounds->y_2); - rx2 = CLAMP (rx2, clip_bounds->x_1, clip_bounds->x_2); - ry2 = CLAMP (ry2, clip_bounds->y_1, clip_bounds->y_2); - - /* Check if the rectangle intersects the clip at all */ - if (rx1 == rx2 || ry1 == ry2) - /* Will set all of the vertex data to 0 in the hope that this - will create a degenerate rectangle and the GL driver will - be able to clip it quickly */ - memset (verts, 0, sizeof (float) * stride * 2); - else - { - if (vx1 > vx2) - { - float t = rx1; - rx1 = rx2; - rx2 = t; - } - if (vy1 > vy2) - { - float t = ry1; - ry1 = ry2; - ry2 = t; - } - - verts[0] = rx1; - verts[1] = ry1; - verts[stride] = rx2; - verts[stride + 1] = ry2; - - /* Convert the rectangle coordinates to a fraction of the original - rectangle */ - rx1 = (rx1 - vx1) / (vx2 - vx1); - ry1 = (ry1 - vy1) / (vy2 - vy1); - rx2 = (rx2 - vx1) / (vx2 - vx1); - ry2 = (ry2 - vy1) / (vy2 - vy1); - - for (layer_num = 0; layer_num < journal_entry->n_layers; layer_num++) - { - float *t = verts + 2 + 2 * layer_num; - float tx1 = t[0], ty1 = t[1]; - float tx2 = t[stride], ty2 = t[stride + 1]; - t[0] = rx1 * (tx2 - tx1) + tx1; - t[1] = ry1 * (ty2 - ty1) + ty1; - t[stride] = rx2 * (tx2 - tx1) + tx1; - t[stride + 1] = ry2 * (ty2 - ty1) + ty1; - } - } -} - -static void -maybe_software_clip_entries (CoglJournalEntry *batch_start, - int batch_len, - CoglJournalFlushState *state) -{ - CoglContext *ctx; - CoglJournal *journal; - CoglClipStack *clip_stack, *clip_entry; - int entry_num; - - /* This tries to find cases where the entry is logged with a clip - but it would be faster to modify the vertex and texture - coordinates rather than flush the clip so that it can batch - better */ - - /* If the batch is reasonably long then it's worthwhile programming - the GPU to do the clip */ - if (batch_len >= COGL_JOURNAL_HARDWARE_CLIP_THRESHOLD) - return; - - clip_stack = batch_start->clip_stack; - - if (clip_stack == NULL) - return; - - /* Verify that all of the clip stack entries are a simple rectangle - clip */ - for (clip_entry = clip_stack; clip_entry; clip_entry = clip_entry->parent) - if (clip_entry->type != COGL_CLIP_STACK_RECT) - return; - - ctx = state->ctx; - journal = state->journal; - - /* This scratch buffer is used to store the translation for each - entry in the journal. We store it in a separate buffer because - it's expensive to calculate but at this point we still don't know - whether we can clip all of the entries so we don't want to do the - rest of the dependent calculations until we're sure we can. */ - if (ctx->journal_clip_bounds == NULL) - ctx->journal_clip_bounds = g_array_new (FALSE, FALSE, sizeof (ClipBounds)); - g_array_set_size (ctx->journal_clip_bounds, batch_len); - - for (entry_num = 0; entry_num < batch_len; entry_num++) - { - CoglJournalEntry *journal_entry = batch_start + entry_num; - CoglJournalEntry *prev_journal_entry = - entry_num ? batch_start + (entry_num - 1) : NULL; - ClipBounds *clip_bounds = &g_array_index (ctx->journal_clip_bounds, - ClipBounds, entry_num); - - if (!can_software_clip_entry (journal_entry, prev_journal_entry, - clip_stack, - clip_bounds)) - return; - } - - /* If we make it here then we know we can software clip the entire batch */ - - COGL_NOTE (CLIPPING, "Software clipping a batch of length %i", batch_len); - - for (entry_num = 0; entry_num < batch_len; entry_num++) - { - CoglJournalEntry *journal_entry = batch_start + entry_num; - float *verts = &g_array_index (journal->vertices, float, - journal_entry->array_offset + 1); - ClipBounds *clip_bounds = &g_array_index (ctx->journal_clip_bounds, - ClipBounds, entry_num); - - software_clip_entry (journal_entry, verts, clip_bounds); - } - - return; -} - -static void -_cogl_journal_maybe_software_clip_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - - COGL_STATIC_TIMER (time_check_software_clip, - "Journal Flush", /* parent */ - "flush: software clipping", - "Time spent software clipping", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, - time_check_software_clip); - - maybe_software_clip_entries (batch_start, batch_len, state); - - COGL_TIMER_STOP (_cogl_uprof_context, - time_check_software_clip); -} - -static gboolean -compare_entry_clip_stacks (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return entry0->clip_stack == entry1->clip_stack; -} - -static void -_cogl_journal_flush_dither_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - COGL_STATIC_TIMER (time_flush_dither_and_entries, - "Journal Flush", /* parent */ - "flush: viewport+dither+clip+vbo+texcoords+pipeline+entries", - "The time spent flushing viewport + dither + clip + vbo + " - "texcoord offsets + pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_dither_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: dither batch len = %d\n", batch_len); - - cogl_framebuffer_set_dither_enabled (framebuffer, batch_start->dither_enabled); - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_DITHER; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_DITHER); - - batch_and_call (batch_start, - batch_len, - compare_entry_clip_stacks, - _cogl_journal_flush_clip_stacks_and_entries, - state); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_dither_and_entries); -} - -static gboolean -compare_entry_dither_states (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return entry0->dither_enabled == entry1->dither_enabled; -} - -static void -_cogl_journal_flush_viewport_and_entries (CoglJournalEntry *batch_start, - int batch_len, - void *data) -{ - CoglJournalFlushState *state = data; - CoglFramebuffer *framebuffer = state->journal->framebuffer; - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - float current_viewport[4]; - - COGL_STATIC_TIMER (time_flush_viewport_and_entries, - "Journal Flush", /* parent */ - "flush: viewport+clip+vbo+texcoords+pipeline+entries", - "The time spent flushing viewport + clip + vbo + texcoord offsets + " - "pipeline + entries", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, time_flush_viewport_and_entries); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: viewport batch len = %d\n", batch_len); - - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_VIEWPORT; - - cogl_framebuffer_get_viewport4fv (framebuffer, current_viewport); - cogl_framebuffer_set_viewport4fv (framebuffer, batch_start->viewport); - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_VIEWPORT); - - batch_and_call (batch_start, - batch_len, - compare_entry_dither_states, - _cogl_journal_flush_dither_and_entries, - state); - - if (memcmp (batch_start->viewport, current_viewport, sizeof (float) * 4) != 0) - cogl_framebuffer_set_viewport4fv (framebuffer, current_viewport); - - COGL_TIMER_STOP (_cogl_uprof_context, time_flush_viewport_and_entries); -} - -static gboolean -compare_entry_viewports (CoglJournalEntry *entry0, CoglJournalEntry *entry1) -{ - return memcmp (entry0->viewport, entry1->viewport, sizeof (float) * 4) == 0; -} - -/* Gets a new vertex array from the pool. A reference is taken on the - array so it can be treated as if it was just newly allocated */ -static CoglAttributeBuffer * -create_attribute_buffer (CoglJournal *journal, - size_t n_bytes) -{ - CoglContext *ctx = cogl_framebuffer_get_context (journal->framebuffer); - CoglAttributeBuffer *vbo; - - vbo = journal->vbo_pool[journal->next_vbo_in_pool]; - - if (vbo == NULL) - { - vbo = cogl_attribute_buffer_new_with_size (ctx, n_bytes); - journal->vbo_pool[journal->next_vbo_in_pool] = vbo; - } - else if (cogl_buffer_get_size (COGL_BUFFER (vbo)) < n_bytes) - { - /* If the buffer is too small then we'll just recreate it */ - cogl_object_unref (vbo); - vbo = cogl_attribute_buffer_new_with_size (ctx, n_bytes); - journal->vbo_pool[journal->next_vbo_in_pool] = vbo; - } - - journal->next_vbo_in_pool = ((journal->next_vbo_in_pool + 1) % - COGL_JOURNAL_VBO_POOL_SIZE); - - return cogl_object_ref (vbo); -} - -static CoglAttributeBuffer * -upload_vertices (CoglJournal *journal, - const CoglJournalEntry *entries, - int n_entries, - size_t needed_vbo_len, - GArray *vertices) -{ - CoglAttributeBuffer *attribute_buffer; - CoglBuffer *buffer; - const float *vin; - float *vout; - int entry_num; - int i; - CoglMatrixEntry *last_modelview_entry = NULL; - graphene_matrix_t modelview; - - g_assert (needed_vbo_len); - - attribute_buffer = create_attribute_buffer (journal, needed_vbo_len * 4); - buffer = COGL_BUFFER (attribute_buffer); - cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC); - - vout = _cogl_buffer_map_range_for_fill_or_fallback (buffer, - 0, /* offset */ - needed_vbo_len * 4); - vin = &g_array_index (vertices, float, 0); - - /* Expand the number of vertices from 2 to 4 while uploading */ - for (entry_num = 0; entry_num < n_entries; entry_num++) - { - const CoglJournalEntry *entry = entries + entry_num; - size_t vb_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (entry->n_layers); - size_t array_stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (entry->n_layers); - - /* Copy the color to all four of the vertices */ - for (i = 0; i < 4; i++) - memcpy (vout + vb_stride * i + POS_STRIDE, vin, 4); - vin++; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))) - { - vout[vb_stride * 0] = vin[0]; - vout[vb_stride * 0 + 1] = vin[1]; - vout[vb_stride * 1] = vin[0]; - vout[vb_stride * 1 + 1] = vin[array_stride + 1]; - vout[vb_stride * 2] = vin[array_stride]; - vout[vb_stride * 2 + 1] = vin[array_stride + 1]; - vout[vb_stride * 3] = vin[array_stride]; - vout[vb_stride * 3 + 1] = vin[1]; - } - else - { - float v[8]; - - v[0] = vin[0]; - v[1] = vin[1]; - v[2] = vin[0]; - v[3] = vin[array_stride + 1]; - v[4] = vin[array_stride]; - v[5] = vin[array_stride + 1]; - v[6] = vin[array_stride]; - v[7] = vin[1]; - - if (entry->modelview_entry != last_modelview_entry) - cogl_matrix_entry_get (entry->modelview_entry, &modelview); - cogl_graphene_matrix_transform_points (&modelview, - 2, /* n_components */ - sizeof (float) * 2, /* stride_in */ - v, /* points_in */ - /* strideout */ - vb_stride * sizeof (float), - vout, /* points_out */ - 4 /* n_points */); - } - - for (i = 0; i < entry->n_layers; i++) - { - const float *tin = vin + 2; - float *tout = vout + POS_STRIDE + COLOR_STRIDE; - - tout[vb_stride * 0 + i * 2] = tin[i * 2]; - tout[vb_stride * 0 + 1 + i * 2] = tin[i * 2 + 1]; - tout[vb_stride * 1 + i * 2] = tin[i * 2]; - tout[vb_stride * 1 + 1 + i * 2] = tin[array_stride + i * 2 + 1]; - tout[vb_stride * 2 + i * 2] = tin[array_stride + i * 2]; - tout[vb_stride * 2 + 1 + i * 2] = tin[array_stride + i * 2 + 1]; - tout[vb_stride * 3 + i * 2] = tin[array_stride + i * 2]; - tout[vb_stride * 3 + 1 + i * 2] = tin[i * 2 + 1]; - } - - vin += array_stride * 2; - vout += vb_stride * 4; - } - - _cogl_buffer_unmap_for_fill_or_fallback (buffer); - - return attribute_buffer; -} - -void -_cogl_journal_discard (CoglJournal *journal) -{ - int i; - - if (journal->entries->len <= 0) - return; - - for (i = 0; i < journal->entries->len; i++) - { - CoglJournalEntry *entry = - &g_array_index (journal->entries, CoglJournalEntry, i); - _cogl_pipeline_journal_unref (entry->pipeline); - cogl_matrix_entry_unref (entry->modelview_entry); - _cogl_clip_stack_unref (entry->clip_stack); - } - - g_array_set_size (journal->entries, 0); - g_array_set_size (journal->vertices, 0); - journal->needed_vbo_len = 0; - journal->fast_read_pixel_count = 0; -} - -/* Note: A return value of FALSE doesn't mean 'no' it means - * 'unknown' */ -gboolean -_cogl_journal_all_entries_within_bounds (CoglJournal *journal, - float clip_x0, - float clip_y0, - float clip_x1, - float clip_y1) -{ - CoglJournalEntry *entry = (CoglJournalEntry *)journal->entries->data; - CoglClipStack *clip_entry; - CoglClipStack *reference = NULL; - int bounds_x0; - int bounds_y0; - int bounds_x1; - int bounds_y1; - int i; - - if (journal->entries->len == 0) - return TRUE; - - /* Find the shortest clip_stack ancestry that leaves us in the - * required bounds */ - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - _cogl_clip_stack_get_bounds (clip_entry, - &bounds_x0, &bounds_y0, - &bounds_x1, &bounds_y1); - - if (bounds_x0 >= clip_x0 && bounds_y0 >= clip_y0 && - bounds_x1 <= clip_x1 && bounds_y1 <= clip_y1) - reference = clip_entry; - else - break; - } - - if (!reference) - return FALSE; - - /* For the remaining journal entries we will only verify they share - * 'reference' as an ancestor in their clip stack since that's - * enough to know that they would be within the required bounds. - */ - for (i = 1; i < journal->entries->len; i++) - { - gboolean found_reference = FALSE; - entry = &g_array_index (journal->entries, CoglJournalEntry, i); - - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - if (clip_entry == reference) - { - found_reference = TRUE; - break; - } - } - - if (!found_reference) - return FALSE; - } - - return TRUE; -} - -static void -post_fences (CoglJournal *journal) -{ - CoglFenceClosure *fence, *tmp; - - _cogl_list_for_each_safe (fence, tmp, &journal->pending_fences, link) - { - _cogl_list_remove (&fence->link); - _cogl_fence_submit (fence); - } -} - -/* XXX NB: When _cogl_journal_flush() returns all state relating - * to pipelines, all glEnable flags and current matrix state - * is undefined. - */ -void -_cogl_journal_flush (CoglJournal *journal) -{ - CoglFramebuffer *framebuffer; - CoglContext *ctx; - CoglJournalFlushState state; - int i; - COGL_STATIC_TIMER (flush_timer, - "Mainloop", /* parent */ - "Journal Flush", - "The time spent flushing the Cogl journal", - 0 /* no application private data */); - COGL_STATIC_TIMER (discard_timer, - "Journal Flush", /* parent */ - "flush: discard", - "The time spent discarding the Cogl journal after a flush", - 0 /* no application private data */); - - if (journal->entries->len == 0) - { - post_fences (journal); - return; - } - - framebuffer = journal->framebuffer; - ctx = cogl_framebuffer_get_context (framebuffer); - - /* The entries in this journal may depend on images in other - * framebuffers which may require that we flush the journals - * associated with those framebuffers before we can flush - * this journal... */ - _cogl_framebuffer_flush_dependency_journals (framebuffer); - - /* Note: we start the timer after flushing dependency journals so - * that the timer isn't started recursively. */ - COGL_TIMER_START (_cogl_uprof_context, flush_timer); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_BATCHING))) - g_print ("BATCHING: journal len = %d\n", journal->entries->len); - - /* NB: the journal deals with flushing the viewport, the modelview - * stack and clip state manually */ - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_ALL & - ~(COGL_FRAMEBUFFER_STATE_DITHER | - COGL_FRAMEBUFFER_STATE_VIEWPORT | - COGL_FRAMEBUFFER_STATE_MODELVIEW | - COGL_FRAMEBUFFER_STATE_CLIP)); - - /* We need to mark the current modelview state of the framebuffer as - * dirty because we are going to manually replace it */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_MODELVIEW; - - state.ctx = ctx; - state.journal = journal; - - state.attributes = ctx->journal_flush_attributes_array; - - if (G_UNLIKELY ((COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_SOFTWARE_CLIP)) == 0)) - { - /* We do an initial walk of the journal to analyse the clip stack - batches to see if we can do software clipping. We do this as a - separate walk of the journal because we can modify entries and - this may end up joining together clip stack batches in the next - iteration. */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, /* first entry */ - journal->entries->len, /* max number of entries to consider */ - compare_entry_clip_stacks, - _cogl_journal_maybe_software_clip_entries, /* callback */ - &state); /* data */ - } - - /* We upload the vertices after the clip stack pass in case it - modifies the entries */ - state.attribute_buffer = - upload_vertices (journal, - &g_array_index (journal->entries, CoglJournalEntry, 0), - journal->entries->len, - journal->needed_vbo_len, - journal->vertices); - state.array_offset = 0; - - /* batch_and_call() batches a list of journal entries according to some - * given criteria and calls a callback once for each determined batch. - * - * The process of flushing the journal is staggered to reduce the amount - * of driver/GPU state changes necessary: - * 1) We split the entries according to the clip state. - * 2) We split the entries according to the stride of the vertices: - * Each time the stride of our vertex data changes we need to call - * gl{Vertex,Color}Pointer to inform GL of new VBO offsets. - * Currently the only thing that affects the stride of our vertex data - * is the number of pipeline layers. - * 3) We split the entries explicitly by the number of pipeline layers: - * We pad our vertex data when the number of layers is < 2 so that we - * can minimize changes in stride. - * 4) We then split according to compatible Cogl pipelines: - * This is where we flush pipeline state - * 5) Finally we split according to modelview matrix changes: - * This is when we finally tell GL to draw something. - * Note: Splitting by modelview changes is skipped when are doing the - * vertex transformation in software at log time. - */ - batch_and_call ((CoglJournalEntry *)journal->entries->data, - journal->entries->len, - compare_entry_viewports, - _cogl_journal_flush_viewport_and_entries, - &state); - - for (i = 0; i < state.attributes->len; i++) - cogl_object_unref (g_array_index (state.attributes, CoglAttribute *, i)); - g_array_set_size (state.attributes, 0); - - cogl_object_unref (state.attribute_buffer); - - COGL_TIMER_START (_cogl_uprof_context, discard_timer); - _cogl_journal_discard (journal); - COGL_TIMER_STOP (_cogl_uprof_context, discard_timer); - - post_fences (journal); - - COGL_TIMER_STOP (_cogl_uprof_context, flush_timer); -} - -static gboolean -add_framebuffer_deps_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglFramebuffer *framebuffer = user_data; - CoglTexture *texture = _cogl_pipeline_layer_get_texture_real (layer); - const GList *l; - - if (!texture) - return TRUE; - - for (l = _cogl_texture_get_associated_framebuffers (texture); l; l = l->next) - _cogl_framebuffer_add_dependency (framebuffer, l->data); - - return TRUE; -} - -void -_cogl_journal_log_quad (CoglJournal *journal, - const float *position, - CoglPipeline *pipeline, - int n_layers, - CoglTexture *layer0_override_texture, - const float *tex_coords, - unsigned int tex_coords_len) -{ - CoglFramebuffer *framebuffer = journal->framebuffer; - size_t stride; - int next_vert; - float *v; - int i; - int next_entry; - uint32_t disable_layers; - CoglJournalEntry *entry; - CoglPipeline *final_pipeline; - CoglClipStack *clip_stack; - CoglPipelineFlushOptions flush_options; - CoglMatrixStack *modelview_stack; - COGL_STATIC_TIMER (log_timer, - "Mainloop", /* parent */ - "Journal Log", - "The time spent logging in the Cogl journal", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, log_timer); - - /* The vertex data is logged into a separate array. The data needs - to be copied into a vertex array before it's given to GL so we - only store two vertices per quad and expand it to four while - uploading. */ - - /* XXX: See definition of GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS for details - * about how we pack our vertex data */ - stride = GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (n_layers); - - next_vert = journal->vertices->len; - g_array_set_size (journal->vertices, next_vert + 2 * stride + 1); - v = &g_array_index (journal->vertices, float, next_vert); - - /* We calculate the needed size of the vbo as we go because it - depends on the number of layers in each entry and it's not easy - calculate based on the length of the logged vertices array */ - journal->needed_vbo_len += GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4; - - /* XXX: All the jumping around to fill in this strided buffer doesn't - * seem ideal. */ - - /* FIXME: This is a hacky optimization, since it will break if we - * change the definition of CoglColor: */ - _cogl_pipeline_get_colorubv (pipeline, (uint8_t *) v); - v++; - - memcpy (v, position, sizeof (float) * 2); - memcpy (v + stride, position + 2, sizeof (float) * 2); - - for (i = 0; i < n_layers; i++) - { - /* XXX: See definition of GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS - * for details about how we pack our vertex data */ - GLfloat *t = v + 2 + i * 2; - - memcpy (t, tex_coords + i * 4, sizeof (float) * 2); - memcpy (t + stride, tex_coords + i * 4 + 2, sizeof (float) * 2); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_JOURNAL))) - { - g_print ("Logged new quad:\n"); - v = &g_array_index (journal->vertices, float, next_vert); - _cogl_journal_dump_logged_quad ((uint8_t *)v, n_layers); - } - - next_entry = journal->entries->len; - g_array_set_size (journal->entries, next_entry + 1); - entry = &g_array_index (journal->entries, CoglJournalEntry, next_entry); - - entry->n_layers = n_layers; - entry->array_offset = next_vert; - - final_pipeline = pipeline; - - flush_options.flags = 0; - if (G_UNLIKELY (cogl_pipeline_get_n_layers (pipeline) != n_layers)) - { - disable_layers = (1 << n_layers) - 1; - disable_layers = ~disable_layers; - flush_options.disable_layers = disable_layers; - flush_options.flags |= COGL_PIPELINE_FLUSH_DISABLE_MASK; - } - if (G_UNLIKELY (layer0_override_texture)) - { - flush_options.flags |= COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE; - flush_options.layer0_override_texture = layer0_override_texture; - } - - if (G_UNLIKELY (flush_options.flags)) - { - final_pipeline = cogl_pipeline_copy (pipeline); - _cogl_pipeline_apply_overrides (final_pipeline, &flush_options); - } - - entry->pipeline = _cogl_pipeline_journal_ref (final_pipeline); - - clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer); - entry->clip_stack = _cogl_clip_stack_ref (clip_stack); - entry->dither_enabled = cogl_framebuffer_get_dither_enabled (framebuffer); - - cogl_framebuffer_get_viewport4fv (framebuffer, entry->viewport); - - if (G_UNLIKELY (final_pipeline != pipeline)) - cogl_object_unref (final_pipeline); - - modelview_stack = - _cogl_framebuffer_get_modelview_stack (framebuffer); - entry->modelview_entry = cogl_matrix_entry_ref (modelview_stack->last_entry); - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_framebuffer_deps_cb, - framebuffer); - - if (COGL_IS_OFFSCREEN (framebuffer)) - { - CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - CoglTexture *texture = cogl_offscreen_get_texture (offscreen); - - _cogl_texture_2d_externally_modified (texture); - } - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_PRIMITIVE))) - { - _cogl_journal_flush (journal); - cogl_framebuffer_finish (framebuffer); - } - else if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING))) - { - _cogl_journal_flush (journal); - } - - COGL_TIMER_STOP (_cogl_uprof_context, log_timer); -} - -static void -entry_to_screen_polygon (CoglFramebuffer *framebuffer, - const CoglJournalEntry *entry, - float *vertices, - float *poly) -{ - size_t array_stride = - GET_JOURNAL_ARRAY_STRIDE_FOR_N_LAYERS (entry->n_layers); - CoglMatrixStack *projection_stack; - graphene_matrix_t projection; - graphene_matrix_t modelview; - int i; - const float *viewport = entry->viewport; - - poly[0] = vertices[0]; - poly[1] = vertices[1]; - poly[2] = 0; - poly[3] = 1; - - poly[4] = vertices[0]; - poly[5] = vertices[array_stride + 1]; - poly[6] = 0; - poly[7] = 1; - - poly[8] = vertices[array_stride]; - poly[9] = vertices[array_stride + 1]; - poly[10] = 0; - poly[11] = 1; - - poly[12] = vertices[array_stride]; - poly[13] = vertices[1]; - poly[14] = 0; - poly[15] = 1; - - /* TODO: perhaps split the following out into a more generalized - * _cogl_transform_points utility... - */ - - cogl_matrix_entry_get (entry->modelview_entry, &modelview); - cogl_graphene_matrix_transform_points (&modelview, - 2, /* n_components */ - sizeof (float) * 4, /* stride_in */ - poly, /* points_in */ - /* strideout */ - sizeof (float) * 4, - poly, /* points_out */ - 4 /* n_points */); - - projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - cogl_matrix_stack_get (projection_stack, &projection); - - cogl_graphene_matrix_transform_points (&projection, - 3, /* n_components */ - sizeof (float) * 4, /* stride_in */ - poly, /* points_in */ - /* strideout */ - sizeof (float) * 4, - poly, /* points_out */ - 4 /* n_points */); - -/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) - * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with - * (0,0) being top left. */ -#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \ - ( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) ) -/* Note: for Y we first flip all coordinates around the X axis while in - * normalized device coordinates */ -#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \ - ( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) ) - - /* Scale from normalized device coordinates (in range [-1,1]) to - * window coordinates ranging [0,window-size] ... */ - for (i = 0; i < 4; i++) - { - float w = poly[4 * i + 3]; - - /* Perform perspective division */ - poly[4 * i] /= w; - poly[4 * i + 1] /= w; - - /* Apply viewport transform */ - poly[4 * i] = VIEWPORT_TRANSFORM_X (poly[4 * i], - viewport[0], viewport[2]); - poly[4 * i + 1] = VIEWPORT_TRANSFORM_Y (poly[4 * i + 1], - viewport[1], viewport[3]); - } - -#undef VIEWPORT_TRANSFORM_X -#undef VIEWPORT_TRANSFORM_Y -} - -static gboolean -try_checking_point_hits_entry_after_clipping (CoglFramebuffer *framebuffer, - CoglJournalEntry *entry, - float *vertices, - float x, - float y, - gboolean *hit) -{ - gboolean can_software_clip = TRUE; - gboolean needs_software_clip = FALSE; - CoglClipStack *clip_entry; - - *hit = TRUE; - - /* Verify that all of the clip stack entries are simple rectangle - * clips */ - for (clip_entry = entry->clip_stack; - clip_entry; - clip_entry = clip_entry->parent) - { - if (x < clip_entry->bounds_x0 || - x >= clip_entry->bounds_x1 || - y < clip_entry->bounds_y0 || - y >= clip_entry->bounds_y1) - { - *hit = FALSE; - return TRUE; - } - - if (clip_entry->type == COGL_CLIP_STACK_WINDOW_RECT) - { - /* XXX: technically we could still run the software clip in - * this case because for our purposes we know this clip - * can be ignored now, but [can_]sofware_clip_entry() doesn't - * know this and will bail out. */ - can_software_clip = FALSE; - } - else if (clip_entry->type == COGL_CLIP_STACK_RECT) - { - CoglClipStackRect *rect_entry = (CoglClipStackRect *)entry; - - if (rect_entry->can_be_scissor == FALSE) - needs_software_clip = TRUE; - /* If can_be_scissor is TRUE then we know it's screen - * aligned and the hit test we did above has determined - * that we are inside this clip. */ - } - else - return FALSE; - } - - if (needs_software_clip) - { - ClipBounds clip_bounds; - float poly[16]; - - if (!can_software_clip) - return FALSE; - - if (!can_software_clip_entry (entry, NULL, - entry->clip_stack, &clip_bounds)) - return FALSE; - - software_clip_entry (entry, vertices, &clip_bounds); - entry_to_screen_polygon (framebuffer, entry, vertices, poly); - - *hit = _cogl_util_point_in_screen_poly (x, y, poly, sizeof (float) * 4, 4); - return TRUE; - } - - return TRUE; -} - -gboolean -_cogl_journal_try_read_pixel (CoglJournal *journal, - int x, - int y, - CoglBitmap *bitmap, - gboolean *found_intersection) -{ - CoglContext *ctx; - CoglPixelFormat format; - int i; - - /* XXX: this number has been plucked out of thin air, but the idea - * is that if so many pixels are being read from the same un-changed - * journal than we expect that it will be more efficient to fail - * here so we end up flushing and rendering the journal so that - * further reads can directly read from the framebuffer. There will - * be a bit more lag to flush the render but if there are going to - * continue being lots of arbitrary single pixel reads they will end - * up faster in the end. */ - if (journal->fast_read_pixel_count > 50) - return FALSE; - - format = cogl_bitmap_get_format (bitmap); - - if (format != COGL_PIXEL_FORMAT_RGBA_8888_PRE && - format != COGL_PIXEL_FORMAT_RGBA_8888) - return FALSE; - - ctx = _cogl_bitmap_get_context (bitmap); - - *found_intersection = FALSE; - - /* NB: The most recently added journal entry is the last entry, and - * assuming this is a simple scene only comprised of opaque coloured - * rectangles with no special pipelines involved (e.g. enabling - * depth testing) then we can assume painter's algorithm for the - * entries and so our fast read-pixel just needs to walk backwards - * through the journal entries trying to intersect each entry with - * the given point of interest. */ - for (i = journal->entries->len - 1; i >= 0; i--) - { - CoglJournalEntry *entry = - &g_array_index (journal->entries, CoglJournalEntry, i); - uint8_t *color = (uint8_t *)&g_array_index (journal->vertices, float, - entry->array_offset); - float *vertices = (float *)color + 1; - float poly[16]; - CoglFramebuffer *framebuffer = journal->framebuffer; - uint8_t *pixel; - GError *ignore_error; - - entry_to_screen_polygon (framebuffer, entry, vertices, poly); - - if (!_cogl_util_point_in_screen_poly (x, y, poly, sizeof (float) * 4, 4)) - continue; - - if (entry->clip_stack) - { - gboolean hit; - - if (!try_checking_point_hits_entry_after_clipping (framebuffer, - entry, - vertices, - x, y, &hit)) - return FALSE; /* hit couldn't be determined */ - - if (!hit) - continue; - } - - *found_intersection = TRUE; - - /* If we find that the rectangle the point of interest - * intersects has any state more complex than a constant opaque - * color then we bail out. */ - if (!_cogl_pipeline_equal (ctx->opaque_color_pipeline, entry->pipeline, - (COGL_PIPELINE_STATE_ALL & - ~COGL_PIPELINE_STATE_COLOR), - COGL_PIPELINE_LAYER_STATE_ALL, - 0)) - return FALSE; - - - /* we currently only care about cases where the premultiplied or - * unpremultipled colors are equivalent... */ - if (color[3] != 0xff) - return FALSE; - - pixel = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - if (pixel == NULL) - { - g_error_free (ignore_error); - return FALSE; - } - - pixel[0] = color[0]; - pixel[1] = color[1]; - pixel[2] = color[2]; - pixel[3] = color[3]; - - _cogl_bitmap_unmap (bitmap); - - goto success; - } - -success: - journal->fast_read_pixel_count++; - return TRUE; -} diff --git a/cogl/cogl/cogl-list.c b/cogl/cogl/cogl-list.c deleted file mode 100644 index 9e855e5f9..000000000 --- a/cogl/cogl/cogl-list.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright © 2008-2011 Kristian Høgsberg - * Copyright © 2011, 2012 Intel Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* This list implementation is based on the Wayland source code */ - -#include "cogl-config.h" - -#include <stdlib.h> -#include <string.h> - -#include "cogl-list.h" - -void -_cogl_list_init (CoglList *list) -{ - list->prev = list; - list->next = list; -} - -void -_cogl_list_insert (CoglList *list, CoglList *elm) -{ - elm->prev = list; - elm->next = list->next; - list->next = elm; - elm->next->prev = elm; -} - -void -_cogl_list_remove (CoglList *elm) -{ - elm->prev->next = elm->next; - elm->next->prev = elm->prev; - elm->next = NULL; - elm->prev = NULL; -} - -int -_cogl_list_length (CoglList *list) -{ - CoglList *e; - int count; - - count = 0; - e = list->next; - while (e != list) - { - e = e->next; - count++; - } - - return count; -} - -int -_cogl_list_empty (CoglList *list) -{ - return list->next == list; -} - -void -_cogl_list_insert_list (CoglList *list, - CoglList *other) -{ - if (_cogl_list_empty (other)) - return; - - other->next->prev = list; - other->prev->next = list->next; - list->next->prev = other->prev; - list->next = other->next; -} diff --git a/cogl/cogl/cogl-list.h b/cogl/cogl/cogl-list.h deleted file mode 100644 index 20cbec82a..000000000 --- a/cogl/cogl/cogl-list.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright © 2008 Kristian Høgsberg - * Copyright © 2012, 2013 Intel Corporation - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - * OF THIS SOFTWARE. - */ - -/* This list implementation is based on the Wayland source code */ - -#ifndef COGL_LIST_H -#define COGL_LIST_H - -#include <stddef.h> - -/** - * CoglList - linked list - * - * The list head is of "CoglList" type, and must be initialized - * using cogl_list_init(). All entries in the list must be of the same - * type. The item type must have a "CoglList" member. This - * member will be initialized by cogl_list_insert(). There is no need to - * call cogl_list_init() on the individual item. To query if the list is - * empty in O(1), use cogl_list_empty(). - * - * Let's call the list reference "CoglList foo_list", the item type as - * "item_t", and the item member as "CoglList link". The following code - * - * The following code will initialize a list: - * - * cogl_list_init (foo_list); - * cogl_list_insert (foo_list, item1); Pushes item1 at the head - * cogl_list_insert (foo_list, item2); Pushes item2 at the head - * cogl_list_insert (item2, item3); Pushes item3 after item2 - * - * The list now looks like [item2, item3, item1] - * - * Will iterate the list in ascending order: - * - * item_t *item; - * cogl_list_for_each(item, foo_list, link) { - * Do_something_with_item(item); - * } - */ - -typedef struct _CoglList CoglList; - -struct _CoglList -{ - CoglList *prev; - CoglList *next; -}; - -void -_cogl_list_init (CoglList *list); - -void -_cogl_list_insert (CoglList *list, - CoglList *elm); - -void -_cogl_list_remove (CoglList *elm); - -int -_cogl_list_length (CoglList *list); - -int -_cogl_list_empty (CoglList *list); - -void -_cogl_list_insert_list (CoglList *list, - CoglList *other); - -/* This assigns to iterator first so that taking a reference to it - * later in the second step won't be an undefined operation. It - * assigns the value of list_node rather than 0 so that it is possible - * have list_node be based on the previous value of iterator. In that - * respect iterator is just used as a convenient temporary variable. - * The compiler optimises all of this down to a single subtraction by - * a constant */ -#define _cogl_list_set_iterator(list_node, iterator, member) \ - ((iterator) = (void *) (list_node), \ - (iterator) = (void *) ((char *) (iterator) - \ - (((char *) &(iterator)->member) - \ - (char *) (iterator)))) - -#define _cogl_container_of(ptr, type, member) \ - (type *) ((char *) (ptr) - offsetof (type, member)) - -#define _cogl_list_for_each(pos, head, member) \ - for (_cogl_list_set_iterator ((head)->next, pos, member); \ - &pos->member != (head); \ - _cogl_list_set_iterator (pos->member.next, pos, member)) - -#define _cogl_list_for_each_safe(pos, tmp, head, member) \ - for (_cogl_list_set_iterator ((head)->next, pos, member), \ - _cogl_list_set_iterator ((pos)->member.next, tmp, member); \ - &pos->member != (head); \ - pos = tmp, \ - _cogl_list_set_iterator (pos->member.next, tmp, member)) - -#define _cogl_list_for_each_reverse(pos, head, member) \ - for (_cogl_list_set_iterator ((head)->prev, pos, member); \ - &pos->member != (head); \ - _cogl_list_set_iterator (pos->member.prev, pos, member)) - -#define _cogl_list_for_each_reverse_safe(pos, tmp, head, member) \ - for (_cogl_list_set_iterator ((head)->prev, pos, member), \ - _cogl_list_set_iterator ((pos)->member.prev, tmp, member); \ - &pos->member != (head); \ - pos = tmp, \ - _cogl_list_set_iterator (pos->member.prev, tmp, member)) - -#endif /* COGL_LIST_H */ diff --git a/cogl/cogl/cogl-macros.h b/cogl/cogl/cogl-macros.h deleted file mode 100644 index 8172354d1..000000000 --- a/cogl/cogl/cogl-macros.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_MACROS_H__ -#define __COGL_MACROS_H__ - -#include <cogl/cogl-version.h> - -/* These macros are used to mark deprecated functions, and thus have - * to be exposed in a public header. - * - * They are only intended for internal use and should not be used by - * other projects. - */ -#if defined(COGL_DISABLE_DEPRECATION_WARNINGS) || defined(COGL_COMPILATION) - -#define COGL_DEPRECATED -#define COGL_DEPRECATED_FOR(f) -#define COGL_UNAVAILABLE(maj,min) - -#else /* COGL_DISABLE_DEPRECATION_WARNINGS */ - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define COGL_DEPRECATED __attribute__((__deprecated__)) -#elif defined(_MSC_VER) && (_MSC_VER >= 1300) -#define COGL_DEPRECATED __declspec(deprecated) -#else -#define COGL_DEPRECATED -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define COGL_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) -#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) -#define COGL_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) -#else -#define COGL_DEPRECATED_FOR(f) G_DEPRECATED -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define COGL_UNAVAILABLE(maj,min) __attribute__((deprecated("Not available before " #maj "." #min))) -#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) -#define COGL_UNAVAILABLE(maj,min) __declspec(deprecated("is not available before " #maj "." #min)) -#else -#define COGL_UNAVAILABLE(maj,min) -#endif - -#endif /* COGL_DISABLE_DEPRECATION_WARNINGS */ - -#define COGL_EXPORT __attribute__((visibility("default"))) extern - -#endif /* __COGL_MACROS_H__ */ diff --git a/cogl/cogl/cogl-magazine-private.h b/cogl/cogl/cogl-magazine-private.h deleted file mode 100644 index 091801be1..000000000 --- a/cogl/cogl/cogl-magazine-private.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_MAGAZINE_PRIVATE_H__ -#define __COGL_MAGAZINE_PRIVATE_H__ - -#include <glib.h> - -#include "cogl-memory-stack-private.h" - -typedef struct _CoglMagazineChunk CoglMagazineChunk; - -struct _CoglMagazineChunk -{ - CoglMagazineChunk *next; -}; - -typedef struct _CoglMagazine -{ - size_t chunk_size; - - CoglMemoryStack *stack; - CoglMagazineChunk *head; -} CoglMagazine; - -CoglMagazine * -_cogl_magazine_new (size_t chunk_size, int initial_chunk_count); - -static inline void * -_cogl_magazine_chunk_alloc (CoglMagazine *magazine) -{ - if (G_LIKELY (magazine->head)) - { - CoglMagazineChunk *chunk = magazine->head; - magazine->head = chunk->next; - return chunk; - } - else - return _cogl_memory_stack_alloc (magazine->stack, magazine->chunk_size); -} - -static inline void -_cogl_magazine_chunk_free (CoglMagazine *magazine, void *data) -{ - CoglMagazineChunk *chunk = data; - - chunk->next = magazine->head; - magazine->head = chunk; -} - -void -_cogl_magazine_free (CoglMagazine *magazine); - -#endif /* __COGL_MAGAZINE_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-magazine.c b/cogl/cogl/cogl-magazine.c deleted file mode 100644 index be5669d81..000000000 --- a/cogl/cogl/cogl-magazine.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * CoglMagazine provides a really light weight allocator for chunks - * of memory with a pre-determined size. - * - * This allocator builds on CoglMemoryStack for making all initial - * allocations but never frees memory back to the stack. - * - * Memory chunks that haven't been allocated yet are stored in a - * singly linked, fifo, list. - * - * Allocating from a magazine is simply a question of popping an entry - * from the head of the fifo list. If no entries are available then - * instead allocate from the memory stack instead. - * - * When an entry is freed, it is put back into the fifo list for - * re-use. - * - * No attempt is ever made to shrink the amount of memory associated - * with a CoglMagazine. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-memory-stack-private.h" -#include "cogl-magazine-private.h" -#include <glib.h> - -#define ROUND_UP_8(X) ((X + (8 - 1)) & ~(8 - 1)) - -CoglMagazine * -_cogl_magazine_new (size_t chunk_size, int initial_chunk_count) -{ - CoglMagazine *magazine = g_new0 (CoglMagazine, 1); - - chunk_size = MAX (chunk_size, sizeof (CoglMagazineChunk)); - chunk_size = ROUND_UP_8 (chunk_size); - - magazine->chunk_size = chunk_size; - magazine->stack = _cogl_memory_stack_new (chunk_size * initial_chunk_count); - magazine->head = NULL; - - return magazine; -} - -void -_cogl_magazine_free (CoglMagazine *magazine) -{ - _cogl_memory_stack_free (magazine->stack); - g_free (magazine); -} diff --git a/cogl/cogl/cogl-matrix-stack-private.h b/cogl/cogl/cogl-matrix-stack-private.h deleted file mode 100644 index cb0885199..000000000 --- a/cogl/cogl/cogl-matrix-stack-private.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Havoc Pennington <hp@pobox.com> for litl - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_MATRIX_STACK_PRIVATE_H_ -#define _COGL_MATRIX_STACK_PRIVATE_H_ - -#include "cogl-object-private.h" -#include "cogl-matrix-stack.h" -#include "cogl-context.h" -#include "cogl-framebuffer.h" - -typedef enum _CoglMatrixOp -{ - COGL_MATRIX_OP_LOAD_IDENTITY, - COGL_MATRIX_OP_TRANSLATE, - COGL_MATRIX_OP_ROTATE, - COGL_MATRIX_OP_ROTATE_EULER, - COGL_MATRIX_OP_SCALE, - COGL_MATRIX_OP_MULTIPLY, - COGL_MATRIX_OP_LOAD, - COGL_MATRIX_OP_SAVE, -} CoglMatrixOp; - -struct _CoglMatrixEntry -{ - CoglMatrixEntry *parent; - CoglMatrixOp op; - unsigned int ref_count; - -#ifdef COGL_DEBUG_ENABLED - /* used for performance tracing */ - int composite_gets; -#endif -}; - -typedef struct _CoglMatrixEntryTranslate -{ - CoglMatrixEntry _parent_data; - - graphene_point3d_t translate; - -} CoglMatrixEntryTranslate; - -typedef struct _CoglMatrixEntryRotate -{ - CoglMatrixEntry _parent_data; - - float angle; - graphene_vec3_t axis; - -} CoglMatrixEntryRotate; - -typedef struct _CoglMatrixEntryRotateEuler -{ - CoglMatrixEntry _parent_data; - - graphene_euler_t euler; -} CoglMatrixEntryRotateEuler; - -typedef struct _CoglMatrixEntryScale -{ - CoglMatrixEntry _parent_data; - - float x; - float y; - float z; - -} CoglMatrixEntryScale; - -typedef struct _CoglMatrixEntryMultiply -{ - CoglMatrixEntry _parent_data; - - graphene_matrix_t matrix; - -} CoglMatrixEntryMultiply; - -typedef struct _CoglMatrixEntryLoad -{ - CoglMatrixEntry _parent_data; - - graphene_matrix_t matrix; - -} CoglMatrixEntryLoad; - -typedef struct _CoglMatrixEntrySave -{ - CoglMatrixEntry _parent_data; - - graphene_matrix_t cache; - gboolean cache_valid; - -} CoglMatrixEntrySave; - -typedef union _CoglMatrixEntryFull -{ - CoglMatrixEntry any; - CoglMatrixEntryTranslate translate; - CoglMatrixEntryRotate rotate; - CoglMatrixEntryRotateEuler rotate_euler; - CoglMatrixEntryScale scale; - CoglMatrixEntryMultiply multiply; - CoglMatrixEntryLoad load; - CoglMatrixEntrySave save; -} CoglMatrixEntryFull; - -struct _CoglMatrixStack -{ - CoglObject _parent; - - CoglContext *context; - - CoglMatrixEntry *last_entry; -}; - -typedef struct _CoglMatrixEntryCache -{ - CoglMatrixEntry *entry; - gboolean flushed_identity; - gboolean flipped; -} CoglMatrixEntryCache; - -void -_cogl_matrix_entry_identity_init (CoglMatrixEntry *entry); - -void -_cogl_matrix_entry_cache_init (CoglMatrixEntryCache *cache); - -gboolean -_cogl_matrix_entry_cache_maybe_update (CoglMatrixEntryCache *cache, - CoglMatrixEntry *entry, - gboolean flip); - -void -_cogl_matrix_entry_cache_destroy (CoglMatrixEntryCache *cache); - -#endif /* _COGL_MATRIX_STACK_PRIVATE_H_ */ diff --git a/cogl/cogl/cogl-matrix-stack.c b/cogl/cogl/cogl-matrix-stack.c deleted file mode 100644 index 47afa43ec..000000000 --- a/cogl/cogl/cogl-matrix-stack.c +++ /dev/null @@ -1,922 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Havoc Pennington <hp@pobox.com> for litl - * Robert Bragg <robert@linux.intel.com> - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-graphene.h" -#include "cogl-matrix-stack.h" -#include "cogl-framebuffer-private.h" -#include "cogl-object-private.h" -#include "cogl-offscreen.h" -#include "cogl-magazine-private.h" -#include "cogl-gtype-private.h" - -static void _cogl_matrix_stack_free (CoglMatrixStack *stack); - -COGL_OBJECT_DEFINE (MatrixStack, matrix_stack); -COGL_GTYPE_DEFINE_CLASS (MatrixStack, matrix_stack); -COGL_GTYPE_DEFINE_BOXED (MatrixEntry, matrix_entry, - cogl_matrix_entry_ref, - cogl_matrix_entry_unref); - -static CoglMagazine *cogl_matrix_stack_magazine; - -/* XXX: Note: this leaves entry->parent uninitialized! */ -static CoglMatrixEntry * -_cogl_matrix_entry_new (CoglMatrixOp operation) -{ - CoglMatrixEntry *entry = - _cogl_magazine_chunk_alloc (cogl_matrix_stack_magazine); - - entry->ref_count = 1; - entry->op = operation; - -#ifdef COGL_DEBUG_ENABLED - entry->composite_gets = 0; -#endif - - return entry; -} - -static void * -_cogl_matrix_stack_push_entry (CoglMatrixStack *stack, - CoglMatrixEntry *entry) -{ - /* NB: The initial reference of the entry is transferred to the - * stack here. - * - * The stack only maintains a reference to the top of the stack (the - * last entry pushed) and each entry in-turn maintains a reference - * to its parent. - * - * We don't need to take a reference to the parent from the entry - * here because the we are stealing the reference that was held by - * the stack while that parent was previously the top of the stack. - */ - entry->parent = stack->last_entry; - stack->last_entry = entry; - - return entry; -} - -static void * -_cogl_matrix_stack_push_operation (CoglMatrixStack *stack, - CoglMatrixOp operation) -{ - CoglMatrixEntry *entry = _cogl_matrix_entry_new (operation); - - _cogl_matrix_stack_push_entry (stack, entry); - - return entry; -} - -static void * -_cogl_matrix_stack_push_replacement_entry (CoglMatrixStack *stack, - CoglMatrixOp operation) -{ - CoglMatrixEntry *old_top = stack->last_entry; - CoglMatrixEntry *new_top; - - /* This would only be called for operations that completely replace - * the matrix. In that case we don't need to keep a reference to - * anything up to the last save entry. This optimisation could be - * important for applications that aren't using the stack but - * instead just perform their own matrix manipulations and load a - * new stack every frame. If this optimisation isn't done then the - * stack would just grow endlessly. See the comments - * cogl_matrix_stack_pop for a description of how popping works. */ - for (new_top = old_top; - new_top->op != COGL_MATRIX_OP_SAVE && new_top->parent; - new_top = new_top->parent) - ; - - cogl_matrix_entry_ref (new_top); - cogl_matrix_entry_unref (old_top); - stack->last_entry = new_top; - - return _cogl_matrix_stack_push_operation (stack, operation); -} - -void -_cogl_matrix_entry_identity_init (CoglMatrixEntry *entry) -{ - entry->ref_count = 1; - entry->op = COGL_MATRIX_OP_LOAD_IDENTITY; - entry->parent = NULL; -#ifdef COGL_DEBUG_ENABLED - entry->composite_gets = 0; -#endif -} - -void -cogl_matrix_stack_load_identity (CoglMatrixStack *stack) -{ - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD_IDENTITY); -} - -void -cogl_matrix_stack_translate (CoglMatrixStack *stack, - float x, - float y, - float z) -{ - CoglMatrixEntryTranslate *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_TRANSLATE); - - graphene_point3d_init (&entry->translate, x, y, z); -} - -void -cogl_matrix_stack_rotate (CoglMatrixStack *stack, - float angle, - float x, - float y, - float z) -{ - CoglMatrixEntryRotate *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_ROTATE); - - entry->angle = angle; - graphene_vec3_init (&entry->axis, x, y, z); -} - -void -cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, - const graphene_euler_t *euler) -{ - CoglMatrixEntryRotateEuler *entry; - - entry = _cogl_matrix_stack_push_operation (stack, - COGL_MATRIX_OP_ROTATE_EULER); - graphene_euler_init_from_euler (&entry->euler, euler); -} - -void -cogl_matrix_stack_scale (CoglMatrixStack *stack, - float x, - float y, - float z) -{ - CoglMatrixEntryScale *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_SCALE); - - entry->x = x; - entry->y = y; - entry->z = z; -} - -void -cogl_matrix_stack_multiply (CoglMatrixStack *stack, - const graphene_matrix_t *matrix) -{ - CoglMatrixEntryMultiply *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_MULTIPLY); - graphene_matrix_init_from_matrix (&entry->matrix, matrix); -} - -void -cogl_matrix_stack_set (CoglMatrixStack *stack, - const graphene_matrix_t *matrix) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - graphene_matrix_init_from_matrix (&entry->matrix, matrix); -} - -void -cogl_matrix_stack_frustum (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - - graphene_matrix_init_frustum (&entry->matrix, - left, right, - bottom, top, - z_near, z_far); -} - -void -cogl_matrix_stack_perspective (CoglMatrixStack *stack, - float fov_y, - float aspect, - float z_near, - float z_far) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - graphene_matrix_init_perspective (&entry->matrix, - fov_y, aspect, - z_near, z_far); -} - -void -cogl_matrix_stack_orthographic (CoglMatrixStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far) -{ - CoglMatrixEntryLoad *entry; - - entry = - _cogl_matrix_stack_push_replacement_entry (stack, - COGL_MATRIX_OP_LOAD); - graphene_matrix_init_ortho (&entry->matrix, - x_1, x_2, - y_2, y_1, - near, far); -} - -void -cogl_matrix_stack_push (CoglMatrixStack *stack) -{ - CoglMatrixEntrySave *entry; - - entry = _cogl_matrix_stack_push_operation (stack, COGL_MATRIX_OP_SAVE); - - entry->cache_valid = FALSE; -} - -CoglMatrixEntry * -cogl_matrix_entry_ref (CoglMatrixEntry *entry) -{ - /* A NULL pointer is considered a valid stack so we should accept - that as an argument */ - if (entry) - entry->ref_count++; - - return entry; -} - -void -cogl_matrix_entry_unref (CoglMatrixEntry *entry) -{ - CoglMatrixEntry *parent; - - for (; entry && --entry->ref_count <= 0; entry = parent) - { - parent = entry->parent; - _cogl_magazine_chunk_free (cogl_matrix_stack_magazine, entry); - } -} - -void -cogl_matrix_stack_pop (CoglMatrixStack *stack) -{ - CoglMatrixEntry *old_top; - CoglMatrixEntry *new_top; - - g_return_if_fail (stack != NULL); - - old_top = stack->last_entry; - g_return_if_fail (old_top != NULL); - - /* To pop we are moving the top of the stack to the old top's parent - * node. The stack always needs to have a reference to the top entry - * so we must take a reference to the new top. The stack would have - * previously had a reference to the old top so we need to decrease - * the ref count on that. We need to ref the new head first in case - * this stack was the only thing referencing the old top. In that - * case the call to cogl_matrix_entry_unref will unref the parent. - */ - - /* Find the last save operation and remove it */ - - /* XXX: it would be an error to pop to the very beginning of the - * stack so we don't need to check for NULL pointer dereferencing. */ - for (new_top = old_top; - new_top->op != COGL_MATRIX_OP_SAVE; - new_top = new_top->parent) - ; - - new_top = new_top->parent; - cogl_matrix_entry_ref (new_top); - - cogl_matrix_entry_unref (old_top); - - stack->last_entry = new_top; -} - -gboolean -cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, - graphene_matrix_t *inverse) -{ - graphene_matrix_t matrix; - graphene_matrix_t *internal = cogl_matrix_stack_get (stack, &matrix); - - if (internal) - return graphene_matrix_inverse (internal, inverse); - else - return graphene_matrix_inverse (&matrix, inverse); -} - -/* In addition to writing the stack matrix into the give @matrix - * argument this function *may* sometimes also return a pointer - * to a matrix too so if we are querying the inverse matrix we - * should query from the return matrix so that the result can - * be cached within the stack. */ -graphene_matrix_t * -cogl_matrix_entry_get (CoglMatrixEntry *entry, - graphene_matrix_t *matrix) -{ - CoglMatrixEntry *current; - int depth; - - graphene_matrix_init_identity (matrix); - - for (current = entry, depth = 0; - current; - current = current->parent, depth++) - { - switch (current->op) - { - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate = - (CoglMatrixEntryTranslate *) current; - graphene_matrix_translate (matrix, &translate->translate); - break; - } - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate = - (CoglMatrixEntryRotate *) current; - graphene_matrix_rotate (matrix, rotate->angle, &rotate->axis); - break; - } - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate = - (CoglMatrixEntryRotateEuler *) current; - graphene_matrix_rotate_euler (matrix, &rotate->euler); - break; - } - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale = - (CoglMatrixEntryScale *) current; - graphene_matrix_scale (matrix, scale->x, scale->y, scale->z); - break; - } - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *multiply = - (CoglMatrixEntryMultiply *) current; - graphene_matrix_multiply (matrix, &multiply->matrix, matrix); - break; - } - - case COGL_MATRIX_OP_LOAD_IDENTITY: - goto applied; - - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *) current; - graphene_matrix_multiply (matrix, &load->matrix, matrix); - goto applied; - } - case COGL_MATRIX_OP_SAVE: - { - CoglMatrixEntrySave *save = (CoglMatrixEntrySave *) current; - if (!save->cache_valid) - { - cogl_matrix_entry_get (current->parent, &save->cache); - save->cache_valid = TRUE; - } - graphene_matrix_multiply (matrix, &save->cache, matrix); - goto applied; - } - } - } - -applied: - -#ifdef COGL_ENABLE_DEBUG - if (!current) - { - g_warning ("Inconsistent matrix stack"); - return NULL; - } - - entry->composite_gets++; - - if (COGL_DEBUG_ENABLED (COGL_DEBUG_PERFORMANCE) && - entry->composite_gets >= 2) - { - COGL_NOTE (PERFORMANCE, - "Re-composing a matrix stack entry multiple times"); - } -#endif - - if (depth == 0) - { - switch (entry->op) - { - case COGL_MATRIX_OP_LOAD_IDENTITY: - case COGL_MATRIX_OP_TRANSLATE: - case COGL_MATRIX_OP_ROTATE: - case COGL_MATRIX_OP_ROTATE_EULER: - case COGL_MATRIX_OP_SCALE: - case COGL_MATRIX_OP_MULTIPLY: - return NULL; - - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry; - return &load->matrix; - } - case COGL_MATRIX_OP_SAVE: - { - CoglMatrixEntrySave *save = (CoglMatrixEntrySave *)entry; - return &save->cache; - } - } - g_warn_if_reached (); - return NULL; - } - - return NULL; -} - -CoglMatrixEntry * -cogl_matrix_stack_get_entry (CoglMatrixStack *stack) -{ - return stack->last_entry; -} - -/* In addition to writing the stack matrix into the give @matrix - * argument this function *may* sometimes also return a pointer - * to a matrix too so if we are querying the inverse matrix we - * should query from the return matrix so that the result can - * be cached within the stack. */ -graphene_matrix_t * -cogl_matrix_stack_get (CoglMatrixStack *stack, - graphene_matrix_t *matrix) -{ - return cogl_matrix_entry_get (stack->last_entry, matrix); -} - -static void -_cogl_matrix_stack_free (CoglMatrixStack *stack) -{ - cogl_matrix_entry_unref (stack->last_entry); - g_free (stack); -} - -CoglMatrixStack * -cogl_matrix_stack_new (CoglContext *ctx) -{ - CoglMatrixStack *stack = g_new0 (CoglMatrixStack, 1); - - if (G_UNLIKELY (cogl_matrix_stack_magazine == NULL)) - { - cogl_matrix_stack_magazine = - _cogl_magazine_new (sizeof (CoglMatrixEntryFull), 20); - } - - stack->context = ctx; - stack->last_entry = NULL; - - cogl_matrix_entry_ref (&ctx->identity_entry); - _cogl_matrix_stack_push_entry (stack, &ctx->identity_entry); - - return _cogl_matrix_stack_object_new (stack); -} - -static CoglMatrixEntry * -_cogl_matrix_entry_skip_saves (CoglMatrixEntry *entry) -{ - /* We currently assume that every stack starts with an - * _OP_LOAD_IDENTITY so we don't need to worry about - * NULL pointer dereferencing here. */ - while (entry->op == COGL_MATRIX_OP_SAVE) - entry = entry->parent; - - return entry; -} - -gboolean -cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1, - float *x, - float *y, - float *z) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglMatrixEntry *node0; - CoglMatrixEntry *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - - /* Algorithm: - * - * 1) Ignoring _OP_SAVE entries walk the ancestors of each entry to - * the root node or any non-translation node, adding a pointer to - * each ancestor node to two linked lists. - * - * 2) Compare the lists to find the nodes where they start to - * differ marking the common_ancestor node for each list. - * - * 3) For the list corresponding to entry0, start iterating after - * the common ancestor applying the negative of all translations - * to x, y and z. - * - * 4) For the list corresponding to entry1, start iterating after - * the common ancestor applying the positive of all translations - * to x, y and z. - * - * If we come across any non-translation operations during 3) or 4) - * then bail out returning FALSE. - */ - - for (node0 = entry0; node0; node0 = node0->parent) - { - GSList *link; - - if (node0->op == COGL_MATRIX_OP_SAVE) - continue; - - link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - - if (node0->op != COGL_MATRIX_OP_TRANSLATE) - break; - } - for (node1 = entry1; node1; node1 = node1->parent) - { - GSList *link; - - if (node1->op == COGL_MATRIX_OP_SAVE) - continue; - - link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - - if (node1->op != COGL_MATRIX_OP_TRANSLATE) - break; - } - - if (head0->data != head1->data) - return FALSE; - - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - *x = 0; - *y = 0; - *z = 0; - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - CoglMatrixEntryTranslate *translate; - - node0 = head0->data; - - if (node0->op != COGL_MATRIX_OP_TRANSLATE) - return FALSE; - - translate = (CoglMatrixEntryTranslate *)node0; - - *x = *x - translate->translate.x; - *y = *y - translate->translate.y; - *z = *z - translate->translate.z; - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - CoglMatrixEntryTranslate *translate; - - node1 = head1->data; - - if (node1->op != COGL_MATRIX_OP_TRANSLATE) - return FALSE; - - translate = (CoglMatrixEntryTranslate *)node1; - - *x = *x + translate->translate.x; - *y = *y + translate->translate.y; - *z = *z + translate->translate.z; - } - - return TRUE; -} - -gboolean -cogl_matrix_entry_is_identity (CoglMatrixEntry *entry) -{ - return entry ? entry->op == COGL_MATRIX_OP_LOAD_IDENTITY : FALSE; -} - -gboolean -cogl_matrix_entry_equal (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1) -{ - for (; - entry0 && entry1; - entry0 = entry0->parent, entry1 = entry1->parent) - { - entry0 = _cogl_matrix_entry_skip_saves (entry0); - entry1 = _cogl_matrix_entry_skip_saves (entry1); - - if (entry0 == entry1) - return TRUE; - - if (entry0->op != entry1->op) - return FALSE; - - switch (entry0->op) - { - case COGL_MATRIX_OP_LOAD_IDENTITY: - return TRUE; - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate0 = - (CoglMatrixEntryTranslate *)entry0; - CoglMatrixEntryTranslate *translate1 = - (CoglMatrixEntryTranslate *)entry1; - /* We could perhaps use an epsilon to compare here? - * I expect the false negatives are probably never going to - * be a problem and this is a bit cheaper. */ - if (!graphene_point3d_equal (&translate0->translate, - &translate1->translate)) - return FALSE; - } - break; - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate0 = - (CoglMatrixEntryRotate *)entry0; - CoglMatrixEntryRotate *rotate1 = - (CoglMatrixEntryRotate *)entry1; - if (rotate0->angle != rotate1->angle || - !graphene_vec3_equal (&rotate0->axis, &rotate1->axis)) - return FALSE; - } - break; - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate0 = - (CoglMatrixEntryRotateEuler *)entry0; - CoglMatrixEntryRotateEuler *rotate1 = - (CoglMatrixEntryRotateEuler *)entry1; - - if (!graphene_euler_equal (&rotate0->euler, &rotate1->euler)) - return FALSE; - } - break; - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0; - CoglMatrixEntryScale *scale1 = (CoglMatrixEntryScale *)entry1; - if (scale0->x != scale1->x || - scale0->y != scale1->y || - scale0->z != scale1->z) - return FALSE; - } - break; - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *mult0 = (CoglMatrixEntryMultiply *)entry0; - CoglMatrixEntryMultiply *mult1 = (CoglMatrixEntryMultiply *)entry1; - if (!graphene_matrix_equal (&mult0->matrix, &mult1->matrix)) - return FALSE; - } - break; - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load0 = (CoglMatrixEntryLoad *)entry0; - CoglMatrixEntryLoad *load1 = (CoglMatrixEntryLoad *)entry1; - /* There's no need to check any further since an - * _OP_LOAD makes all the ancestors redundant as far as - * the final matrix value is concerned. */ - return graphene_matrix_equal (&load0->matrix, &load1->matrix); - } - case COGL_MATRIX_OP_SAVE: - /* We skip over saves above so we shouldn't see save entries */ - g_warn_if_reached (); - } - } - - return FALSE; -} - -void -cogl_debug_matrix_entry_print (CoglMatrixEntry *entry) -{ - int depth; - CoglMatrixEntry *e; - CoglMatrixEntry **children; - int i; - - for (depth = 0, e = entry; e; e = e->parent) - depth++; - - children = g_alloca (sizeof (CoglMatrixEntry) * depth); - - for (i = depth - 1, e = entry; - i >= 0 && e; - i--, e = e->parent) - { - children[i] = e; - } - - g_print ("MatrixEntry %p =\n", entry); - - for (i = 0; i < depth; i++) - { - entry = children[i]; - - switch (entry->op) - { - case COGL_MATRIX_OP_LOAD_IDENTITY: - g_print (" LOAD IDENTITY\n"); - continue; - case COGL_MATRIX_OP_TRANSLATE: - { - CoglMatrixEntryTranslate *translate = - (CoglMatrixEntryTranslate *)entry; - g_print (" TRANSLATE X=%f Y=%f Z=%f\n", - translate->translate.x, - translate->translate.y, - translate->translate.z); - continue; - } - case COGL_MATRIX_OP_ROTATE: - { - CoglMatrixEntryRotate *rotate = - (CoglMatrixEntryRotate *)entry; - g_print (" ROTATE ANGLE=%f X=%f Y=%f Z=%f\n", - rotate->angle, - graphene_vec3_get_x (&rotate->axis), - graphene_vec3_get_y (&rotate->axis), - graphene_vec3_get_z (&rotate->axis)); - continue; - } - case COGL_MATRIX_OP_ROTATE_EULER: - { - CoglMatrixEntryRotateEuler *rotate = - (CoglMatrixEntryRotateEuler *)entry; - g_print (" ROTATE EULER heading=%f pitch=%f roll=%f\n", - graphene_euler_get_y (&rotate->euler), - graphene_euler_get_x (&rotate->euler), - graphene_euler_get_z (&rotate->euler)); - continue; - } - case COGL_MATRIX_OP_SCALE: - { - CoglMatrixEntryScale *scale = (CoglMatrixEntryScale *)entry; - g_print (" SCALE X=%f Y=%f Z=%f\n", - scale->x, - scale->y, - scale->z); - continue; - } - case COGL_MATRIX_OP_MULTIPLY: - { - CoglMatrixEntryMultiply *mult = (CoglMatrixEntryMultiply *)entry; - g_print (" MULT:\n"); - graphene_matrix_print (&mult->matrix); - continue; - } - case COGL_MATRIX_OP_LOAD: - { - CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry; - g_print (" LOAD:\n"); - graphene_matrix_print (&load->matrix); - continue; - } - case COGL_MATRIX_OP_SAVE: - g_print (" SAVE\n"); - } - } -} - -void -_cogl_matrix_entry_cache_init (CoglMatrixEntryCache *cache) -{ - cache->entry = NULL; - cache->flushed_identity = FALSE; - cache->flipped = FALSE; -} - -/* NB: This function can report false negatives since it never does a - * deep comparison of the stack matrices. */ -gboolean -_cogl_matrix_entry_cache_maybe_update (CoglMatrixEntryCache *cache, - CoglMatrixEntry *entry, - gboolean flip) -{ - gboolean is_identity; - gboolean updated = FALSE; - - if (cache->flipped != flip) - { - cache->flipped = flip; - updated = TRUE; - } - - is_identity = (entry->op == COGL_MATRIX_OP_LOAD_IDENTITY); - if (cache->flushed_identity != is_identity) - { - cache->flushed_identity = is_identity; - updated = TRUE; - } - - if (cache->entry != entry) - { - cogl_matrix_entry_ref (entry); - if (cache->entry) - cogl_matrix_entry_unref (cache->entry); - cache->entry = entry; - - /* We want to make sure here that if the cache->entry and the - * given @entry are both identity matrices then even though they - * are different entries we don't want to consider this an - * update... - */ - updated |= !is_identity; - } - - return updated; -} - -void -_cogl_matrix_entry_cache_destroy (CoglMatrixEntryCache *cache) -{ - if (cache->entry) - cogl_matrix_entry_unref (cache->entry); -} diff --git a/cogl/cogl/cogl-matrix-stack.h b/cogl/cogl/cogl-matrix-stack.h deleted file mode 100644 index 3e330916f..000000000 --- a/cogl/cogl/cogl-matrix-stack.h +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Havoc Pennington <hp@pobox.com> for litl - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_MATRIX_STACK_H_ -#define _COGL_MATRIX_STACK_H_ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#include "cogl-context.h" - -#include <graphene.h> - -/** - * SECTION:cogl-matrix-stack - * @short_description: Functions for efficiently tracking many - * related transformations - * - * Matrices can be used (for example) to describe the model-view - * transforms of objects, texture transforms, and projective - * transforms. - * - * The #graphene_matrix_t api provides a good way to manipulate individual - * matrices representing a single transformation but if you need to - * track many-many such transformations for many objects that are - * organized in a scenegraph for example then using a separate - * #graphene_matrix_t for each object may not be the most efficient way. - * - * A #CoglMatrixStack enables applications to track lots of - * transformations that are related to each other in some kind of - * hierarchy. In a scenegraph for example if you want to know how to - * transform a particular node then you usually have to walk up - * through the ancestors and accumulate their transforms before - * finally applying the transform of the node itself. In this model - * things are grouped together spatially according to their ancestry - * and all siblings with the same parent share the same initial - * transformation. The #CoglMatrixStack API is suited to tracking lots - * of transformations that fit this kind of model. - * - * Compared to using the #graphene_matrix_t api directly to track many - * related transforms, these can be some advantages to using a - * #CoglMatrixStack: - * <itemizedlist> - * <listitem>Faster equality comparisons of transformations</listitem> - * <listitem>Efficient comparisons of the differences between arbitrary - * transformations</listitem> - * <listitem>Avoid redundant arithmetic related to common transforms - * </listitem> - * <listitem>Can be more space efficient (not always though)</listitem> - * </itemizedlist> - * - * For reference (to give an idea of when a #CoglMatrixStack can - * provide a space saving) a #graphene_matrix_t can be expected to take 72 - * bytes whereas a single #CoglMatrixEntry in a #CoglMatrixStack is - * currently around 32 bytes on a 32bit CPU or 36 bytes on a 64bit - * CPU. An entry is needed for each individual operation applied to - * the stack (such as rotate, scale, translate) so if most of your - * leaf node transformations only need one or two simple operations - * relative to their parent then a matrix stack will likely take less - * space than having a #graphene_matrix_t for each node. - * - * Even without any space saving though the ability to perform fast - * comparisons and avoid redundant arithmetic (especially sine and - * cosine calculations for rotations) can make using a matrix stack - * worthwhile. - */ - -/** - * CoglMatrixStack: - * - * Tracks your current position within a hierarchy and lets you build - * up a graph of transformations as you traverse through a hierarchy - * such as a scenegraph. - * - * A #CoglMatrixStack always maintains a reference to a single - * transformation at any point in time, representing the - * transformation at the current position in the hierarchy. You can - * get a reference to the current transformation by calling - * cogl_matrix_stack_get_entry(). - * - * When a #CoglMatrixStack is first created with - * cogl_matrix_stack_new() then it is conceptually positioned at the - * root of your hierarchy and the current transformation simply - * represents an identity transformation. - * - * As you traverse your object hierarchy (your scenegraph) then you - * should call cogl_matrix_stack_push() whenever you move down one - * level and call cogl_matrix_stack_pop() whenever you move back up - * one level towards the root. - * - * At any time you can apply a set of operations, such as "rotate", - * "scale", "translate" on top of the current transformation of a - * #CoglMatrixStack using functions such as - * cogl_matrix_stack_rotate(), cogl_matrix_stack_scale() and - * cogl_matrix_stack_translate(). These operations will derive a new - * current transformation and will never affect a transformation - * that you have referenced using cogl_matrix_stack_get_entry(). - * - * Internally applying operations to a #CoglMatrixStack builds up a - * graph of #CoglMatrixEntry structures which each represent a single - * immutable transform. - */ -typedef struct _CoglMatrixStack CoglMatrixStack; - -/** - * cogl_matrix_stack_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_matrix_stack_get_gtype (void); - -/** - * CoglMatrixEntry: - * - * Represents a single immutable transformation that was retrieved - * from a #CoglMatrixStack using cogl_matrix_stack_get_entry(). - * - * Internally a #CoglMatrixEntry represents a single matrix - * operation (such as "rotate", "scale", "translate") which is applied - * to the transform of a single parent entry. - * - * Using the #CoglMatrixStack api effectively builds up a graph of - * these immutable #CoglMatrixEntry structures whereby operations - * that can be shared between multiple transformations will result - * in shared #CoglMatrixEntry nodes in the graph. - * - * When a #CoglMatrixStack is first created it references one - * #CoglMatrixEntry that represents a single "load identity" - * operation. This serves as the root entry and all operations - * that are then applied to the stack will extend the graph - * starting from this root "load identity" entry. - * - * Given the typical usage model for a #CoglMatrixStack and the way - * the entries are built up while traversing a scenegraph then in most - * cases where an application is interested in comparing two - * transformations for equality then it is enough to simply compare - * two #CoglMatrixEntry pointers directly. Technically this can lead - * to false negatives that could be identified with a deeper - * comparison but often these false negatives are unlikely and - * don't matter anyway so this enables extremely cheap comparisons. - * - * <note>#CoglMatrixEntry<!-- -->s are reference counted using - * cogl_matrix_entry_ref() and cogl_matrix_entry_unref() not with - * cogl_object_ref() and cogl_object_unref().</note> - */ -typedef struct _CoglMatrixEntry CoglMatrixEntry; - -/** - * cogl_matrix_entry_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_matrix_entry_get_gtype (void); - - -/** - * cogl_matrix_stack_new: - * @ctx: A #CoglContext - * - * Allocates a new #CoglMatrixStack that can be used to build up - * transformations relating to objects in a scenegraph like hierarchy. - * (See the description of #CoglMatrixStack and #CoglMatrixEntry for - * more details of what a matrix stack is best suited for) - * - * When a #CoglMatrixStack is first allocated it is conceptually - * positioned at the root of your scenegraph hierarchy. As you - * traverse your scenegraph then you should call - * cogl_matrix_stack_push() whenever you move down a level and - * cogl_matrix_stack_pop() whenever you move back up a level towards - * the root. - * - * Once you have allocated a #CoglMatrixStack you can get a reference - * to the current transformation for the current position in the - * hierarchy by calling cogl_matrix_stack_get_entry(). - * - * Once you have allocated a #CoglMatrixStack you can apply operations - * such as rotate, scale and translate to modify the current transform - * for the current position in the hierarchy by calling - * cogl_matrix_stack_rotate(), cogl_matrix_stack_scale() and - * cogl_matrix_stack_translate(). - * - * Return value: (transfer full): A newly allocated #CoglMatrixStack - */ -COGL_EXPORT CoglMatrixStack * -cogl_matrix_stack_new (CoglContext *ctx); - -/** - * cogl_matrix_stack_push: - * @stack: A #CoglMatrixStack - * - * Saves the current transform and starts a new transform that derives - * from the current transform. - * - * This is usually called while traversing a scenegraph whenever you - * traverse one level deeper. cogl_matrix_stack_pop() can then be - * called when going back up one layer to restore the previous - * transform of an ancestor. - */ -COGL_EXPORT void -cogl_matrix_stack_push (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_pop: - * @stack: A #CoglMatrixStack - * - * Restores the previous transform that was last saved by calling - * cogl_matrix_stack_push(). - * - * This is usually called while traversing a scenegraph whenever you - * return up one level in the graph towards the root node. - */ -COGL_EXPORT void -cogl_matrix_stack_pop (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_load_identity: - * @stack: A #CoglMatrixStack - * - * Resets the current matrix to the identity matrix. - */ -COGL_EXPORT void -cogl_matrix_stack_load_identity (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_scale: - * @stack: A #CoglMatrixStack - * @x: Amount to scale along the x-axis - * @y: Amount to scale along the y-axis - * @z: Amount to scale along the z-axis - * - * Multiplies the current matrix by one that scales the x, y and z - * axes by the given values. - */ -COGL_EXPORT void -cogl_matrix_stack_scale (CoglMatrixStack *stack, - float x, - float y, - float z); - -/** - * cogl_matrix_stack_translate: - * @stack: A #CoglMatrixStack - * @x: Distance to translate along the x-axis - * @y: Distance to translate along the y-axis - * @z: Distance to translate along the z-axis - * - * Multiplies the current matrix by one that translates along all - * three axes according to the given values. - */ -COGL_EXPORT void -cogl_matrix_stack_translate (CoglMatrixStack *stack, - float x, - float y, - float z); - -/** - * cogl_matrix_stack_rotate: - * @stack: A #CoglMatrixStack - * @angle: Angle in degrees to rotate. - * @x: X-component of vertex to rotate around. - * @y: Y-component of vertex to rotate around. - * @z: Z-component of vertex to rotate around. - * - * Multiplies the current matrix by one that rotates the around the - * axis-vector specified by @x, @y and @z. The rotation follows the - * right-hand thumb rule so for example rotating by 10 degrees about - * the axis-vector (0, 0, 1) causes a small counter-clockwise - * rotation. - */ -COGL_EXPORT void -cogl_matrix_stack_rotate (CoglMatrixStack *stack, - float angle, - float x, - float y, - float z); - -/** - * cogl_matrix_stack_rotate_euler: - * @stack: A #CoglMatrixStack - * @euler: A #graphene_euler_t - * - * Multiplies the current matrix by one that rotates according to the - * rotation described by @euler. - */ -COGL_EXPORT void -cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, - const graphene_euler_t *euler); - -/** - * cogl_matrix_stack_multiply: - * @stack: A #CoglMatrixStack - * @matrix: the matrix to multiply with the current model-view - * - * Multiplies the current matrix by the given matrix. - */ -COGL_EXPORT void -cogl_matrix_stack_multiply (CoglMatrixStack *stack, - const graphene_matrix_t *matrix); - -/** - * cogl_matrix_stack_frustum: - * @stack: A #CoglMatrixStack - * @left: X position of the left clipping plane where it - * intersects the near clipping plane - * @right: X position of the right clipping plane where it - * intersects the near clipping plane - * @bottom: Y position of the bottom clipping plane where it - * intersects the near clipping plane - * @top: Y position of the top clipping plane where it intersects - * the near clipping plane - * @z_near: The distance to the near clipping plane (Must be positive) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current matrix with a perspective matrix for a given - * viewing frustum defined by 4 side clip planes that all cross - * through the origin and 2 near and far clip planes. - */ -COGL_EXPORT void -cogl_matrix_stack_frustum (CoglMatrixStack *stack, - float left, - float right, - float bottom, - float top, - float z_near, - float z_far); - -/** - * cogl_matrix_stack_perspective: - * @stack: A #CoglMatrixStack - * @fov_y: Vertical field of view angle in degrees. - * @aspect: The (width over height) aspect ratio for display - * @z_near: The distance to the near clipping plane (Must be positive, - * and must not be 0) - * @z_far: The distance to the far clipping plane (Must be positive) - * - * Replaces the current matrix with a perspective matrix based on the - * provided values. - * - * <note>You should be careful not to have too great a @z_far / @z_near - * ratio since that will reduce the effectiveness of depth testing - * since there won't be enough precision to identify the depth of - * objects near to each other.</note> - */ -COGL_EXPORT void -cogl_matrix_stack_perspective (CoglMatrixStack *stack, - float fov_y, - float aspect, - float z_near, - float z_far); - -/** - * cogl_matrix_stack_orthographic: - * @stack: A #CoglMatrixStack - * @x_1: The x coordinate for the first vertical clipping plane - * @y_1: The y coordinate for the first horizontal clipping plane - * @x_2: The x coordinate for the second vertical clipping plane - * @y_2: The y coordinate for the second horizontal clipping plane - * @near: The <emphasis>distance</emphasis> to the near clipping - * plane (will be <emphasis>negative</emphasis> if the plane is - * behind the viewer) - * @far: The <emphasis>distance</emphasis> to the far clipping - * plane (will be <emphasis>negative</emphasis> if the plane is - * behind the viewer) - * - * Replaces the current matrix with an orthographic projection matrix. - */ -COGL_EXPORT void -cogl_matrix_stack_orthographic (CoglMatrixStack *stack, - float x_1, - float y_1, - float x_2, - float y_2, - float near, - float far); - -/** - * cogl_matrix_stack_get_inverse: - * @stack: A #CoglMatrixStack - * @inverse: (out): The destination for a 4x4 inverse transformation matrix - * - * Gets the inverse transform of the current matrix and uses it to - * initialize a new #graphene_matrix_t. - * - * Return value: %TRUE if the inverse was successfully calculated or %FALSE - * for degenerate transformations that can't be inverted (in this case the - * @inverse matrix will simply be initialized with the identity matrix) - */ -COGL_EXPORT gboolean -cogl_matrix_stack_get_inverse (CoglMatrixStack *stack, - graphene_matrix_t *inverse); - -/** - * cogl_matrix_stack_get_entry: - * @stack: A #CoglMatrixStack - * - * Gets a reference to the current transform represented by a - * #CoglMatrixEntry pointer. - * - * <note>The transform represented by a #CoglMatrixEntry is - * immutable.</note> - * - * <note>#CoglMatrixEntry<!-- -->s are reference counted using - * cogl_matrix_entry_ref() and cogl_matrix_entry_unref() and you - * should call cogl_matrix_entry_unref() when you are finished with - * and entry you get via cogl_matrix_stack_get_entry().</note> - * - * Return value: (transfer none): A pointer to the #CoglMatrixEntry - * representing the current matrix stack transform. - */ -COGL_EXPORT CoglMatrixEntry * -cogl_matrix_stack_get_entry (CoglMatrixStack *stack); - -/** - * cogl_matrix_stack_get: - * @stack: A #CoglMatrixStack - * @matrix: (out): The potential destination for the current matrix - * - * Resolves the current @stack transform into a #graphene_matrix_t by - * combining the operations that have been applied to build up the - * current transform. - * - * There are two possible ways that this function may return its - * result depending on whether the stack is able to directly point - * to an internal #graphene_matrix_t or whether the result needs to be - * composed of multiple operations. - * - * If an internal matrix contains the required result then this - * function will directly return a pointer to that matrix, otherwise - * if the function returns %NULL then @matrix will be initialized - * to match the current transform of @stack. - * - * <note>@matrix will be left untouched if a direct pointer is - * returned.</note> - * - * Return value: A direct pointer to the current transform or %NULL - * and in that case @matrix will be initialized with - * the value of the current transform. - */ -COGL_EXPORT graphene_matrix_t * -cogl_matrix_stack_get (CoglMatrixStack *stack, - graphene_matrix_t *matrix); - -/** - * cogl_matrix_entry_get: - * @entry: A #CoglMatrixEntry - * @matrix: (out): The potential destination for the transform as - * a matrix - * - * Resolves the current @entry transform into a #graphene_matrix_t by - * combining the sequence of operations that have been applied to - * build up the current transform. - * - * There are two possible ways that this function may return its - * result depending on whether it's possible to directly point - * to an internal #graphene_matrix_t or whether the result needs to be - * composed of multiple operations. - * - * If an internal matrix contains the required result then this - * function will directly return a pointer to that matrix, otherwise - * if the function returns %NULL then @matrix will be initialized - * to match the transform of @entry. - * - * <note>@matrix will be left untouched if a direct pointer is - * returned.</note> - * - * Return value: A direct pointer to a #graphene_matrix_t transform or %NULL - * and in that case @matrix will be initialized with - * the effective transform represented by @entry. - */ -COGL_EXPORT graphene_matrix_t * -cogl_matrix_entry_get (CoglMatrixEntry *entry, - graphene_matrix_t *matrix); - -/** - * cogl_matrix_stack_set: - * @stack: A #CoglMatrixStack - * @matrix: A #graphene_matrix_t replace the current matrix value with - * - * Replaces the current @stack matrix value with the value of @matrix. - * This effectively discards any other operations that were applied - * since the last time cogl_matrix_stack_push() was called or since - * the stack was initialized. - */ -COGL_EXPORT void -cogl_matrix_stack_set (CoglMatrixStack *stack, - const graphene_matrix_t *matrix); - -/** - * cogl_is_matrix_stack: - * @object: a #CoglObject - * - * Determines if the given #CoglObject refers to a #CoglMatrixStack. - * - * Return value: %TRUE if @object is a #CoglMatrixStack, otherwise - * %FALSE. - */ -COGL_EXPORT gboolean -cogl_is_matrix_stack (void *object); - -/** - * cogl_matrix_entry_calculate_translation: - * @entry0: The first reference transform - * @entry1: A second reference transform - * @x: (out): The destination for the x-component of the translation - * @y: (out): The destination for the y-component of the translation - * @z: (out): The destination for the z-component of the translation - * - * Determines if the only difference between two transforms is a - * translation and if so returns what the @x, @y, and @z components of - * the translation are. - * - * If the difference between the two translations involves anything - * other than a translation then the function returns %FALSE. - * - * Return value: %TRUE if the only difference between the transform of - * @entry0 and the transform of @entry1 is a translation, - * otherwise %FALSE. - */ -COGL_EXPORT gboolean -cogl_matrix_entry_calculate_translation (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1, - float *x, - float *y, - float *z); - -/** - * cogl_matrix_entry_is_identity: - * @entry: A #CoglMatrixEntry - * - * Determines whether @entry is known to represent an identity - * transform. - * - * If this returns %TRUE then the entry is definitely the identity - * matrix. If it returns %FALSE it may or may not be the identity - * matrix but no expensive comparison is performed to verify it. - * - * Return value: %TRUE if @entry is definitely an identity transform, - * otherwise %FALSE. - */ -COGL_EXPORT gboolean -cogl_matrix_entry_is_identity (CoglMatrixEntry *entry); - -/** - * cogl_matrix_entry_equal: - * @entry0: The first #CoglMatrixEntry to compare - * @entry1: A second #CoglMatrixEntry to compare - * - * Compares two arbitrary #CoglMatrixEntry transforms for equality - * returning %TRUE if they are equal or %FALSE otherwise. - * - * <note>In many cases it is unnecessary to use this api and instead - * direct pointer comparisons of entries are good enough and much - * cheaper too.</note> - * - * Return value: %TRUE if @entry0 represents the same transform as - * @entry1, otherwise %FALSE. - */ -COGL_EXPORT gboolean -cogl_matrix_entry_equal (CoglMatrixEntry *entry0, - CoglMatrixEntry *entry1); - -/** - * cogl_debug_matrix_entry_print: - * @entry: A #CoglMatrixEntry - * - * Allows visualizing the operations that build up the given @entry - * for debugging purposes by printing to stdout. - */ -COGL_EXPORT void -cogl_debug_matrix_entry_print (CoglMatrixEntry *entry); - -/** - * cogl_matrix_entry_ref: - * @entry: A #CoglMatrixEntry - * - * Takes a reference on the given @entry to ensure the @entry stays - * alive and remains valid. When you are finished with the @entry then - * you should call cogl_matrix_entry_unref(). - * - * It is an error to pass an @entry pointer to cogl_object_ref() and - * cogl_object_unref() - */ -COGL_EXPORT CoglMatrixEntry * -cogl_matrix_entry_ref (CoglMatrixEntry *entry); - -/** - * cogl_matrix_entry_unref: - * @entry: A #CoglMatrixEntry - * - * Releases a reference on @entry either taken by calling - * cogl_matrix_entry_unref() or to release the reference given when - * calling cogl_matrix_stack_get_entry(). - */ -COGL_EXPORT void -cogl_matrix_entry_unref (CoglMatrixEntry *entry); - -#endif /* _COGL_MATRIX_STACK_H_ */ diff --git a/cogl/cogl/cogl-memory-stack-private.h b/cogl/cogl/cogl-memory-stack-private.h deleted file mode 100644 index 2b6ee828c..000000000 --- a/cogl/cogl/cogl-memory-stack-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_MEMORY_STACK__ -#define __COGL_MEMORY_STACK__ - -#include <glib.h> - -typedef struct _CoglMemoryStack CoglMemoryStack; - -CoglMemoryStack * -_cogl_memory_stack_new (size_t initial_size_bytes); - -void * -_cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes); - -void -_cogl_memory_stack_rewind (CoglMemoryStack *stack); - -void -_cogl_memory_stack_free (CoglMemoryStack *stack); - -#endif /* __COGL_MEMORY_STACK__ */ diff --git a/cogl/cogl/cogl-memory-stack.c b/cogl/cogl/cogl-memory-stack.c deleted file mode 100644 index 2ea6e8f88..000000000 --- a/cogl/cogl/cogl-memory-stack.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * CoglMemoryStack provides a really simple, but lightning fast - * memory stack allocation strategy: - * - * - The underlying pool of memory is grow-only. - * - The pool is considered to be a stack which may be comprised - * of multiple smaller stacks. Allocation is done as follows: - * - If there's enough memory in the current sub-stack then the - * stack-pointer will be returned as the allocation and the - * stack-pointer will be incremented by the allocation size. - * - If there isn't enough memory in the current sub-stack - * then a new sub-stack is allocated twice as big as the current - * sub-stack or twice as big as the requested allocation size if - * that's bigger and the stack-pointer is set to the start of the - * new sub-stack. - * - Allocations can't be freed in a random-order, you can only - * rewind the entire stack back to the start. There is no - * the concept of stack frames to allow partial rewinds. - * - * For example; we plan to use this in our tessellator which has to - * allocate lots of small vertex, edge and face structures because - * when tessellation has been finished we just want to free the whole - * lot in one go. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-memory-stack-private.h" -#include "cogl-list.h" - -#include <stdint.h> - -#include <glib.h> - -typedef struct _CoglMemorySubStack -{ - CoglList link; - size_t bytes; - uint8_t *data; -} CoglMemorySubStack; - -struct _CoglMemoryStack -{ - CoglList sub_stacks; - - CoglMemorySubStack *sub_stack; - size_t sub_stack_offset; -}; - -static CoglMemorySubStack * -_cogl_memory_sub_stack_alloc (size_t bytes) -{ - CoglMemorySubStack *sub_stack = g_new0 (CoglMemorySubStack, 1); - sub_stack->bytes = bytes; - sub_stack->data = g_malloc (bytes); - return sub_stack; -} - -static void -_cogl_memory_stack_add_sub_stack (CoglMemoryStack *stack, - size_t sub_stack_bytes) -{ - CoglMemorySubStack *sub_stack = - _cogl_memory_sub_stack_alloc (sub_stack_bytes); - _cogl_list_insert (stack->sub_stacks.prev, &sub_stack->link); - stack->sub_stack = sub_stack; - stack->sub_stack_offset = 0; -} - -CoglMemoryStack * -_cogl_memory_stack_new (size_t initial_size_bytes) -{ - CoglMemoryStack *stack = g_new0 (CoglMemoryStack, 1); - - _cogl_list_init (&stack->sub_stacks); - - _cogl_memory_stack_add_sub_stack (stack, initial_size_bytes); - - return stack; -} - -void * -_cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes) -{ - CoglMemorySubStack *sub_stack; - void *ret; - - sub_stack = stack->sub_stack; - if (G_LIKELY (sub_stack->bytes - stack->sub_stack_offset >= bytes)) - { - ret = sub_stack->data + stack->sub_stack_offset; - stack->sub_stack_offset += bytes; - return ret; - } - - /* If the stack has been rewound and then a large initial allocation - * is made then we may need to skip over one or more of the - * sub-stacks that are too small for the requested allocation - * size... */ - for (_cogl_list_set_iterator (sub_stack->link.next, sub_stack, link); - &sub_stack->link != &stack->sub_stacks; - _cogl_list_set_iterator (sub_stack->link.next, sub_stack, link)) - { - if (sub_stack->bytes >= bytes) - { - ret = sub_stack->data; - stack->sub_stack = sub_stack; - stack->sub_stack_offset = bytes; - return ret; - } - } - - /* Finally if we couldn't find a free sub-stack with enough space - * for the requested allocation we allocate another sub-stack that's - * twice as big as the last sub-stack or twice as big as the - * requested allocation if that's bigger. - */ - - sub_stack = _cogl_container_of (stack->sub_stacks.prev, - CoglMemorySubStack, - link); - - _cogl_memory_stack_add_sub_stack (stack, MAX (sub_stack->bytes, bytes) * 2); - - sub_stack = _cogl_container_of (stack->sub_stacks.prev, - CoglMemorySubStack, - link); - - stack->sub_stack_offset += bytes; - - return sub_stack->data; -} - -void -_cogl_memory_stack_rewind (CoglMemoryStack *stack) -{ - stack->sub_stack = _cogl_container_of (stack->sub_stacks.next, - CoglMemorySubStack, - link); - stack->sub_stack_offset = 0; -} - -static void -_cogl_memory_sub_stack_free (CoglMemorySubStack *sub_stack) -{ - g_free (sub_stack->data); - g_free (sub_stack); -} - -void -_cogl_memory_stack_free (CoglMemoryStack *stack) -{ - - while (!_cogl_list_empty (&stack->sub_stacks)) - { - CoglMemorySubStack *sub_stack = - _cogl_container_of (stack->sub_stacks.next, CoglMemorySubStack, link); - _cogl_list_remove (&sub_stack->link); - _cogl_memory_sub_stack_free (sub_stack); - } - - g_free (stack); -} diff --git a/cogl/cogl/cogl-meta-texture.c b/cogl/cogl/cogl-meta-texture.c deleted file mode 100644 index b8b91aa4a..000000000 --- a/cogl/cogl/cogl-meta-texture.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-texture.h" -#include "cogl-spans.h" -#include "cogl-meta-texture.h" -#include "cogl-texture-private.h" - -#include <string.h> -#include <math.h> - -typedef struct _ForeachData -{ - float meta_region_coords[4]; - CoglPipelineWrapMode wrap_s; - CoglPipelineWrapMode wrap_t; - CoglMetaTextureCallback callback; - void *user_data; - - int width; - int height; - - CoglTexture *padded_textures[9]; - const float *grid_slice_texture_coords; - float slice_offset_s; - float slice_offset_t; - float slice_range_s; - float slice_range_t; -} ForeachData; - -static void -padded_grid_repeat_cb (CoglTexture *slice_texture, - const float *slice_texture_coords, - const float *meta_coords, - void *user_data) -{ - ForeachData *data; - float mapped_coords[4]; - - /* Ignore padding slices for the current grid */ - if (!slice_texture) - return; - - data = user_data; - - /* NB: the slice_texture_coords[] we get here will always be - * normalized. - * - * We now need to map the normalized slice_texture_coords[] we have - * here back to the real slice coordinates we saved in the previous - * stage... - */ - mapped_coords[0] = - slice_texture_coords[0] * data->slice_range_s + data->slice_offset_s; - mapped_coords[1] = - slice_texture_coords[1] * data->slice_range_t + data->slice_offset_t; - mapped_coords[2] = - slice_texture_coords[2] * data->slice_range_s + data->slice_offset_s; - mapped_coords[3] = - slice_texture_coords[3] * data->slice_range_t + data->slice_offset_t; - - data->callback (slice_texture, - mapped_coords, meta_coords, data->user_data); -} - -static int -setup_padded_spans (CoglSpan *spans, - float start, - float end, - float range, - int *real_index) -{ - int span_index = 0; - - if (start > 0) - { - spans[0].start = 0; - spans[0].size = start; - spans[0].waste = 0; - span_index++; - spans[1].start = spans[0].size; - } - else - spans[span_index].start = 0; - - spans[span_index].size = end - start; - spans[span_index].waste = 0; - *real_index = span_index; - span_index++; - - if (end < range) - { - spans[span_index].start = - spans[span_index - 1].start + spans[span_index - 1].size; - spans[span_index].size = range - end; - spans[span_index].waste = 0; - span_index++; - } - - return span_index; -} - -/* This handles each sub-texture within the range [0,1] of our - * original meta texture and repeats each one separately across the - * users requested virtual texture coordinates. - * - * A notable advantage of this approach is that we will batch - * together callbacks corresponding to the same underlying slice - * together. - */ -static void -create_grid_and_repeat_cb (CoglTexture *slice_texture, - const float *slice_texture_coords, - const float *meta_coords, - void *user_data) -{ - ForeachData *data = user_data; - CoglSpan x_spans[3]; - int n_x_spans; - int x_real_index; - CoglSpan y_spans[3]; - int n_y_spans; - int y_real_index; - - /* NB: This callback is called for each slice of the meta-texture - * in the range [0,1]. - * - * We define a "padded grid" for each slice of the meta-texture in - * the range [0,1]. The x axis and y axis grid lines are defined - * using CoglSpans. - * - * The padded grid maps over the meta-texture coordinates in the - * range [0,1] but only contains one valid cell that corresponds to - * current slice being iterated and all the surrounding cells just - * provide padding. - * - * Once we've defined our padded grid we then repeat that across - * the user's original region, calling their callback whenever - * we see our current slice - ignoring padding. - * - * NB: we can assume meta_coords[] are normalized at this point - * since TextureRectangles aren't iterated with this code-path. - * - * NB: spans are always defined using non-normalized coordinates - */ - n_x_spans = setup_padded_spans (x_spans, - meta_coords[0] * data->width, - meta_coords[2] * data->width, - data->width, - &x_real_index); - n_y_spans = setup_padded_spans (y_spans, - meta_coords[1] * data->height, - meta_coords[3] * data->height, - data->height, - &y_real_index); - - data->padded_textures[n_x_spans * y_real_index + x_real_index] = - slice_texture; - - /* Our callback is going to be passed normalized slice texture - * coordinates, and we will need to map the range [0,1] to the real - * slice_texture_coords we have here... */ - data->grid_slice_texture_coords = slice_texture_coords; - data->slice_range_s = fabs (data->grid_slice_texture_coords[2] - - data->grid_slice_texture_coords[0]); - data->slice_range_t = fabs (data->grid_slice_texture_coords[3] - - data->grid_slice_texture_coords[1]); - data->slice_offset_s = MIN (data->grid_slice_texture_coords[0], - data->grid_slice_texture_coords[2]); - data->slice_offset_t = MIN (data->grid_slice_texture_coords[1], - data->grid_slice_texture_coords[3]); - - /* Now actually iterate the region the user originally requested - * using the current padded grid */ - _cogl_texture_spans_foreach_in_region (x_spans, - n_x_spans, - y_spans, - n_y_spans, - data->padded_textures, - data->meta_region_coords, - data->width, - data->height, - data->wrap_s, - data->wrap_t, - padded_grid_repeat_cb, - data); - - /* Clear the padded_textures ready for the next iteration */ - data->padded_textures[n_x_spans * y_real_index + x_real_index] = NULL; -} - -#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0) - -typedef struct _ClampData -{ - float start; - float end; - gboolean s_flipped; - gboolean t_flipped; - CoglMetaTextureCallback callback; - void *user_data; -} ClampData; - -static void -clamp_s_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - ClampData *clamp_data = user_data; - float mapped_meta_coords[4] = { - clamp_data->start, - meta_coords[1], - clamp_data->end, - meta_coords[3] - }; - if (clamp_data->s_flipped) - SWAP (mapped_meta_coords[0], mapped_meta_coords[2]); - /* NB: we never need to flip the t coords when dealing with - * s-axis clamping so no need to check if ->t_flipped */ - clamp_data->callback (sub_texture, - sub_texture_coords, mapped_meta_coords, - clamp_data->user_data); -} - -static void -clamp_t_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - ClampData *clamp_data = user_data; - float mapped_meta_coords[4] = { - meta_coords[0], - clamp_data->start, - meta_coords[2], - clamp_data->end, - }; - if (clamp_data->s_flipped) - SWAP (mapped_meta_coords[0], mapped_meta_coords[2]); - if (clamp_data->t_flipped) - SWAP (mapped_meta_coords[1], mapped_meta_coords[3]); - clamp_data->callback (sub_texture, - sub_texture_coords, mapped_meta_coords, - clamp_data->user_data); -} - -static gboolean -foreach_clamped_region (CoglMetaTexture *meta_texture, - float *tx_1, - float *ty_1, - float *tx_2, - float *ty_2, - CoglPipelineWrapMode wrap_s, - CoglPipelineWrapMode wrap_t, - CoglMetaTextureCallback callback, - void *user_data) -{ - float width = cogl_texture_get_width (COGL_TEXTURE (meta_texture)); - ClampData clamp_data; - - /* Consider that *tx_1 may be > *tx_2 and to simplify things - * we just flip them around if that's the case and keep a note - * of the fact that they are flipped. */ - if (*tx_1 > *tx_2) - { - SWAP (*tx_1, *tx_2); - clamp_data.s_flipped = TRUE; - } - else - clamp_data.s_flipped = FALSE; - - /* The same goes for ty_1 and ty_2... */ - if (*ty_1 > *ty_2) - { - SWAP (*ty_1, *ty_2); - clamp_data.t_flipped = TRUE; - } - else - clamp_data.t_flipped = FALSE; - - clamp_data.callback = callback; - clamp_data.user_data = user_data; - - if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - { - float max_s_coord = 1.0; - float half_texel_width; - - half_texel_width = max_s_coord / (width * 2); - - /* Handle any left clamped region */ - if (*tx_1 < 0) - { - clamp_data.start = *tx_1; - clamp_data.end = MIN (0, *tx_2); - cogl_meta_texture_foreach_in_region (meta_texture, - half_texel_width, *ty_1, - half_texel_width, *ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - wrap_t, - clamp_s_cb, - &clamp_data); - /* Have we handled everything? */ - if (*tx_2 <= 0) - return TRUE; - - /* clamp tx_1 since we've handled everything with x < 0 */ - *tx_1 = 0; - } - - /* Handle any right clamped region - including the corners */ - if (*tx_2 > max_s_coord) - { - clamp_data.start = MAX (max_s_coord, *tx_1); - clamp_data.end = *tx_2; - cogl_meta_texture_foreach_in_region (meta_texture, - max_s_coord - half_texel_width, - *ty_1, - max_s_coord - half_texel_width, - *ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - wrap_t, - clamp_s_cb, - &clamp_data); - /* Have we handled everything? */ - if (*tx_1 >= max_s_coord) - return TRUE; - - /* clamp tx_2 since we've handled everything with x > - * max_s_coord */ - *tx_2 = max_s_coord; - } - } - - if (wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - { - float height = cogl_texture_get_height (COGL_TEXTURE (meta_texture)); - float max_t_coord = 1.0; - float half_texel_height; - - half_texel_height = max_t_coord / (height * 2); - - /* Handle any top clamped region */ - if (*ty_1 < 0) - { - clamp_data.start = *ty_1; - clamp_data.end = MIN (0, *ty_2); - cogl_meta_texture_foreach_in_region (meta_texture, - *tx_1, half_texel_height, - *tx_2, half_texel_height, - wrap_s, - COGL_PIPELINE_WRAP_MODE_REPEAT, - clamp_t_cb, - &clamp_data); - /* Have we handled everything? */ - if (*tx_2 <= 0) - return TRUE; - - /* clamp ty_1 since we've handled everything with y < 0 */ - *ty_1 = 0; - } - - /* Handle any bottom clamped region */ - if (*ty_2 > max_t_coord) - { - clamp_data.start = MAX (max_t_coord, *ty_1); - clamp_data.end = *ty_2; - cogl_meta_texture_foreach_in_region (meta_texture, - *tx_1, - max_t_coord - half_texel_height, - *tx_2, - max_t_coord - half_texel_height, - wrap_s, - COGL_PIPELINE_WRAP_MODE_REPEAT, - clamp_t_cb, - &clamp_data); - /* Have we handled everything? */ - if (*ty_1 >= max_t_coord) - return TRUE; - - /* clamp ty_2 since we've handled everything with y > - * max_t_coord */ - *ty_2 = max_t_coord; - } - } - - if (clamp_data.s_flipped) - SWAP (*tx_1, *tx_2); - if (clamp_data.t_flipped) - SWAP (*ty_1, *ty_2); - - return FALSE; -} - -typedef struct _NormalizeData -{ - CoglMetaTextureCallback callback; - void *user_data; - float s_normalize_factor; - float t_normalize_factor; -} NormalizeData; - -static void -normalize_meta_coords_cb (CoglTexture *slice_texture, - const float *slice_coords, - const float *meta_coords, - void *user_data) -{ - NormalizeData *data = user_data; - float normalized_meta_coords[4] = { - meta_coords[0] * data->s_normalize_factor, - meta_coords[1] * data->t_normalize_factor, - meta_coords[2] * data->s_normalize_factor, - meta_coords[3] * data->t_normalize_factor - }; - - data->callback (slice_texture, - slice_coords, normalized_meta_coords, - data->user_data); -} - -void -cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, - float tx_1, - float ty_1, - float tx_2, - float ty_2, - CoglPipelineWrapMode wrap_s, - CoglPipelineWrapMode wrap_t, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglTexture *texture = COGL_TEXTURE (meta_texture); - float width = cogl_texture_get_width (texture); - float height = cogl_texture_get_height (texture); - NormalizeData normalize_data; - - if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_s = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_t = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - - if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE || - wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - { - gboolean finished = foreach_clamped_region (meta_texture, - &tx_1, &ty_1, &tx_2, &ty_2, - wrap_s, wrap_t, - callback, - user_data); - if (finished) - return; - - /* Since clamping has been handled we now want to normalize our - * wrap modes we se can assume from this point on we don't - * need to consider CLAMP_TO_EDGE. (NB: The spans code will - * assert that CLAMP_TO_EDGE isn't requested) */ - if (wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; - if (wrap_t == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) - wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT; - } - - /* It makes things simpler to deal with non-normalized region - * coordinates beyond this point and only re-normalize just before - * calling the user's callback... */ - - normalize_data.callback = callback; - normalize_data.user_data = user_data; - normalize_data.s_normalize_factor = 1.0f / width; - normalize_data.t_normalize_factor = 1.0f / height; - callback = normalize_meta_coords_cb; - user_data = &normalize_data; - tx_1 *= width; - ty_1 *= height; - tx_2 *= width; - ty_2 *= height; - - /* XXX: at some point this won't be routed through the CoglTexture - * vtable, instead there will be a separate CoglMetaTexture - * interface vtable. */ - - if (texture->vtable->foreach_sub_texture_in_region) - { - ForeachData data; - - data.meta_region_coords[0] = tx_1; - data.meta_region_coords[1] = ty_1; - data.meta_region_coords[2] = tx_2; - data.meta_region_coords[3] = ty_2; - data.wrap_s = wrap_s; - data.wrap_t = wrap_t; - data.callback = callback; - data.user_data = user_data; - - data.width = width; - data.height = height; - - memset (data.padded_textures, 0, sizeof (data.padded_textures)); - - /* - * 1) We iterate all the slices of the meta-texture only within - * the range [0,1]. - * - * 2) We define a "padded grid" for each slice of the - * meta-texture in the range [0,1]. - * - * The padded grid maps over the meta-texture coordinates in - * the range [0,1] but only contains one valid cell that - * corresponds to current slice being iterated and all the - * surrounding cells just provide padding. - * - * 3) Once we've defined our padded grid we then repeat that - * across the user's original region, calling their callback - * whenever we see our current slice - ignoring padding. - * - * A notable benefit of this design is that repeating a texture - * made of multiple slices will result in us repeating each - * slice in-turn so the user gets repeat callbacks for the same - * texture batched together. For manual emulation of texture - * repeats done by drawing geometry this makes it more likely - * that we can batch geometry. - */ - - texture->vtable->foreach_sub_texture_in_region (texture, - 0, 0, 1, 1, - create_grid_and_repeat_cb, - &data); - } - else - { - CoglSpan x_span = { 0, width, 0 }; - CoglSpan y_span = { 0, height, 0 }; - float meta_region_coords[4] = { tx_1, ty_1, tx_2, ty_2 }; - - _cogl_texture_spans_foreach_in_region (&x_span, 1, - &y_span, 1, - &texture, - meta_region_coords, - width, - height, - wrap_s, - wrap_t, - callback, - user_data); - } -} -#undef SWAP diff --git a/cogl/cogl/cogl-meta-texture.h b/cogl/cogl/cogl-meta-texture.h deleted file mode 100644 index 9f7784d7d..000000000 --- a/cogl/cogl/cogl-meta-texture.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_META_TEXTURE_H__ -#define __COGL_META_TEXTURE_H__ - -#include <cogl/cogl-pipeline-layer-state.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-meta-texture - * @short_description: Interface for high-level textures built from - * low-level textures like #CoglTexture2D. - * - * Cogl helps to make it easy to deal with high level textures such - * as #CoglAtlasTexture<!-- -->s, #CoglSubTexture<!-- -->s, - * #CoglTexturePixmapX11 textures and #CoglTexture2DSliced textures - * consistently. - * - * A #CoglMetaTexture is a texture that might internally be - * represented by one or more low-level #CoglTexture<!-- -->s - * such as #CoglTexture2D. These low-level textures are the only ones - * that a GPU really understands but because applications often want - * more high-level texture abstractions (such as storing multiple - * textures inside one larger "atlas" texture) it's desirable to be - * able to deal with these using a common interface. - * - * For example the GPU is not able to automatically handle repeating a - * texture that is part of a larger atlas texture but if you use - * %COGL_PIPELINE_WRAP_MODE_REPEAT with an atlas texture when drawing - * with cogl_rectangle() you should see that it "Just Works™" - at - * least if you don't use multi-texturing. The reason this works is - * because cogl_rectangle() internally understands the #CoglMetaTexture - * interface and is able to manually resolve the low-level textures - * using this interface and by making multiple draw calls it can - * emulate the texture repeat modes. - * - * Cogl doesn't aim to pretend that meta-textures are just like real - * textures because it would get extremely complex to try and emulate - * low-level GPU semantics transparently for these textures. The low - * level drawing APIs of Cogl, such as cogl_primitive_draw() don't - * actually know anything about the #CoglMetaTexture interface and its - * the developer's responsibility to resolve all textures referenced - * by a #CoglPipeline to low-level textures before drawing. - * - * If you want to develop custom primitive APIs like - * cogl_framebuffer_draw_rectangle() and you want to support drawing - * with #CoglAtlasTexture<!-- -->s or #CoglSubTexture<!-- -->s for - * example, then you will need to use this #CoglMetaTexture interface - * to be able to resolve high-level textures into low-level textures - * before drawing with Cogl's low-level drawing APIs such as - * cogl_primitive_draw(). - * - * <note>Most developers won't need to use this interface directly - * but still it is worth understanding the distinction between - * low-level and meta textures because you may find other references - * in the documentation that detail limitations of using - * meta-textures.</note> - */ - -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ - !defined(COGL_GIR_SCANNING) -/* For the public C api we typedef interface types as void to avoid needing - * lots of casting in code and instead we will rely on runtime type checking - * for these objects. */ -typedef void CoglMetaTexture; -#else -typedef struct _CoglMetaTexture CoglMetaTexture; -#define COGL_META_TEXTURE(X) ((CoglMetaTexture *)X) -#endif - -/** - * CoglMetaTextureCallback: - * @sub_texture: A low-level #CoglTexture making up part of a - * #CoglMetaTexture. - * @sub_texture_coords: A float 4-tuple ordered like - * (tx1,ty1,tx2,ty2) defining what region of the - * current @sub_texture maps to a sub-region of a - * #CoglMetaTexture. (tx1,ty1) is the top-left - * sub-region coordinate and (tx2,ty2) is the - * bottom-right. These are low-level texture - * coordinates. - * @meta_coords: A float 4-tuple ordered like (tx1,ty1,tx2,ty2) - * defining what sub-region of a #CoglMetaTexture this - * low-level @sub_texture maps too. (tx1,ty1) is - * the top-left sub-region coordinate and (tx2,ty2) is - * the bottom-right. These are high-level meta-texture - * coordinates. - * @user_data: A private pointer passed to - * cogl_meta_texture_foreach_in_region(). - * - * A callback used with cogl_meta_texture_foreach_in_region() to - * retrieve details of all the low-level #CoglTexture<!-- -->s that - * make up a given #CoglMetaTexture. - * - * Since: 1.10 - * Stability: unstable - */ -typedef void (*CoglMetaTextureCallback) (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data); - -/** - * cogl_meta_texture_foreach_in_region: - * @meta_texture: An object implementing the #CoglMetaTexture - * interface. - * @tx_1: The top-left x coordinate of the region to iterate - * @ty_1: The top-left y coordinate of the region to iterate - * @tx_2: The bottom-right x coordinate of the region to iterate - * @ty_2: The bottom-right y coordinate of the region to iterate - * @wrap_s: The wrap mode for the x-axis - * @wrap_t: The wrap mode for the y-axis - * @callback: A #CoglMetaTextureCallback pointer to be called - * for each low-level texture within the specified region. - * @user_data: A private pointer that is passed to @callback. - * - * Allows you to manually iterate the low-level textures that define a - * given region of a high-level #CoglMetaTexture. - * - * For example cogl_texture_2d_sliced_new_with_size() can be used to - * create a meta texture that may slice a large image into multiple, - * smaller power-of-two sized textures. These high level textures are - * not directly understood by a GPU and so this API must be used to - * manually resolve the underlying textures for drawing. - * - * All high level textures (#CoglAtlasTexture, #CoglSubTexture, - * #CoglTexturePixmapX11, and #CoglTexture2DSliced) can be handled - * consistently using this interface which greately simplifies - * implementing primitives that support all texture types. - * - * For example if you use the cogl_rectangle() API then Cogl will - * internally use this API to resolve the low level textures of any - * meta textures you have associated with CoglPipeline layers. - * - * <note>The low level drawing APIs such as cogl_primitive_draw() - * don't understand the #CoglMetaTexture interface and so it is your - * responsibility to use this API to resolve all CoglPipeline textures - * into low-level textures before drawing.</note> - * - * For each low-level texture that makes up part of the given region - * of the @meta_texture, @callback is called specifying how the - * low-level texture maps to the original region. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_meta_texture_foreach_in_region (CoglMetaTexture *meta_texture, - float tx_1, - float ty_1, - float tx_2, - float ty_2, - CoglPipelineWrapMode wrap_s, - CoglPipelineWrapMode wrap_t, - CoglMetaTextureCallback callback, - void *user_data); - -G_END_DECLS - -#endif /* __COGL_META_TEXTURE_H__ */ diff --git a/cogl/cogl/cogl-mutter.h b/cogl/cogl/cogl-mutter.h deleted file mode 100644 index a8bf45919..000000000 --- a/cogl/cogl/cogl-mutter.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2016 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_MUTTER_H___ -#define __COGL_MUTTER_H___ - -#include "cogl-config.h" -#include "cogl-defines.h" - -#include <cogl/cogl-texture.h> -#include <cogl/cogl-meta-texture.h> -#include <cogl/cogl-frame-info-private.h> -#include <cogl/cogl-renderer-private.h> -#if defined (COGL_HAS_EGL_SUPPORT) -#include <cogl/winsys/cogl-onscreen-egl.h> -#include <cogl/winsys/cogl-winsys-egl-private.h> -#endif -#if defined (COGL_HAS_GLX_SUPPORT) -#include <cogl/winsys/cogl-onscreen-glx.h> -#endif -#if defined (COGL_HAS_XLIB_SUPPORT) -#include <cogl/winsys/cogl-onscreen-xlib.h> -#endif -#ifdef COGL_HAS_X11 -#include <cogl/cogl-x11-onscreen.h> -#endif -#include <cogl/winsys/cogl-winsys-private.h> - -COGL_EXPORT -void cogl_renderer_set_custom_winsys (CoglRenderer *renderer, - CoglCustomWinsysVtableGetter winsys_vtable_getter, - void *user_data); - -COGL_EXPORT -gboolean cogl_context_format_supports_upload (CoglContext *ctx, - CoglPixelFormat format); - -#endif /* __COGL_MUTTER_H___ */ diff --git a/cogl/cogl/cogl-node-private.h b/cogl/cogl/cogl-node-private.h deleted file mode 100644 index b167f05f1..000000000 --- a/cogl/cogl/cogl-node-private.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_NODE_PRIVATE_H -#define __COGL_NODE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-list.h" - -typedef struct _CoglNode CoglNode; - -/* Pipelines and layers represent their state in a tree structure where - * some of the state relating to a given pipeline or layer may actually - * be owned by one if is ancestors in the tree. We have a common data - * type to track the tree hierarchy so we can share code... */ -struct _CoglNode -{ - /* the parent in terms of class hierarchy, so anything inheriting - * from CoglNode also inherits from CoglObject. */ - CoglObject _parent; - - /* The parent pipeline/layer */ - CoglNode *parent; - - /* The list entry here contains pointers to the node's siblings */ - CoglList link; - - /* List of children */ - CoglList children; - - /* TRUE if the node took a strong reference on its parent. Weak - * pipelines for instance don't take a reference on their parent. */ - gboolean has_parent_reference; -}; - -#define COGL_NODE(X) ((CoglNode *)(X)) - -void -_cogl_pipeline_node_init (CoglNode *node); - -typedef void (*CoglNodeUnparentVFunc) (CoglNode *node); - -void -_cogl_pipeline_node_set_parent_real (CoglNode *node, - CoglNode *parent, - CoglNodeUnparentVFunc unparent, - gboolean take_strong_reference); - -void -_cogl_pipeline_node_unparent_real (CoglNode *node); - -typedef gboolean (*CoglNodeChildCallback) (CoglNode *child, void *user_data); - -void -_cogl_pipeline_node_foreach_child (CoglNode *node, - CoglNodeChildCallback callback, - void *user_data); - -#endif /* __COGL_NODE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-node.c b/cogl/cogl/cogl-node.c deleted file mode 100644 index 07b524f94..000000000 --- a/cogl/cogl/cogl-node.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-node-private.h" - -void -_cogl_pipeline_node_init (CoglNode *node) -{ - node->parent = NULL; - _cogl_list_init (&node->children); -} - -void -_cogl_pipeline_node_set_parent_real (CoglNode *node, - CoglNode *parent, - CoglNodeUnparentVFunc unparent, - gboolean take_strong_reference) -{ - /* NB: the old parent may indirectly be keeping the new parent alive - * so we have to ref the new parent before unrefing the old. - * - * Note: we take a reference here regardless of - * take_strong_reference because weak children may need special - * handling when the parent disposes itself which relies on a - * consistent link to all weak nodes. Once the node is linked to its - * parent then we remove the reference at the end if - * take_strong_reference == FALSE. */ - cogl_object_ref (parent); - - if (node->parent) - unparent (node); - - _cogl_list_insert (&parent->children, &node->link); - - node->parent = parent; - node->has_parent_reference = take_strong_reference; - - /* Now that there is a consistent parent->child link we can remove - * the parent reference if no reference was requested. If it turns - * out that the new parent was only being kept alive by the old - * parent then it will be disposed of here. */ - if (!take_strong_reference) - cogl_object_unref (parent); -} - -void -_cogl_pipeline_node_unparent_real (CoglNode *node) -{ - CoglNode *parent = node->parent; - - if (parent == NULL) - return; - - g_return_if_fail (!_cogl_list_empty (&parent->children)); - - _cogl_list_remove (&node->link); - - if (node->has_parent_reference) - cogl_object_unref (parent); - - node->parent = NULL; -} - -void -_cogl_pipeline_node_foreach_child (CoglNode *node, - CoglNodeChildCallback callback, - void *user_data) -{ - CoglNode *child, *next; - - _cogl_list_for_each_safe (child, next, &node->children, link) - callback (child, user_data); -} - - diff --git a/cogl/cogl/cogl-object-private.h b/cogl/cogl/cogl-object-private.h deleted file mode 100644 index 83f42b410..000000000 --- a/cogl/cogl/cogl-object-private.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_OBJECT_PRIVATE_H -#define __COGL_OBJECT_PRIVATE_H - -#include <glib.h> - -#include "cogl-types.h" -#include "cogl-object.h" -#include "cogl-debug.h" - -/* For compatibility until all components have been converted */ -typedef struct _CoglObjectClass CoglHandleClass; -typedef struct _CoglObject CoglHandleObject; - -/* XXX: sadly we didn't fully consider when we copied the cairo API - * for _set_user_data that the callback doesn't get a pointer to the - * instance which is desired in most cases. This means you tend to end - * up creating micro allocations for the private data just so you can - * pair up the data of interest with the original instance for - * identification when it is later destroyed. - * - * Internally we use a small hack to avoid needing these micro - * allocations by actually passing the instance as a second argument - * to the callback */ -typedef void (*CoglUserDataDestroyInternalCallback) (void *user_data, - void *instance); - -typedef struct _CoglObjectClass -{ - GTypeClass base_class; - const char *name; - void *virt_free; - void *virt_unref; -} CoglObjectClass; - -#define COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES 2 - -typedef struct -{ - CoglUserDataKey *key; - void *user_data; - CoglUserDataDestroyInternalCallback destroy; -} CoglUserDataEntry; - -/* All Cogl objects inherit from this base object by adding a member: - * - * CoglObject _parent; - * - * at the top of its main structure. This structure is initialized - * when you call _cogl_#type_name#_object_new (new_object); - */ -struct _CoglObject -{ - CoglObjectClass *klass; /* equivalent to GTypeInstance */ - - CoglUserDataEntry user_data_entry[ - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES]; - GArray *user_data_array; - int n_user_data_entries; - - unsigned int ref_count; -}; - -/* Helper macro to encapsulate the common code for COGL reference - counted objects */ - -#ifdef COGL_OBJECT_DEBUG - -#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) \ - COGL_NOTE (OBJECT, "COGL " G_STRINGIFY (type_name) " NEW %p %i", \ - (obj), (obj)->ref_count) - -#define _COGL_OBJECT_DEBUG_REF(type_name, object) G_STMT_START { \ - CoglObject *__obj = (CoglObject *)object; \ - COGL_NOTE (OBJECT, "COGL %s REF %p %i", \ - (__obj)->klass->name, \ - (__obj), (__obj)->ref_count); } G_STMT_END - -#define _COGL_OBJECT_DEBUG_UNREF(type_name, object) G_STMT_START { \ - CoglObject *__obj = (CoglObject *)object; \ - COGL_NOTE (OBJECT, "COGL %s UNREF %p %i", \ - (__obj)->klass->name, \ - (__obj), (__obj)->ref_count - 1); } G_STMT_END - -#define COGL_OBJECT_DEBUG_FREE(obj) \ - COGL_NOTE (OBJECT, "COGL %s FREE %p", \ - (obj)->klass->name, (obj)) - -#else /* !COGL_OBJECT_DEBUG */ - -#define _COGL_OBJECT_DEBUG_NEW(type_name, obj) -#define _COGL_OBJECT_DEBUG_REF(type_name, obj) -#define _COGL_OBJECT_DEBUG_UNREF(type_name, obj) -#define COGL_OBJECT_DEBUG_FREE(obj) - -#endif /* COGL_OBJECT_DEBUG */ - -#define _COGL_GTYPE_INIT_CLASS(type_name) do { \ - _cogl_##type_name##_class.base_class.g_type = cogl_##type_name##_get_gtype (); \ -} while (0) - -#define COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -CoglObjectClass _cogl_##type_name##_class; \ -static unsigned long _cogl_object_##type_name##_count; \ - \ -static inline void \ -_cogl_object_##type_name##_inc (void) \ -{ \ - _cogl_object_##type_name##_count++; \ -} \ - \ -static inline void \ -_cogl_object_##type_name##_dec (void) \ -{ \ - _cogl_object_##type_name##_count--; \ -} \ - \ -static void \ -_cogl_object_##type_name##_indirect_free (CoglObject *obj) \ -{ \ - _cogl_##type_name##_free ((Cogl##TypeName *) obj); \ - _cogl_object_##type_name##_dec (); \ -} \ - \ -static void \ -_cogl_object_##type_name##_class_init (void) \ -{ \ - _cogl_object_##type_name##_count = 0; \ - \ - if (_cogl_debug_instances == NULL) \ - _cogl_debug_instances = \ - g_hash_table_new (g_str_hash, g_str_equal); \ - \ - _cogl_##type_name##_class.virt_free = \ - _cogl_object_##type_name##_indirect_free; \ - _cogl_##type_name##_class.virt_unref = \ - _cogl_object_default_unref; \ - _cogl_##type_name##_class.name = "Cogl"#TypeName; \ - \ - g_hash_table_insert (_cogl_debug_instances, \ - (void *) _cogl_##type_name##_class.name, \ - &_cogl_object_##type_name##_count); \ - \ - { code; } \ -} \ - \ -static Cogl##TypeName * \ -_cogl_##type_name##_object_new (Cogl##TypeName *new_obj) \ -{ \ - CoglObject *obj = (CoglObject *)&new_obj->_parent; \ - obj->ref_count = 0; \ - cogl_object_ref (obj); \ - obj->n_user_data_entries = 0; \ - obj->user_data_array = NULL; \ - \ - obj->klass = &_cogl_##type_name##_class; \ - if (!obj->klass->virt_free) \ - { \ - _cogl_object_##type_name##_class_init (); \ - } \ - \ - _cogl_object_##type_name##_inc (); \ - _COGL_OBJECT_DEBUG_NEW (TypeName, obj); \ - return new_obj; \ -} - -#define COGL_OBJECT_DEFINE_WITH_CODE_GTYPE(TypeName, type_name, code) \ - \ -COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, \ - type_name, \ - do { code; } while (0); \ - _COGL_GTYPE_INIT_CLASS (type_name)) \ - \ -gboolean \ -cogl_is_##type_name (void *object) \ -{ \ - CoglObject *obj = object; \ - \ - if (object == NULL) \ - return FALSE; \ - \ - return obj->klass == &_cogl_##type_name##_class; \ -} - -#define COGL_OBJECT_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -gboolean \ -cogl_is_##type_name (void *object) \ -{ \ - CoglObject *obj = object; \ - \ - if (object == NULL) \ - return FALSE; \ - \ - return obj->klass == &_cogl_##type_name##_class; \ -} - -#define COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_COMMON_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -gboolean \ -_cogl_is_##type_name (void *object) \ -{ \ - CoglObject *obj = object; \ - \ - if (object == NULL) \ - return FALSE; \ - \ - return obj->klass == &_cogl_##type_name##_class; \ -} - -#define COGL_OBJECT_DEFINE(TypeName, type_name) \ - COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (TypeName, type_name, (void) 0) - -#define COGL_OBJECT_INTERNAL_DEFINE(TypeName, type_name) \ - COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, (void) 0) - -/* For temporary compatibility */ -#define COGL_HANDLE_INTERNAL_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE (TypeName, type_name, code) \ - \ -static Cogl##TypeName * \ -_cogl_##type_name##_handle_new (CoglHandle handle) \ -{ \ - return _cogl_##type_name##_object_new (handle); \ -} - -#define COGL_HANDLE_DEFINE_WITH_CODE(TypeName, type_name, code) \ - \ -COGL_OBJECT_DEFINE_WITH_CODE (TypeName, type_name, code) \ - \ -static Cogl##TypeName * \ -_cogl_##type_name##_handle_new (CoglHandle handle) \ -{ \ - return _cogl_##type_name##_object_new (handle); \ -} - -#define COGL_HANDLE_DEFINE(TypeName, type_name) \ - COGL_HANDLE_DEFINE_WITH_CODE (TypeName, type_name, (void) 0) - -void -_cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyInternalCallback destroy); - -COGL_EXPORT void -_cogl_object_default_unref (void *obj); - -#endif /* __COGL_OBJECT_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-object.c b/cogl/cogl/cogl-object.c deleted file mode 100644 index d3713f4cb..000000000 --- a/cogl/cogl/cogl-object.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <glib.h> -#include <string.h> - -#include "cogl-util.h" -#include "cogl-types.h" -#include "cogl-object-private.h" -#include "cogl-gtype-private.h" - -COGL_GTYPE_DEFINE_BASE_CLASS (Object, object); - -void * -cogl_object_ref (void *object) -{ - CoglObject *obj = object; - - g_return_val_if_fail (object != NULL, NULL); - - obj->ref_count++; - return object; -} - -void -_cogl_object_default_unref (void *object) -{ - CoglObject *obj = object; - - g_return_if_fail (object != NULL); - g_return_if_fail (obj->ref_count > 0); - - if (--obj->ref_count < 1) - { - void (*free_func)(void *obj); - - if (obj->n_user_data_entries) - { - int i; - int count = MIN (obj->n_user_data_entries, - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES); - - for (i = 0; i < count; i++) - { - CoglUserDataEntry *entry = &obj->user_data_entry[i]; - if (entry->destroy) - entry->destroy (entry->user_data, obj); - } - - if (obj->user_data_array != NULL) - { - for (i = 0; i < obj->user_data_array->len; i++) - { - CoglUserDataEntry *entry = - &g_array_index (obj->user_data_array, - CoglUserDataEntry, i); - - if (entry->destroy) - entry->destroy (entry->user_data, obj); - } - g_array_free (obj->user_data_array, TRUE); - } - } - - COGL_OBJECT_DEBUG_FREE (obj); - free_func = obj->klass->virt_free; - free_func (obj); - } -} - -void -cogl_object_unref (void *obj) -{ - void (* unref_func) (void *); - - g_return_if_fail (obj != NULL); - - unref_func = ((CoglObject *) obj)->klass->virt_unref; - unref_func (obj); -} - -GType -cogl_handle_get_type (void) -{ - static GType our_type = 0; - - /* XXX: We are keeping the "CoglHandle" name for now in case it would - * break bindings to change to "CoglObject" */ - if (G_UNLIKELY (our_type == 0)) - our_type = g_boxed_type_register_static (g_intern_static_string ("CoglHandle"), - (GBoxedCopyFunc) cogl_object_ref, - (GBoxedFreeFunc) cogl_object_unref); - - return our_type; -} - -/* XXX: Unlike for cogl_object_get_user_data this code will return - * an empty entry if available and no entry for the given key can be - * found. */ -static CoglUserDataEntry * -_cogl_object_find_entry (CoglObject *object, CoglUserDataKey *key) -{ - CoglUserDataEntry *entry = NULL; - int count; - int i; - - count = MIN (object->n_user_data_entries, - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES); - - for (i = 0; i < count; i++) - { - CoglUserDataEntry *current = &object->user_data_entry[i]; - if (current->key == key) - return current; - if (current->user_data == NULL) - entry = current; - } - - if (G_UNLIKELY (object->user_data_array != NULL)) - { - for (i = 0; i < object->user_data_array->len; i++) - { - CoglUserDataEntry *current = - &g_array_index (object->user_data_array, CoglUserDataEntry, i); - - if (current->key == key) - return current; - if (current->user_data == NULL) - entry = current; - } - } - - return entry; -} - -void -_cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyInternalCallback destroy) -{ - CoglUserDataEntry new_entry; - CoglUserDataEntry *entry; - - if (user_data) - { - new_entry.key = key; - new_entry.user_data = user_data; - new_entry.destroy = destroy; - } - else - memset (&new_entry, 0, sizeof (new_entry)); - - entry = _cogl_object_find_entry (object, key); - if (entry) - { - if (G_LIKELY (entry->destroy)) - entry->destroy (entry->user_data, object); - } - else - { - /* NB: Setting a value of NULL is documented to delete the - * corresponding entry so we can return immediately in this - * case. */ - if (user_data == NULL) - return; - - if (G_LIKELY (object->n_user_data_entries < - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES)) - entry = &object->user_data_entry[object->n_user_data_entries++]; - else - { - if (G_UNLIKELY (object->user_data_array == NULL)) - { - object->user_data_array = - g_array_new (FALSE, FALSE, sizeof (CoglUserDataEntry)); - } - - g_array_set_size (object->user_data_array, - object->user_data_array->len + 1); - entry = - &g_array_index (object->user_data_array, CoglUserDataEntry, - object->user_data_array->len - 1); - - object->n_user_data_entries++; - } - } - - *entry = new_entry; -} - -void -cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyCallback destroy) -{ - _cogl_object_set_user_data (object, key, user_data, - (CoglUserDataDestroyInternalCallback)destroy); -} - -void * -cogl_object_get_user_data (CoglObject *object, CoglUserDataKey *key) -{ - int count; - int i; - - count = MIN (object->n_user_data_entries, - COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES); - - for (i = 0; i < count; i++) - { - CoglUserDataEntry *entry = &object->user_data_entry[i]; - if (entry->key == key) - return entry->user_data; - } - - if (object->user_data_array != NULL) - { - for (i = 0; i < object->user_data_array->len; i++) - { - CoglUserDataEntry *entry = - &g_array_index (object->user_data_array, CoglUserDataEntry, i); - - if (entry->key == key) - return entry->user_data; - } - } - - return NULL; -} - -void -cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func, - void *user_data) -{ - GHashTableIter iter; - unsigned long *instance_count; - CoglDebugObjectTypeInfo info; - - g_hash_table_iter_init (&iter, _cogl_debug_instances); - while (g_hash_table_iter_next (&iter, - (void *) &info.name, - (void *) &instance_count)) - { - info.instance_count = *instance_count; - func (&info, user_data); - } -} - -static void -print_instances_cb (const CoglDebugObjectTypeInfo *info, - void *user_data) -{ - g_print ("\t%s: %lu\n", info->name, info->instance_count); -} - -void -cogl_debug_object_print_instances (void) -{ - g_print ("Cogl instances:\n"); - - cogl_debug_object_foreach_type (print_instances_cb, NULL); -} diff --git a/cogl/cogl/cogl-object.h b/cogl/cogl/cogl-object.h deleted file mode 100644 index c93983f71..000000000 --- a/cogl/cogl/cogl-object.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_OBJECT_H -#define __COGL_OBJECT_H - -#include <cogl/cogl-types.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -typedef struct _CoglObject CoglObject; - -#define COGL_OBJECT(X) ((CoglObject *)X) - -/** - * CoglObject: (ref-func cogl_object_ref) (unref-func cogl_object_unref) - * (set-value-func cogl_object_value_set_object) - * (get-value-func cogl_object_value_get_object) - */ - -/** - * cogl_object_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_object_get_gtype (void); - -/** - * cogl_object_ref: (skip) - * @object: a #CoglObject - * - * Increases the reference count of @object by 1 - * - * Returns: the @object, with its reference count increased - */ -COGL_EXPORT void * -cogl_object_ref (void *object); - -/** - * cogl_object_unref: (skip) - * @object: a #CoglObject - * - * Drecreases the reference count of @object by 1; if the reference - * count reaches 0, the resources allocated by @object will be freed - */ -COGL_EXPORT void -cogl_object_unref (void *object); - -/** - * cogl_clear_object: (skip) - * @object_ptr: a pointer to a #CoglObject reference - * - * Clears a reference to a #CoglObject. - * - * @object_ptr must not be %NULL. - * - * If the reference is %NULL then this function does nothing. - * Otherwise, the reference count of the object is decreased using - * cogl_object_unref() and the pointer is set to %NULL. - */ -#define cogl_clear_object(object_ptr) g_clear_pointer ((object_ptr), cogl_object_unref) - -/** - * CoglUserDataKey: - * @unused: ignored. - * - * A #CoglUserDataKey is used to declare a key for attaching data to a - * #CoglObject using cogl_object_set_user_data. The typedef only exists as a - * formality to make code self documenting since only the unique address of a - * #CoglUserDataKey is used. - * - * Typically you would declare a static #CoglUserDataKey and set private data - * on an object something like this: - * - * |[ - * static CoglUserDataKey path_private_key; - * - * static void - * destroy_path_private_cb (void *data) - * { - * g_free (data); - * } - * - * static void - * my_path_set_data (CoglPipeline *pipeline, void *data) - * { - * cogl_object_set_user_data (COGL_OBJECT (pipeline), - * &private_key, - * data, - * destroy_pipeline_private_cb); - * } - * ]| - * - * Since: 1.4 - */ -typedef struct { - int unused; -} CoglUserDataKey; - -/** - * CoglUserDataDestroyCallback: - * @user_data: The data whose association with a #CoglObject has been - * destroyed. - * - * When associating private data with a #CoglObject a callback can be - * given which will be called either if the object is destroyed or if - * cogl_object_set_user_data() is called with NULL user_data for the - * same key. - * - * Since: 1.4 - */ -typedef GDestroyNotify CoglUserDataDestroyCallback; - -/** - * CoglDebugObjectTypeInfo: - * @name: A human readable name for the type. - * @instance_count: The number of objects of this type that are - * currently in use - * - * This struct is used to pass information to the callback when - * cogl_debug_object_foreach_type() is called. - * - * Since: 1.8 - * Stability: unstable - */ -typedef struct { - const char *name; - unsigned long instance_count; -} CoglDebugObjectTypeInfo; - -/** - * CoglDebugObjectForeachTypeCallback: - * @info: A pointer to a struct containing information about the type. - * - * A callback function to use for cogl_debug_object_foreach_type(). - * - * Since: 1.8 - * Stability: unstable - */ -typedef void -(* CoglDebugObjectForeachTypeCallback) (const CoglDebugObjectTypeInfo *info, - void *user_data); - -/** - * cogl_object_set_user_data: (skip) - * @object: The object to associate private data with - * @key: The address of a #CoglUserDataKey which provides a unique value - * with which to index the private data. - * @user_data: The data to associate with the given object, - * or %NULL to remove a previous association. - * @destroy: A #CoglUserDataDestroyCallback to call if the object is - * destroyed or if the association is removed by later setting - * %NULL data for the same key. - * - * Associates some private @user_data with a given #CoglObject. To - * later remove the association call cogl_object_set_user_data() with - * the same @key but NULL for the @user_data. - * - * Since: 1.4 - */ -COGL_EXPORT void -cogl_object_set_user_data (CoglObject *object, - CoglUserDataKey *key, - void *user_data, - CoglUserDataDestroyCallback destroy); - -/** - * cogl_object_get_user_data: (skip) - * @object: The object with associated private data to query - * @key: The address of a #CoglUserDataKey which provides a unique value - * with which to index the private data. - * - * Finds the user data previously associated with @object using - * the given @key. If no user data has been associated with @object - * for the given @key this function returns NULL. - * - * Returns: (transfer none): The user data previously associated - * with @object using the given @key; or %NULL if no associated - * data is found. - * - * Since: 1.4 - */ -COGL_EXPORT void * -cogl_object_get_user_data (CoglObject *object, - CoglUserDataKey *key); - -/** - * cogl_debug_object_foreach_type: - * @func: (scope call): A callback function for each type - * @user_data: (closure): A pointer to pass to @func - * - * Invokes @func once for each type of object that Cogl uses and - * passes a count of the number of objects for that type. This is - * intended to be used solely for debugging purposes to track down - * issues with objects leaking. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_debug_object_foreach_type (CoglDebugObjectForeachTypeCallback func, - void *user_data); - -/** - * cogl_debug_object_print_instances: - * - * Prints a list of all the object types that Cogl uses along with the - * number of objects of that type that are currently in use. This is - * intended to be used solely for debugging purposes to track down - * issues with objects leaking. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_debug_object_print_instances (void); - -G_END_DECLS - -#endif /* __COGL_OBJECT_H */ - diff --git a/cogl/cogl/cogl-offscreen-private.h b/cogl/cogl/cogl-offscreen-private.h deleted file mode 100644 index c88fc8535..000000000 --- a/cogl/cogl/cogl-offscreen-private.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef COGL_OFFSCREEN_PRIVATE_H -#define COGL_OFFSCREEN_PRIVATE_H - -#include "cogl-gl-header.h" -#include "cogl-offscreen.h" - -/* Flags to pass to _cogl_offscreen_new_with_texture_full */ -typedef enum -{ - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL = 1 -} CoglOffscreenFlags; - -typedef enum -{ - COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL = 1 << 0, - COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH = 1 << 1, - COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL = 1 << 2, -} CoglOffscreenAllocateFlags; - -/* - * _cogl_offscreen_new_with_texture_full: - * @texture: A #CoglTexture pointer - * @create_flags: Flags specifying how to create the FBO - * @level: The mipmap level within the texture to target - * - * Creates a new offscreen buffer which will target the given - * texture. By default the buffer will have a depth and stencil - * buffer. This can be disabled by passing - * %COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL in @create_flags. - * - * Return value: the new CoglOffscreen object. - */ -CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags create_flags, - int level); - -int -cogl_offscreen_get_texture_level (CoglOffscreen *offscreen); - -#endif /* COGL_OFFSCREEN_PRIVATE_H */ diff --git a/cogl/cogl/cogl-offscreen.c b/cogl/cogl/cogl-offscreen.c deleted file mode 100644 index a9b25cc79..000000000 --- a/cogl/cogl/cogl-offscreen.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-offscreen-private.h" -#include "cogl-texture-private.h" - -struct _CoglOffscreen -{ - CoglFramebuffer parent; - - CoglTexture *texture; - int texture_level; -}; - -G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen, - COGL_TYPE_FRAMEBUFFER) - -CoglOffscreen * -_cogl_offscreen_new_with_texture_full (CoglTexture *texture, - CoglOffscreenFlags flags, - int level) -{ - CoglContext *ctx = texture->context; - CoglFramebufferDriverConfig driver_config; - CoglOffscreen *offscreen; - CoglFramebuffer *fb; - - g_return_val_if_fail (cogl_is_texture (texture), NULL); - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_FBO, - .disable_depth_and_stencil = - !!(flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL), - }; - offscreen = g_object_new (COGL_TYPE_OFFSCREEN, - "context", ctx, - "driver-config", &driver_config, - NULL); - offscreen->texture = cogl_object_ref (texture); - offscreen->texture_level = level; - - fb = COGL_FRAMEBUFFER (offscreen); - - /* NB: we can't assume we can query the texture's width yet, since - * it might not have been allocated yet and for example if the - * texture is being loaded from a file then the file might not - * have been read yet. */ - - _cogl_texture_associate_framebuffer (texture, fb); - - return offscreen; -} - -CoglOffscreen * -cogl_offscreen_new_with_texture (CoglTexture *texture) -{ - return _cogl_offscreen_new_with_texture_full (texture, 0, 0); -} - -CoglTexture * -cogl_offscreen_get_texture (CoglOffscreen *offscreen) -{ - return offscreen->texture; -} - -int -cogl_offscreen_get_texture_level (CoglOffscreen *offscreen) -{ - return offscreen->texture_level; -} - -static gboolean -cogl_offscreen_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer); - CoglPixelFormat texture_format; - int width, height; - - if (!cogl_texture_allocate (offscreen->texture, error)) - return FALSE; - - /* NB: it's only after allocating the texture that we will - * determine whether a texture needs slicing... */ - if (cogl_texture_is_sliced (offscreen->texture)) - { - g_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, - "Can't create offscreen framebuffer from " - "sliced texture"); - return FALSE; - } - - width = cogl_texture_get_width (offscreen->texture); - height = cogl_texture_get_height (offscreen->texture); - cogl_framebuffer_update_size (framebuffer, width, height); - - texture_format = _cogl_texture_get_format (offscreen->texture); - _cogl_framebuffer_set_internal_format (framebuffer, texture_format); - - return TRUE; -} - -static gboolean -cogl_offscreen_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return TRUE; -} - -static void -cogl_offscreen_dispose (GObject *object) -{ - CoglOffscreen *offscreen = COGL_OFFSCREEN (object); - - G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object); - - cogl_clear_object (&offscreen->texture); -} - -static void -cogl_offscreen_init (CoglOffscreen *offscreen) -{ -} - -static void -cogl_offscreen_class_init (CoglOffscreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_offscreen_dispose; - - framebuffer_class->allocate = cogl_offscreen_allocate; - framebuffer_class->is_y_flipped = cogl_offscreen_is_y_flipped; -} diff --git a/cogl/cogl/cogl-offscreen.h b/cogl/cogl/cogl-offscreen.h deleted file mode 100644 index 2fa21dcc4..000000000 --- a/cogl/cogl/cogl-offscreen.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_OFFSCREEN_H__ -#define __COGL_OFFSCREEN_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-texture.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-offscreen - * @short_description: Functions for creating and manipulating offscreen - * framebuffers. - * - * Cogl allows creating and operating on offscreen framebuffers. - */ - -/* Offscreen api */ - -#define COGL_TYPE_OFFSCREEN (cogl_offscreen_get_type ()) -COGL_EXPORT -G_DECLARE_FINAL_TYPE (CoglOffscreen, cogl_offscreen, - COGL, OFFSCREEN, - CoglFramebuffer) - -/** - * cogl_offscreen_new_with_texture: - * @texture: A #CoglTexture pointer - * - * This creates an offscreen framebuffer object using the given - * @texture as the primary color buffer. It doesn't just initialize - * the contents of the offscreen buffer with the @texture; they are - * tightly bound so that drawing to the offscreen buffer effectively - * updates the contents of the given texture. You don't need to - * destroy the offscreen buffer before you can use the @texture again. - * - * <note>This api only works with low-level #CoglTexture types such as - * #CoglTexture2D and not with meta-texture types such as - * #CoglTexture2DSliced.</note> - * - * The storage for the framebuffer is actually allocated lazily - * so this function will never return %NULL to indicate a runtime - * error. This means it is still possible to configure the framebuffer - * before it is really allocated. - * - * Simple applications without full error handling can simply rely on - * Cogl to lazily allocate the storage of framebuffers but you should - * be aware that if Cogl encounters an error (such as running out of - * GPU memory) then your application will simply abort with an error - * message. If you need to be able to catch such exceptions at runtime - * then you can explicitly allocate your framebuffer when you have - * finished configuring it by calling cogl_framebuffer_allocate() and - * passing in a #GError argument to catch any exceptions. - * - * Return value: (transfer full): a newly instantiated #CoglOffscreen - * framebuffer. - */ -COGL_EXPORT CoglOffscreen * -cogl_offscreen_new_with_texture (CoglTexture *texture); - -/** - * cogl_offscreen_get_texture: (skip) - */ -COGL_EXPORT CoglTexture * -cogl_offscreen_get_texture (CoglOffscreen *offscreen); - -G_END_DECLS - -#endif /* __COGL_OFFSCREEN_H__ */ diff --git a/cogl/cogl/cogl-onscreen-private.h b/cogl/cogl/cogl-onscreen-private.h deleted file mode 100644 index dffe018d2..000000000 --- a/cogl/cogl/cogl-onscreen-private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_ONSCREEN_PRIVATE_H -#define __COGL_ONSCREEN_PRIVATE_H - -#include "cogl-onscreen.h" -#include "cogl-framebuffer-private.h" -#include "cogl-closure-list-private.h" -#include "cogl-list.h" - -#include <glib.h> - -typedef struct _CoglOnscreenEvent -{ - CoglList link; - - CoglOnscreen *onscreen; - CoglFrameInfo *info; - CoglFrameEvent type; -} CoglOnscreenEvent; - -typedef struct _CoglOnscreenQueuedDirty -{ - CoglList link; - - CoglOnscreen *onscreen; - CoglOnscreenDirtyInfo info; -} CoglOnscreenQueuedDirty; - -COGL_EXPORT void -_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, - int width, int height); - -void -_cogl_onscreen_queue_event (CoglOnscreen *onscreen, - CoglFrameEvent type, - CoglFrameInfo *info); - -COGL_EXPORT void -_cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info); - -COGL_EXPORT void -_cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info); - -void -_cogl_onscreen_queue_dirty (CoglOnscreen *onscreen, - const CoglOnscreenDirtyInfo *info); - - -void -_cogl_onscreen_queue_full_dirty (CoglOnscreen *onscreen); - -void -cogl_onscreen_bind (CoglOnscreen *onscreen); - -COGL_EXPORT void -cogl_onscreen_set_winsys (CoglOnscreen *onscreen, - gpointer winsys); - -COGL_EXPORT gpointer -cogl_onscreen_get_winsys (CoglOnscreen *onscreen); - -COGL_EXPORT CoglFrameInfo * -cogl_onscreen_peek_head_frame_info (CoglOnscreen *onscreen); - -COGL_EXPORT CoglFrameInfo * -cogl_onscreen_peek_tail_frame_info (CoglOnscreen *onscreen); - -COGL_EXPORT CoglFrameInfo * -cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen); - -#endif /* __COGL_ONSCREEN_PRIVATE_H */ diff --git a/cogl/cogl/cogl-onscreen-template-private.h b/cogl/cogl/cogl-onscreen-template-private.h deleted file mode 100644 index 1b19d35d7..000000000 --- a/cogl/cogl/cogl-onscreen-template-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_ONSCREEN_TEMPLATE_PRIVATE_H -#define __COGL_ONSCREEN_TEMPLATE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-swap-chain.h" -#include "cogl-framebuffer-private.h" - -struct _CoglOnscreenTemplate -{ - CoglObject _parent; - - CoglFramebufferConfig config; -}; - -#endif /* __COGL_ONSCREEN_TEMPLATE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-onscreen-template.c b/cogl/cogl/cogl-onscreen-template.c deleted file mode 100644 index 59fa1af18..000000000 --- a/cogl/cogl/cogl-onscreen-template.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-object.h" - -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-gtype-private.h" - -#include <stdlib.h> - -static void _cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template); - -COGL_OBJECT_DEFINE (OnscreenTemplate, onscreen_template); -COGL_GTYPE_DEFINE_CLASS (OnscreenTemplate, onscreen_template); - -static void -_cogl_onscreen_template_free (CoglOnscreenTemplate *onscreen_template) -{ - g_free (onscreen_template); -} - -CoglOnscreenTemplate * -cogl_onscreen_template_new (CoglSwapChain *swap_chain) -{ - CoglOnscreenTemplate *onscreen_template = g_new0 (CoglOnscreenTemplate, 1); - char *user_config; - - onscreen_template->config.swap_chain = swap_chain; - if (swap_chain) - cogl_object_ref (swap_chain); - else - onscreen_template->config.swap_chain = cogl_swap_chain_new (); - - onscreen_template->config.need_stencil = TRUE; - onscreen_template->config.samples_per_pixel = 0; - - user_config = getenv ("COGL_POINT_SAMPLES_PER_PIXEL"); - if (user_config) - { - unsigned long samples_per_pixel = strtoul (user_config, NULL, 10); - if (samples_per_pixel != ULONG_MAX) - onscreen_template->config.samples_per_pixel = - samples_per_pixel; - } - - return _cogl_onscreen_template_object_new (onscreen_template); -} - -void -cogl_onscreen_template_set_samples_per_pixel ( - CoglOnscreenTemplate *onscreen_template, - int samples_per_pixel) -{ - onscreen_template->config.samples_per_pixel = samples_per_pixel; -} - -void -cogl_onscreen_template_set_stereo_enabled ( - CoglOnscreenTemplate *onscreen_template, - gboolean enabled) -{ - onscreen_template->config.stereo_enabled = enabled; -} diff --git a/cogl/cogl/cogl-onscreen-template.h b/cogl/cogl/cogl-onscreen-template.h deleted file mode 100644 index 9881e1c48..000000000 --- a/cogl/cogl/cogl-onscreen-template.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_ONSCREEN_TEMPLATE_H__ -#define __COGL_ONSCREEN_TEMPLATE_H__ - -#include <cogl/cogl-swap-chain.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -typedef struct _CoglOnscreenTemplate CoglOnscreenTemplate; - -#define COGL_ONSCREEN_TEMPLATE(OBJECT) ((CoglOnscreenTemplate *)OBJECT) - -/** - * cogl_onscreen_template_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_onscreen_template_get_gtype (void); - -COGL_EXPORT CoglOnscreenTemplate * -cogl_onscreen_template_new (CoglSwapChain *swap_chain); - -/** - * cogl_onscreen_template_set_samples_per_pixel: - * @onscreen_template: A #CoglOnscreenTemplate template framebuffer - * @n: The minimum number of samples per pixel - * - * Requires that any future CoglOnscreen framebuffers derived from - * this template must support making at least @n samples per pixel - * which will all contribute to the final resolved color for that - * pixel. - * - * By default this value is usually set to 0 and that is referred to - * as "single-sample" rendering. A value of 1 or greater is referred - * to as "multisample" rendering. - * - * <note>There are some semantic differences between single-sample - * rendering and multisampling with just 1 point sample such as it - * being redundant to use the cogl_framebuffer_resolve_samples() and - * cogl_framebuffer_resolve_samples_region() apis with single-sample - * rendering.</note> - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_template_set_samples_per_pixel ( - CoglOnscreenTemplate *onscreen_template, - int n); - -/** - * cogl_onscreen_template_set_stereo_enabled: - * @onscreen_template: A #CoglOnscreenTemplate template framebuffer - * @enabled: Whether framebuffers are created with stereo buffers - * - * Sets whether future #CoglOnscreen framebuffers derived from this - * template are attempted to be created with both left and right - * buffers, for use with stereo display. If the display system - * does not support stereo, then creation of the framebuffer will - * fail. - * - * Since: 1.20 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_template_set_stereo_enabled ( - CoglOnscreenTemplate *onscreen_template, - gboolean enabled); -/** - * cogl_is_onscreen_template: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglOnscreenTemplate. - * - * Return value: %TRUE if the object references a #CoglOnscreenTemplate - * and %FALSE otherwise. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_onscreen_template (void *object); - -G_END_DECLS - -#endif /* __COGL_ONSCREEN_TEMPLATE_H__ */ diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c deleted file mode 100644 index cff5df50c..000000000 --- a/cogl/cogl/cogl-onscreen.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <gio/gio.h> - -#include "cogl-util.h" -#include "cogl-onscreen-private.h" -#include "cogl-frame-info-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl1-context.h" -#include "cogl-closure-list-private.h" -#include "cogl-poll-private.h" -#include "cogl-gtype-private.h" - -typedef struct _CoglOnscreenPrivate -{ - CoglList frame_closures; - - CoglList dirty_closures; - - int64_t frame_counter; - int64_t swap_frame_counter; /* frame counter at last all to - * cogl_onscreen_swap_region() or - * cogl_onscreen_swap_buffers() */ - GQueue pending_frame_infos; -} CoglOnscreenPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (CoglOnscreen, cogl_onscreen, COGL_TYPE_FRAMEBUFFER) - -static gpointer -cogl_dummy_copy (gpointer data) -{ - return data; -} - -static void -cogl_dummy_free (gpointer data) -{ -} - -COGL_GTYPE_DEFINE_BOXED (FrameClosure, frame_closure, - cogl_dummy_copy, - cogl_dummy_free); -COGL_GTYPE_DEFINE_BOXED (OnscreenDirtyClosure, - onscreen_dirty_closure, - cogl_dummy_copy, - cogl_dummy_free); - -G_DEFINE_QUARK (cogl-scanout-error-quark, cogl_scanout_error) - -static gboolean -cogl_onscreen_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - /* If the winsys doesn't support dirty events then we'll report - * one on allocation so that if the application only paints in - * response to dirty events then it will at least paint once to - * start */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_DIRTY_EVENTS)) - _cogl_onscreen_queue_full_dirty (onscreen); - - return TRUE; -} - -static gboolean -cogl_onscreen_is_y_flipped (CoglFramebuffer *framebuffer) -{ - return FALSE; -} - -static void -cogl_onscreen_init_from_template (CoglOnscreen *onscreen, - CoglOnscreenTemplate *onscreen_template) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - _cogl_list_init (&priv->frame_closures); - _cogl_list_init (&priv->dirty_closures); - - cogl_framebuffer_init_config (framebuffer, &onscreen_template->config); -} - -static void -cogl_onscreen_constructed (GObject *object) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglOnscreenTemplate *onscreen_template; - - onscreen_template = ctx->display->onscreen_template; - cogl_onscreen_init_from_template (onscreen, onscreen_template); - - G_OBJECT_CLASS (cogl_onscreen_parent_class)->constructed (object); -} - -static void -cogl_onscreen_dispose (GObject *object) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (object); - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFrameInfo *frame_info; - - _cogl_closure_list_disconnect_all (&priv->frame_closures); - _cogl_closure_list_disconnect_all (&priv->dirty_closures); - - while ((frame_info = g_queue_pop_tail (&priv->pending_frame_infos))) - cogl_object_unref (frame_info); - g_queue_clear (&priv->pending_frame_infos); - - G_OBJECT_CLASS (cogl_onscreen_parent_class)->dispose (object); -} - -static void -cogl_onscreen_init (CoglOnscreen *onscreen) -{ -} - -static void -cogl_onscreen_class_init (CoglOnscreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->constructed = cogl_onscreen_constructed; - object_class->dispose = cogl_onscreen_dispose; - - framebuffer_class->allocate = cogl_onscreen_allocate; - framebuffer_class->is_y_flipped = cogl_onscreen_is_y_flipped; -} - -static void -notify_event (CoglOnscreen *onscreen, - CoglFrameEvent event, - CoglFrameInfo *info) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - _cogl_closure_list_invoke (&priv->frame_closures, - CoglFrameCallback, - onscreen, event, info); -} - -static void -_cogl_dispatch_onscreen_cb (CoglContext *context) -{ - CoglOnscreenEvent *event, *tmp; - CoglList queue; - - /* Dispatching the event callback may cause another frame to be - * drawn which in may cause another event to be queued immediately. - * To make sure this loop will only dispatch one set of events we'll - * steal the queue and iterate that separately */ - _cogl_list_init (&queue); - _cogl_list_insert_list (&queue, &context->onscreen_events_queue); - _cogl_list_init (&context->onscreen_events_queue); - - g_clear_pointer (&context->onscreen_dispatch_idle, - _cogl_closure_disconnect); - - _cogl_list_for_each_safe (event, tmp, &queue, link) - { - CoglOnscreen *onscreen = event->onscreen; - CoglFrameInfo *info = event->info; - - notify_event (onscreen, event->type, info); - - g_object_unref (onscreen); - cogl_object_unref (info); - - g_free (event); - } - - while (!_cogl_list_empty (&context->onscreen_dirty_queue)) - { - CoglOnscreenQueuedDirty *qe = - _cogl_container_of (context->onscreen_dirty_queue.next, - CoglOnscreenQueuedDirty, - link); - CoglOnscreen *onscreen = qe->onscreen; - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - _cogl_list_remove (&qe->link); - - _cogl_closure_list_invoke (&priv->dirty_closures, - CoglOnscreenDirtyCallback, - qe->onscreen, - &qe->info); - - g_object_unref (qe->onscreen); - - g_free (qe); - } -} - -static void -_cogl_onscreen_queue_dispatch_idle (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - if (!ctx->onscreen_dispatch_idle) - { - ctx->onscreen_dispatch_idle = - _cogl_poll_renderer_add_idle (ctx->display->renderer, - (CoglIdleCallback) - _cogl_dispatch_onscreen_cb, - ctx, - NULL); - } -} - -void -_cogl_onscreen_queue_dirty (CoglOnscreen *onscreen, - const CoglOnscreenDirtyInfo *info) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglOnscreenQueuedDirty *qe = g_new0 (CoglOnscreenQueuedDirty, 1); - - qe->onscreen = g_object_ref (onscreen); - qe->info = *info; - _cogl_list_insert (ctx->onscreen_dirty_queue.prev, &qe->link); - - _cogl_onscreen_queue_dispatch_idle (onscreen); -} - -void -_cogl_onscreen_queue_full_dirty (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenDirtyInfo info; - - info.x = 0; - info.y = 0; - info.width = cogl_framebuffer_get_width (framebuffer); - info.height = cogl_framebuffer_get_height (framebuffer); - - _cogl_onscreen_queue_dirty (onscreen, &info); -} - -void -_cogl_onscreen_queue_event (CoglOnscreen *onscreen, - CoglFrameEvent type, - CoglFrameInfo *info) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - CoglOnscreenEvent *event = g_new0 (CoglOnscreenEvent, 1); - - event->onscreen = g_object_ref (onscreen); - event->info = cogl_object_ref (info); - event->type = type; - - _cogl_list_insert (ctx->onscreen_events_queue.prev, &event->link); - - _cogl_onscreen_queue_dispatch_idle (onscreen); -} - -void -cogl_onscreen_bind (CoglOnscreen *onscreen) -{ - COGL_ONSCREEN_GET_CLASS (onscreen)->bind (onscreen); -} - -void -cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_return_if_fail (COGL_IS_ONSCREEN (framebuffer)); - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); - - _cogl_framebuffer_flush_journal (framebuffer); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) - cogl_framebuffer_finish (framebuffer); - - klass->swap_buffers_with_damage (onscreen, - rectangles, - n_rectangles, - info, - user_data); - - cogl_framebuffer_discard_buffers (framebuffer, - COGL_BUFFER_BIT_COLOR | - COGL_BUFFER_BIT_DEPTH | - COGL_BUFFER_BIT_STENCIL); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - CoglFrameInfo *info; - - g_warn_if_fail (priv->pending_frame_infos.length == 1); - - info = g_queue_pop_tail (&priv->pending_frame_infos); - - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_SYNC, info); - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_COMPLETE, info); - - cogl_object_unref (info); - } - - priv->frame_counter++; -} - -void -cogl_onscreen_swap_buffers (CoglOnscreen *onscreen, - CoglFrameInfo *info, - gpointer user_data) -{ - cogl_onscreen_swap_buffers_with_damage (onscreen, NULL, 0, info, user_data); -} - -void -cogl_onscreen_swap_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_return_if_fail (COGL_IS_ONSCREEN (framebuffer)); - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); - - _cogl_framebuffer_flush_journal (framebuffer); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SYNC_FRAME))) - cogl_framebuffer_finish (framebuffer); - - /* This should only be called if the winsys advertises - COGL_WINSYS_FEATURE_SWAP_REGION */ - g_return_if_fail (klass->swap_region); - - klass->swap_region (onscreen, - rectangles, - n_rectangles, - info, - user_data); - - cogl_framebuffer_discard_buffers (framebuffer, - COGL_BUFFER_BIT_COLOR | - COGL_BUFFER_BIT_DEPTH | - COGL_BUFFER_BIT_STENCIL); - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - CoglFrameInfo *info; - - g_warn_if_fail (priv->pending_frame_infos.length == 1); - - info = g_queue_pop_tail (&priv->pending_frame_infos); - - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_SYNC, info); - _cogl_onscreen_queue_event (onscreen, COGL_FRAME_EVENT_COMPLETE, info); - - cogl_object_unref (info); - } - - priv->frame_counter++; -} - -int -cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_return_val_if_fail (COGL_IS_ONSCREEN (framebuffer), 0); - - if (!klass->get_buffer_age) - return 0; - - return klass->get_buffer_age (onscreen); -} - -gboolean -cogl_onscreen_direct_scanout (CoglOnscreen *onscreen, - CoglScanout *scanout, - CoglFrameInfo *info, - gpointer user_data, - GError **error) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen); - - g_warn_if_fail (COGL_IS_ONSCREEN (framebuffer)); - g_warn_if_fail (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)); - - if (!klass->direct_scanout) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Direct scanout not supported"); - return FALSE; - } - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); - - if (!klass->direct_scanout (onscreen, - scanout, - info, - user_data, - error)) - { - g_queue_pop_tail (&priv->pending_frame_infos); - return FALSE; - } - - info->flags |= COGL_FRAME_INFO_FLAG_ZERO_COPY; - priv->frame_counter++; - return TRUE; -} - -void -cogl_onscreen_add_frame_info (CoglOnscreen *onscreen, - CoglFrameInfo *info) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - info->frame_counter = priv->frame_counter; - g_queue_push_tail (&priv->pending_frame_infos, info); -} - -CoglFrameInfo * -cogl_onscreen_peek_head_frame_info (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return g_queue_peek_head (&priv->pending_frame_infos); -} - -CoglFrameInfo * -cogl_onscreen_peek_tail_frame_info (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return g_queue_peek_tail (&priv->pending_frame_infos); -} - -CoglFrameInfo * -cogl_onscreen_pop_head_frame_info (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return g_queue_pop_head (&priv->pending_frame_infos); -} - -CoglFrameClosure * -cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, - CoglFrameCallback callback, - void *user_data, - CoglUserDataDestroyCallback destroy) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return _cogl_closure_list_add (&priv->frame_closures, - callback, - user_data, - destroy); -} - -void -cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, - CoglFrameClosure *closure) -{ - g_return_if_fail (closure); - - _cogl_closure_disconnect (closure); -} - -void -_cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info) -{ - notify_event (onscreen, COGL_FRAME_EVENT_SYNC, info); -} - -void -_cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info) -{ - notify_event (onscreen, COGL_FRAME_EVENT_COMPLETE, info); -} - -void -_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer, - int width, int height) -{ - if (cogl_framebuffer_get_width (framebuffer) == width && - cogl_framebuffer_get_height (framebuffer) == height) - return; - - cogl_framebuffer_update_size (framebuffer, width, height); - - if (!_cogl_has_private_feature (cogl_framebuffer_get_context (framebuffer), - COGL_PRIVATE_FEATURE_DIRTY_EVENTS)) - _cogl_onscreen_queue_full_dirty (COGL_ONSCREEN (framebuffer)); -} - -CoglOnscreenDirtyClosure * -cogl_onscreen_add_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyCallback callback, - void *user_data, - CoglUserDataDestroyCallback destroy) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return _cogl_closure_list_add (&priv->dirty_closures, - callback, - user_data, - destroy); -} - -void -cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyClosure *closure) -{ - g_return_if_fail (closure); - - _cogl_closure_disconnect (closure); -} - -int64_t -cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen) -{ - CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen); - - return priv->frame_counter; -} diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h deleted file mode 100644 index 7284e04d5..000000000 --- a/cogl/cogl/cogl-onscreen.h +++ /dev/null @@ -1,611 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_ONSCREEN_H -#define __COGL_ONSCREEN_H - -#include <cogl/cogl-context.h> -#include <cogl/cogl-framebuffer.h> -#include <cogl/cogl-frame-info.h> -#include <cogl/cogl-object.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -typedef struct _CoglScanout CoglScanout; - -#define COGL_TYPE_ONSCREEN (cogl_onscreen_get_type ()) -COGL_EXPORT -G_DECLARE_DERIVABLE_TYPE (CoglOnscreen, cogl_onscreen, - COGL, ONSCREEN, - CoglFramebuffer) - -struct _CoglOnscreenClass -{ - /*< private >*/ - CoglFramebufferClass parent_class; - - void (* bind) (CoglOnscreen *onscreen); - - void (* swap_buffers_with_damage) (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - - void (* swap_region) (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - - gboolean (* direct_scanout) (CoglOnscreen *onscreen, - CoglScanout *scanout, - CoglFrameInfo *info, - gpointer user_data, - GError **error); - - int (* get_buffer_age) (CoglOnscreen *onscreen); -}; - -#define COGL_SCANOUT_ERROR (cogl_scanout_error_quark ()) -COGL_EXPORT GQuark -cogl_scanout_error_quark (void); - -typedef enum _CoglScanoutError -{ - COGL_SCANOUT_ERROR_INHIBITED, -} CoglScanoutError; - -/** - * cogl_onscreen_show: - * @onscreen: The onscreen framebuffer to make visible - * - * This requests to make @onscreen visible to the user. - * - * Actually the precise semantics of this function depend on the - * window system currently in use, and if you don't have a - * multi-windowining system this function may in-fact do nothing. - * - * This function will implicitly allocate the given @onscreen - * framebuffer before showing it if it hasn't already been allocated. - * - * When using the Wayland winsys calling this will set the surface to - * a toplevel type which will make it appear. If the application wants - * to set a different type for the surface, it can avoid calling - * cogl_onscreen_show() and set its own type directly with the Wayland - * client API via cogl_wayland_onscreen_get_surface(). - * - * <note>Since Cogl doesn't explicitly track the visibility status of - * onscreen framebuffers it won't try to avoid redundant window system - * requests e.g. to show an already visible window. This also means - * that it's acceptable to alternatively use native APIs to show and - * hide windows without confusing Cogl.</note> - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_onscreen_show (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_hide: - * @onscreen: The onscreen framebuffer to make invisible - * - * This requests to make @onscreen invisible to the user. - * - * Actually the precise semantics of this function depend on the - * window system currently in use, and if you don't have a - * multi-windowining system this function may in-fact do nothing. - * - * This function does not implicitly allocate the given @onscreen - * framebuffer before hiding it. - * - * <note>Since Cogl doesn't explicitly track the visibility status of - * onscreen framebuffers it won't try to avoid redundant window system - * requests e.g. to show an already visible window. This also means - * that it's acceptable to alternatively use native APIs to show and - * hide windows without confusing Cogl.</note> - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_onscreen_hide (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_swap_buffers: - * @onscreen: A #CoglOnscreen framebuffer - * - * Swaps the current back buffer being rendered too, to the front for display. - * - * This function also implicitly discards the contents of the color, depth and - * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The - * significance of the discard is that you should not expect to be able to - * start a new frame that incrementally builds on the contents of the previous - * frame. - * - * <note>It is highly recommended that applications use - * cogl_onscreen_swap_buffers_with_damage() instead whenever possible - * and also use the cogl_onscreen_get_buffer_age() api so they can - * perform incremental updates to older buffers instead of having to - * render a full buffer for every frame.</note> - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_swap_buffers (CoglOnscreen *onscreen, - CoglFrameInfo *frame_info, - gpointer user_data); - - -/** - * cogl_onscreen_get_buffer_age: - * @onscreen: A #CoglOnscreen framebuffer - * - * Gets the current age of the buffer contents. - * - * This function allows applications to query the age of the current - * back buffer contents for a #CoglOnscreen as the number of frames - * elapsed since the contents were most recently defined. - * - * These age values exposes enough information to applications about - * how Cogl internally manages back buffers to allow applications to - * re-use the contents of old frames and minimize how much must be - * redrawn for the next frame. - * - * The back buffer contents can either be reported as invalid (has an - * age of 0) or it may be reported to be the same contents as from n - * frames prior to the current frame. - * - * The queried value remains valid until the next buffer swap. - * - * <note>One caveat is that under X11 the buffer age does not reflect - * changes to buffer contents caused by the window systems. X11 - * applications must track Expose events to determine what buffer - * regions need to additionally be repaired each frame.</note> - * - * The recommended way to take advantage of this buffer age api is to - * build up a circular buffer of length 3 for tracking damage regions - * over the last 3 frames and when starting a new frame look at the - * age of the buffer and combine the damage regions for the current - * frame with the damage regions of previous @age frames so you know - * everything that must be redrawn to update the old contents for the - * new frame. - * - * <note>If the system doesn't not support being able to track the age - * of back buffers then this function will always return 0 which - * implies that the contents are undefined.</note> - * - * <note>The %COGL_FEATURE_ID_BUFFER_AGE feature can optionally be - * explicitly checked to determine if Cogl is currently tracking the - * age of #CoglOnscreen back buffer contents. If this feature is - * missing then this function will always return 0.</note> - * - * Return value: The age of the buffer contents or 0 when the buffer - * contents are undefined. - * - * Since: 1.14 - * Stability: stable - */ -COGL_EXPORT int -cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen); - -/** - * cogl_onscreen_swap_buffers_with_damage: - * @onscreen: A #CoglOnscreen framebuffer - * @rectangles: An array of integer 4-tuples representing damaged - * rectangles as (x, y, width, height) tuples. - * @n_rectangles: The number of 4-tuples to be read from @rectangles - * - * Swaps the current back buffer being rendered too, to the front for - * display and provides information to any system compositor about - * what regions of the buffer have changed (damage) with respect to - * the last swapped buffer. - * - * This function has the same semantics as - * cogl_framebuffer_swap_buffers() except that it additionally allows - * applications to pass a list of damaged rectangles which may be - * passed on to a compositor so that it can minimize how much of the - * screen is redrawn in response to this applications newly swapped - * front buffer. - * - * For example if your application is only animating a small object in - * the corner of the screen and everything else is remaining static - * then it can help the compositor to know that only the bottom right - * corner of your newly swapped buffer has really changed with respect - * to your previously swapped front buffer. - * - * If @n_rectangles is 0 then the whole buffer will implicitly be - * reported as damaged as if cogl_onscreen_swap_buffers() had been - * called. - * - * This function also implicitly discards the contents of the color, - * depth and stencil buffers as if cogl_framebuffer_discard_buffers() - * were used. The significance of the discard is that you should not - * expect to be able to start a new frame that incrementally builds on - * the contents of the previous frame. If you want to perform - * incremental updates to older back buffers then please refer to the - * cogl_onscreen_get_buffer_age() api. - * - * Whenever possible it is recommended that applications use this - * function instead of cogl_onscreen_swap_buffers() to improve - * performance when running under a compositor. - * - * <note>It is highly recommended to use this API in conjunction with - * the cogl_onscreen_get_buffer_age() api so that your application can - * perform incremental rendering based on old back buffers.</note> - * - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - -/** - * cogl_onscreen_direct_scanout: (skip) - */ -COGL_EXPORT gboolean -cogl_onscreen_direct_scanout (CoglOnscreen *onscreen, - CoglScanout *scanout, - CoglFrameInfo *info, - gpointer user_data, - GError **error); - -/** - * cogl_onscreen_add_frame_info: (skip) - */ -COGL_EXPORT void -cogl_onscreen_add_frame_info (CoglOnscreen *onscreen, - CoglFrameInfo *info); - -/** - * cogl_onscreen_swap_region: - * @onscreen: A #CoglOnscreen framebuffer - * @rectangles: An array of integer 4-tuples representing rectangles as - * (x, y, width, height) tuples. - * @n_rectangles: The number of 4-tuples to be read from @rectangles - * - * Swaps a region of the back buffer being rendered too, to the front for - * display. @rectangles represents the region as array of @n_rectangles each - * defined by 4 sequential (x, y, width, height) integers. - * - * This function also implicitly discards the contents of the color, depth and - * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The - * significance of the discard is that you should not expect to be able to - * start a new frame that incrementally builds on the contents of the previous - * frame. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_swap_region (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data); - -/** - * CoglFrameEvent: - * @COGL_FRAME_EVENT_SYNC: Notifies that the system compositor has - * acknowledged a frame and is ready for a - * new frame to be created. - * @COGL_FRAME_EVENT_COMPLETE: Notifies that a frame has ended. This - * is a good time for applications to - * collect statistics about the frame - * since the #CoglFrameInfo should hold - * the most data at this point. No other - * events should be expected after a - * @COGL_FRAME_EVENT_COMPLETE event. - * - * Identifiers that are passed to #CoglFrameCallback functions - * (registered using cogl_onscreen_add_frame_callback()) that - * mark the progression of a frame in some way which usually - * means that new information will have been accumulated in the - * frame's corresponding #CoglFrameInfo object. - * - * The last event that will be sent for a frame will be a - * @COGL_FRAME_EVENT_COMPLETE event and so these are a good - * opportunity to collect statistics about a frame since the - * #CoglFrameInfo should hold the most data at this point. - * - * <note>A frame may not be completed before the next frame can start - * so applications should avoid needing to collect all statistics for - * a particular frame before they can start a new frame.</note> - * - * Since: 1.14 - * Stability: unstable - */ -typedef enum _CoglFrameEvent -{ - COGL_FRAME_EVENT_SYNC = 1, - COGL_FRAME_EVENT_COMPLETE -} CoglFrameEvent; - -/** - * CoglFrameCallback: - * @onscreen: The onscreen that the frame is associated with - * @event: A #CoglFrameEvent notifying how the frame has progressed - * @info: The meta information, such as timing information, about - * the frame that has progressed. - * @user_data: The user pointer passed to - * cogl_onscreen_add_frame_callback() - * - * Is a callback that can be registered via - * cogl_onscreen_add_frame_callback() to be called when a frame - * progresses in some notable way. - * - * Please see the documentation for #CoglFrameEvent and - * cogl_onscreen_add_frame_callback() for more details about what - * events can be notified. - * - * Since: 1.14 - * Stability: unstable - */ -typedef void (*CoglFrameCallback) (CoglOnscreen *onscreen, - CoglFrameEvent event, - CoglFrameInfo *info, - void *user_data); - -/** - * CoglFrameClosure: - * - * An opaque type that tracks a #CoglFrameCallback and associated user - * data. A #CoglFrameClosure pointer will be returned from - * cogl_onscreen_add_frame_callback() and it allows you to remove a - * callback later using cogl_onscreen_remove_frame_callback(). - * - * Since: 1.14 - * Stability: unstable - */ -typedef struct _CoglClosure CoglFrameClosure; - -/** - * cogl_frame_closure_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_frame_closure_get_gtype (void); - -/** - * cogl_onscreen_add_frame_callback: - * @onscreen: A #CoglOnscreen framebuffer - * @callback: (scope notified): A callback function to call for frame events - * @user_data: (closure): A private pointer to be passed to @callback - * @destroy: (allow-none): An optional callback to destroy @user_data - * when the @callback is removed or @onscreen is freed. - * - * Installs a @callback function that will be called for significant - * events relating to the given @onscreen framebuffer. - * - * The @callback will be used to notify when the system compositor is - * ready for this application to render a new frame. In this case - * %COGL_FRAME_EVENT_SYNC will be passed as the event argument to the - * given @callback in addition to the #CoglFrameInfo corresponding to - * the frame being acknowledged by the compositor. - * - * The @callback will also be called to notify when the frame has - * ended. In this case %COGL_FRAME_EVENT_COMPLETE will be passed as - * the event argument to the given @callback in addition to the - * #CoglFrameInfo corresponding to the newly presented frame. The - * meaning of "ended" here simply means that no more timing - * information will be collected within the corresponding - * #CoglFrameInfo and so this is a good opportunity to analyse the - * given info. It does not necessarily mean that the GPU has finished - * rendering the corresponding frame. - * - * We highly recommend throttling your application according to - * %COGL_FRAME_EVENT_SYNC events so that your application can avoid - * wasting resources, drawing more frames than your system compositor - * can display. - * - * Return value: a #CoglFrameClosure pointer that can be used to - * remove the callback and associated @user_data later. - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT CoglFrameClosure * -cogl_onscreen_add_frame_callback (CoglOnscreen *onscreen, - CoglFrameCallback callback, - void *user_data, - CoglUserDataDestroyCallback destroy); - -/** - * cogl_onscreen_remove_frame_callback: - * @onscreen: A #CoglOnscreen - * @closure: A #CoglFrameClosure returned from - * cogl_onscreen_add_frame_callback() - * - * Removes a callback and associated user data that were previously - * registered using cogl_onscreen_add_frame_callback(). - * - * If a destroy callback was passed to - * cogl_onscreen_add_frame_callback() to destroy the user data then - * this will get called. - * - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen, - CoglFrameClosure *closure); - -/** - * CoglOnscreenDirtyInfo: - * @x: Left edge of the dirty rectangle - * @y: Top edge of the dirty rectangle, measured from the top of the window - * @width: Width of the dirty rectangle - * @height: Height of the dirty rectangle - * - * A structure passed to callbacks registered using - * cogl_onscreen_add_dirty_callback(). The members describe a - * rectangle within the onscreen buffer that should be redrawn. - * - * Since: 1.16 - * Stability: unstable - */ -typedef struct _CoglOnscreenDirtyInfo CoglOnscreenDirtyInfo; - -struct _CoglOnscreenDirtyInfo -{ - int x, y; - int width, height; -}; - -/** - * CoglOnscreenDirtyCallback: - * @onscreen: The onscreen that the frame is associated with - * @info: A #CoglOnscreenDirtyInfo struct containing the details of the - * dirty area - * @user_data: The user pointer passed to - * cogl_onscreen_add_frame_callback() - * - * Is a callback that can be registered via - * cogl_onscreen_add_dirty_callback() to be called when the windowing - * system determines that a region of the onscreen window has been - * lost and the application should redraw it. - * - * Since: 1.16 - * Stability: unstable - */ -typedef void (*CoglOnscreenDirtyCallback) (CoglOnscreen *onscreen, - const CoglOnscreenDirtyInfo *info, - void *user_data); - -/** - * CoglOnscreenDirtyClosure: - * - * An opaque type that tracks a #CoglOnscreenDirtyCallback and associated - * user data. A #CoglOnscreenDirtyClosure pointer will be returned from - * cogl_onscreen_add_dirty_callback() and it allows you to remove a - * callback later using cogl_onscreen_remove_dirty_callback(). - * - * Since: 1.16 - * Stability: unstable - */ -typedef struct _CoglClosure CoglOnscreenDirtyClosure; - -/** - * cogl_onscreen_dirty_closure_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_onscreen_dirty_closure_get_gtype (void); - -/** - * cogl_onscreen_add_dirty_callback: - * @onscreen: A #CoglOnscreen framebuffer - * @callback: (scope notified): A callback function to call for dirty events - * @user_data: (closure): A private pointer to be passed to @callback - * @destroy: (allow-none): An optional callback to destroy @user_data when the - * @callback is removed or @onscreen is freed. - * - * Installs a @callback function that will be called whenever the - * window system has lost the contents of a region of the onscreen - * buffer and the application should redraw it to repair the buffer. - * For example this may happen in a window system without a compositor - * if a window that was previously covering up the onscreen window has - * been moved causing a region of the onscreen to be exposed. - * - * The @callback will be passed a #CoglOnscreenDirtyInfo struct which - * describes a rectangle containing the newly dirtied region. Note that - * this may be called multiple times to describe a non-rectangular - * region composed of multiple smaller rectangles. - * - * The dirty events are separate from %COGL_FRAME_EVENT_SYNC events so - * the application should also listen for this event before rendering - * the dirty region to ensure that the framebuffer is actually ready - * for rendering. - * - * Return value: a #CoglOnscreenDirtyClosure pointer that can be used to - * remove the callback and associated @user_data later. - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT CoglOnscreenDirtyClosure * -cogl_onscreen_add_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyCallback callback, - void *user_data, - CoglUserDataDestroyCallback destroy); - -/** - * cogl_onscreen_remove_dirty_callback: - * @onscreen: A #CoglOnscreen - * @closure: A #CoglOnscreenDirtyClosure returned from - * cogl_onscreen_add_dirty_callback() - * - * Removes a callback and associated user data that were previously - * registered using cogl_onscreen_add_dirty_callback(). - * - * If a destroy callback was passed to - * cogl_onscreen_add_dirty_callback() to destroy the user data then - * this will also get called. - * - * Since: 1.16 - * Stability: unstable - */ -COGL_EXPORT void -cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen, - CoglOnscreenDirtyClosure *closure); - -/** - * cogl_onscreen_get_frame_counter: - * - * Gets the value of the framebuffers frame counter. This is - * a counter that increases by one each time - * cogl_onscreen_swap_buffers() or cogl_onscreen_swap_region() - * is called. - * - * Return value: the current frame counter value - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int64_t -cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen); - -G_END_DECLS - -#endif /* __COGL_ONSCREEN_H */ diff --git a/cogl/cogl/cogl-output-private.h b/cogl/cogl/cogl-output-private.h deleted file mode 100644 index 4f8b60ed5..000000000 --- a/cogl/cogl/cogl-output-private.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_OUTPUT_PRIVATE_H -#define __COGL_OUTPUT_PRIVATE_H - -#include "cogl-output.h" -#include "cogl-object-private.h" - -struct _CoglOutput -{ - CoglObject _parent; - - char *name; - - int x; /* Must be first field for _cogl_output_values_equal() */ - int y; - int width; - int height; - int mm_width; - int mm_height; - float refresh_rate; - CoglSubpixelOrder subpixel_order; -}; - -CoglOutput *_cogl_output_new (const char *name); -gboolean _cogl_output_values_equal (CoglOutput *output, - CoglOutput *other); - -#endif /* __COGL_OUTPUT_PRIVATE_H */ diff --git a/cogl/cogl/cogl-output.c b/cogl/cogl/cogl-output.c deleted file mode 100644 index 5ad0e4022..000000000 --- a/cogl/cogl/cogl-output.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-output-private.h" -#include "cogl-gtype-private.h" - -#include <string.h> - -static void _cogl_output_free (CoglOutput *output); - -COGL_OBJECT_DEFINE (Output, output); -COGL_GTYPE_DEFINE_CLASS (Output, output); - -CoglOutput * -_cogl_output_new (const char *name) -{ - CoglOutput *output; - - output = g_new0 (CoglOutput, 1); - output->name = g_strdup (name); - - return _cogl_output_object_new (output); -} - -static void -_cogl_output_free (CoglOutput *output) -{ - g_free (output->name); - - g_free (output); -} - -gboolean -_cogl_output_values_equal (CoglOutput *output, - CoglOutput *other) -{ - return memcmp ((const char *)output + G_STRUCT_OFFSET (CoglOutput, x), - (const char *)other + G_STRUCT_OFFSET (CoglOutput, x), - sizeof (CoglOutput) - G_STRUCT_OFFSET (CoglOutput, x)) == 0; -} - -int -cogl_output_get_x (CoglOutput *output) -{ - return output->x; -} - -int -cogl_output_get_y (CoglOutput *output) -{ - return output->y; -} - -int -cogl_output_get_width (CoglOutput *output) -{ - return output->width; -} - -int -cogl_output_get_height (CoglOutput *output) -{ - return output->height; -} - -int -cogl_output_get_mm_width (CoglOutput *output) -{ - return output->mm_width; -} - -int -cogl_output_get_mm_height (CoglOutput *output) -{ - return output->mm_height; -} - -CoglSubpixelOrder -cogl_output_get_subpixel_order (CoglOutput *output) -{ - return output->subpixel_order; -} - -float -cogl_output_get_refresh_rate (CoglOutput *output) -{ - return output->refresh_rate; -} diff --git a/cogl/cogl/cogl-output.h b/cogl/cogl/cogl-output.h deleted file mode 100644 index 6ea135cff..000000000 --- a/cogl/cogl/cogl-output.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Owen Taylor <otaylor@redhat.com> - */ -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_OUTPUT_H -#define __COGL_OUTPUT_H - -#include <cogl/cogl-types.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-output - * @short_description: information about an output device - * - * The #CoglOutput object holds information about an output device - * such as a monitor or laptop display. It can be queried to find - * out the position of the output with respect to the screen - * coordinate system and other information such as the resolution - * and refresh rate of the device. - * - * There can be any number of outputs which may overlap: the - * same area of the screen may be displayed by multiple output - * devices. - * - * XXX: though it's possible to query the position of the output - * with respect to screen coordinates, there is currently no way - * of finding out the position of a #CoglOnscreen in screen - * coordinates, at least without using windowing-system specific - * API's, so it's not easy to get the output positions relative - * to the #CoglOnscreen. - */ - -typedef struct _CoglOutput CoglOutput; -#define COGL_OUTPUT(X) ((CoglOutput *)(X)) - -/** - * cogl_output_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_output_get_gtype (void); - -/** - * CoglSubpixelOrder: - * @COGL_SUBPIXEL_ORDER_UNKNOWN: the layout of subpixel - * components for the device is unknown. - * @COGL_SUBPIXEL_ORDER_NONE: the device displays colors - * without geometrically-separated subpixel components, - * or the positioning or colors of the components do not - * match any of the values in the enumeration. - * @COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB: the device has - * horizontally arranged components in the order - * red-green-blue from left to right. - * @COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR: the device has - * horizontally arranged components in the order - * blue-green-red from left to right. - * @COGL_SUBPIXEL_ORDER_VERTICAL_RGB: the device has - * vertically arranged components in the order - * red-green-blue from top to bottom. - * @COGL_SUBPIXEL_ORDER_VERTICAL_BGR: the device has - * vertically arranged components in the order - * blue-green-red from top to bottom. - * - * Some output devices (such as LCD panels) display colors - * by making each pixel consist of smaller "subpixels" - * that each have a particular color. By using knowledge - * of the layout of this subpixel components, it is possible - * to create image content with higher resolution than the - * pixel grid. - * - * Since: 1.14 - * Stability: unstable - */ -typedef enum -{ - COGL_SUBPIXEL_ORDER_UNKNOWN, - COGL_SUBPIXEL_ORDER_NONE, - COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB, - COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR, - COGL_SUBPIXEL_ORDER_VERTICAL_RGB, - COGL_SUBPIXEL_ORDER_VERTICAL_BGR -} CoglSubpixelOrder; - -/** - * cogl_is_output: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglOutput. - * - * Return value: %TRUE if the object references a #CoglOutput - * and %FALSE otherwise. - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_output (void *object); - -/** - * cogl_output_get_x: - * @output: a #CoglOutput - * - * Gets the X position of the output with respect to the coordinate - * system of the screen. - * - * Return value: the X position of the output as a pixel offset - * from the left side of the screen coordinate space - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int -cogl_output_get_x (CoglOutput *output); - -/** - * cogl_output_get_y: - * @output: a #CoglOutput - * - * Gets the Y position of the output with respect to the coordinate - * system of the screen. - * - * Return value: the Y position of the output as a pixel offset - * from the top side of the screen coordinate space - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int -cogl_output_get_y (CoglOutput *output); - -/** - * cogl_output_get_width: - * @output: a #CoglOutput - * - * Gets the width of the output in pixels. - * - * Return value: the width of the output in pixels - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int -cogl_output_get_width (CoglOutput *output); - -/** - * cogl_output_get_height: - * @output: a #CoglOutput - * - * Gets the height of the output in pixels. - * - * Return value: the height of the output in pixels - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int -cogl_output_get_height (CoglOutput *output); - -/** - * cogl_output_get_mm_width: - * @output: a #CoglOutput - * - * Gets the physical width of the output. In some cases (such as - * as a projector), the value returned here might correspond to - * nominal resolution rather than the actual physical size of the - * output device. - * - * Return value: the height of the output in millimeters. A value - * of 0 indicates the width is unknown - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int -cogl_output_get_mm_width (CoglOutput *output); - -/** - * cogl_output_get_mm_height: - * @output: a #CoglOutput - * - * Gets the physical height of the output. In some cases (such as - * as a projector), the value returned here might correspond to - * nominal resolution rather than the actual physical size of the - * output device. - * - * Return value: the height of the output in millimeters. A value - * of 0 indicates that the height is unknown - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT int -cogl_output_get_mm_height (CoglOutput *output); - -/** - * cogl_output_get_subpixel_order: - * @output: a #CoglOutput - * - * For an output device where each pixel is made up of smaller components - * with different colors, returns the layout of the subpixel - * components. - * - * Return value: the order of subpixel components for the output device - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT CoglSubpixelOrder -cogl_output_get_subpixel_order (CoglOutput *output); - -/** - * cogl_output_get_refresh_rate: - * @output: a #CoglOutput - * - * Gets the number of times per second that the output device refreshes - * the display contents. - * - * Return value: the refresh rate of the output device. A value of zero - * indicates that the refresh rate is unknown. - * Since: 1.14 - * Stability: unstable - */ -COGL_EXPORT float -cogl_output_get_refresh_rate (CoglOutput *output); - -G_END_DECLS - -#endif /* __COGL_OUTPUT_H */ - - - diff --git a/cogl/cogl/cogl-pipeline-cache.c b/cogl/cogl/cogl-pipeline-cache.c deleted file mode 100644 index 6bfc37732..000000000 --- a/cogl/cogl/cogl-pipeline-cache.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <test-fixtures/test-unit.h> - -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-cache.h" -#include "cogl-pipeline-hash-table.h" - -struct _CoglPipelineCache -{ - CoglPipelineHashTable fragment_hash; - CoglPipelineHashTable vertex_hash; - CoglPipelineHashTable combined_hash; -}; - -CoglPipelineCache * -_cogl_pipeline_cache_new (void) -{ - g_autofree CoglPipelineCache *cache = g_new (CoglPipelineCache, 1); - unsigned long vertex_state; - unsigned long layer_vertex_state; - unsigned int fragment_state; - unsigned int layer_fragment_state; - - _COGL_GET_CONTEXT (ctx, 0); - - vertex_state = - _cogl_pipeline_get_state_for_vertex_codegen (ctx); - layer_vertex_state = - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN; - fragment_state = - _cogl_pipeline_get_state_for_fragment_codegen (ctx); - layer_fragment_state = - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx); - - _cogl_pipeline_hash_table_init (&cache->vertex_hash, - vertex_state, - layer_vertex_state, - "vertex shaders"); - _cogl_pipeline_hash_table_init (&cache->fragment_hash, - fragment_state, - layer_fragment_state, - "fragment shaders"); - _cogl_pipeline_hash_table_init (&cache->combined_hash, - vertex_state | fragment_state, - layer_vertex_state | layer_fragment_state, - "programs"); - - return g_steal_pointer (&cache); -} - -void -_cogl_pipeline_cache_free (CoglPipelineCache *cache) -{ - _cogl_pipeline_hash_table_destroy (&cache->fragment_hash); - _cogl_pipeline_hash_table_destroy (&cache->vertex_hash); - _cogl_pipeline_hash_table_destroy (&cache->combined_hash); - g_free (cache); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_fragment_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline) -{ - return _cogl_pipeline_hash_table_get (&cache->fragment_hash, - key_pipeline); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_vertex_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline) -{ - return _cogl_pipeline_hash_table_get (&cache->vertex_hash, - key_pipeline); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline) -{ - return _cogl_pipeline_hash_table_get (&cache->combined_hash, - key_pipeline); -} - -#ifdef ENABLE_UNIT_TESTS - -static void -create_pipelines (CoglPipeline **pipelines, - int n_pipelines) -{ - int i; - - for (i = 0; i < n_pipelines; i++) - { - char *source = g_strdup_printf (" cogl_color_out = " - "vec4 (%f, 0.0, 0.0, 1.0);\n", - i / 255.0f); - CoglSnippet *snippet = - cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - NULL, /* declarations */ - source); - - g_free (source); - - pipelines[i] = cogl_pipeline_new (test_ctx); - cogl_pipeline_add_snippet (pipelines[i], snippet); - cogl_object_unref (snippet); - } - - /* Test that drawing with them works. This should create the entries - * in the cache */ - for (i = 0; i < n_pipelines; i++) - { - cogl_framebuffer_draw_rectangle (test_fb, - pipelines[i], - i, 0, - i + 1, 1); - test_utils_check_pixel_rgb (test_fb, i, 0, i, 0, 0); - } - -} - -UNIT_TEST (check_pipeline_pruning, - TEST_REQUIREMENT_GLSL, /* requirements */ - 0 /* no failure cases */) -{ - CoglPipeline *pipelines[18]; - int fb_width, fb_height; - CoglPipelineHashTable *fragment_hash = - &test_ctx->pipeline_cache->fragment_hash; - CoglPipelineHashTable *combined_hash = - &test_ctx->pipeline_cache->combined_hash; - int i; - - fb_width = cogl_framebuffer_get_width (test_fb); - fb_height = cogl_framebuffer_get_height (test_fb); - - cogl_framebuffer_orthographic (test_fb, - 0, 0, - fb_width, - fb_height, - -1, - 100); - - /* Create 18 unique pipelines. This should end up being more than - * the initial expected minimum size so it will trigger the garbage - * collection. However all of the pipelines will be in use so they - * won't be collected */ - create_pipelines (pipelines, 18); - - /* These pipelines should all have unique entries in the cache. We - * should have run the garbage collection once and at that point the - * expected minimum size would have been 17 */ - g_assert_cmpint (g_hash_table_size (fragment_hash->table), ==, 18); - g_assert_cmpint (g_hash_table_size (combined_hash->table), ==, 18); - g_assert_cmpint (fragment_hash->expected_min_size, ==, 17); - g_assert_cmpint (combined_hash->expected_min_size, ==, 17); - - /* Destroy the original pipelines and create some new ones. This - * should run the garbage collector again but this time the - * pipelines won't be in use so it should free some of them */ - for (i = 0; i < 18; i++) - cogl_object_unref (pipelines[i]); - - create_pipelines (pipelines, 18); - - /* The garbage collection should have freed half of the original 18 - * pipelines which means there should now be 18*1.5 = 27 */ - g_assert_cmpint (g_hash_table_size (fragment_hash->table), ==, 27); - g_assert_cmpint (g_hash_table_size (combined_hash->table), ==, 27); - /* The 35th pipeline would have caused the garbage collection. At - * that point there would be 35-18=17 used unique pipelines. */ - g_assert_cmpint (fragment_hash->expected_min_size, ==, 17); - g_assert_cmpint (combined_hash->expected_min_size, ==, 17); - - for (i = 0; i < 18; i++) - cogl_object_unref (pipelines[i]); -} - -#endif /* ENABLE_UNIT_TESTS */ diff --git a/cogl/cogl/cogl-pipeline-cache.h b/cogl/cogl/cogl-pipeline-cache.h deleted file mode 100644 index bd5862ee5..000000000 --- a/cogl/cogl/cogl-pipeline-cache.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PIPELINE_CACHE_H__ -#define __COGL_PIPELINE_CACHE_H__ - -#include "cogl-pipeline.h" - -typedef struct _CoglPipelineCache CoglPipelineCache; - -typedef struct -{ - CoglPipeline *pipeline; - - /* Number of usages of this template. If this drops to zero then it - * will be a candidate for removal from the cache */ - int usage_count; -} CoglPipelineCacheEntry; - -CoglPipelineCache * -_cogl_pipeline_cache_new (void); - -void -_cogl_pipeline_cache_free (CoglPipelineCache *cache); - -/* - * Gets a pipeline from the cache that has the same state as - * @key_pipeline for the state in - * COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN. If there is no - * matching pipline already then a copy of key_pipeline is stored in - * the cache so that it will be used next time the function is called - * with a similar pipeline. In that case the copy itself will be - * returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_fragment_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline); - -/* - * Gets a pipeline from the cache that has the same state as - * @key_pipeline for the state in - * COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN. If there is no - * matching pipline already then a copy of key_pipeline is stored in - * the cache so that it will be used next time the function is called - * with a similar pipeline. In that case the copy itself will be - * returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_vertex_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline); - -/* - * Gets a pipeline from the cache that has the same state as - * @key_pipeline for the combination of the state state in - * COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN and - * COGL_PIPELINE_STATE_AFFECTS_FRAGMENT_CODEGEN. If there is no - * matching pipline already then a copy of key_pipeline is stored in - * the cache so that it will be used next time the function is called - * with a similar pipeline. In that case the copy itself will be - * returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache, - CoglPipeline *key_pipeline); - -#endif /* __COGL_PIPELINE_CACHE_H__ */ diff --git a/cogl/cogl/cogl-pipeline-debug.c b/cogl/cogl/cogl-pipeline-debug.c deleted file mode 100644 index 7555257d0..000000000 --- a/cogl/cogl/cogl-pipeline-debug.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-layer-private.h" -#include "cogl-node-private.h" - -#include <glib.h> - -typedef struct -{ - int parent_id; - int *node_id_ptr; - GString *graph; - int indent; -} PrintDebugState; - -static gboolean -dump_layer_cb (CoglNode *node, void *user_data) -{ - CoglPipelineLayer *layer = COGL_PIPELINE_LAYER (node); - PrintDebugState *state = user_data; - int layer_id = *state->node_id_ptr; - PrintDebugState state_out; - GString *changes_label; - gboolean changes = FALSE; - - if (state->parent_id >= 0) - g_string_append_printf (state->graph, "%*slayer%p -> layer%p;\n", - state->indent, "", - layer->_parent.parent, - layer); - - g_string_append_printf (state->graph, - "%*slayer%p [label=\"layer=0x%p\\n" - "ref count=%d\" " - "color=\"blue\"];\n", - state->indent, "", - layer, - layer, - COGL_OBJECT (layer)->ref_count); - - changes_label = g_string_new (""); - g_string_append_printf (changes_label, - "%*slayer%p -> layer_state%d [weight=100];\n" - "%*slayer_state%d [shape=box label=\"", - state->indent, "", - layer, - layer_id, - state->indent, "", - layer_id); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_UNIT) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lunit=%u\\n", - layer->unit_index); - } - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\ltexture=%p\\n", - layer->texture); - } - - if (changes) - { - g_string_append_printf (changes_label, "\"];\n"); - g_string_append (state->graph, changes_label->str); - g_string_free (changes_label, TRUE); - } - - state_out.parent_id = layer_id; - - state_out.node_id_ptr = state->node_id_ptr; - (*state_out.node_id_ptr)++; - - state_out.graph = state->graph; - state_out.indent = state->indent + 2; - - _cogl_pipeline_node_foreach_child (COGL_NODE (layer), - dump_layer_cb, - &state_out); - - return TRUE; -} - -static gboolean -dump_layer_ref_cb (CoglPipelineLayer *layer, void *data) -{ - PrintDebugState *state = data; - int pipeline_id = *state->node_id_ptr; - - g_string_append_printf (state->graph, - "%*spipeline_state%d -> layer%p;\n", - state->indent, "", - pipeline_id, - layer); - - return TRUE; -} - -static gboolean -dump_pipeline_cb (CoglNode *node, void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - PrintDebugState *state = user_data; - int pipeline_id = *state->node_id_ptr; - PrintDebugState state_out; - GString *changes_label; - gboolean changes = FALSE; - gboolean layers = FALSE; - - if (state->parent_id >= 0) - g_string_append_printf (state->graph, "%*spipeline%d -> pipeline%d;\n", - state->indent, "", - state->parent_id, - pipeline_id); - - g_string_append_printf (state->graph, - "%*spipeline%d [label=\"pipeline=0x%p\\n" - "ref count=%d\\n" - "breadcrumb=\\\"%s\\\"\" color=\"red\"];\n", - state->indent, "", - pipeline_id, - pipeline, - COGL_OBJECT (pipeline)->ref_count, - pipeline->has_static_breadcrumb ? -#ifdef COGL_DEBUG_ENABLED - pipeline->static_breadcrumb : "NULL" -#else - "NULL" -#endif - ); - - changes_label = g_string_new (""); - g_string_append_printf (changes_label, - "%*spipeline%d -> pipeline_state%d [weight=100];\n" - "%*spipeline_state%d [shape=box label=\"", - state->indent, "", - pipeline_id, - pipeline_id, - state->indent, "", - pipeline_id); - - - if (pipeline->differences & COGL_PIPELINE_STATE_COLOR) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lcolor=0x%02X%02X%02X%02X\\n", - cogl_color_get_red_byte (&pipeline->color), - cogl_color_get_green_byte (&pipeline->color), - cogl_color_get_blue_byte (&pipeline->color), - cogl_color_get_alpha_byte (&pipeline->color)); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_BLEND) - { - changes = TRUE; - g_string_append_printf (changes_label, - "\\lblend\\n"); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - changes = TRUE; - layers = TRUE; - g_string_append_printf (changes_label, "\\ln_layers=%d\\n", - pipeline->n_layers); - } - - if (changes) - { - g_string_append_printf (changes_label, "\"];\n"); - g_string_append (state->graph, changes_label->str); - g_string_free (changes_label, TRUE); - } - - if (layers) - { - g_list_foreach (pipeline->layer_differences, - (GFunc)dump_layer_ref_cb, - state); - } - - state_out.parent_id = pipeline_id; - - state_out.node_id_ptr = state->node_id_ptr; - (*state_out.node_id_ptr)++; - - state_out.graph = state->graph; - state_out.indent = state->indent + 2; - - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - dump_pipeline_cb, - &state_out); - - return TRUE; -} - -/* This function is just here to be called from GDB so we don't really - want to put a declaration in a header and we just add it here to - avoid a warning */ -void -_cogl_debug_dump_pipelines_dot_file (const char *filename); - -void -_cogl_debug_dump_pipelines_dot_file (const char *filename) -{ - GString *graph; - PrintDebugState layer_state; - PrintDebugState pipeline_state; - int layer_id = 0; - int pipeline_id = 0; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!ctx->default_pipeline) - return; - - graph = g_string_new (""); - g_string_append_printf (graph, "digraph {\n"); - - layer_state.graph = graph; - layer_state.parent_id = -1; - layer_state.node_id_ptr = &layer_id; - layer_state.indent = 0; - dump_layer_cb ((CoglNode *)ctx->default_layer_0, &layer_state); - - pipeline_state.graph = graph; - pipeline_state.parent_id = -1; - pipeline_state.node_id_ptr = &pipeline_id; - pipeline_state.indent = 0; - dump_pipeline_cb ((CoglNode *)ctx->default_pipeline, &pipeline_state); - - g_string_append_printf (graph, "}\n"); - - if (filename) - g_file_set_contents (filename, graph->str, -1, NULL); - else - g_print ("%s", graph->str); - - g_string_free (graph, TRUE); -} diff --git a/cogl/cogl/cogl-pipeline-hash-table.c b/cogl/cogl/cogl-pipeline-hash-table.c deleted file mode 100644 index 53df22d28..000000000 --- a/cogl/cogl/cogl-pipeline-hash-table.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-hash-table.h" -#include "cogl-pipeline-cache.h" - -typedef struct -{ - CoglPipelineCacheEntry parent; - - /* Calculating the hash is a little bit expensive for pipelines so - * we don't want to do it repeatedly for entries that are already in - * the hash table. Instead we cache the value here and calculate it - * outside of the GHashTable. */ - unsigned int hash_value; - - /* GHashTable annoyingly doesn't let us pass a user data pointer to - * the hash and equal functions so to work around it we have to - * store the pointer in every hash table entry. We will use this - * entry as both the key and the value */ - CoglPipelineHashTable *hash; - - /* The number of unique pipelines that had been created when this - * pipeline was last accessed */ - int age; -} CoglPipelineHashTableEntry; - -static void -value_destroy_cb (void *value) -{ - CoglPipelineHashTableEntry *entry = value; - - cogl_object_unref (entry->parent.pipeline); - - g_free (entry); -} - -static unsigned int -entry_hash (const void *data) -{ - const CoglPipelineHashTableEntry *entry = data; - - return entry->hash_value; -} - -static gboolean -entry_equal (const void *a, - const void *b) -{ - const CoglPipelineHashTableEntry *entry_a = a; - const CoglPipelineHashTableEntry *entry_b = b; - const CoglPipelineHashTable *hash = entry_a->hash; - - return _cogl_pipeline_equal (entry_a->parent.pipeline, - entry_b->parent.pipeline, - hash->main_state, - hash->layer_state, - 0); -} - -void -_cogl_pipeline_hash_table_init (CoglPipelineHashTable *hash, - unsigned int main_state, - unsigned int layer_state, - const char *debug_string) -{ - hash->n_unique_pipelines = 0; - hash->debug_string = debug_string; - hash->main_state = main_state; - hash->layer_state = layer_state; - /* We'll only start pruning once we get to 16 unique pipelines */ - hash->expected_min_size = 8; - hash->table = g_hash_table_new_full (entry_hash, - entry_equal, - NULL, /* key destroy */ - value_destroy_cb); -} - -void -_cogl_pipeline_hash_table_destroy (CoglPipelineHashTable *hash) -{ - g_hash_table_destroy (hash->table); -} - -static void -collect_prunable_entries_cb (void *key, - void *value, - void *user_data) -{ - GQueue *entries = user_data; - CoglPipelineCacheEntry *entry = value; - - if (entry->usage_count == 0) - g_queue_push_tail (entries, entry); -} - -static int -compare_pipeline_age_cb (const void *a, - const void *b) -{ - const CoglPipelineHashTableEntry *ae = a; - const CoglPipelineHashTableEntry *be = b; - - return be->age - ae->age; -} - -static void -prune_old_pipelines (CoglPipelineHashTable *hash) -{ - GQueue entries; - GList *l; - int i; - - /* Collect all of the prunable entries into a GQueue */ - g_queue_init (&entries); - g_hash_table_foreach (hash->table, - collect_prunable_entries_cb, - &entries); - - /* Sort the entries by increasing order of age */ - entries.head = g_list_sort (entries.head, compare_pipeline_age_cb); - - /* The +1 is to include the pipeline that we're about to add */ - hash->expected_min_size = (g_hash_table_size (hash->table) - - entries.length + - 1); - - /* Remove oldest half of the prunable pipelines. We still want to - * keep some of the prunable entries that are recently used because - * it's not unlikely that the application will recreate the same - * pipeline */ - for (l = entries.head, i = 0; i < entries.length / 2; l = l->next, i++) - { - CoglPipelineCacheEntry *entry = l->data; - - g_hash_table_remove (hash->table, entry); - } - - g_list_free (entries.head); -} - -CoglPipelineCacheEntry * -_cogl_pipeline_hash_table_get (CoglPipelineHashTable *hash, - CoglPipeline *key_pipeline) -{ - CoglPipelineHashTableEntry dummy_entry; - CoglPipelineHashTableEntry *entry; - unsigned int copy_state; - - dummy_entry.parent.pipeline = key_pipeline; - dummy_entry.hash = hash; - dummy_entry.hash_value = _cogl_pipeline_hash (key_pipeline, - hash->main_state, - hash->layer_state, - 0); - entry = g_hash_table_lookup (hash->table, &dummy_entry); - - if (entry) - { - entry->age = hash->n_unique_pipelines; - return &entry->parent; - } - - if (hash->n_unique_pipelines == 50) - g_warning ("Over 50 separate %s have been generated which is very " - "unusual, so something is probably wrong!\n", - hash->debug_string); - - /* If we are going to have more than twice the expected minimum - * number of pipelines in the hash then we'll try pruning and update - * the minimum */ - if (g_hash_table_size (hash->table) >= hash->expected_min_size * 2) - prune_old_pipelines (hash); - - entry = g_new0 (CoglPipelineHashTableEntry, 1); - entry->parent.usage_count = 0; - entry->hash = hash; - entry->hash_value = dummy_entry.hash_value; - entry->age = hash->n_unique_pipelines; - - copy_state = hash->main_state; - if (hash->layer_state) - copy_state |= COGL_PIPELINE_STATE_LAYERS; - - /* Create a new pipeline that is a child of the root pipeline - * instead of a normal copy so that the template pipeline won't hold - * a reference to the original pipeline */ - entry->parent.pipeline = _cogl_pipeline_deep_copy (key_pipeline, - copy_state, - hash->layer_state); - - g_hash_table_insert (hash->table, entry, entry); - - hash->n_unique_pipelines++; - - return &entry->parent; -} diff --git a/cogl/cogl/cogl-pipeline-hash-table.h b/cogl/cogl/cogl-pipeline-hash-table.h deleted file mode 100644 index 035e8dfb3..000000000 --- a/cogl/cogl/cogl-pipeline-hash-table.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PIPELINE_HASH_H__ -#define __COGL_PIPELINE_HASH_H__ - -#include "cogl-pipeline-cache.h" - -typedef struct -{ - /* Total number of pipelines that were ever added to the hash. This - * is not decremented when a pipeline is removed. It is only used to - * generate a warning if an unusually high number of pipelines are - * generated */ - int n_unique_pipelines; - - /* This is the expected minimum size we could prune the hash table - * to if we were to remove all pipelines that are not in use. This - * is only updated after we prune the table */ - int expected_min_size; - - /* String that will be used to describe the usage of this hash table - * in the debug warning when too many pipelines are generated. This - * must be a static string because it won't be copied or freed */ - const char *debug_string; - - unsigned int main_state; - unsigned int layer_state; - - GHashTable *table; -} CoglPipelineHashTable; - -void -_cogl_pipeline_hash_table_init (CoglPipelineHashTable *hash, - unsigned int main_state, - unsigned int layer_state, - const char *debug_string); - -void -_cogl_pipeline_hash_table_destroy (CoglPipelineHashTable *hash); - -/* - * Gets a pipeline from the hash that has the same state as - * @key_pipeline according to the limited state bits passed to - * _cogl_pipeline_hash_table_init(). If there is no matching pipelines - * already then a copy of key_pipeline is stored in the hash so that - * it will be used next time the function is called with a similar - * pipeline. In that case the copy itself will be returned - */ -CoglPipelineCacheEntry * -_cogl_pipeline_hash_table_get (CoglPipelineHashTable *hash, - CoglPipeline *key_pipeline); - -#endif /* __COGL_PIPELINE_HASH_H__ */ diff --git a/cogl/cogl/cogl-pipeline-layer-private.h b/cogl/cogl/cogl-pipeline-layer-private.h deleted file mode 100644 index 461a45519..000000000 --- a/cogl/cogl/cogl-pipeline-layer-private.h +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_LAYER_PRIVATE_H -#define __COGL_PIPELINE_LAYER_PRIVATE_H - -#include "cogl-private.h" -#include "cogl-pipeline.h" -#include "cogl-node-private.h" -#include "cogl-texture.h" -#include "cogl-pipeline-layer-state.h" -#include "cogl-pipeline-snippet-private.h" -#include "cogl-sampler-cache-private.h" - -#include <glib.h> - -typedef struct _CoglPipelineLayer CoglPipelineLayer; -#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT) - -/* XXX: should I rename these as - * COGL_PIPELINE_LAYER_STATE_INDEX_XYZ... ? - */ -typedef enum -{ - /* sparse state */ - COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, - COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX, - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX, - - /* note: layers don't currently have any non-sparse state */ - - COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT, - COGL_PIPELINE_LAYER_STATE_COUNT = COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT -} CoglPipelineLayerStateIndex; - -/* XXX: If you add or remove state groups here you may need to update - * some of the state masks following this enum too! - * - * FIXME: perhaps it would be better to rename this enum to - * CoglPipelineLayerStateGroup to better convey the fact that a single - * enum here can map to multiple properties. - */ -typedef enum -{ - COGL_PIPELINE_LAYER_STATE_UNIT = - 1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA = - 1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, - COGL_PIPELINE_LAYER_STATE_SAMPLER = - 1L<<COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX, - - COGL_PIPELINE_LAYER_STATE_COMBINE = - 1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT = - 1L<<COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX = - 1L<<COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS = - 1L<<COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - - COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS = - 1L<<COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX, - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS = - 1L<<COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX, - - /* COGL_PIPELINE_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */ - -} CoglPipelineLayerState; - -/* - * Various special masks that tag state-groups in different ways... - */ - -#define COGL_PIPELINE_LAYER_STATE_ALL \ - ((1L<<COGL_PIPELINE_LAYER_STATE_COUNT) - 1) - -#define COGL_PIPELINE_LAYER_STATE_ALL_SPARSE \ - COGL_PIPELINE_LAYER_STATE_ALL - -#define COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE \ - (COGL_PIPELINE_LAYER_STATE_COMBINE | \ - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT | \ - COGL_PIPELINE_LAYER_STATE_USER_MATRIX | \ - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS | \ - COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS | \ - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS) - -#define COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY \ - (COGL_PIPELINE_LAYER_STATE_COMBINE | \ - COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS | \ - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS) - -#define COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN \ - COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS - -typedef enum -{ - /* These are the same values as GL */ - COGL_PIPELINE_COMBINE_FUNC_ADD = 0x0104, - COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED = 0x8574, - COGL_PIPELINE_COMBINE_FUNC_SUBTRACT = 0x84E7, - COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE = 0x8575, - COGL_PIPELINE_COMBINE_FUNC_REPLACE = 0x1E01, - COGL_PIPELINE_COMBINE_FUNC_MODULATE = 0x2100, - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB = 0x86AE, - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA = 0x86AF -} CoglPipelineCombineFunc; - -typedef enum -{ - /* Note that these numbers are deliberately not the same as the GL - numbers so that we can reserve all numbers > TEXTURE0 to store - very large layer numbers */ - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE, - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT, - COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR, - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS, - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 -} CoglPipelineCombineSource; - -typedef enum -{ - /* These are the same values as GL */ - COGL_PIPELINE_COMBINE_OP_SRC_COLOR = 0x0300, - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR = 0x0301, - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA = 0x0302, - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA = 0x0303 -} CoglPipelineCombineOp; - -typedef struct -{ - /* The texture combine state determines how the color of individual - * texture fragments are calculated. */ - CoglPipelineCombineFunc texture_combine_rgb_func; - CoglPipelineCombineSource texture_combine_rgb_src[3]; - CoglPipelineCombineOp texture_combine_rgb_op[3]; - - CoglPipelineCombineFunc texture_combine_alpha_func; - CoglPipelineCombineSource texture_combine_alpha_src[3]; - CoglPipelineCombineOp texture_combine_alpha_op[3]; - - float texture_combine_constant[4]; - - /* The texture matrix dscribes how to transform texture coordinates */ - graphene_matrix_t matrix; - - CoglPipelineSnippetList vertex_snippets; - CoglPipelineSnippetList fragment_snippets; - - gboolean point_sprite_coords; -} CoglPipelineLayerBigState; - -struct _CoglPipelineLayer -{ - /* XXX: Please think twice about adding members that *have* be - * initialized during a _cogl_pipeline_layer_copy. We are aiming - * to have copies be as cheap as possible and copies may be - * done by the primitives APIs which means they may happen - * in performance critical code paths. - * - * XXX: If you are extending the state we track please consider if - * the state is expected to vary frequently across many pipelines or - * if the state can be shared among many derived pipelines instead. - * This will determine if the state should be added directly to this - * structure which will increase the memory overhead for *all* - * layers or if instead it can go under ->big_state. - */ - - /* Layers represent their state in a tree structure where some of - * the state relating to a given pipeline or layer may actually be - * owned by one if is ancestors in the tree. We have a common data - * type to track the tree hierarchy so we can share code... */ - CoglNode _parent; - - /* Some layers have a pipeline owner, which is to say that the layer - * is referenced in that pipelines->layer_differences list. A layer - * doesn't always have an owner and may simply be an ancestor for - * other layers that keeps track of some shared state. */ - CoglPipeline *owner; - - /* The lowest index is blended first then others on top */ - int index; - - /* A mask of which state groups are different in this layer - * in comparison to its parent. */ - unsigned int differences; - - /* Common differences - * - * As a basic way to reduce memory usage we divide the layer - * state into two groups; the minimal state modified in 90% of - * all layers and the rest, so that the second group can - * be allocated dynamically when required. - */ - - /* Each layer is directly associated with a single texture unit */ - int unit_index; - - /* The texture for this layer, or NULL for an empty - * layer */ - CoglTexture *texture; - - const CoglSamplerCacheEntry *sampler_cache_entry; - - /* Infrequent differences aren't currently tracked in - * a separate, dynamically allocated structure as they are - * for pipelines... */ - CoglPipelineLayerBigState *big_state; - - /* bitfields */ - - /* Determines if layer->big_state is valid */ - unsigned int has_big_state:1; - -}; - -typedef gboolean -(*CoglPipelineLayerStateComparator) (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - - - -void -_cogl_pipeline_init_default_layers (void); - -static inline CoglPipelineLayer * -_cogl_pipeline_layer_get_parent (CoglPipelineLayer *layer) -{ - CoglNode *parent_node = COGL_NODE (layer)->parent; - return COGL_PIPELINE_LAYER (parent_node); -} - -CoglPipelineLayer * -_cogl_pipeline_layer_copy (CoglPipelineLayer *layer); - -void -_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer, - unsigned long differences, - CoglPipelineLayer **authorities); - -gboolean -_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1, - unsigned long differences_mask, - CoglPipelineEvalFlags flags); - -CoglPipelineLayer * -_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); - -void -_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, - int layer_index); - -/* - * Calls the pre_paint method on the layer texture if there is - * one. This will determine whether mipmaps are needed based on the - * filter settings. - */ -void -_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layerr); - -void -_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, - CoglSamplerCacheWrapMode *wrap_mode_s, - CoglSamplerCacheWrapMode *wrap_mode_t); - -void -_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter); - -const CoglSamplerCacheEntry * -_cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer); - -void -_cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter); - -typedef enum -{ - COGL_PIPELINE_LAYER_TYPE_TEXTURE -} CoglPipelineLayerType; - -CoglPipelineLayerType -_cogl_pipeline_layer_get_type (CoglPipelineLayer *layer); - -COGL_EXPORT CoglTexture * -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer); - -CoglTexture * -_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer); - -CoglPipelineFilter -_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer); - -CoglPipelineFilter -_cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer); - -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer); - -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer); - -void -_cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest, - CoglPipelineLayer *src, - unsigned long differences); - -unsigned long -_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1); - -CoglPipelineLayer * -_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer, - unsigned long difference); - -int -_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer); - -gboolean -_cogl_pipeline_layer_needs_combine_separate - (CoglPipelineLayer *combine_authority); - -#endif /* __COGL_PIPELINE_LAYER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-pipeline-layer-state-private.h b/cogl/cogl/cogl-pipeline-layer-state-private.h deleted file mode 100644 index a09208964..000000000 --- a/cogl/cogl/cogl-pipeline-layer-state-private.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_LAYER_STATE_PRIVATE_H -#define __COGL_PIPELINE_LAYER_STATE_PRIVATE_H - -#include "cogl-pipeline-layer-state.h" -#include "cogl-pipeline-private.h" - -CoglPipelineLayer * -_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - int unit_index); - -CoglPipelineFilter -_cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, - int layer_index); - -CoglPipelineFilter -_cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, - int layer_index); - -gboolean -_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1, - CoglPipelineEvalFlags flags); - -gboolean -_cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_sampler_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_vertex_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -gboolean -_cogl_pipeline_layer_fragment_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1); - -void -_cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_sampler_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_combine_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_combine_constant_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_user_matrix_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_point_sprite_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_vertex_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -void -_cogl_pipeline_layer_hash_fragment_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -#endif /* __COGL_PIPELINE_LAYER_STATE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-pipeline-layer-state.c b/cogl/cogl/cogl-pipeline-layer-state.c deleted file mode 100644 index b2503148d..000000000 --- a/cogl/cogl/cogl-pipeline-layer-state.c +++ /dev/null @@ -1,1546 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-blend-string.h" -#include "cogl-util.h" -#include "cogl-snippet-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline-layer-state-private.h" - -#include "string.h" -#if 0 -#include "cogl-context-private.h" -#include "cogl-color-private.h" - -#endif - -/* - * XXX: consider special casing layer->unit_index so it's not a sparse - * property so instead we can assume it's valid for all layer - * instances. - * - We would need to initialize ->unit_index in - * _cogl_pipeline_layer_copy (). - * - * XXX: If you use this API you should consider that the given layer - * might not be writeable and so a new derived layer will be allocated - * and modified instead. The layer modified will be returned so you - * can identify when this happens. - */ -CoglPipelineLayer * -_cogl_pipeline_set_layer_unit (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - int unit_index) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_UNIT; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, change); - CoglPipelineLayer *new; - - if (authority->unit_index == unit_index) - return layer; - - new = - _cogl_pipeline_layer_pre_change_notify (required_owner, - layer, - change); - if (new != layer) - layer = new; - else - { - /* If the layer we found is currently the authority on the state - * we are changing see if we can revert to one of our ancestors - * being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->unit_index == unit_index) - { - layer->differences &= ~change; - return layer; - } - } - } - - layer->unit_index = unit_index; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - - return layer; -} - -CoglTexture * -_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - - return authority->texture; -} - -CoglTexture * -cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayer *layer = - _cogl_pipeline_get_layer (pipeline, layer_index); - return _cogl_pipeline_layer_get_texture (layer); -} - -static void -_cogl_pipeline_set_layer_texture_data (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (authority->texture == texture) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->texture == texture) - { - layer->differences &= ~change; - - if (layer->texture != NULL) - cogl_object_unref (layer->texture); - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - if (texture != NULL) - cogl_object_ref (texture); - if (layer == authority && - layer->texture != NULL) - cogl_object_unref (layer->texture); - layer->texture = texture; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture) -{ - _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture); -} - -void -cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, - int layer_index) -{ - _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, NULL); -} - -static void -_cogl_pipeline_set_layer_sampler_state (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - CoglPipelineLayer *authority, - const CoglSamplerCacheEntry *state) -{ - CoglPipelineLayer *new; - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - - if (authority->sampler_cache_entry == state) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->sampler_cache_entry == state) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->sampler_cache_entry = state; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -static CoglSamplerCacheWrapMode -public_to_internal_wrap_mode (CoglPipelineWrapMode mode) -{ - return (CoglSamplerCacheWrapMode)mode; -} - -static CoglPipelineWrapMode -internal_to_public_wrap_mode (CoglSamplerCacheWrapMode internal_mode) -{ - g_return_val_if_fail (internal_mode != - COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_BORDER, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC); - return (CoglPipelineWrapMode)internal_mode; -} - -void -cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - internal_mode, - authority->sampler_cache_entry-> - wrap_mode_t); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -void -cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - authority->sampler_cache_entry-> - wrap_mode_s, - internal_mode); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -void -cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglSamplerCacheWrapMode internal_mode = - public_to_internal_wrap_mode (mode); - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = - _cogl_sampler_cache_update_wrap_modes (ctx->sampler_cache, - authority->sampler_cache_entry, - internal_mode, - internal_mode); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -/* FIXME: deprecate this API */ -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_s (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *authority; - const CoglSamplerCacheEntry *sampler_state; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), FALSE); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = authority->sampler_cache_entry; - return internal_to_public_wrap_mode (sampler_state->wrap_mode_s); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - return _cogl_pipeline_layer_get_wrap_mode_s (layer); -} - -/* FIXME: deprecate this API */ -CoglPipelineWrapMode -_cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *authority; - const CoglSamplerCacheEntry *sampler_state; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), FALSE); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - sampler_state = authority->sampler_cache_entry; - return internal_to_public_wrap_mode (sampler_state->wrap_mode_t); -} - -CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayer *layer; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - return _cogl_pipeline_layer_get_wrap_mode_t (layer); -} - -void -_cogl_pipeline_layer_get_wrap_modes (CoglPipelineLayer *layer, - CoglSamplerCacheWrapMode *wrap_mode_s, - CoglSamplerCacheWrapMode *wrap_mode_t) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - *wrap_mode_s = authority->sampler_cache_entry->wrap_mode_s; - *wrap_mode_t = authority->sampler_cache_entry->wrap_mode_t; -} - -gboolean -cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index, - gboolean enable, - GError **error) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *layer; - CoglPipelineLayer *new; - CoglPipelineLayer *authority; - - _COGL_GET_CONTEXT (ctx, FALSE); - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - if (authority->big_state->point_sprite_coords == enable) - return TRUE; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, change); - - if (old_authority->big_state->point_sprite_coords == enable) - { - layer->differences &= ~change; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return TRUE; - } - } - } - - layer->big_state->point_sprite_coords = enable; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - - return TRUE; -} - -gboolean -cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - authority = _cogl_pipeline_layer_get_authority (layer, change); - - return authority->big_state->point_sprite_coords; -} - -static void -_cogl_pipeline_layer_add_vertex_snippet (CoglPipeline *pipeline, - int layer_index, - CoglSnippet *snippet) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; - CoglPipelineLayer *layer, *authority; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - - _cogl_pipeline_snippet_list_add (&layer->big_state->vertex_snippets, - snippet); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -static void -_cogl_pipeline_layer_add_fragment_snippet (CoglPipeline *pipeline, - int layer_index, - CoglSnippet *snippet) -{ - CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS; - CoglPipelineLayer *layer, *authority; - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, change); - - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); - - _cogl_pipeline_snippet_list_add (&layer->big_state->fragment_snippets, - snippet); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= change; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -void -cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, - int layer_index, - CoglSnippet *snippet) -{ - g_return_if_fail (cogl_is_pipeline (pipeline)); - g_return_if_fail (cogl_is_snippet (snippet)); - g_return_if_fail (snippet->hook >= COGL_SNIPPET_FIRST_LAYER_HOOK); - - if (snippet->hook < COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK) - _cogl_pipeline_layer_add_vertex_snippet (pipeline, - layer_index, - snippet); - else - _cogl_pipeline_layer_add_fragment_snippet (pipeline, - layer_index, - snippet); -} - -gboolean -_cogl_pipeline_layer_texture_data_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1, - CoglPipelineEvalFlags flags) -{ - if (authority0->texture == NULL) - { - if (authority1->texture == NULL) - return TRUE; - else - return FALSE; - } - else if (authority1->texture == NULL) - return FALSE; - else - { - GLuint gl_handle0, gl_handle1; - - cogl_texture_get_gl_texture (authority0->texture, &gl_handle0, NULL); - cogl_texture_get_gl_texture (authority1->texture, &gl_handle1, NULL); - - return gl_handle0 == gl_handle1; - } -} - -gboolean -_cogl_pipeline_layer_combine_state_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - int n_args; - int i; - - if (big_state0->texture_combine_rgb_func != - big_state1->texture_combine_rgb_func) - return FALSE; - - if (big_state0->texture_combine_alpha_func != - big_state1->texture_combine_alpha_func) - return FALSE; - - n_args = - _cogl_get_n_args_for_combine_func (big_state0->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - if ((big_state0->texture_combine_rgb_src[i] != - big_state1->texture_combine_rgb_src[i]) || - (big_state0->texture_combine_rgb_op[i] != - big_state1->texture_combine_rgb_op[i])) - return FALSE; - } - - n_args = - _cogl_get_n_args_for_combine_func (big_state0->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - if ((big_state0->texture_combine_alpha_src[i] != - big_state1->texture_combine_alpha_src[i]) || - (big_state0->texture_combine_alpha_op[i] != - big_state1->texture_combine_alpha_op[i])) - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_layer_combine_constant_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return memcmp (authority0->big_state->texture_combine_constant, - authority1->big_state->texture_combine_constant, - sizeof (float) * 4) == 0 ? TRUE : FALSE; -} - -gboolean -_cogl_pipeline_layer_sampler_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - /* We compare the actual sampler objects rather than just the entry - pointers because two states with different values can lead to the - same state in GL terms when AUTOMATIC is used as a wrap mode */ - return (authority0->sampler_cache_entry->sampler_object == - authority1->sampler_cache_entry->sampler_object); -} - -gboolean -_cogl_pipeline_layer_user_matrix_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - - if (!graphene_matrix_equal (&big_state0->matrix, &big_state1->matrix)) - return FALSE; - - return TRUE; -} - -gboolean -_cogl_pipeline_layer_point_sprite_coords_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - CoglPipelineLayerBigState *big_state0 = authority0->big_state; - CoglPipelineLayerBigState *big_state1 = authority1->big_state; - - return big_state0->point_sprite_coords == big_state1->point_sprite_coords; -} - -gboolean -_cogl_pipeline_layer_vertex_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - vertex_snippets, - &authority1->big_state-> - vertex_snippets); -} - -gboolean -_cogl_pipeline_layer_fragment_snippets_equal (CoglPipelineLayer *authority0, - CoglPipelineLayer *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - fragment_snippets, - &authority1->big_state-> - fragment_snippets); -} - -static void -setup_texture_combine_state (CoglBlendStringStatement *statement, - CoglPipelineCombineFunc *texture_combine_func, - CoglPipelineCombineSource *texture_combine_src, - CoglPipelineCombineOp *texture_combine_op) -{ - int i; - - switch (statement->function->type) - { - case COGL_BLEND_STRING_FUNCTION_REPLACE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_REPLACE; - break; - case COGL_BLEND_STRING_FUNCTION_MODULATE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_MODULATE; - break; - case COGL_BLEND_STRING_FUNCTION_ADD: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_ADD; - break; - case COGL_BLEND_STRING_FUNCTION_ADD_SIGNED: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED; - break; - case COGL_BLEND_STRING_FUNCTION_INTERPOLATE: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE; - break; - case COGL_BLEND_STRING_FUNCTION_SUBTRACT: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_SUBTRACT; - break; - case COGL_BLEND_STRING_FUNCTION_DOT3_RGB: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB; - break; - case COGL_BLEND_STRING_FUNCTION_DOT3_RGBA: - *texture_combine_func = COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA; - break; - } - - for (i = 0; i < statement->function->argc; i++) - { - CoglBlendStringArgument *arg = &statement->args[i]; - - switch (arg->source.info->type) - { - case COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_CONSTANT; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_TEXTURE_N: - texture_combine_src[i] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0 + arg->source.texture; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_PRIMARY: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR; - break; - case COGL_BLEND_STRING_COLOR_SOURCE_PREVIOUS: - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - break; - default: - g_warning ("Unexpected texture combine source"); - texture_combine_src[i] = COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - } - - if (arg->source.mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) - { - if (statement->args[i].source.one_minus) - texture_combine_op[i] = - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR; - else - texture_combine_op[i] = COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - } - else - { - if (statement->args[i].source.one_minus) - texture_combine_op[i] = - COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA; - else - texture_combine_op[i] = COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - } - } -} - -gboolean -cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, - int layer_index, - const char *combine_description, - GError **error) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE; - CoglPipelineLayer *authority; - CoglPipelineLayer *layer; - CoglBlendStringStatement statements[2]; - CoglBlendStringStatement split[2]; - CoglBlendStringStatement *rgb; - CoglBlendStringStatement *a; - int count; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - count = - _cogl_blend_string_compile (combine_description, - COGL_BLEND_STRING_CONTEXT_TEXTURE_COMBINE, - statements, - error); - if (!count) - return FALSE; - - if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGBA) - { - _cogl_blend_string_split_rgba_statement (statements, - &split[0], &split[1]); - rgb = &split[0]; - a = &split[1]; - } - else - { - rgb = &statements[0]; - a = &statements[1]; - } - - /* FIXME: compare the new state with the current state! */ - - /* possibly flush primitives referencing the current state... */ - layer = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - - setup_texture_combine_state (rgb, - &layer->big_state->texture_combine_rgb_func, - layer->big_state->texture_combine_rgb_src, - layer->big_state->texture_combine_rgb_op); - - setup_texture_combine_state (a, - &layer->big_state->texture_combine_alpha_func, - layer->big_state->texture_combine_alpha_src, - layer->big_state->texture_combine_alpha_op); - - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (_cogl_pipeline_layer_combine_state_equal (authority, - old_authority)) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; - return TRUE; -} - -void -cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - const CoglColor *constant_color) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - float color_as_floats[4]; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - color_as_floats[0] = cogl_color_get_red_float (constant_color); - color_as_floats[1] = cogl_color_get_green_float (constant_color); - color_as_floats[2] = cogl_color_get_blue_float (constant_color); - color_as_floats[3] = cogl_color_get_alpha_float (constant_color); - - if (memcmp (authority->big_state->texture_combine_constant, - color_as_floats, sizeof (float) * 4) == 0) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - CoglPipelineLayerBigState *old_big_state = old_authority->big_state; - - if (memcmp (old_big_state->texture_combine_constant, - color_as_floats, sizeof (float) * 4) == 0) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - goto changed; - } - } - } - - memcpy (layer->big_state->texture_combine_constant, - color_as_floats, - sizeof (color_as_floats)); - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } - -changed: - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - float *constant) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - /* FIXME: we shouldn't ever construct a layer in a getter function */ - - authority = _cogl_pipeline_layer_get_authority (layer, change); - memcpy (constant, authority->big_state->texture_combine_constant, - sizeof (float) * 4); -} - -/* We should probably make a public API version of this that has a - matrix out-param. For an internal API it's good to be able to avoid - copying the matrix */ -const graphene_matrix_t * -_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, int layer_index) -{ - CoglPipelineLayerState change = - COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = _cogl_pipeline_layer_get_authority (layer, change); - return &authority->big_state->matrix; -} - -void -cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, - int layer_index, - const graphene_matrix_t *matrix) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_USER_MATRIX; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - CoglPipelineLayer *new; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - if (graphene_matrix_equal (matrix, &authority->big_state->matrix)) - return; - - new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, state); - if (new != layer) - layer = new; - else - { - /* If the original layer we found is currently the authority on - * the state we are changing see if we can revert to one of our - * ancestors being the authority. */ - if (layer == authority && - _cogl_pipeline_layer_get_parent (authority) != NULL) - { - CoglPipelineLayer *parent = - _cogl_pipeline_layer_get_parent (authority); - CoglPipelineLayer *old_authority = - _cogl_pipeline_layer_get_authority (parent, state); - - if (graphene_matrix_equal (matrix, &old_authority->big_state->matrix)) - { - layer->differences &= ~state; - - g_assert (layer->owner == pipeline); - if (layer->differences == 0) - _cogl_pipeline_prune_empty_layer_difference (pipeline, - layer); - return; - } - } - } - - layer->big_state->matrix = *matrix; - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (layer != authority) - { - layer->differences |= state; - _cogl_pipeline_layer_prune_redundant_ancestry (layer); - } -} - -CoglTexture * -_cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer) -{ - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), NULL); - - return _cogl_pipeline_layer_get_texture_real (layer); -} - -gboolean -_cogl_pipeline_layer_has_user_matrix (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_USER_MATRIX); - - /* If the authority is the default pipeline then no, otherwise yes */ - return _cogl_pipeline_layer_get_parent (authority) ? TRUE : FALSE; -} - -void -_cogl_pipeline_layer_get_filters (CoglPipelineLayer *layer, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - *min_filter = authority->sampler_cache_entry->min_filter; - *mag_filter = authority->sampler_cache_entry->mag_filter; -} - -void -_cogl_pipeline_get_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter *min_filter, - CoglPipelineFilter *mag_filter) -{ - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - *min_filter = authority->sampler_cache_entry->min_filter; - *mag_filter = authority->sampler_cache_entry->mag_filter; -} - -CoglPipelineFilter -cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_get_layer_filters (pipeline, layer_index, - &min_filter, &mag_filter); - return min_filter; -} - -CoglPipelineFilter -cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_get_layer_filters (pipeline, layer_index, - &min_filter, &mag_filter); - return mag_filter; -} - -CoglPipelineFilter -_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), 0); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - return authority->sampler_cache_entry->min_filter; -} - -CoglPipelineFilter -_cogl_pipeline_layer_get_mag_filter (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority; - - g_return_val_if_fail (_cogl_is_pipeline_layer (layer), 0); - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - return authority->sampler_cache_entry->mag_filter; -} - -void -cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter min_filter, - CoglPipelineFilter mag_filter) -{ - CoglPipelineLayerState state = COGL_PIPELINE_LAYER_STATE_SAMPLER; - CoglPipelineLayer *layer; - CoglPipelineLayer *authority; - const CoglSamplerCacheEntry *sampler_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - g_return_if_fail (mag_filter == COGL_PIPELINE_FILTER_NEAREST || - mag_filter == COGL_PIPELINE_FILTER_LINEAR); - - /* Note: this will ensure that the layer exists, creating one if it - * doesn't already. - * - * Note: If the layer already existed it's possibly owned by another - * pipeline. If the layer is created then it will be owned by - * pipeline. */ - layer = _cogl_pipeline_get_layer (pipeline, layer_index); - - /* Now find the ancestor of the layer that is the authority for the - * state we want to change */ - authority = _cogl_pipeline_layer_get_authority (layer, state); - - sampler_state = - _cogl_sampler_cache_update_filters (ctx->sampler_cache, - authority->sampler_cache_entry, - min_filter, - mag_filter); - _cogl_pipeline_set_layer_sampler_state (pipeline, - layer, - authority, - sampler_state); -} - -void -cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline, - int layer, - int max_level) -{ - CoglTexture *texture = cogl_pipeline_get_layer_texture (pipeline, layer); - - if (texture != NULL) - cogl_texture_set_max_level (texture, max_level); -} - -const CoglSamplerCacheEntry * -_cogl_pipeline_layer_get_sampler_state (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority; - - authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_SAMPLER); - - return authority->sampler_cache_entry; -} - -void -_cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - int unit = authority->unit_index; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &unit, sizeof (unit)); -} - -void -_cogl_pipeline_layer_hash_texture_data_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - GLuint gl_handle; - - cogl_texture_get_gl_texture (authority->texture, &gl_handle, NULL); - - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &gl_handle, sizeof (gl_handle)); -} - -void -_cogl_pipeline_layer_hash_sampler_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, - &authority->sampler_cache_entry, - sizeof (authority->sampler_cache_entry)); -} - -void -_cogl_pipeline_layer_hash_combine_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - unsigned int hash = state->hash; - CoglPipelineLayerBigState *b = authority->big_state; - int n_args; - int i; - - hash = _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_func, - sizeof (b->texture_combine_rgb_func)); - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_src[i], - sizeof (b->texture_combine_rgb_src[i])); - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_rgb_op[i], - sizeof (b->texture_combine_rgb_op[i])); - } - - hash = _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_func, - sizeof (b->texture_combine_alpha_func)); - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_src[i], - sizeof (b->texture_combine_alpha_src[i])); - hash = - _cogl_util_one_at_a_time_hash (hash, &b->texture_combine_alpha_op[i], - sizeof (b->texture_combine_alpha_op[i])); - } - - state->hash = hash; -} - -void -_cogl_pipeline_layer_hash_combine_constant_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglPipelineLayerBigState *b = authority->big_state; - gboolean need_hash = FALSE; - int n_args; - int i; - - /* XXX: If the user also asked to hash the ALPHA_FUNC_STATE then it - * would be nice if we could combine the n_args loops in this - * function and _cogl_pipeline_layer_hash_combine_state. - */ - - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_rgb_func); - for (i = 0; i < n_args; i++) - { - if (b->texture_combine_rgb_src[i] == - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT) - { - /* XXX: should we be careful to only hash the alpha - * component in the COGL_PIPELINE_COMBINE_OP_SRC_ALPHA case? */ - need_hash = TRUE; - goto done; - } - } - - n_args = _cogl_get_n_args_for_combine_func (b->texture_combine_alpha_func); - for (i = 0; i < n_args; i++) - { - if (b->texture_combine_alpha_src[i] == - COGL_PIPELINE_COMBINE_SOURCE_CONSTANT) - { - /* XXX: should we be careful to only hash the alpha - * component in the COGL_PIPELINE_COMBINE_OP_SRC_ALPHA case? */ - need_hash = TRUE; - goto done; - } - } - -done: - if (need_hash) - { - float *constant = b->texture_combine_constant; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, constant, - sizeof (float) * 4); - } -} - -void -_cogl_pipeline_layer_hash_user_matrix_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglPipelineLayerBigState *big_state = authority->big_state; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &big_state->matrix, - sizeof (float) * 16); -} - -void -_cogl_pipeline_layer_hash_point_sprite_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - CoglPipelineLayerBigState *big_state = authority->big_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &big_state->point_sprite_coords, - sizeof (big_state->point_sprite_coords)); -} - -void -_cogl_pipeline_layer_hash_vertex_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->vertex_snippets, - &state->hash); -} - -void -_cogl_pipeline_layer_hash_fragment_snippets_state (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->fragment_snippets, - &state->hash); -} diff --git a/cogl/cogl/cogl-pipeline-layer-state.h b/cogl/cogl/cogl-pipeline-layer-state.h deleted file mode 100644 index 13bc46578..000000000 --- a/cogl/cogl/cogl-pipeline-layer-state.h +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PIPELINE_LAYER_STATE_H__ -#define __COGL_PIPELINE_LAYER_STATE_H__ - -#include <cogl/cogl-pipeline.h> -#include <cogl/cogl-color.h> -#include <cogl/cogl-texture.h> - -G_BEGIN_DECLS - -/** - * CoglPipelineFilter: - * @COGL_PIPELINE_FILTER_NEAREST: Measuring in manhatten distance from the, - * current pixel center, use the nearest texture texel - * @COGL_PIPELINE_FILTER_LINEAR: Use the weighted average of the 4 texels - * nearest the current pixel center - * @COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_PIPELINE_FILTER_NEAREST criterion - * @COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_PIPELINE_FILTER_LINEAR criterion - * @COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_PIPELINE_FILTER_NEAREST criterion on each one and take - * their weighted average - * @COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_PIPELINE_FILTER_LINEAR criterion on each one and take - * their weighted average - * - * Texture filtering is used whenever the current pixel maps either to more - * than one texture element (texel) or less than one. These filter enums - * correspond to different strategies used to come up with a pixel color, by - * possibly referring to multiple neighbouring texels and taking a weighted - * average or simply using the nearest texel. - */ -typedef enum -{ - COGL_PIPELINE_FILTER_NEAREST = 0x2600, - COGL_PIPELINE_FILTER_LINEAR = 0x2601, - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701, - COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702, - COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703 -} CoglPipelineFilter; -/* NB: these values come from the equivalents in gl.h */ - -/** - * CoglPipelineWrapMode: - * @COGL_PIPELINE_WRAP_MODE_REPEAT: The texture will be repeated. This - * is useful for example to draw a tiled background. - * @COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE: The coordinates outside the - * range 0→1 will sample copies of the edge pixels of the - * texture. This is useful to avoid artifacts if only one copy of - * the texture is being rendered. - * @COGL_PIPELINE_WRAP_MODE_AUTOMATIC: Cogl will try to automatically - * decide which of the above two to use. For cogl_rectangle(), it - * will use repeat mode if any of the texture coordinates are - * outside the range 0→1, otherwise it will use clamp to edge. For - * cogl_polygon() it will always use repeat mode. For - * cogl_vertex_buffer_draw() it will use repeat mode except for - * layers that have point sprite coordinate generation enabled. This - * is the default value. - * - * The wrap mode specifies what happens when texture coordinates - * outside the range 0→1 are used. Note that if the filter mode is - * anything but %COGL_PIPELINE_FILTER_NEAREST then texels outside the - * range 0→1 might be used even when the coordinate is exactly 0 or 1 - * because OpenGL will try to sample neighbouring pixels. For example - * if you are trying to render the full texture then you may get - * artifacts around the edges when the pixels from the other side are - * merged in if the wrap mode is set to repeat. - * - * Since: 2.0 - */ -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes - * - * XXX: keep the values in sync with the CoglPipelineWrapModeInternal - * enum so no conversion is actually needed. - */ -typedef enum -{ - COGL_PIPELINE_WRAP_MODE_REPEAT = 0x2901, - COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT = 0x8370, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, - COGL_PIPELINE_WRAP_MODE_AUTOMATIC = 0x0207 /* GL_ALWAYS */ -} CoglPipelineWrapMode; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_pipeline_set_layer: - * @pipeline: A #CoglPipeline object - * @layer_index: the index of the layer - * @texture: a #CoglTexture for the layer object - * - * In addition to the standard OpenGL lighting model a Cogl pipeline may have - * one or more layers comprised of textures that can be blended together in - * order, with a number of different texture combine modes. This function - * defines a new texture layer. - * - * The index values of multiple layers do not have to be consecutive; it is - * only their relative order that is important. - * - * The @texture parameter can also be %NULL in which case the pipeline - * will use a default white texture. The type of the default texture - * will be the same as whatever texture was last used for the pipeline - * or %COGL_TEXTURE_TYPE_2D if none has been specified yet. To - * explicitly specify the type of default texture required, use - * cogl_pipeline_set_layer_null_texture() instead. - * - * <note>In the future, we may define other types of pipeline layers, such - * as purely GLSL based layers.</note> - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture); - -/** - * cogl_pipeline_set_layer_null_texture: - * @pipeline: A #CoglPipeline - * @layer_index: The layer number to modify - * - * Sets the texture for this layer to be the default texture for the - * given type. The default texture is a 1x1 pixel white texture. - * - * This function is mostly useful if you want to create a base - * pipeline that you want to create multiple copies from using - * cogl_pipeline_copy(). In that case this function can be used to - * specify the texture type so that any pipeline copies can share the - * internal texture type state for efficiency. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_null_texture (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_get_layer_texture: - * @pipeline: A #CoglPipeline object - * @layer_index: the index of the layer - * - * Return value: (transfer none): the texture that was set for the - * given layer of the pipeline or %NULL if no texture was set. - * Stability: unstable - * Since: 1.10 - */ -COGL_EXPORT CoglTexture * -cogl_pipeline_get_layer_texture (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_remove_layer: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want to remove - * - * This function removes a layer from your pipeline - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_remove_layer (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_combine: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want define a combine function for - * @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link> - * describing the desired texture combine function. - * @error: A #GError that may report parse errors or lack of GPU/driver - * support. May be %NULL, in which case a warning will be printed out if an - * error is encountered. - * - * If not already familiar; you can refer - * <link linkend="cogl-Blend-Strings">here</link> for an overview of what blend - * strings are and there syntax. - * - * These are all the functions available for texture combining: - * <itemizedlist> - * <listitem>REPLACE(arg0) = arg0</listitem> - * <listitem>MODULATE(arg0, arg1) = arg0 x arg1</listitem> - * <listitem>ADD(arg0, arg1) = arg0 + arg1</listitem> - * <listitem>ADD_SIGNED(arg0, arg1) = arg0 + arg1 - 0.5</listitem> - * <listitem>INTERPOLATE(arg0, arg1, arg2) = arg0 x arg2 + arg1 x (1 - arg2)</listitem> - * <listitem>SUBTRACT(arg0, arg1) = arg0 - arg1</listitem> - * <listitem> - * <programlisting> - * DOT3_RGB(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * </programlisting> - * </listitem> - * <listitem> - * <programlisting> - * DOT3_RGBA(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * </programlisting> - * </listitem> - * </itemizedlist> - * - * Refer to the - * <link linkend="cogl-Blend-String-syntax">color-source syntax</link> for - * describing the arguments. The valid source names for texture combining - * are: - * <variablelist> - * <varlistentry> - * <term>TEXTURE</term> - * <listitem>Use the color from the current texture layer</listitem> - * </varlistentry> - * <varlistentry> - * <term>TEXTURE_0, TEXTURE_1, etc</term> - * <listitem>Use the color from the specified texture layer</listitem> - * </varlistentry> - * <varlistentry> - * <term>CONSTANT</term> - * <listitem>Use the color from the constant given with - * cogl_pipeline_set_layer_combine_constant()</listitem> - * </varlistentry> - * <varlistentry> - * <term>PRIMARY</term> - * <listitem>Use the color of the pipeline as set with - * cogl_pipeline_set_color()</listitem> - * </varlistentry> - * <varlistentry> - * <term>PREVIOUS</term> - * <listitem>Either use the texture color from the previous layer, or - * if this is layer 0, use the color of the pipeline as set with - * cogl_pipeline_set_color()</listitem> - * </varlistentry> - * </variablelist> - * - * <refsect2 id="cogl-Layer-Combine-Examples"> - * <title>Layer Combine Examples</title> - * <para>This is effectively what the default blending is:</para> - * <informalexample><programlisting> - * RGBA = MODULATE (PREVIOUS, TEXTURE) - * </programlisting></informalexample> - * <para>This could be used to cross-fade between two images, using - * the alpha component of a constant as the interpolator. The constant - * color is given by calling - * cogl_pipeline_set_layer_combine_constant().</para> - * <informalexample><programlisting> - * RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A]) - * </programlisting></informalexample> - * </refsect2> - * - * <note>You can't give a multiplication factor for arguments as you can - * with blending.</note> - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described texture combining is supported by the underlying driver and - * or hardware. On failure, %FALSE is returned and @error is set - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_pipeline_set_layer_combine (CoglPipeline *pipeline, - int layer_index, - const char *blend_string, - GError **error); - -/** - * cogl_pipeline_set_layer_combine_constant: - * @pipeline: A #CoglPipeline object - * @layer_index: Specifies the layer you want to specify a constant used - * for texture combining - * @constant: The constant color you want - * - * When you are using the 'CONSTANT' color source in a layer combine - * description then you can use this function to define its value. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - const CoglColor *constant); - -/** - * cogl_pipeline_set_layer_matrix: - * @pipeline: A #CoglPipeline object - * @layer_index: the index for the layer inside @pipeline - * @matrix: the transformation matrix for the layer - * - * This function lets you set a matrix that can be used to e.g. translate - * and rotate a single layer of a pipeline used to fill your geometry. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_matrix (CoglPipeline *pipeline, - int layer_index, - const graphene_matrix_t *matrix); - -/** - * cogl_pipeline_get_n_layers: - * @pipeline: A #CoglPipeline object - * - * Retrieves the number of layers defined for the given @pipeline - * - * Return value: the number of layers - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT int -cogl_pipeline_get_n_layers (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_layer_filters: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @min_filter: the filter used when scaling a texture down. - * @mag_filter: the filter used when magnifying a texture. - * - * Changes the decimation and interpolation filters used when a texture is - * drawn at other scales than 100%. - * - * <note>It is an error to pass anything other than - * %COGL_PIPELINE_FILTER_NEAREST or %COGL_PIPELINE_FILTER_LINEAR as - * magnification filters since magnification doesn't ever need to - * reference values stored in the mipmap chain.</note> - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_filters (CoglPipeline *pipeline, - int layer_index, - CoglPipelineFilter min_filter, - CoglPipelineFilter mag_filter); - -/** - * cogl_pipeline_get_layer_min_filter: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Retrieves the currently set minification #CoglPipelineFilter set on - * the specified layer. The miniifcation filter determines how the - * layer should be sampled when down-scaled. - * - * The default filter is %COGL_PIPELINE_FILTER_LINEAR but this can be - * changed using cogl_pipeline_set_layer_filters(). - * - * Return value: The minification #CoglPipelineFilter for the - * specified layer. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglPipelineFilter -cogl_pipeline_get_layer_min_filter (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_get_layer_mag_filter: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Retrieves the currently set magnification #CoglPipelineFilter set on - * the specified layer. The magnification filter determines how the - * layer should be sampled when up-scaled. - * - * The default filter is %COGL_PIPELINE_FILTER_LINEAR but this can be - * changed using cogl_pipeline_set_layer_filters(). - * - * Return value: The magnification #CoglPipelineFilter for the - * specified layer. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglPipelineFilter -cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_point_sprite_coords_enabled: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @enable: whether to enable point sprite coord generation. - * @error: A return location for a #GError, or NULL to ignore errors. - * - * When rendering points, if @enable is %TRUE then the texture - * coordinates for this layer will be replaced with coordinates that - * vary from 0.0 to 1.0 across the primitive. The top left of the - * point will have the coordinates 0.0,0.0 and the bottom right will - * have 1.0,1.0. If @enable is %FALSE then the coordinates will be - * fixed for the entire point. - * - * Return value: %TRUE if the function succeeds, %FALSE otherwise. - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_pipeline_set_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index, - gboolean enable, - GError **error); - -/** - * cogl_pipeline_get_layer_point_sprite_coords_enabled: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to check. - * - * Gets whether point sprite coordinate generation is enabled for this - * texture layer. - * - * Return value: whether the texture coordinates will be replaced with - * point sprite coordinates. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_pipeline_get_layer_point_sprite_coords_enabled (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_get_layer_wrap_mode_s: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 's' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 's' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - * Stability: unstable - */ -COGL_EXPORT CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index); - -/** - * cogl_pipeline_set_layer_wrap_mode_s: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 's' coordinate of texture lookups on this layer. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_wrap_mode_s (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_get_layer_wrap_mode_t: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * - * Returns the wrap mode for the 't' coordinate of texture lookups on this - * layer. - * - * Return value: the wrap mode for the 't' coordinate of texture lookups on - * this layer. - * - * Since: 1.6 - * Stability: unstable - */ -COGL_EXPORT CoglPipelineWrapMode -cogl_pipeline_get_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index); - - -/** - * cogl_pipeline_set_layer_wrap_mode_t: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for the 't' coordinate of texture lookups on this layer. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_wrap_mode_t (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_set_layer_wrap_mode: - * @pipeline: A #CoglPipeline object - * @layer_index: the layer number to change. - * @mode: the new wrap mode - * - * Sets the wrap mode for all three coordinates of texture lookups on - * this layer. This is equivalent to calling - * cogl_pipeline_set_layer_wrap_mode_s() and - * cogl_pipeline_set_layer_wrap_mode_t() separately. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_pipeline_set_layer_wrap_mode (CoglPipeline *pipeline, - int layer_index, - CoglPipelineWrapMode mode); - -/** - * cogl_pipeline_add_layer_snippet: (skip) - * @pipeline: A #CoglPipeline - * @layer: The layer to hook the snippet to - * @snippet: A #CoglSnippet - * - * Adds a shader snippet that will hook on to the given layer of the - * pipeline. The exact part of the pipeline that the snippet wraps - * around depends on the hook that is given to - * cogl_snippet_new(). Note that some hooks can't be used with a layer - * and need to be added with cogl_pipeline_add_snippet() instead. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline, - int layer, - CoglSnippet *snippet); - -COGL_EXPORT void -cogl_pipeline_set_layer_max_mipmap_level (CoglPipeline *pipeline, - int layer, - int max_level); - -G_END_DECLS - -#endif /* __COGL_PIPELINE_LAYER_STATE_H__ */ diff --git a/cogl/cogl/cogl-pipeline-layer.c b/cogl/cogl/cogl-pipeline-layer.c deleted file mode 100644 index 698f7f14a..000000000 --- a/cogl/cogl/cogl-pipeline-layer.c +++ /dev/null @@ -1,908 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" - -#include "cogl-pipeline.h" -#include "cogl-pipeline-layer-private.h" -#include "cogl-pipeline-layer-state-private.h" -#include "cogl-pipeline-layer-state.h" -#include "cogl-node-private.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" - -#include <string.h> - -static void -_cogl_pipeline_layer_free (CoglPipelineLayer *layer); - -/* This type was made deprecated before the cogl_is_pipeline_layer - function was ever exposed in the public headers so there's no need - to make the cogl_is_pipeline_layer function public. We use INTERNAL - so that the cogl_is_* function won't get defined */ -COGL_OBJECT_INTERNAL_DEFINE (PipelineLayer, pipeline_layer); - - -CoglPipelineLayer * -_cogl_pipeline_layer_get_authority (CoglPipelineLayer *layer, - unsigned long difference) -{ - CoglPipelineLayer *authority = layer; - while (!(authority->differences & difference)) - authority = _cogl_pipeline_layer_get_parent (authority); - return authority; -} - -int -_cogl_pipeline_layer_get_unit_index (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, COGL_PIPELINE_LAYER_STATE_UNIT); - return authority->unit_index; -} - -gboolean -_cogl_pipeline_layer_has_alpha (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - CoglPipelineLayer *tex_authority; - CoglPipelineLayer *snippets_authority; - - /* has_alpha maintains the alpha status for the GL_PREVIOUS layer */ - - /* For anything but the default texture combine we currently just - * assume it may result in an alpha value < 1 - * - * FIXME: we could do better than this. */ - if (big_state->texture_combine_alpha_func != - COGL_PIPELINE_COMBINE_FUNC_MODULATE || - big_state->texture_combine_alpha_src[0] != - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS || - big_state->texture_combine_alpha_op[0] != - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA || - big_state->texture_combine_alpha_src[1] != - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE || - big_state->texture_combine_alpha_op[1] != - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA) - { - return TRUE; - } - - /* NB: A layer may have a combine mode set on it but not yet - * have an associated texture which would mean we'd fallback - * to the default texture which doesn't have an alpha component - */ - tex_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - if (tex_authority->texture && - _cogl_texture_get_format (tex_authority->texture) & COGL_A_BIT) - { - return TRUE; - } - - /* All bets are off if the layer contains any snippets */ - snippets_authority = _cogl_pipeline_layer_get_authority - (layer, COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS); - if (snippets_authority->big_state->vertex_snippets.entries != NULL) - return TRUE; - snippets_authority = _cogl_pipeline_layer_get_authority - (layer, COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); - if (snippets_authority->big_state->fragment_snippets.entries != NULL) - return TRUE; - - return FALSE; -} - -unsigned int -_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func) -{ - switch (func) - { - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - return 1; - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - case COGL_PIPELINE_COMBINE_FUNC_ADD: - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - return 2; - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - return 3; - } - return 0; -} - -void -_cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest, - CoglPipelineLayer *src, - unsigned long differences) -{ - CoglPipelineLayerBigState *big_dest, *big_src; - - if ((differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE) && - !dest->has_big_state) - { - dest->big_state = g_new0 (CoglPipelineLayerBigState, 1); - dest->has_big_state = TRUE; - } - - big_dest = dest->big_state; - big_src = src->big_state; - - dest->differences |= differences; - - while (differences) - { - int index = ffs (differences) - 1; - - differences &= ~(1 << index); - - /* This convoluted switch statement is just here so that we'll - * get a warning if a new state is added without handling it - * here */ - switch (index) - { - case COGL_PIPELINE_LAYER_STATE_COUNT: - case COGL_PIPELINE_LAYER_STATE_UNIT_INDEX: - g_warn_if_reached (); - break; - - case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX: - dest->texture = src->texture; - if (dest->texture) - cogl_object_ref (dest->texture); - break; - - case COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX: - dest->sampler_cache_entry = src->sampler_cache_entry; - break; - - case COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX: - { - CoglPipelineCombineFunc func; - int n_args, i; - - func = big_src->texture_combine_rgb_func; - big_dest->texture_combine_rgb_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - big_dest->texture_combine_rgb_src[i] = - big_src->texture_combine_rgb_src[i]; - big_dest->texture_combine_rgb_op[i] = - big_src->texture_combine_rgb_op[i]; - } - - func = big_src->texture_combine_alpha_func; - big_dest->texture_combine_alpha_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - big_dest->texture_combine_alpha_src[i] = - big_src->texture_combine_alpha_src[i]; - big_dest->texture_combine_alpha_op[i] = - big_src->texture_combine_alpha_op[i]; - } - } - break; - - case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX: - memcpy (big_dest->texture_combine_constant, - big_src->texture_combine_constant, - sizeof (big_dest->texture_combine_constant)); - break; - - case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX: - big_dest->point_sprite_coords = big_src->point_sprite_coords; - break; - - case COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX: - _cogl_pipeline_snippet_list_copy (&big_dest->vertex_snippets, - &big_src->vertex_snippets); - break; - - case COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX: - _cogl_pipeline_snippet_list_copy (&big_dest->fragment_snippets, - &big_src->fragment_snippets); - break; - } - } -} - -static void -_cogl_pipeline_layer_init_multi_property_sparse_state ( - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineLayer *authority; - - /* Nothing to initialize in these cases since they are all comprised - * of one member which we expect to immediately be overwritten. */ - if (!(change & COGL_PIPELINE_LAYER_STATE_MULTI_PROPERTY)) - return; - - authority = _cogl_pipeline_layer_get_authority (layer, change); - - switch (change) - { - /* XXX: avoid using a default: label so we get a warning if we - * don't explicitly handle a newly defined state-group here. */ - case COGL_PIPELINE_LAYER_STATE_UNIT: - case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA: - case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS: - case COGL_PIPELINE_LAYER_STATE_USER_MATRIX: - case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT: - case COGL_PIPELINE_LAYER_STATE_SAMPLER: - g_return_if_reached (); - - /* XXX: technically we could probably even consider these as - * single property state-groups from the pov that currently the - * corresponding property setters always update all of the values - * at the same time. */ - case COGL_PIPELINE_LAYER_STATE_COMBINE: - { - int n_args; - int i; - CoglPipelineLayerBigState *src_big_state = authority->big_state; - CoglPipelineLayerBigState *dest_big_state = layer->big_state; - GLint func = src_big_state->texture_combine_rgb_func; - - dest_big_state->texture_combine_rgb_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - dest_big_state->texture_combine_rgb_src[i] = - src_big_state->texture_combine_rgb_src[i]; - dest_big_state->texture_combine_rgb_op[i] = - src_big_state->texture_combine_rgb_op[i]; - } - - func = src_big_state->texture_combine_alpha_func; - dest_big_state->texture_combine_alpha_func = func; - n_args = _cogl_get_n_args_for_combine_func (func); - for (i = 0; i < n_args; i++) - { - dest_big_state->texture_combine_alpha_src[i] = - src_big_state->texture_combine_alpha_src[i]; - dest_big_state->texture_combine_alpha_op[i] = - src_big_state->texture_combine_alpha_op[i]; - } - break; - } - case COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&layer->big_state->vertex_snippets, - &authority->big_state-> - vertex_snippets); - break; - case COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&layer->big_state->fragment_snippets, - &authority->big_state-> - fragment_snippets); - break; - } -} - -/* NB: If a layer has descendants we can't modify the layer - * NB: If the layer is owned and the owner has descendants we can't - * modify the layer. - * - * This function will allocate a new derived layer if you are trying - * to change the state of a layer with dependants (as described above) - * so you must always check the return value. - * - * If a new layer is returned it will be owned by required_owner. - * (NB: a layer is always modified with respect to a pipeline - the - * "required_owner") - * - * required_owner can only by NULL for new, currently unowned layers - * with no dependants. - */ -CoglPipelineLayer * -_cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - /* Identify the case where the layer is new with no owner or - * dependants and so we don't need to do anything. */ - if (_cogl_list_empty (&COGL_NODE (layer)->children) && - layer->owner == NULL) - goto init_layer_state; - - /* We only allow a NULL required_owner for new layers */ - g_return_val_if_fail (required_owner != NULL, layer); - - /* Chain up: - * A modification of a layer is indirectly also a modification of - * its owner so first make sure to flush the journal of any - * references to the current owner state and if necessary perform - * a copy-on-write for the required_owner if it has dependants. - */ - _cogl_pipeline_pre_change_notify (required_owner, - COGL_PIPELINE_STATE_LAYERS, - NULL, - TRUE); - - /* Unlike pipelines; layers are simply considered immutable once - * they have dependants - either direct children, or another - * pipeline as an owner. - */ - if (!_cogl_list_empty (&COGL_NODE (layer)->children) || - layer->owner != required_owner) - { - CoglPipelineLayer *new = _cogl_pipeline_layer_copy (layer); - if (layer->owner == required_owner) - _cogl_pipeline_remove_layer_difference (required_owner, layer, FALSE); - _cogl_pipeline_add_layer_difference (required_owner, new, FALSE); - cogl_object_unref (new); - layer = new; - goto init_layer_state; - } - - /* Note: At this point we know there is only one pipeline dependent on - * this layer (required_owner), and there are no other layers - * dependent on this layer so it's ok to modify it. */ - - /* NB: Although layers can have private state associated with them - * by multiple backends we know that a layer can't be *changed* if - * it has multiple dependants so if we reach here we know we only - * have a single owner and can only be associated with a single - * backend that needs to be notified of the layer change... - */ - { - const CoglPipelineProgend *progend = _cogl_pipeline_progend; - const CoglPipelineFragend *fragend = _cogl_pipeline_fragend; - const CoglPipelineVertend *vertend = _cogl_pipeline_vertend; - - if (fragend->layer_pre_change_notify) - fragend->layer_pre_change_notify (required_owner, layer, change); - if (vertend->layer_pre_change_notify) - vertend->layer_pre_change_notify (required_owner, layer, change); - if (progend->layer_pre_change_notify) - progend->layer_pre_change_notify (required_owner, layer, change); - } - -init_layer_state: - - if (required_owner) - required_owner->age++; - - if (change & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE && - !layer->has_big_state) - { - layer->big_state = g_new0 (CoglPipelineLayerBigState, 1); - layer->has_big_state = TRUE; - } - - /* Note: conceptually we have just been notified that a single - * property value is about to change, but since some state-groups - * contain multiple properties and 'layer' is about to take over - * being the authority for the property's corresponding state-group - * we need to maintain the integrity of the other property values - * too. - * - * To ensure this we handle multi-property state-groups by copying - * all the values from the old-authority to the new... - * - * We don't have to worry about non-sparse property groups since - * we never take over being an authority for such properties so - * they automatically maintain integrity. - */ - if (change & COGL_PIPELINE_LAYER_STATE_ALL_SPARSE && - !(layer->differences & change)) - { - _cogl_pipeline_layer_init_multi_property_sparse_state (layer, change); - layer->differences |= change; - } - - return layer; -} - -static void -_cogl_pipeline_layer_unparent (CoglNode *layer) -{ - /* Chain up */ - _cogl_pipeline_node_unparent_real (layer); -} - -static void -_cogl_pipeline_layer_set_parent (CoglPipelineLayer *layer, - CoglPipelineLayer *parent) -{ - /* Chain up */ - _cogl_pipeline_node_set_parent_real (COGL_NODE (layer), - COGL_NODE (parent), - _cogl_pipeline_layer_unparent, - TRUE); -} - -CoglPipelineLayer * -_cogl_pipeline_layer_copy (CoglPipelineLayer *src) -{ - CoglPipelineLayer *layer = g_new0 (CoglPipelineLayer, 1); - - _cogl_pipeline_node_init (COGL_NODE (layer)); - - layer->owner = NULL; - layer->index = src->index; - layer->differences = 0; - layer->has_big_state = FALSE; - - _cogl_pipeline_layer_set_parent (layer, src); - - return _cogl_pipeline_layer_object_new (layer); -} - -/* XXX: This is duplicated logic; the same as for - * _cogl_pipeline_prune_redundant_ancestry it would be nice to find a - * way to consolidate these functions! */ -void -_cogl_pipeline_layer_prune_redundant_ancestry (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *new_parent = _cogl_pipeline_layer_get_parent (layer); - - /* walk up past ancestors that are now redundant and potentially - * reparent the layer. */ - while (_cogl_pipeline_layer_get_parent (new_parent) && - (new_parent->differences | layer->differences) == - layer->differences) - new_parent = _cogl_pipeline_layer_get_parent (new_parent); - - _cogl_pipeline_layer_set_parent (layer, new_parent); -} - -/* Determine the mask of differences between two layers. - * - * XXX: If layers and pipelines could both be cast to a common Tree - * type of some kind then we could have a unified - * compare_differences() function. - */ -unsigned long -_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglPipelineLayer *node0; - CoglPipelineLayer *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - unsigned long layers_difference = 0; - - /* Algorithm: - * - * 1) Walk the ancestors of each layer to the root node, adding a - * pointer to each ancester node to two linked lists - * - * 2) Compare the lists to find the nodes where they start to - * differ marking the common_ancestor node for each list. - * - * 3) For each list now iterate starting after the common_ancestor - * nodes ORing each nodes ->difference mask into the final - * differences mask. - */ - - for (node0 = layer0; node0; node0 = _cogl_pipeline_layer_get_parent (node0)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - } - for (node1 = layer1; node1; node1 = _cogl_pipeline_layer_get_parent (node1)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - } - - /* NB: There's no point looking at the head entries since we know both layers - * must have the same default layer as their root node. */ - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - node0 = head0->data; - layers_difference |= node0->differences; - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - node1 = head1->data; - layers_difference |= node1->differences; - } - - return layers_difference; -} - -static gboolean -layer_state_equal (CoglPipelineLayerStateIndex state_index, - CoglPipelineLayer **authorities0, - CoglPipelineLayer **authorities1, - CoglPipelineLayerStateComparator comparator) -{ - return comparator (authorities0[state_index], authorities1[state_index]); -} - -void -_cogl_pipeline_layer_resolve_authorities (CoglPipelineLayer *layer, - unsigned long differences, - CoglPipelineLayer **authorities) -{ - unsigned long remaining = differences; - CoglPipelineLayer *authority = layer; - - do - { - unsigned long found = authority->differences & remaining; - int i; - - if (found == 0) - continue; - - for (i = 0; TRUE; i++) - { - unsigned long state = (1L<<i); - - if (state & found) - authorities[i] = authority; - else if (state > found) - break; - } - - remaining &= ~found; - if (remaining == 0) - return; - } - while ((authority = _cogl_pipeline_layer_get_parent (authority))); - - g_assert (remaining == 0); -} - -gboolean -_cogl_pipeline_layer_equal (CoglPipelineLayer *layer0, - CoglPipelineLayer *layer1, - unsigned long differences_mask, - CoglPipelineEvalFlags flags) -{ - unsigned long layers_difference; - CoglPipelineLayer *authorities0[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - CoglPipelineLayer *authorities1[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - - if (layer0 == layer1) - return TRUE; - - layers_difference = - _cogl_pipeline_layer_compare_differences (layer0, layer1); - - /* Only compare the sparse state groups requested by the caller... */ - layers_difference &= differences_mask; - - _cogl_pipeline_layer_resolve_authorities (layer0, - layers_difference, - authorities0); - _cogl_pipeline_layer_resolve_authorities (layer1, - layers_difference, - authorities1); - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - CoglPipelineLayerStateIndex state_index = - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX; - if (!_cogl_pipeline_layer_texture_data_equal (authorities0[state_index], - authorities1[state_index], - flags)) - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_combine_state_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_combine_constant_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_SAMPLER && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_sampler_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_USER_MATRIX && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_user_matrix_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_point_sprite_coords_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_vertex_snippets_equal)) - return FALSE; - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS && - !layer_state_equal (COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX, - authorities0, authorities1, - _cogl_pipeline_layer_fragment_snippets_equal)) - return FALSE; - - return TRUE; -} - -static void -_cogl_pipeline_layer_free (CoglPipelineLayer *layer) -{ - _cogl_pipeline_layer_unparent (COGL_NODE (layer)); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA && - layer->texture != NULL) - cogl_object_unref (layer->texture); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS) - _cogl_pipeline_snippet_list_free (&layer->big_state->vertex_snippets); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS) - _cogl_pipeline_snippet_list_free (&layer->big_state->fragment_snippets); - - if (layer->differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE) - g_free (layer->big_state); - - g_free (layer); -} - -void -_cogl_pipeline_init_default_layers (void) -{ - CoglPipelineLayer *layer = g_new0 (CoglPipelineLayer, 1); - CoglPipelineLayerBigState *big_state = - g_new0 (CoglPipelineLayerBigState, 1); - CoglPipelineLayer *new; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_pipeline_node_init (COGL_NODE (layer)); - - layer->index = 0; - - layer->differences = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - - layer->unit_index = 0; - - layer->texture = NULL; - - layer->sampler_cache_entry = - _cogl_sampler_cache_get_default_entry (ctx->sampler_cache); - - layer->big_state = big_state; - layer->has_big_state = TRUE; - - /* Choose the same default combine mode as OpenGL: - * RGBA = MODULATE(PREVIOUS[RGBA],TEXTURE[RGBA]) */ - big_state->texture_combine_rgb_func = - COGL_PIPELINE_COMBINE_FUNC_MODULATE; - big_state->texture_combine_rgb_src[0] = - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - big_state->texture_combine_rgb_src[1] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - big_state->texture_combine_rgb_op[0] = - COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - big_state->texture_combine_rgb_op[1] = - COGL_PIPELINE_COMBINE_OP_SRC_COLOR; - big_state->texture_combine_alpha_func = - COGL_PIPELINE_COMBINE_FUNC_MODULATE; - big_state->texture_combine_alpha_src[0] = - COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS; - big_state->texture_combine_alpha_src[1] = - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE; - big_state->texture_combine_alpha_op[0] = - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - big_state->texture_combine_alpha_op[1] = - COGL_PIPELINE_COMBINE_OP_SRC_ALPHA; - - big_state->point_sprite_coords = FALSE; - - graphene_matrix_init_identity (&big_state->matrix); - - ctx->default_layer_0 = _cogl_pipeline_layer_object_new (layer); - - /* TODO: we should make default_layer_n comprise of two - * descendants of default_layer_0: - * - the first descendant should change the texture combine - * to what we expect is most commonly used for multitexturing - * - the second should revert the above change. - * - * why? the documentation for how a new layer is initialized - * doesn't say that layers > 0 have different defaults so unless - * we change the documentation we can't use different defaults, - * but if the user does what we expect and changes the - * texture combine then we can revert the authority to the - * first descendant which means we can maximize the number - * of layers with a common ancestor. - * - * The main problem will be that we'll need to disable the - * optimizations for flattening the ancestry when we make - * the second descendant which reverts the state. - */ - ctx->default_layer_n = _cogl_pipeline_layer_copy (layer); - new = _cogl_pipeline_set_layer_unit (NULL, ctx->default_layer_n, 1); - g_assert (new == ctx->default_layer_n); - /* Since we passed a newly allocated layer we don't expect that - * _set_layer_unit() will have to allocate *another* layer. */ - - /* Finally we create a dummy dependent for ->default_layer_n which - * effectively ensures that ->default_layer_n and ->default_layer_0 - * remain immutable. - */ - ctx->dummy_layer_dependant = - _cogl_pipeline_layer_copy (ctx->default_layer_n); -} - -void -_cogl_pipeline_layer_pre_paint (CoglPipelineLayer *layer) -{ - CoglPipelineLayer *texture_authority; - - texture_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); - - if (texture_authority->texture != NULL) - { - CoglTexturePrePaintFlags flags = 0; - CoglPipelineFilter min_filter; - CoglPipelineFilter mag_filter; - - _cogl_pipeline_layer_get_filters (layer, &min_filter, &mag_filter); - - if (min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST - || min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_NEAREST - || min_filter == COGL_PIPELINE_FILTER_NEAREST_MIPMAP_LINEAR - || min_filter == COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR) - flags |= COGL_TEXTURE_NEEDS_MIPMAP; - - _cogl_texture_pre_paint (texture_authority->texture, flags); - } -} - -/* Determines if we need to handle the RGB and A texture combining - * separately or is the same function used for both channel masks and - * with the same arguments... - */ -gboolean -_cogl_pipeline_layer_needs_combine_separate - (CoglPipelineLayer *combine_authority) -{ - CoglPipelineLayerBigState *big_state = combine_authority->big_state; - int n_args; - int i; - - if (big_state->texture_combine_rgb_func != - big_state->texture_combine_alpha_func) - return TRUE; - - n_args = _cogl_get_n_args_for_combine_func (big_state->texture_combine_rgb_func); - - for (i = 0; i < n_args; i++) - { - if (big_state->texture_combine_rgb_src[i] != - big_state->texture_combine_alpha_src[i]) - return TRUE; - - /* - * We can allow some variation of the source operands without - * needing a separation... - * - * "A = REPLACE (CONSTANT[A])" + either of the following... - * "RGB = REPLACE (CONSTANT[RGB])" - * "RGB = REPLACE (CONSTANT[A])" - * - * can be combined as: - * "RGBA = REPLACE (CONSTANT)" or - * "RGBA = REPLACE (CONSTANT[A])" or - * - * And "A = REPLACE (1-CONSTANT[A])" + either of the following... - * "RGB = REPLACE (1-CONSTANT)" or - * "RGB = REPLACE (1-CONSTANT[A])" - * - * can be combined as: - * "RGBA = REPLACE (1-CONSTANT)" or - * "RGBA = REPLACE (1-CONSTANT[A])" - */ - switch (big_state->texture_combine_alpha_op[i]) - { - case GL_SRC_ALPHA: - switch (big_state->texture_combine_rgb_op[i]) - { - case GL_SRC_COLOR: - case GL_SRC_ALPHA: - break; - default: - return FALSE; - } - break; - case GL_ONE_MINUS_SRC_ALPHA: - switch (big_state->texture_combine_rgb_op[i]) - { - case GL_ONE_MINUS_SRC_COLOR: - case GL_ONE_MINUS_SRC_ALPHA: - break; - default: - return FALSE; - } - break; - default: - return FALSE; /* impossible */ - } - } - - return FALSE; -} - - diff --git a/cogl/cogl/cogl-pipeline-private.h b/cogl/cogl/cogl-pipeline-private.h deleted file mode 100644 index 045af8fa0..000000000 --- a/cogl/cogl/cogl-pipeline-private.h +++ /dev/null @@ -1,821 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_PRIVATE_H -#define __COGL_PIPELINE_PRIVATE_H - -#include "cogl-node-private.h" -#include "cogl-pipeline-layer-private.h" -#include "cogl-pipeline.h" -#include "cogl-object-private.h" -#include "cogl-profile.h" -#include "cogl-list.h" -#include "cogl-boxed-value.h" -#include "cogl-pipeline-snippet-private.h" -#include "cogl-pipeline-state.h" -#include "cogl-framebuffer.h" -#include "cogl-bitmask.h" - -#include <glib.h> - -#if !(defined(HAVE_COGL_GL) || defined(HAVE_COGL_GLES2)) - -#error No drivers defined - -#endif /* defined(HAVE_COGL_GL) || defined(HAVE_COGL_GLES2) */ - -/* XXX: should I rename these as - * COGL_PIPELINE_STATE_INDEX_XYZ... ? - */ -typedef enum -{ - /* sparse state */ - COGL_PIPELINE_STATE_COLOR_INDEX, - COGL_PIPELINE_STATE_LAYERS_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, - COGL_PIPELINE_STATE_BLEND_INDEX, - COGL_PIPELINE_STATE_USER_SHADER_INDEX, - COGL_PIPELINE_STATE_DEPTH_INDEX, - COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_CULL_FACE_INDEX, - COGL_PIPELINE_STATE_UNIFORMS_INDEX, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX, - - /* non-sparse */ - COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX, - - COGL_PIPELINE_STATE_COUNT -} CoglPipelineStateIndex; - -#define COGL_PIPELINE_STATE_SPARSE_COUNT (COGL_PIPELINE_STATE_COUNT - 1) - -/* Used in pipeline->differences masks and for notifying pipeline - * state changes. - * - * XXX: If you add or remove state groups here you may need to update - * some of the state masks following this enum too! - * - * FIXME: perhaps it would be better to rename this enum to - * CoglPipelineStateGroup to better convey the fact that a single enum - * here can map to multiple properties. - */ -typedef enum _CoglPipelineState -{ - COGL_PIPELINE_STATE_COLOR = - 1L<<COGL_PIPELINE_STATE_COLOR_INDEX, - COGL_PIPELINE_STATE_LAYERS = - 1L<<COGL_PIPELINE_STATE_LAYERS_INDEX, - - COGL_PIPELINE_STATE_ALPHA_FUNC = - 1L<<COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE = - 1L<<COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX, - COGL_PIPELINE_STATE_BLEND = - 1L<<COGL_PIPELINE_STATE_BLEND_INDEX, - COGL_PIPELINE_STATE_USER_SHADER = - 1L<<COGL_PIPELINE_STATE_USER_SHADER_INDEX, - COGL_PIPELINE_STATE_DEPTH = - 1L<<COGL_PIPELINE_STATE_DEPTH_INDEX, - COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE = - 1L<<COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_POINT_SIZE = - 1L<<COGL_PIPELINE_STATE_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE = - 1L<<COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX, - COGL_PIPELINE_STATE_CULL_FACE = - 1L<<COGL_PIPELINE_STATE_CULL_FACE_INDEX, - COGL_PIPELINE_STATE_UNIFORMS = - 1L<<COGL_PIPELINE_STATE_UNIFORMS_INDEX, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS = - 1L<<COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS = - 1L<<COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX, - - COGL_PIPELINE_STATE_REAL_BLEND_ENABLE = - 1L<<COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX, - -} CoglPipelineState; - -/* - * Various special masks that tag state-groups in different ways... - */ - -#define COGL_PIPELINE_STATE_ALL \ - ((1L<<COGL_PIPELINE_STATE_COUNT) - 1) - -#define COGL_PIPELINE_STATE_ALL_SPARSE \ - (COGL_PIPELINE_STATE_ALL \ - & ~COGL_PIPELINE_STATE_REAL_BLEND_ENABLE) - -#define COGL_PIPELINE_STATE_AFFECTS_BLENDING \ - (COGL_PIPELINE_STATE_COLOR | \ - COGL_PIPELINE_STATE_LAYERS | \ - COGL_PIPELINE_STATE_BLEND | \ - COGL_PIPELINE_STATE_USER_SHADER | \ - COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \ - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - -#define COGL_PIPELINE_STATE_NEEDS_BIG_STATE \ - (COGL_PIPELINE_STATE_ALPHA_FUNC | \ - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE | \ - COGL_PIPELINE_STATE_BLEND | \ - COGL_PIPELINE_STATE_USER_SHADER | \ - COGL_PIPELINE_STATE_DEPTH | \ - COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE | \ - COGL_PIPELINE_STATE_POINT_SIZE | \ - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE | \ - COGL_PIPELINE_STATE_CULL_FACE | \ - COGL_PIPELINE_STATE_UNIFORMS | \ - COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \ - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - -#define COGL_PIPELINE_STATE_MULTI_PROPERTY \ - (COGL_PIPELINE_STATE_LAYERS | \ - COGL_PIPELINE_STATE_BLEND | \ - COGL_PIPELINE_STATE_DEPTH | \ - COGL_PIPELINE_STATE_CULL_FACE | \ - COGL_PIPELINE_STATE_UNIFORMS | \ - COGL_PIPELINE_STATE_VERTEX_SNIPPETS | \ - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - -typedef struct -{ - /* Determines what fragments are discarded based on their alpha */ - CoglPipelineAlphaFunc alpha_func; - float alpha_func_reference; -} CoglPipelineAlphaFuncState; - -typedef struct -{ - /* Determines how this pipeline is blended with other primitives */ -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - GLenum blend_equation_rgb; - GLenum blend_equation_alpha; - GLint blend_src_factor_alpha; - GLint blend_dst_factor_alpha; - CoglColor blend_constant; -#endif - GLint blend_src_factor_rgb; - GLint blend_dst_factor_rgb; -} CoglPipelineBlendState; - -typedef struct -{ - CoglPipelineCullFaceMode mode; - CoglWinding front_winding; -} CoglPipelineCullFaceState; - -typedef struct -{ - CoglBitmask override_mask; - - /* This is an array of values. Only the uniforms that have a bit set - in override_mask have a corresponding value here. The uniform's - location is implicit from the order in this array */ - CoglBoxedValue *override_values; - - /* Uniforms that have been modified since this pipeline was last - flushed */ - CoglBitmask changed_mask; -} CoglPipelineUniformsState; - -typedef struct -{ - CoglPipelineAlphaFuncState alpha_state; - CoglPipelineBlendState blend_state; - CoglHandle user_program; - CoglDepthState depth_state; - float point_size; - unsigned int non_zero_point_size : 1; - unsigned int per_vertex_point_size : 1; - CoglPipelineCullFaceState cull_face_state; - CoglPipelineUniformsState uniforms_state; - CoglPipelineSnippetList vertex_snippets; - CoglPipelineSnippetList fragment_snippets; -} CoglPipelineBigState; - -typedef struct -{ - CoglPipeline *owner; - CoglPipelineLayer *layer; -} CoglPipelineLayerCacheEntry; - -typedef struct _CoglPipelineHashState -{ - unsigned long layer_differences; - CoglPipelineEvalFlags flags; - unsigned int hash; -} CoglPipelineHashState; - -/* - * CoglPipelineDestroyCallback - * @pipeline: The #CoglPipeline that has been destroyed - * @user_data: The private data associated with the callback - * - * Notifies when a weak pipeline has been destroyed because one - * of its ancestors has been freed or modified. - */ -typedef void (*CoglPipelineDestroyCallback)(CoglPipeline *pipeline, - void *user_data); - -struct _CoglPipeline -{ - /* XXX: Please think twice about adding members that *have* be - * initialized during a cogl_pipeline_copy. We are aiming to have - * copies be as cheap as possible and copies may be done by the - * primitives APIs which means they may happen in performance - * critical code paths. - * - * XXX: If you are extending the state we track please consider if - * the state is expected to vary frequently across many pipelines or - * if the state can be shared among many derived pipelines instead. - * This will determine if the state should be added directly to this - * structure which will increase the memory overhead for *all* - * pipelines or if instead it can go under ->big_state. - */ - - /* Layers represent their state in a tree structure where some of - * the state relating to a given pipeline or layer may actually be - * owned by one if is ancestors in the tree. We have a common data - * type to track the tree hierarchy so we can share code... */ - CoglNode _parent; - - /* When weak pipelines are destroyed the user is notified via this - * callback */ - CoglPipelineDestroyCallback destroy_callback; - - /* When notifying that a weak pipeline has been destroyed this - * private data is passed to the above callback */ - void *destroy_data; - - /* We need to track if a pipeline is referenced in the journal - * because we can't allow modification to these pipelines without - * flushing the journal first */ - unsigned int journal_ref_count; - - /* A mask of which sparse state groups are different in this - * pipeline in comparison to its parent. */ - unsigned int differences; - - /* Whenever a pipeline is modified we increment the age. There's no - * guarantee that it won't wrap but it can nevertheless be a - * convenient mechanism to determine when a pipeline has been - * changed to you can invalidate some some associated cache that - * depends on the old state. */ - unsigned int age; - - /* This is the primary color of the pipeline. - * - * This is a sparse property, ref COGL_PIPELINE_STATE_COLOR */ - CoglColor color; - - /* A pipeline may be made up with multiple layers used to combine - * textures together. - * - * This is sparse state, ref COGL_PIPELINE_STATE_LAYERS */ - unsigned int n_layers; - GList *layer_differences; - - /* As a basic way to reduce memory usage we divide the pipeline - * state into two groups; the minimal state modified in 90% of - * all pipelines and the rest, so that the second group can - * be allocated dynamically when required... */ - CoglPipelineBigState *big_state; - -#ifdef COGL_DEBUG_ENABLED - /* For debugging purposes it's possible to associate a static const - * string with a pipeline which can be an aid when trying to trace - * where the pipeline originates from */ - const char *static_breadcrumb; -#endif - - /* Cached state... */ - - /* A cached, complete list of the layers this pipeline depends - * on sorted by layer->unit_index. */ - CoglPipelineLayer **layers_cache; - /* To avoid a separate ->layers_cache allocation for common - * pipelines with only a few layers... */ - CoglPipelineLayer *short_layers_cache[3]; - - /* XXX: consider adding an authorities cache to speed up sparse - * property value lookups: - * CoglPipeline *authorities_cache[COGL_PIPELINE_N_SPARSE_PROPERTIES]; - * and corresponding authorities_cache_dirty:1 bitfield - */ - - /* bitfields */ - - /* Weak pipelines don't count as dependants on their parents which - * means that the parent pipeline can be modified without - * considering how the modifications may affect the weak pipeline. - */ - unsigned int is_weak:1; - - /* Determines if pipeline->big_state is valid */ - unsigned int has_big_state:1; - - /* There are many factors that can determine if we need to enable - * blending, this holds our final decision */ - unsigned int real_blend_enable:1; - - /* Since the code for deciding if blending really needs to be - * enabled for a particular pipeline is quite expensive we update - * the real_blend_enable flag lazily when flushing a pipeline if - * this dirty flag has been set. */ - unsigned int dirty_real_blend_enable:1; - - /* Whenever a pipeline is flushed we keep track of whether the - * pipeline was used with a color attribute where we don't know - * whether the colors are opaque. The real_blend_enable state - * depends on this, and must be updated whenever this changes (even - * if dirty_real_blend_enable isn't set) */ - unsigned int unknown_color_alpha:1; - - unsigned int layers_cache_dirty:1; - -#ifdef COGL_DEBUG_ENABLED - /* For debugging purposes it's possible to associate a static const - * string with a pipeline which can be an aid when trying to trace - * where the pipeline originates from */ - unsigned int has_static_breadcrumb:1; -#endif -}; - -typedef struct _CoglPipelineFragend -{ - void (*start) (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference); - gboolean (*add_layer) (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference); - gboolean (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); -} CoglPipelineFragend; - -typedef struct _CoglPipelineVertend -{ - void (*start) (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference); - gboolean (*add_layer) (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference, - CoglFramebuffer *framebuffer); - gboolean (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); -} CoglPipelineVertend; - -typedef struct -{ - gboolean (*start) (CoglPipeline *pipeline); - void (*end) (CoglPipeline *pipeline, - unsigned long pipelines_difference); - void (*pipeline_pre_change_notify) (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color); - void (*layer_pre_change_notify) (CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change); - /* This is called after all of the other functions whenever the - pipeline is flushed, even if the pipeline hasn't changed since - the last flush */ - void (* pre_paint) (CoglPipeline *pipeline, CoglFramebuffer *framebuffer); -} CoglPipelineProgend; - -extern const CoglPipelineFragend *_cogl_pipeline_fragend; -extern const CoglPipelineVertend *_cogl_pipeline_vertend; -extern const CoglPipelineProgend *_cogl_pipeline_progend; - -void -_cogl_pipeline_init_default_pipeline (void); - -static inline CoglPipeline * -_cogl_pipeline_get_parent (CoglPipeline *pipeline) -{ - CoglNode *parent_node = COGL_NODE (pipeline)->parent; - return COGL_PIPELINE (parent_node); -} - -static inline CoglPipeline * -_cogl_pipeline_get_authority (CoglPipeline *pipeline, - unsigned long difference) -{ - CoglPipeline *authority = pipeline; - while (!(authority->differences & difference)) - authority = _cogl_pipeline_get_parent (authority); - return authority; -} - -typedef gboolean (*CoglPipelineStateComparator) (CoglPipeline *authority0, - CoglPipeline *authority1); - -void -_cogl_pipeline_update_authority (CoglPipeline *pipeline, - CoglPipeline *authority, - CoglPipelineState state, - CoglPipelineStateComparator comparator); - -void -_cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color, - gboolean from_layer_change); - -void -_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline); - -void -_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline, - gboolean unknown_color_alpha); - -typedef enum -{ - COGL_PIPELINE_GET_LAYER_NO_CREATE = 1<<0 -} CoglPipelineGetLayerFlags; - -CoglPipelineLayer * -_cogl_pipeline_get_layer_with_flags (CoglPipeline *pipeline, - int layer_index, - CoglPipelineGetLayerFlags flags); - -#define _cogl_pipeline_get_layer(p, l) \ - _cogl_pipeline_get_layer_with_flags (p, l, 0) - -gboolean -_cogl_is_pipeline_layer (void *object); - -void -_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, - CoglPipelineLayer *layer); - -/* - * SECTION:cogl-pipeline-internals - * @short_description: Functions for creating custom primitives that make use - * of Cogl pipelines for filling. - * - * Normally you shouldn't need to use this API directly, but if you need to - * developing a custom/specialised primitive - probably using raw OpenGL - then - * this API aims to expose enough of the pipeline internals to support being - * able to fill your geometry according to a given Cogl pipeline. - */ - -gboolean -_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline); - -/* - * Calls the pre_paint method on the layer texture if there is - * one. This will determine whether mipmaps are needed based on the - * filter settings. - */ -void -_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline, - int layer_id); - -/* - * CoglPipelineFlushFlag: - * @COGL_PIPELINE_FLUSH_FALLBACK_MASK: The fallback_layers member is set to - * a uint32_t mask of the layers that can't be supported with the user - * supplied texture and need to be replaced with fallback textures. (1 = - * fallback, and the least significant bit = layer 0) - * @COGL_PIPELINE_FLUSH_DISABLE_MASK: The disable_layers member is set to - * a uint32_t mask of the layers that you want to completely disable - * texturing for (1 = fallback, and the least significant bit = layer 0) - * @COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE: The layer0_override_texture member is - * set to a GLuint OpenGL texture name to override the texture used for - * layer 0 of the pipeline. This is intended for dealing with sliced - * textures where you will need to point to each of the texture slices in - * turn when drawing your geometry. Passing a value of 0 is the same as - * not passing the option at all. - * @COGL_PIPELINE_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the - * pipeline don't call glColor. - */ -typedef enum _CoglPipelineFlushFlag -{ - COGL_PIPELINE_FLUSH_FALLBACK_MASK = 1L<<0, - COGL_PIPELINE_FLUSH_DISABLE_MASK = 1L<<1, - COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE = 1L<<2, - COGL_PIPELINE_FLUSH_SKIP_GL_COLOR = 1L<<3 -} CoglPipelineFlushFlag; - -/* - * CoglPipelineFlushOptions: - * - */ -typedef struct _CoglPipelineFlushOptions -{ - CoglPipelineFlushFlag flags; - - uint32_t fallback_layers; - uint32_t disable_layers; - CoglTexture *layer0_override_texture; -} CoglPipelineFlushOptions; - -unsigned int -_cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func); - -/* - * _cogl_pipeline_weak_copy: - * @pipeline: A #CoglPipeline object - * @callback: A callback to notify when your weak pipeline is destroyed - * @user_data: Private data to pass to your given callback. - * - * Returns a weak copy of the given source @pipeline. Unlike a normal - * copy no internal reference is taken on the source @pipeline and you - * can expect that later modifications of the source pipeline (or in - * fact any other pipeline) can result in the weak pipeline being - * destroyed. - * - * To understand this better its good to know a bit about the internal - * design of #CoglPipeline... - * - * Internally #CoglPipeline<!-- -->s are represented as a graph of - * property diff's, where each node is a diff of properties that gets - * applied on top of its parent. Copying a pipeline creates an empty - * diff and a child->parent relationship between the empty diff and - * the source @pipeline, parent. - * - * Because of this internal graph design a single #CoglPipeline may - * indirectly depend on a chain of ancestors to fully define all of - * its properties. Because a node depends on its ancestors it normally - * owns a reference to its parent to stop it from being freed. Also if - * you try to modify a pipeline with children we internally use a - * copy-on-write mechanism to ensure that you don't indirectly change - * the properties those children. - * - * Weak pipelines avoid the use of copy-on-write to preserve the - * integrity of weak dependants and instead weak dependants are - * simply destroyed allowing the parent to be modified directly. Also - * because weak pipelines don't own a reference to their parent they - * won't stop the source @pipeline from being freed when the user - * releases their reference on it. - * - * Because weak pipelines don't own a reference on their parent they - * are the recommended mechanism for creating derived pipelines that you - * want to cache as a private property of the original pipeline - * because they won't result in a circular dependency. - * - * An example use case: - * - * Consider for example you are implementing a custom primitive that is - * not compatible with certain source pipelines. To handle this you - * implement a validation stage that given an arbitrary pipeline as - * input will create a derived pipeline that is suitable for drawing - * your primitive. - * - * Because you don't want to have to repeat this validation every time - * the same incompatible pipeline is given as input you want to cache - * the result as a private property of the original pipeline. If the - * derived pipeline were created using cogl_pipeline_copy that would - * create a circular dependency so the original pipeline can never be - * freed. - * - * If you instead create a weak copy you won't stop the original pipeline - * from being freed if it's no longer needed, and you will instead simply - * be notified that your weak pipeline has been destroyed. - * - * This is the recommended coding pattern for validating an input - * pipeline and caching a derived result: - * |[ - * static CoglUserDataKey _cogl_my_cache_key; - * - * typedef struct { - * CoglPipeline *validated_source; - * } MyValidatedMaterialCache; - * - * static void - * destroy_cache_cb (CoglObject *object, void *user_data) - * { - * g_free (user_data); - * } - * - * static void - * invalidate_cache_cb (CoglPipeline *destroyed, void *user_data) - * { - * MyValidatedMaterialCache *cache = user_data; - * cogl_object_unref (cache->validated_source); - * cache->validated_source = NULL; - * } - * - * static CoglPipeline * - * get_validated_pipeline (CoglPipeline *source) - * { - * MyValidatedMaterialCache *cache = - * cogl_object_get_user_data (COGL_OBJECT (source), - * &_cogl_my_cache_key); - * if (G_UNLIKELY (cache == NULL)) - * { - * cache = g_new0 (MyValidatedMaterialCache, 1); - * cogl_object_set_user_data (COGL_OBJECT (source), - * &_cogl_my_cache_key, - * cache, destroy_cache_cb); - * cache->validated_source = source; - * } - * - * if (G_UNLIKELY (cache->validated_source == NULL)) - * { - * cache->validated_source = source; - * - * / * Start validating source... * / - * - * / * If you find you need to change something... * / - * if (cache->validated_source == source) - * cache->validated_source = - * cogl_pipeline_weak_copy (source, - * invalidate_cache_cb, - * cache); - * - * / * Modify cache->validated_source * / - * } - * - * return cache->validated_source; - * } - * ]| - */ -CoglPipeline * -_cogl_pipeline_weak_copy (CoglPipeline *pipeline, - CoglPipelineDestroyCallback callback, - void *user_data); - -void -_cogl_pipeline_set_progend (CoglPipeline *pipeline, int progend); - -void -_cogl_pipeline_get_colorubv (CoglPipeline *pipeline, - uint8_t *color); - -/* XXX: At some point it could be good for this to accept a mask of - * the state groups we are interested in comparing since we can - * probably use that information in a number situations to reduce - * the work we do. */ -unsigned long -_cogl_pipeline_compare_differences (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -gboolean -_cogl_pipeline_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1, - unsigned int differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags); - -unsigned int -_cogl_pipeline_hash (CoglPipeline *pipeline, - unsigned int differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags); - -/* Makes a copy of the given pipeline that is a child of the root - * pipeline rather than a child of the source pipeline. That way the - * new pipeline won't hold a reference to the source pipeline. The - * differences specified in @differences and @layer_differences are - * copied across and all other state is left with the default - * values. */ -CoglPipeline * -_cogl_pipeline_deep_copy (CoglPipeline *pipeline, - unsigned long differences, - unsigned long layer_differences); - -CoglPipeline * -_cogl_pipeline_journal_ref (CoglPipeline *pipeline); - -void -_cogl_pipeline_journal_unref (CoglPipeline *pipeline); - -const graphene_matrix_t * -_cogl_pipeline_get_layer_matrix (CoglPipeline *pipeline, - int layer_index); - -void -_cogl_pipeline_texture_storage_change_notify (CoglTexture *texture); - -void -_cogl_pipeline_apply_legacy_state (CoglPipeline *pipeline); - -void -_cogl_pipeline_apply_overrides (CoglPipeline *pipeline, - CoglPipelineFlushOptions *options); - -#ifdef COGL_DEBUG_ENABLED -void -_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, - const char *breadcrumb); -#endif - -unsigned long -_cogl_pipeline_get_age (CoglPipeline *pipeline); - -void -_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean inc_n_layers); - -void -_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean dec_n_layers); - -CoglPipeline * -_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, - CoglPipelineState pipeline_state, - CoglPipelineLayerState layer_state); - -void -_cogl_pipeline_get_layer_combine_constant (CoglPipeline *pipeline, - int layer_index, - float *constant); - -COGL_EXPORT void -_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n); - - -/* - * API to support the deprecate cogl_pipeline_layer_xyz functions... - */ - -typedef gboolean (*CoglPipelineInternalLayerCallback) (CoglPipelineLayer *layer, - void *user_data); - -COGL_EXPORT void -_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, - CoglPipelineInternalLayerCallback callback, - void *user_data); - -gboolean -_cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -gboolean -_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -gboolean -_cogl_pipeline_need_texture_combine_separate - (CoglPipelineLayer *combine_authority); - -void -_cogl_pipeline_init_state_hash_functions (void); - -void -_cogl_pipeline_init_layer_state_hash_functions (void); - -CoglPipelineState -_cogl_pipeline_get_state_for_vertex_codegen (CoglContext *context); - -CoglPipelineLayerState -_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context); - -CoglPipelineState -_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context); - -#endif /* __COGL_PIPELINE_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-pipeline-snippet-private.h b/cogl/cogl/cogl-pipeline-snippet-private.h deleted file mode 100644 index 9207f2036..000000000 --- a/cogl/cogl/cogl-pipeline-snippet-private.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_SNIPPET_PRIVATE_H -#define __COGL_PIPELINE_SNIPPET_PRIVATE_H - -#include <glib.h> - -#include "cogl-snippet.h" - -typedef struct -{ - GList *entries; -} CoglPipelineSnippetList; - -/* Arguments to pass to _cogl_pipeline_snippet_generate_code() */ -typedef struct -{ - CoglPipelineSnippetList *snippets; - - /* Only snippets at this hook point will be used */ - CoglSnippetHook hook; - - /* The final function to chain on to after all of the snippets code - has been run */ - const char *chain_function; - - /* The name of the final generated function */ - const char *final_name; - - /* A prefix to insert before each generate function name */ - const char *function_prefix; - - /* The return type of all of the functions, or NULL to use void */ - const char *return_type; - - /* A variable to return from the functions. The snippets are - expected to modify this variable. Ignored if return_type is - NULL */ - const char *return_variable; - - /* If this is TRUE then it won't allocate a separate variable for - the return value. Instead it is expected that the snippet will - modify one of the argument variables directly and that will be - returned */ - gboolean return_variable_is_argument; - - /* The argument names or NULL if there are none */ - const char *arguments; - - /* The argument types or NULL */ - const char *argument_declarations; - - /* The string to generate the source into */ - GString *source_buf; -} CoglPipelineSnippetData; - -void -_cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data); - -void -_cogl_pipeline_snippet_generate_declarations (GString *declarations_buf, - CoglSnippetHook hook, - CoglPipelineSnippetList *list); - -void -_cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list); - -void -_cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list, - CoglSnippet *snippet); - -void -_cogl_pipeline_snippet_list_copy (CoglPipelineSnippetList *dst, - const CoglPipelineSnippetList *src); - -void -_cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list, - unsigned int *hash); - -gboolean -_cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0, - CoglPipelineSnippetList *list1); - -#endif /* __COGL_PIPELINE_SNIPPET_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-pipeline-snippet.c b/cogl/cogl/cogl-pipeline-snippet.c deleted file mode 100644 index ae83bc398..000000000 --- a/cogl/cogl/cogl-pipeline-snippet.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-types.h" -#include "cogl-pipeline-snippet-private.h" -#include "cogl-snippet-private.h" -#include "cogl-util.h" - -/* Helper functions that are used by both GLSL pipeline backends */ - -void -_cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data) -{ - GList *first_snippet, *l; - CoglSnippet *snippet; - int snippet_num = 0; - int n_snippets = 0; - - first_snippet = data->snippets->entries; - - /* First count the number of snippets so we can easily tell when - we're at the last one */ - for (l = data->snippets->entries; l; l = l->next) - { - snippet = l->data; - - if (snippet->hook == data->hook) - { - /* Don't bother processing any previous snippets if we reach - one that has a replacement */ - if (snippet->replace) - { - n_snippets = 1; - first_snippet = l; - } - else - n_snippets++; - } - } - - /* If there weren't any snippets then generate a stub function with - the final name */ - if (n_snippets == 0) - { - if (data->return_type) - g_string_append_printf (data->source_buf, - "\n" - "%s\n" - "%s (%s)\n" - "{\n" - " return %s (%s);\n" - "}\n", - data->return_type, - data->final_name, - data->argument_declarations ? - data->argument_declarations : "", - data->chain_function, - data->arguments ? data->arguments : ""); - else - g_string_append_printf (data->source_buf, - "\n" - "void\n" - "%s (%s)\n" - "{\n" - " %s (%s);\n" - "}\n", - data->final_name, - data->argument_declarations ? - data->argument_declarations : "", - data->chain_function, - data->arguments ? data->arguments : ""); - - return; - } - - for (l = first_snippet; snippet_num < n_snippets; l = l->next) - { - snippet = l->data; - - if (snippet->hook == data->hook) - { - const char *source; - - if ((source = cogl_snippet_get_declarations (snippet))) - g_string_append (data->source_buf, source); - - g_string_append_printf (data->source_buf, - "\n" - "%s\n", - data->return_type ? - data->return_type : - "void"); - - if (snippet_num + 1 < n_snippets) - g_string_append_printf (data->source_buf, - "%s_%i", - data->function_prefix, - snippet_num); - else - g_string_append (data->source_buf, data->final_name); - - g_string_append (data->source_buf, " ("); - - if (data->argument_declarations) - g_string_append (data->source_buf, data->argument_declarations); - - g_string_append (data->source_buf, - ")\n" - "{\n"); - - if (data->return_type && !data->return_variable_is_argument) - g_string_append_printf (data->source_buf, - " %s %s;\n" - "\n", - data->return_type, - data->return_variable); - - if ((source = cogl_snippet_get_pre (snippet))) - g_string_append (data->source_buf, source); - - /* Chain on to the next function, or bypass it if there is - a replace string */ - if ((source = cogl_snippet_get_replace (snippet))) - g_string_append (data->source_buf, source); - else - { - g_string_append (data->source_buf, " "); - - if (data->return_type) - g_string_append_printf (data->source_buf, - "%s = ", - data->return_variable); - - if (snippet_num > 0) - g_string_append_printf (data->source_buf, - "%s_%i", - data->function_prefix, - snippet_num - 1); - else - g_string_append (data->source_buf, data->chain_function); - - g_string_append (data->source_buf, " ("); - - if (data->arguments) - g_string_append (data->source_buf, data->arguments); - - g_string_append (data->source_buf, ");\n"); - } - - if ((source = cogl_snippet_get_post (snippet))) - g_string_append (data->source_buf, source); - - if (data->return_type) - g_string_append_printf (data->source_buf, - " return %s;\n", - data->return_variable); - - g_string_append (data->source_buf, "}\n"); - snippet_num++; - } - } -} - -void -_cogl_pipeline_snippet_generate_declarations (GString *declarations_buf, - CoglSnippetHook hook, - CoglPipelineSnippetList *snippets) -{ - GList *l; - - for (l = snippets->entries; l; l = l->next) - { - CoglSnippet *snippet = l->data; - - if (snippet->hook == hook) - { - const char *source; - - if ((source = cogl_snippet_get_declarations (snippet))) - g_string_append (declarations_buf, source); - } - } -} - -void -_cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list) -{ - GList *l, *tmp; - - for (l = list->entries; l; l = tmp) - { - tmp = l->next; - - cogl_object_unref (l->data); - g_list_free_1 (l); - } -} - -void -_cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list, - CoglSnippet *snippet) -{ - list->entries = g_list_append (list->entries, cogl_object_ref (snippet)); - - _cogl_snippet_make_immutable (snippet); -} - -void -_cogl_pipeline_snippet_list_copy (CoglPipelineSnippetList *dst, - const CoglPipelineSnippetList *src) -{ - GQueue queue = G_QUEUE_INIT; - const GList *l; - - for (l = src->entries; l; l = l->next) - g_queue_push_tail (&queue, cogl_object_ref (l->data)); - - dst->entries = queue.head; -} - -void -_cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list, - unsigned int *hash) -{ - GList *l; - - for (l = list->entries; l; l = l->next) - { - CoglSnippet *snippet = l->data; - - *hash = _cogl_util_one_at_a_time_hash (*hash, - &snippet, - sizeof (CoglSnippet *)); - } -} - -gboolean -_cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0, - CoglPipelineSnippetList *list1) -{ - GList *l0, *l1; - - for (l0 = list0->entries, l1 = list1->entries; - l0 && l1; - l0 = l0->next, l1 = l1->next) - if (l0->data != l1->data) - return FALSE; - - return l0 == NULL && l1 == NULL; -} diff --git a/cogl/cogl/cogl-pipeline-state-private.h b/cogl/cogl/cogl-pipeline-state-private.h deleted file mode 100644 index e49fe8a45..000000000 --- a/cogl/cogl/cogl-pipeline-state-private.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_STATE_PRIVATE_H -#define __COGL_PIPELINE_STATE_PRIVATE_H - -CoglPipeline * -_cogl_pipeline_get_user_program (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_has_fragment_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline); - -gboolean -_cogl_pipeline_color_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_blend_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_depth_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1); -gboolean -_cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_logic_ops_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_user_shader_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -gboolean -_cogl_pipeline_fragment_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1); - -void -_cogl_pipeline_hash_color_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_layers_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_alpha_func_reference_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_blend_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_user_shader_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_depth_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_non_zero_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_logic_ops_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_uniforms_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_vertex_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_hash_fragment_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state); - -void -_cogl_pipeline_compare_uniform_differences (unsigned long *differences, - CoglPipeline *pipeline0, - CoglPipeline *pipeline1); - -#endif /* __COGL_PIPELINE_STATE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-pipeline-state.c b/cogl/cogl/cogl-pipeline-state.c deleted file mode 100644 index ecfc4cd3b..000000000 --- a/cogl/cogl/cogl-pipeline-state.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-color-private.h" -#include "cogl-blend-string.h" -#include "cogl-util.h" -#include "cogl-depth-state-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-snippet-private.h" - -#include <test-fixtures/test-unit.h> - -#include "string.h" - -#ifndef GL_FUNC_ADD -#define GL_FUNC_ADD 0x8006 -#endif - -CoglPipeline * -_cogl_pipeline_get_user_program (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); - - return authority->big_state->user_program; -} - -gboolean -_cogl_pipeline_color_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return cogl_color_equal (&authority0->color, &authority1->color); -} - -gboolean -_cogl_pipeline_alpha_func_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineAlphaFuncState *alpha_state0 = - &authority0->big_state->alpha_state; - CoglPipelineAlphaFuncState *alpha_state1 = - &authority1->big_state->alpha_state; - - return alpha_state0->alpha_func == alpha_state1->alpha_func; -} - -gboolean -_cogl_pipeline_alpha_func_reference_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineAlphaFuncState *alpha_state0 = - &authority0->big_state->alpha_state; - CoglPipelineAlphaFuncState *alpha_state1 = - &authority1->big_state->alpha_state; - - return (alpha_state0->alpha_func_reference == - alpha_state1->alpha_func_reference); -} - -gboolean -_cogl_pipeline_blend_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineBlendState *blend_state0 = &authority0->big_state->blend_state; - CoglPipelineBlendState *blend_state1 = &authority1->big_state->blend_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (blend_state0->blend_equation_rgb != blend_state1->blend_equation_rgb) - return FALSE; - - if (blend_state0->blend_equation_alpha != - blend_state1->blend_equation_alpha) - return FALSE; - if (blend_state0->blend_src_factor_alpha != - blend_state1->blend_src_factor_alpha) - return FALSE; - if (blend_state0->blend_dst_factor_alpha != - blend_state1->blend_dst_factor_alpha) - return FALSE; - - if (blend_state0->blend_src_factor_rgb != - blend_state1->blend_src_factor_rgb) - return FALSE; - if (blend_state0->blend_dst_factor_rgb != - blend_state1->blend_dst_factor_rgb) - return FALSE; - - if (blend_state0->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state0->blend_src_factor_rgb == GL_CONSTANT_COLOR || - blend_state0->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state0->blend_dst_factor_rgb == GL_CONSTANT_COLOR) - { - if (!cogl_color_equal (&blend_state0->blend_constant, - &blend_state1->blend_constant)) - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_depth_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - if (authority0->big_state->depth_state.test_enabled == FALSE && - authority1->big_state->depth_state.test_enabled == FALSE) - return TRUE; - else - { - CoglDepthState *s0 = &authority0->big_state->depth_state; - CoglDepthState *s1 = &authority1->big_state->depth_state; - return s0->test_enabled == s1->test_enabled && - s0->test_function == s1->test_function && - s0->write_enabled == s1->write_enabled && - s0->range_near == s1->range_near && - s0->range_far == s1->range_far; - } -} - -gboolean -_cogl_pipeline_non_zero_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->non_zero_point_size == - authority1->big_state->non_zero_point_size); -} - -gboolean -_cogl_pipeline_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return authority0->big_state->point_size == authority1->big_state->point_size; -} - -gboolean -_cogl_pipeline_per_vertex_point_size_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->per_vertex_point_size == - authority1->big_state->per_vertex_point_size); -} - -gboolean -_cogl_pipeline_cull_face_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - CoglPipelineCullFaceState *cull_face_state0 - = &authority0->big_state->cull_face_state; - CoglPipelineCullFaceState *cull_face_state1 - = &authority1->big_state->cull_face_state; - - /* The cull face state is considered equal if two pipelines are both - set to no culling. If the front winding property is ever used for - anything else or the comparison is used not just for drawing then - this would have to change */ - - if (cull_face_state0->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE) - return cull_face_state1->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE; - - return (cull_face_state0->mode == cull_face_state1->mode && - cull_face_state0->front_winding == cull_face_state1->front_winding); -} - -gboolean -_cogl_pipeline_user_shader_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return (authority0->big_state->user_program == - authority1->big_state->user_program); -} - -typedef struct -{ - const CoglBoxedValue **dst_values; - const CoglBoxedValue *src_values; - int override_count; -} GetUniformsClosure; - -static gboolean -get_uniforms_cb (int uniform_num, void *user_data) -{ - GetUniformsClosure *data = user_data; - - if (data->dst_values[uniform_num] == NULL) - data->dst_values[uniform_num] = data->src_values + data->override_count; - - data->override_count++; - - return TRUE; -} - -static void -_cogl_pipeline_get_all_uniform_values (CoglPipeline *pipeline, - const CoglBoxedValue **values) -{ - GetUniformsClosure data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - memset (values, 0, - sizeof (const CoglBoxedValue *) * ctx->n_uniform_names); - - data.dst_values = values; - - do - { - if ((pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS)) - { - const CoglPipelineUniformsState *uniforms_state = - &pipeline->big_state->uniforms_state; - - data.override_count = 0; - data.src_values = uniforms_state->override_values; - - _cogl_bitmask_foreach (&uniforms_state->override_mask, - get_uniforms_cb, - &data); - } - pipeline = _cogl_pipeline_get_parent (pipeline); - } - while (pipeline); -} - -gboolean -_cogl_pipeline_uniforms_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - unsigned long *differences; - const CoglBoxedValue **values0, **values1; - int n_longs; - int i; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (authority0 == authority1) - return TRUE; - - values0 = g_alloca (sizeof (const CoglBoxedValue *) * ctx->n_uniform_names); - values1 = g_alloca (sizeof (const CoglBoxedValue *) * ctx->n_uniform_names); - - n_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (ctx->n_uniform_names); - differences = g_alloca (n_longs * sizeof (unsigned long)); - memset (differences, 0, sizeof (unsigned long) * n_longs); - _cogl_pipeline_compare_uniform_differences (differences, - authority0, - authority1); - - _cogl_pipeline_get_all_uniform_values (authority0, values0); - _cogl_pipeline_get_all_uniform_values (authority1, values1); - - COGL_FLAGS_FOREACH_START (differences, n_longs, i) - { - const CoglBoxedValue *value0 = values0[i]; - const CoglBoxedValue *value1 = values1[i]; - - if (value0 == NULL) - { - if (value1 != NULL && value1->type != COGL_BOXED_NONE) - return FALSE; - } - else if (value1 == NULL) - { - if (value0 != NULL && value0->type != COGL_BOXED_NONE) - return FALSE; - } - else if (!_cogl_boxed_value_equal (value0, value1)) - return FALSE; - } - COGL_FLAGS_FOREACH_END; - - return TRUE; -} - -gboolean -_cogl_pipeline_vertex_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - vertex_snippets, - &authority1->big_state-> - vertex_snippets); -} - -gboolean -_cogl_pipeline_fragment_snippets_state_equal (CoglPipeline *authority0, - CoglPipeline *authority1) -{ - return _cogl_pipeline_snippet_list_equal (&authority0->big_state-> - fragment_snippets, - &authority1->big_state-> - fragment_snippets); -} - -void -cogl_pipeline_get_color (CoglPipeline *pipeline, - CoglColor *color) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - *color = authority->color; -} - -/* This is used heavily by the cogl journal when logging quads */ -void -_cogl_pipeline_get_colorubv (CoglPipeline *pipeline, - uint8_t *color) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - - _cogl_color_get_rgba_4ubv (&authority->color, color); -} - -void -cogl_pipeline_set_color (CoglPipeline *pipeline, - const CoglColor *color) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_COLOR; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (cogl_color_equal (color, &authority->color)) - return; - - /* - 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, color, FALSE); - - pipeline->color = *color; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_color_equal); - - pipeline->dirty_real_blend_enable = TRUE; -} - -void -cogl_pipeline_set_color4ub (CoglPipeline *pipeline, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha) -{ - CoglColor color; - cogl_color_init_from_4ub (&color, red, green, blue, alpha); - cogl_pipeline_set_color (pipeline, &color); -} - -void -cogl_pipeline_set_color4f (CoglPipeline *pipeline, - float red, - float green, - float blue, - float alpha) -{ - CoglColor color; - cogl_color_init_from_4f (&color, red, green, blue, alpha); - cogl_pipeline_set_color (pipeline, &color); -} - -static void -_cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC; - CoglPipeline *authority; - CoglPipelineAlphaFuncState *alpha_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - alpha_state = &authority->big_state->alpha_state; - if (alpha_state->alpha_func == alpha_func) - return; - - /* - 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); - - alpha_state = &pipeline->big_state->alpha_state; - alpha_state->alpha_func = alpha_func; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_alpha_func_state_equal); -} - -static void -_cogl_pipeline_set_alpha_test_function_reference (CoglPipeline *pipeline, - float alpha_reference) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE; - CoglPipeline *authority; - CoglPipelineAlphaFuncState *alpha_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - alpha_state = &authority->big_state->alpha_state; - if (alpha_state->alpha_func_reference == alpha_reference) - return; - - /* - 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); - - alpha_state = &pipeline->big_state->alpha_state; - alpha_state->alpha_func_reference = alpha_reference; - - _cogl_pipeline_update_authority - (pipeline, authority, state, - _cogl_pipeline_alpha_func_reference_state_equal); -} - -void -cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func, - float alpha_reference) -{ - _cogl_pipeline_set_alpha_test_function (pipeline, alpha_func); - _cogl_pipeline_set_alpha_test_function_reference (pipeline, alpha_reference); -} - -CoglPipelineAlphaFunc -cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_ALPHA_FUNC); - - return authority->big_state->alpha_state.alpha_func; -} - -float -cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0.0f); - - authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE); - - return authority->big_state->alpha_state.alpha_func_reference; -} - -static GLenum -arg_to_gl_blend_factor (CoglBlendStringArgument *arg) -{ - if (arg->source.is_zero) - return GL_ZERO; - if (arg->factor.is_one) - return GL_ONE; - else if (arg->factor.is_src_alpha_saturate) - return GL_SRC_ALPHA_SATURATE; - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_SRC_COLOR) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_SRC_COLOR; - else - return GL_SRC_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_SRC_ALPHA; - else - return GL_SRC_ALPHA; - } - } - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_DST_COLOR) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_DST_COLOR; - else - return GL_DST_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_DST_ALPHA; - else - return GL_DST_ALPHA; - } - } -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - else if (arg->factor.source.info->type == - COGL_BLEND_STRING_COLOR_SOURCE_CONSTANT) - { - if (arg->factor.source.mask != COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_CONSTANT_COLOR; - else - return GL_CONSTANT_COLOR; - } - else - { - if (arg->factor.source.one_minus) - return GL_ONE_MINUS_CONSTANT_ALPHA; - else - return GL_CONSTANT_ALPHA; - } - } -#endif - - g_warning ("Unable to determine valid blend factor from blend string\n"); - return GL_ONE; -} - -static void -setup_blend_state (CoglBlendStringStatement *statement, - GLenum *blend_equation, - GLint *blend_src_factor, - GLint *blend_dst_factor) -{ - switch (statement->function->type) - { - case COGL_BLEND_STRING_FUNCTION_ADD: - *blend_equation = GL_FUNC_ADD; - break; - /* TODO - add more */ - default: - g_warning ("Unsupported blend function given"); - *blend_equation = GL_FUNC_ADD; - } - - *blend_src_factor = arg_to_gl_blend_factor (&statement->args[0]); - *blend_dst_factor = arg_to_gl_blend_factor (&statement->args[1]); -} - -gboolean -cogl_pipeline_set_blend (CoglPipeline *pipeline, - const char *blend_description, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; - CoglPipeline *authority; - CoglBlendStringStatement statements[2]; - CoglBlendStringStatement *rgb; - CoglBlendStringStatement *a; - int count; - CoglPipelineBlendState *blend_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - count = - _cogl_blend_string_compile (blend_description, - COGL_BLEND_STRING_CONTEXT_BLENDING, - statements, - error); - if (!count) - return FALSE; - - if (count == 1) - rgb = a = statements; - else - { - rgb = &statements[0]; - a = &statements[1]; - } - - authority = - _cogl_pipeline_get_authority (pipeline, state); - - /* - 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); - - blend_state = &pipeline->big_state->blend_state; - - setup_blend_state (rgb, - &blend_state->blend_equation_rgb, - &blend_state->blend_src_factor_rgb, - &blend_state->blend_dst_factor_rgb); - setup_blend_state (a, - &blend_state->blend_equation_alpha, - &blend_state->blend_src_factor_alpha, - &blend_state->blend_dst_factor_alpha); - - /* If we are the current authority see if we can revert to one of our - * ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (_cogl_pipeline_blend_state_equal (authority, old_authority)) - pipeline->differences &= ~state; - } - - /* If we weren't previously the authority on this state then we need - * to extended our differences mask and so it's possible that some - * of our ancestry will now become redundant, so we aim to reparent - * ourselves if that's true... */ - if (pipeline != authority) - { - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } - - pipeline->dirty_real_blend_enable = TRUE; - - return TRUE; -} - -void -cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, - const CoglColor *constant_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_return_if_fail (cogl_is_pipeline (pipeline)); - -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - { - CoglPipelineState state = COGL_PIPELINE_STATE_BLEND; - CoglPipeline *authority; - CoglPipelineBlendState *blend_state; - - authority = _cogl_pipeline_get_authority (pipeline, state); - - blend_state = &authority->big_state->blend_state; - if (cogl_color_equal (constant_color, &blend_state->blend_constant)) - return; - - /* - 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); - - blend_state = &pipeline->big_state->blend_state; - blend_state->blend_constant = *constant_color; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_blend_state_equal); - - pipeline->dirty_real_blend_enable = TRUE; - } -#endif -} - -CoglHandle -cogl_pipeline_get_user_program (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_USER_SHADER); - - return authority->big_state->user_program; -} - -/* XXX: for now we don't mind if the program has vertex shaders - * attached but if we ever make a similar API public we should only - * allow attaching of programs containing fragment shaders. Eventually - * we will have a CoglPipeline abstraction to also cover vertex - * processing. - */ -void -cogl_pipeline_set_user_program (CoglPipeline *pipeline, - CoglHandle program) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_USER_SHADER; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->user_program == program) - return; - - /* - 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); - - /* If we are the current authority see if we can revert to one of our - * ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (old_authority->big_state->user_program == program) - pipeline->differences &= ~state; - } - else if (pipeline != authority) - { - /* If we weren't previously the authority on this state then we - * need to extended our differences mask and so it's possible - * that some of our ancestry will now become redundant, so we - * aim to reparent ourselves if that's true... */ - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } - - if (program != NULL) - cogl_object_ref (program); - if (authority == pipeline && - pipeline->big_state->user_program != NULL) - cogl_object_unref (pipeline->big_state->user_program); - pipeline->big_state->user_program = program; - - pipeline->dirty_real_blend_enable = TRUE; -} - -gboolean -cogl_pipeline_set_depth_state (CoglPipeline *pipeline, - const CoglDepthState *depth_state, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; - CoglPipeline *authority; - CoglDepthState *orig_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - g_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; - - /* - 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; -} - -void -cogl_pipeline_get_depth_state (CoglPipeline *pipeline, - CoglDepthState *state) -{ - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - *state = authority->big_state->depth_state; -} - -void -cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, - CoglPipelineCullFaceMode cull_face_mode) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - CoglPipelineCullFaceState *cull_face_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - cull_face_state = &authority->big_state->cull_face_state; - - if (cull_face_state->mode == cull_face_mode) - return; - - /* - 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->cull_face_state.mode = cull_face_mode; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_cull_face_state_equal); -} - -void -cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, - CoglWinding front_winding) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - CoglPipelineCullFaceState *cull_face_state; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - cull_face_state = &authority->big_state->cull_face_state; - - if (cull_face_state->front_winding == front_winding) - return; - - /* - 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->cull_face_state.front_winding = front_winding; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_cull_face_state_equal); -} - -CoglPipelineCullFaceMode -cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), - COGL_PIPELINE_CULL_FACE_MODE_NONE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - return authority->big_state->cull_face_state.mode; -} - -CoglWinding -cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_CULL_FACE; - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), - COGL_WINDING_CLOCKWISE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - return authority->big_state->cull_face_state.front_winding; -} - -float -cogl_pipeline_get_point_size (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_POINT_SIZE); - - return authority->big_state->point_size; -} - -static void -_cogl_pipeline_set_non_zero_point_size (CoglPipeline *pipeline, - gboolean value) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - /* - 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->non_zero_point_size = !!value; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_non_zero_point_size_equal); -} - -void -cogl_pipeline_set_point_size (CoglPipeline *pipeline, - float point_size) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_POINT_SIZE; - CoglPipeline *authority; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - if (authority->big_state->point_size == point_size) - return; - - /* Changing the point size may additionally modify - * COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE. */ - - if ((authority->big_state->point_size > 0.0f) != (point_size > 0.0f)) - _cogl_pipeline_set_non_zero_point_size (pipeline, point_size > 0.0f); - - /* - 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->point_size = point_size; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_point_size_equal); -} - -gboolean -cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, - gboolean enable, - GError **error) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE; - CoglPipeline *authority; - - _COGL_GET_CONTEXT (ctx, FALSE); - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - authority = _cogl_pipeline_get_authority (pipeline, state); - - enable = !!enable; - - if (authority->big_state->per_vertex_point_size == enable) - return TRUE; - - /* - 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->per_vertex_point_size = enable; - - _cogl_pipeline_update_authority (pipeline, authority, state, - _cogl_pipeline_point_size_equal); - - return TRUE; -} - -gboolean -cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE); - - return authority->big_state->per_vertex_point_size; -} - -static CoglBoxedValue * -_cogl_pipeline_override_uniform (CoglPipeline *pipeline, - int location) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_UNIFORMS; - CoglPipelineUniformsState *uniforms_state; - int override_index; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_return_val_if_fail (cogl_is_pipeline (pipeline), NULL); - g_return_val_if_fail (location >= 0, NULL); - g_return_val_if_fail (location < ctx->n_uniform_names, NULL); - - /* - 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); - - uniforms_state = &pipeline->big_state->uniforms_state; - - /* Count the number of bits that are set below this location. That - should give us the position where our new value should lie */ - override_index = _cogl_bitmask_popcount_upto (&uniforms_state->override_mask, - location); - - _cogl_bitmask_set (&uniforms_state->changed_mask, location, TRUE); - - /* If this pipeline already has an override for this value then we - can just use it directly */ - if (_cogl_bitmask_get (&uniforms_state->override_mask, location)) - return uniforms_state->override_values + override_index; - - /* We need to create a new override value in the right position - within the array. This is pretty inefficient but the hope is that - it will be much more common to modify an existing uniform rather - than modify a new one so it is more important to optimise the - former case. */ - - if (uniforms_state->override_values == NULL) - { - g_assert (override_index == 0); - uniforms_state->override_values = g_new (CoglBoxedValue, 1); - } - else - { - /* We need to grow the array and copy in the old values */ - CoglBoxedValue *old_values = uniforms_state->override_values; - int old_size = _cogl_bitmask_popcount (&uniforms_state->override_mask); - - uniforms_state->override_values = g_new (CoglBoxedValue, old_size + 1); - - /* Copy in the old values leaving a gap for the new value */ - memcpy (uniforms_state->override_values, - old_values, - sizeof (CoglBoxedValue) * override_index); - memcpy (uniforms_state->override_values + override_index + 1, - old_values + override_index, - sizeof (CoglBoxedValue) * (old_size - override_index)); - - g_free (old_values); - } - - _cogl_boxed_value_init (uniforms_state->override_values + override_index); - - _cogl_bitmask_set (&uniforms_state->override_mask, location, TRUE); - - return uniforms_state->override_values + override_index; -} - -void -cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, - int uniform_location, - float value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_1f (boxed_value, value); -} - -void -cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, - int uniform_location, - int value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_1i (boxed_value, value); -} - -void -cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const float *value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_float (boxed_value, n_components, count, value); -} - -void -cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const int *value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_int (boxed_value, n_components, count, value); -} - -void -cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - CoglBoxedValue *boxed_value; - - boxed_value = _cogl_pipeline_override_uniform (pipeline, uniform_location); - - _cogl_boxed_value_set_matrix (boxed_value, - dimensions, - count, - transpose, - value); -} - -static void -_cogl_pipeline_add_vertex_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_VERTEX_SNIPPETS; - - /* - 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); - - _cogl_pipeline_snippet_list_add (&pipeline->big_state->vertex_snippets, - snippet); -} - -static void -_cogl_pipeline_add_fragment_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet) -{ - CoglPipelineState state = COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS; - - /* - 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); - - _cogl_pipeline_snippet_list_add (&pipeline->big_state->fragment_snippets, - snippet); -} - -void -cogl_pipeline_add_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet) -{ - g_return_if_fail (cogl_is_pipeline (pipeline)); - g_return_if_fail (cogl_is_snippet (snippet)); - g_return_if_fail (snippet->hook < COGL_SNIPPET_FIRST_LAYER_HOOK); - - if (snippet->hook < COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK) - _cogl_pipeline_add_vertex_snippet (pipeline, snippet); - else - _cogl_pipeline_add_fragment_snippet (pipeline, snippet); -} - -gboolean -_cogl_pipeline_has_non_layer_vertex_snippets (CoglPipeline *pipeline) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - - return authority->big_state->vertex_snippets.entries != NULL; -} - -static gboolean -check_layer_has_vertex_snippet (CoglPipelineLayer *layer, - void *user_data) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - gboolean *found_vertex_snippet = user_data; - - if (authority->big_state->vertex_snippets.entries) - { - *found_vertex_snippet = TRUE; - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_has_vertex_snippets (CoglPipeline *pipeline) -{ - gboolean found_vertex_snippet = FALSE; - - if (_cogl_pipeline_has_non_layer_vertex_snippets (pipeline)) - return TRUE; - - _cogl_pipeline_foreach_layer_internal (pipeline, - check_layer_has_vertex_snippet, - &found_vertex_snippet); - - return found_vertex_snippet; -} - -gboolean -_cogl_pipeline_has_non_layer_fragment_snippets (CoglPipeline *pipeline) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS); - - return authority->big_state->fragment_snippets.entries != NULL; -} - -static gboolean -check_layer_has_fragment_snippet (CoglPipelineLayer *layer, - void *user_data) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS; - CoglPipelineLayer *authority = - _cogl_pipeline_layer_get_authority (layer, state); - gboolean *found_fragment_snippet = user_data; - - if (authority->big_state->fragment_snippets.entries) - { - *found_fragment_snippet = TRUE; - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_has_fragment_snippets (CoglPipeline *pipeline) -{ - gboolean found_fragment_snippet = FALSE; - - if (_cogl_pipeline_has_non_layer_fragment_snippets (pipeline)) - return TRUE; - - _cogl_pipeline_foreach_layer_internal (pipeline, - check_layer_has_fragment_snippet, - &found_fragment_snippet); - - return found_fragment_snippet; -} - -void -_cogl_pipeline_hash_color_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &authority->color, - _COGL_COLOR_DATA_SIZE); -} - -void -_cogl_pipeline_hash_alpha_func_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineAlphaFuncState *alpha_state = &authority->big_state->alpha_state; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &alpha_state->alpha_func, - sizeof (alpha_state->alpha_func)); -} - -void -_cogl_pipeline_hash_alpha_func_reference_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineAlphaFuncState *alpha_state = &authority->big_state->alpha_state; - float ref = alpha_state->alpha_func_reference; - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &ref, sizeof (float)); -} - -void -_cogl_pipeline_hash_blend_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineBlendState *blend_state = &authority->big_state->blend_state; - unsigned int hash; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!authority->real_blend_enable) - return; - - hash = state->hash; - - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_rgb, - sizeof (blend_state->blend_equation_rgb)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_equation_alpha, - sizeof (blend_state->blend_equation_alpha)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_alpha, - sizeof (blend_state->blend_src_factor_alpha)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_alpha, - sizeof (blend_state->blend_dst_factor_alpha)); - - if (blend_state->blend_src_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state->blend_src_factor_rgb == GL_CONSTANT_COLOR || - blend_state->blend_dst_factor_rgb == GL_ONE_MINUS_CONSTANT_COLOR || - blend_state->blend_dst_factor_rgb == GL_CONSTANT_COLOR) - { - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_constant, - sizeof (blend_state->blend_constant)); - } - - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_src_factor_rgb, - sizeof (blend_state->blend_src_factor_rgb)); - hash = - _cogl_util_one_at_a_time_hash (hash, &blend_state->blend_dst_factor_rgb, - sizeof (blend_state->blend_dst_factor_rgb)); - - state->hash = hash; -} - -void -_cogl_pipeline_hash_user_shader_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglHandle user_program = authority->big_state->user_program; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &user_program, - sizeof (user_program)); -} - -void -_cogl_pipeline_hash_depth_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglDepthState *depth_state = &authority->big_state->depth_state; - unsigned int hash = state->hash; - - if (depth_state->test_enabled) - { - uint8_t enabled = depth_state->test_enabled; - CoglDepthTestFunction function = depth_state->test_function; - hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled)); - hash = _cogl_util_one_at_a_time_hash (hash, &function, sizeof (function)); - } - - if (depth_state->write_enabled) - { - uint8_t enabled = depth_state->write_enabled; - float near_val = depth_state->range_near; - float far_val = depth_state->range_far; - hash = _cogl_util_one_at_a_time_hash (hash, &enabled, sizeof (enabled)); - hash = _cogl_util_one_at_a_time_hash (hash, &near_val, sizeof (near_val)); - hash = _cogl_util_one_at_a_time_hash (hash, &far_val, sizeof (far_val)); - } - - state->hash = hash; -} - -void -_cogl_pipeline_hash_non_zero_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - gboolean non_zero_point_size = authority->big_state->non_zero_point_size; - - state->hash = _cogl_util_one_at_a_time_hash (state->hash, - &non_zero_point_size, - sizeof (non_zero_point_size)); -} - -void -_cogl_pipeline_hash_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - float point_size = authority->big_state->point_size; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, &point_size, - sizeof (point_size)); -} - -void -_cogl_pipeline_hash_per_vertex_point_size_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - gboolean per_vertex_point_size = authority->big_state->per_vertex_point_size; - state->hash = _cogl_util_one_at_a_time_hash (state->hash, - &per_vertex_point_size, - sizeof (per_vertex_point_size)); -} - -void -_cogl_pipeline_hash_cull_face_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - CoglPipelineCullFaceState *cull_face_state - = &authority->big_state->cull_face_state; - - /* The cull face state is considered equal if two pipelines are both - set to no culling. If the front winding property is ever used for - anything else or the hashing is used not just for drawing then - this would have to change */ - if (cull_face_state->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE) - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, - &cull_face_state->mode, - sizeof (CoglPipelineCullFaceMode)); - else - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, - cull_face_state, - sizeof (CoglPipelineCullFaceState)); -} - -void -_cogl_pipeline_hash_uniforms_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - /* This isn't used anywhere yet because the uniform state doesn't - affect program generation. It's quite a hassle to implement so - let's just leave it until something actually needs it */ - g_warn_if_reached (); -} - -void -_cogl_pipeline_compare_uniform_differences (unsigned long *differences, - CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglPipeline *node0; - CoglPipeline *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - - /* This algorithm is copied from - _cogl_pipeline_compare_differences(). It might be nice to share - the code more */ - - for (node0 = pipeline0; node0; node0 = _cogl_pipeline_get_parent (node0)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - } - for (node1 = pipeline1; node1; node1 = _cogl_pipeline_get_parent (node1)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - } - - /* NB: There's no point looking at the head entries since we know both - * pipelines must have the same default pipeline as their root node. */ - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - node0 = head0->data; - if ((node0->differences & COGL_PIPELINE_STATE_UNIFORMS)) - { - const CoglPipelineUniformsState *uniforms_state = - &node0->big_state->uniforms_state; - _cogl_bitmask_set_flags (&uniforms_state->override_mask, - differences); - } - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - node1 = head1->data; - if ((node1->differences & COGL_PIPELINE_STATE_UNIFORMS)) - { - const CoglPipelineUniformsState *uniforms_state = - &node1->big_state->uniforms_state; - _cogl_bitmask_set_flags (&uniforms_state->override_mask, - differences); - } - } -} - -void -_cogl_pipeline_hash_vertex_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->vertex_snippets, - &state->hash); -} - -void -_cogl_pipeline_hash_fragment_snippets_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - _cogl_pipeline_snippet_list_hash (&authority->big_state->fragment_snippets, - &state->hash); -} - -UNIT_TEST (check_blend_constant_ancestry, - 0 /* no requirements */, - 0 /* no known failures */) -{ - CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); - CoglNode *node; - int pipeline_length = 0; - int i; - - /* Repeatedly making a copy of a pipeline and changing the same - * state (in this case the blend constant) shouldn't cause a long - * chain of pipelines to be created because the redundant ancestry - * should be pruned. */ - - for (i = 0; i < 20; i++) - { - CoglColor color; - CoglPipeline *tmp_pipeline; - - cogl_color_init_from_4f (&color, i / 20.0f, 0.0f, 0.0f, 1.0f); - - tmp_pipeline = cogl_pipeline_copy (pipeline); - cogl_object_unref (pipeline); - pipeline = tmp_pipeline; - - cogl_pipeline_set_blend_constant (pipeline, &color); - } - - for (node = (CoglNode *) pipeline; node; node = node->parent) - pipeline_length++; - - g_assert_cmpint (pipeline_length, <=, 2); - - cogl_object_unref (pipeline); -} - -UNIT_TEST (check_uniform_ancestry, - 0 /* no requirements */, - TEST_KNOWN_FAILURE) -{ - CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); - CoglNode *node; - int pipeline_length = 0; - int i; - - /* Repeatedly making a copy of a pipeline and changing a uniform - * shouldn't cause a long chain of pipelines to be created */ - - for (i = 0; i < 20; i++) - { - CoglPipeline *tmp_pipeline; - int uniform_location; - - tmp_pipeline = cogl_pipeline_copy (pipeline); - cogl_object_unref (pipeline); - pipeline = tmp_pipeline; - - uniform_location = - cogl_pipeline_get_uniform_location (pipeline, "a_uniform"); - - cogl_pipeline_set_uniform_1i (pipeline, uniform_location, i); - } - - for (node = (CoglNode *) pipeline; node; node = node->parent) - pipeline_length++; - - g_assert_cmpint (pipeline_length, <=, 2); - - cogl_object_unref (pipeline); -} diff --git a/cogl/cogl/cogl-pipeline-state.h b/cogl/cogl/cogl-pipeline-state.h deleted file mode 100644 index 438768546..000000000 --- a/cogl/cogl/cogl-pipeline-state.h +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PIPELINE_STATE_H__ -#define __COGL_PIPELINE_STATE_H__ - -#include <cogl/cogl-pipeline.h> -#include <cogl/cogl-color.h> -#include <cogl/cogl-depth-state.h> - -G_BEGIN_DECLS - -/** - * cogl_pipeline_set_color: - * @pipeline: A #CoglPipeline object - * @color: The components of the color - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * Note that if you don't add any layers to the pipeline then the color - * will be blended unmodified with the destination; the default blend - * expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for - * semi-transparent red. See cogl_color_premultiply(). - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_color (CoglPipeline *pipeline, - const CoglColor *color); - -/** - * cogl_pipeline_set_color4ub: - * @pipeline: A #CoglPipeline object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * The default value is (0xff, 0xff, 0xff, 0xff) - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_color4ub (CoglPipeline *pipeline, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha); - -/** - * cogl_pipeline_set_color4f: - * @pipeline: A #CoglPipeline object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the pipeline, used when no lighting is enabled. - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_color4f (CoglPipeline *pipeline, - float red, - float green, - float blue, - float alpha); - -/** - * cogl_pipeline_get_color: - * @pipeline: A #CoglPipeline object - * @color: (out): The location to store the color - * - * Retrieves the current pipeline color. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_get_color (CoglPipeline *pipeline, - CoglColor *color); - -/** - * CoglPipelineAlphaFunc: - * @COGL_PIPELINE_ALPHA_FUNC_NEVER: Never let the fragment through. - * @COGL_PIPELINE_ALPHA_FUNC_LESS: Let the fragment through if the incoming - * alpha value is less than the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_EQUAL: Let the fragment through if the incoming - * alpha value equals the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_LEQUAL: Let the fragment through if the incoming - * alpha value is less than or equal to the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_GREATER: Let the fragment through if the incoming - * alpha value is greater than the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL: Let the fragment through if the incoming - * alpha value does not equal the reference alpha value - * @COGL_PIPELINE_ALPHA_FUNC_GEQUAL: Let the fragment through if the incoming - * alpha value is greater than or equal to the reference alpha value. - * @COGL_PIPELINE_ALPHA_FUNC_ALWAYS: Always let the fragment through. - * - * Alpha testing happens before blending primitives with the framebuffer and - * gives an opportunity to discard fragments based on a comparison with the - * incoming alpha value and a reference alpha value. The #CoglPipelineAlphaFunc - * determines how the comparison is done. - */ -typedef enum -{ - COGL_PIPELINE_ALPHA_FUNC_NEVER = 0x0200, - COGL_PIPELINE_ALPHA_FUNC_LESS = 0x0201, - COGL_PIPELINE_ALPHA_FUNC_EQUAL = 0x0202, - COGL_PIPELINE_ALPHA_FUNC_LEQUAL = 0x0203, - COGL_PIPELINE_ALPHA_FUNC_GREATER = 0x0204, - COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL = 0x0205, - COGL_PIPELINE_ALPHA_FUNC_GEQUAL = 0x0206, - COGL_PIPELINE_ALPHA_FUNC_ALWAYS = 0x0207 -} CoglPipelineAlphaFunc; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_pipeline_set_alpha_test_function: - * @pipeline: A #CoglPipeline object - * @alpha_func: A @CoglPipelineAlphaFunc constant - * @alpha_reference: A reference point that the chosen alpha function uses - * to compare incoming fragments to. - * - * Before a primitive is blended with the framebuffer, it goes through an - * alpha test stage which lets you discard fragments based on the current - * alpha value. This function lets you change the function used to evaluate - * the alpha channel, and thus determine which fragments are discarded - * and which continue on to the blending stage. - * - * The default is %COGL_PIPELINE_ALPHA_FUNC_ALWAYS - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_alpha_test_function (CoglPipeline *pipeline, - CoglPipelineAlphaFunc alpha_func, - float alpha_reference); - -/** - * cogl_pipeline_get_alpha_test_function: - * @pipeline: A #CoglPipeline object - * - * Return value: The alpha test function of @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT CoglPipelineAlphaFunc -cogl_pipeline_get_alpha_test_function (CoglPipeline *pipeline); - -/** - * cogl_pipeline_get_alpha_test_reference: - * @pipeline: A #CoglPipeline object - * - * Return value: The alpha test reference value of @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT float -cogl_pipeline_get_alpha_test_reference (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_blend: - * @pipeline: A #CoglPipeline object - * @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link> - * describing the desired blend function. - * @error: return location for a #GError that may report lack of driver - * support if you give separate blend string statements for the alpha - * channel and RGB channels since some drivers, or backends such as - * GLES 1.1, don't support this feature. May be %NULL, in which case a - * warning will be printed out using GLib's logging facilities if an - * error is encountered. - * - * If not already familiar; please refer <link linkend="cogl-Blend-Strings">here</link> - * for an overview of what blend strings are, and their syntax. - * - * Blending occurs after the alpha test function, and combines fragments with - * the framebuffer. - - * Currently the only blend function Cogl exposes is ADD(). So any valid - * blend statements will be of the form: - * - * |[ - * <channel-mask>=ADD(SRC_COLOR*(<factor>), DST_COLOR*(<factor>)) - * ]| - * - * This is the list of source-names usable as blend factors: - * <itemizedlist> - * <listitem><para>SRC_COLOR: The color of the incoming fragment</para></listitem> - * <listitem><para>DST_COLOR: The color of the framebuffer</para></listitem> - * <listitem><para>CONSTANT: The constant set via cogl_pipeline_set_blend_constant()</para></listitem> - * </itemizedlist> - * - * The source names can be used according to the - * <link linkend="cogl-Blend-String-syntax">color-source and factor syntax</link>, - * so for example "(1-SRC_COLOR[A])" would be a valid factor, as would - * "(CONSTANT[RGB])" - * - * These can also be used as factors: - * <itemizedlist> - * <listitem>0: (0, 0, 0, 0)</listitem> - * <listitem>1: (1, 1, 1, 1)</listitem> - * <listitem>SRC_ALPHA_SATURATE_FACTOR: (f,f,f,1) where f = MIN(SRC_COLOR[A],1-DST_COLOR[A])</listitem> - * </itemizedlist> - * - * <note>Remember; all color components are normalized to the range [0, 1] - * before computing the result of blending.</note> - * - * <example id="cogl-Blend-Strings-blend-unpremul"> - * <title>Blend Strings/1</title> - * <para>Blend a non-premultiplied source over a destination with - * premultiplied alpha:</para> - * <programlisting> - * "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))" - * "A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * </programlisting> - * </example> - * - * <example id="cogl-Blend-Strings-blend-premul"> - * <title>Blend Strings/2</title> - * <para>Blend a premultiplied source over a destination with - * premultiplied alpha</para> - * <programlisting> - * "RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * </programlisting> - * </example> - * - * The default blend string is: - * |[ - * RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A])) - * ]| - * - * That gives normal alpha-blending when the calculated color for the pipeline - * is in premultiplied form. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described blending is supported by the underlying driver/hardware. If - * there was an error, %FALSE is returned and @error is set accordingly (if - * present). - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_pipeline_set_blend (CoglPipeline *pipeline, - const char *blend_string, - GError **error); - -/** - * cogl_pipeline_set_blend_constant: - * @pipeline: A #CoglPipeline object - * @constant_color: The constant color you want - * - * When blending is setup to reference a CONSTANT blend factor then - * blending will depend on the constant set with this function. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_blend_constant (CoglPipeline *pipeline, - const CoglColor *constant_color); - -/** - * cogl_pipeline_set_point_size: - * @pipeline: a #CoglPipeline pointer - * @point_size: the new point size. - * - * Changes the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the attribute buffer API. Note that typically the GPU - * will only support a limited minimum and maximum range of point - * sizes. If the chosen point size is outside that range then the - * nearest value within that range will be used instead. The size of a - * point is in screen space so it will be the same regardless of any - * transformations. - * - * If the point size is set to 0.0 then drawing points with the - * pipeline will have undefined results. This is the default value so - * if an application wants to draw points it must make sure to use a - * pipeline that has an explicit point size set on it. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_point_size (CoglPipeline *pipeline, - float point_size); - -/** - * cogl_pipeline_get_point_size: - * @pipeline: a #CoglPipeline pointer - * - * Get the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. - * - * Return value: the point size of the @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT float -cogl_pipeline_get_point_size (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_per_vertex_point_size: - * @pipeline: a #CoglPipeline pointer - * @enable: whether to enable per-vertex point size - * @error: a location to store a #GError if the change failed - * - * Sets whether to use a per-vertex point size or to use the value set - * by cogl_pipeline_set_point_size(). If per-vertex point size is - * enabled then the point size can be set for an individual point - * either by drawing with a #CoglAttribute with the name - * ‘cogl_point_size_in’ or by writing to the GLSL builtin - * ‘cogl_point_size_out’ from a vertex shader snippet. - * - * If per-vertex point size is enabled and this attribute is not used - * and cogl_point_size_out is not written to then the results are - * undefined. - * - * Since: 2.0 - * Stability: Unstable - * Return value: %TRUE if the change succeeded or %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_pipeline_set_per_vertex_point_size (CoglPipeline *pipeline, - gboolean enable, - GError **error); - -/** - * cogl_pipeline_get_per_vertex_point_size: - * @pipeline: a #CoglPipeline pointer - * - * Since: 2.0 - * Stability: Unstable - * Return value: %TRUE if the pipeline has per-vertex point size - * enabled or %FALSE otherwise. The per-vertex point size can be - * enabled with cogl_pipeline_set_per_vertex_point_size(). - */ -COGL_EXPORT gboolean -cogl_pipeline_get_per_vertex_point_size (CoglPipeline *pipeline); - -/** - * cogl_pipeline_get_user_program: - * @pipeline: a #CoglPipeline object. - * - * Queries what user program has been associated with the given - * @pipeline using cogl_pipeline_set_user_program(). - * - * Return value: (transfer none): The current user program or %NULL. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT CoglHandle -cogl_pipeline_get_user_program (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_user_program: - * @pipeline: a #CoglPipeline object. - * @program: A #CoglHandle to a linked CoglProgram - * - * Associates a linked CoglProgram with the given pipeline so that the - * program can take full control of vertex and/or fragment processing. - * - * This is an example of how it can be used to associate an ARBfp - * program with a #CoglPipeline: - * |[ - * CoglHandle shader; - * CoglHandle program; - * CoglPipeline *pipeline; - * - * shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - * cogl_shader_source (shader, - * "!!ARBfp1.0\n" - * "MOV result.color,fragment.color;\n" - * "END\n"); - * - * program = cogl_create_program (); - * cogl_program_attach_shader (program, shader); - * cogl_program_link (program); - * - * pipeline = cogl_pipeline_new (); - * cogl_pipeline_set_user_program (pipeline, program); - * - * cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - * cogl_rectangle (0, 0, 100, 100); - * ]| - * - * It is possibly worth keeping in mind that this API is not part of - * the long term design for how we want to expose shaders to Cogl - * developers (We are planning on deprecating the cogl_program and - * cogl_shader APIs in favour of a "snippet" framework) but in the - * meantime we hope this will handle most practical GLSL and ARBfp - * requirements. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_user_program (CoglPipeline *pipeline, - CoglHandle program); - -/** - * cogl_pipeline_set_depth_state: (skip) - * @pipeline: A #CoglPipeline object - * @state: A #CoglDepthState struct - * @error: A #GError to report failures to setup the given @state. - * - * This commits all the depth state configured in @state struct to the - * given @pipeline. The configuration values are copied into the - * pipeline so there is no requirement to keep the #CoglDepthState - * struct around if you don't need it any more. - * - * Note: Since some platforms do not support the depth range feature - * it is possible for this function to fail and report an @error. - * - * Returns: TRUE if the GPU supports all the given @state else %FALSE - * and returns an @error. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_pipeline_set_depth_state (CoglPipeline *pipeline, - const CoglDepthState *state, - GError **error); - -/** - * cogl_pipeline_get_depth_state: (skip) - * @pipeline: A #CoglPipeline object - * @state_out: (out): A destination #CoglDepthState struct - * - * Retrieves the current depth state configuration for the given - * @pipeline as previously set using cogl_pipeline_set_depth_state(). - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_get_depth_state (CoglPipeline *pipeline, - CoglDepthState *state_out); - -/** - * CoglPipelineCullFaceMode: - * @COGL_PIPELINE_CULL_FACE_MODE_NONE: Neither face will be - * culled. This is the default. - * @COGL_PIPELINE_CULL_FACE_MODE_FRONT: Front faces will be culled. - * @COGL_PIPELINE_CULL_FACE_MODE_BACK: Back faces will be culled. - * @COGL_PIPELINE_CULL_FACE_MODE_BOTH: All faces will be culled. - * - * Specifies which faces should be culled. This can be set on a - * pipeline using cogl_pipeline_set_cull_face_mode(). - */ -typedef enum -{ - COGL_PIPELINE_CULL_FACE_MODE_NONE, - COGL_PIPELINE_CULL_FACE_MODE_FRONT, - COGL_PIPELINE_CULL_FACE_MODE_BACK, - COGL_PIPELINE_CULL_FACE_MODE_BOTH -} CoglPipelineCullFaceMode; - -/** - * cogl_pipeline_set_cull_face_mode: - * @pipeline: A #CoglPipeline - * @cull_face_mode: The new mode to set - * - * Sets which faces will be culled when drawing. Face culling can be - * used to increase efficiency by avoiding drawing faces that would - * get overridden. For example, if a model has gaps so that it is - * impossible to see the inside then faces which are facing away from - * the screen will never be seen so there is no point in drawing - * them. This can be achieved by setting the cull face mode to - * %COGL_PIPELINE_CULL_FACE_MODE_BACK. - * - * Face culling relies on the primitives being drawn with a specific - * order to represent which faces are facing inside and outside the - * model. This order can be specified by calling - * cogl_pipeline_set_front_face_winding(). - * - * Status: Unstable - * Since: 2.0 - */ -COGL_EXPORT void -cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline, - CoglPipelineCullFaceMode cull_face_mode); - -/** - * cogl_pipeline_get_cull_face_mode: - * - * Return value: the cull face mode that was previously set with - * cogl_pipeline_set_cull_face_mode(). - * - * Status: Unstable - * Since: 2.0 - */ -COGL_EXPORT CoglPipelineCullFaceMode -cogl_pipeline_get_cull_face_mode (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_front_face_winding: - * @pipeline: a #CoglPipeline - * @front_winding: the winding order - * - * The order of the vertices within a primitive specifies whether it - * is considered to be front or back facing. This function specifies - * which order is considered to be the front - * faces. %COGL_WINDING_COUNTER_CLOCKWISE sets the front faces to - * primitives with vertices in a counter-clockwise order and - * %COGL_WINDING_CLOCKWISE sets them to be clockwise. The default is - * %COGL_WINDING_COUNTER_CLOCKWISE. - * - * Status: Unstable - * Since: 2.0 - */ -COGL_EXPORT void -cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline, - CoglWinding front_winding); - -/** - * cogl_pipeline_get_front_face_winding: - * @pipeline: a #CoglPipeline - * - * The order of the vertices within a primitive specifies whether it - * is considered to be front or back facing. This function specifies - * which order is considered to be the front - * faces. %COGL_WINDING_COUNTER_CLOCKWISE sets the front faces to - * primitives with vertices in a counter-clockwise order and - * %COGL_WINDING_CLOCKWISE sets them to be clockwise. The default is - * %COGL_WINDING_COUNTER_CLOCKWISE. - * - * Returns: The @pipeline front face winding - * - * Status: Unstable - * Since: 2.0 - */ -COGL_EXPORT CoglWinding -cogl_pipeline_get_front_face_winding (CoglPipeline *pipeline); - -/** - * cogl_pipeline_set_uniform_1f: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @value: The new value for the uniform - * - * Sets a new value for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given value will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function should be used to set uniforms that are of type - * float. It can also be used to set a single member of a float array - * uniform. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline, - int uniform_location, - float value); - -/** - * cogl_pipeline_set_uniform_1i: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @value: The new value for the uniform - * - * Sets a new value for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given value will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function should be used to set uniforms that are of type - * int. It can also be used to set a single member of a int array - * uniform or a sampler uniform. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline, - int uniform_location, - int value); - -/** - * cogl_pipeline_set_uniform_float: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @n_components: The number of components in the corresponding uniform's type - * @count: The number of values to set - * @value: Pointer to the new values to set - * - * Sets new values for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given values will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function can be used to set any floating point type uniform, - * including float arrays and float vectors. For example, to set a - * single vec4 uniform you would use 4 for @n_components and 1 for - * @count. To set an array of 8 float values, you could use 1 for - * @n_components and 8 for @count. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_float (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const float *value); - -/** - * cogl_pipeline_set_uniform_int: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @n_components: The number of components in the corresponding uniform's type - * @count: The number of values to set - * @value: Pointer to the new values to set - * - * Sets new values for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given values will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function can be used to set any integer type uniform, - * including int arrays and int vectors. For example, to set a single - * ivec4 uniform you would use 4 for @n_components and 1 for - * @count. To set an array of 8 int values, you could use 1 for - * @n_components and 8 for @count. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_int (CoglPipeline *pipeline, - int uniform_location, - int n_components, - int count, - const int *value); - -/** - * cogl_pipeline_set_uniform_matrix: - * @pipeline: A #CoglPipeline object - * @uniform_location: The uniform's location identifier - * @dimensions: The size of the matrix - * @count: The number of values to set - * @transpose: Whether to transpose the matrix - * @value: Pointer to the new values to set - * - * Sets new values for the uniform at @uniform_location. If this - * pipeline has a user program attached and is later used as a source - * for drawing, the given values will be assigned to the uniform which - * can be accessed from the shader's source. The value for - * @uniform_location should be retrieved from the string name of the - * uniform by calling cogl_pipeline_get_uniform_location(). - * - * This function can be used to set any matrix type uniform, including - * matrix arrays. For example, to set a single mat4 uniform you would - * use 4 for @dimensions and 1 for @count. To set an array of 8 - * mat3 values, you could use 3 for @dimensions and 8 for @count. - * - * If @transpose is %FALSE then the matrix is expected to be in - * column-major order or if it is %TRUE then the matrix is in - * row-major order. You can pass a #graphene_matrix_t by calling by passing - * the result of graphene_matrix_to_float() in @value and setting - * @transpose to %FALSE. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value); - -/** - * cogl_pipeline_add_snippet: (skip) - * @pipeline: A #CoglPipeline - * @snippet: The #CoglSnippet to add to the vertex processing hook - * - * Adds a shader snippet to @pipeline. The snippet will wrap around or - * replace some part of the pipeline as defined by the hook point in - * @snippet. Note that some hook points are specific to a layer and - * must be added with cogl_pipeline_add_layer_snippet() instead. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_add_snippet (CoglPipeline *pipeline, - CoglSnippet *snippet); - -G_END_DECLS - -#endif /* __COGL_PIPELINE_STATE_H__ */ diff --git a/cogl/cogl/cogl-pipeline.c b/cogl/cogl/cogl-pipeline.c deleted file mode 100644 index 90499ce5e..000000000 --- a/cogl/cogl/cogl-pipeline.c +++ /dev/null @@ -1,2823 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-context-private.h" -#include "cogl-object.h" - -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-pipeline-layer-state-private.h" -#include "cogl-texture-private.h" -#include "cogl-blend-string.h" -#include "cogl-journal-private.h" -#include "cogl-color-private.h" -#include "cogl-util.h" -#include "cogl-profile.h" -#include "cogl-depth-state-private.h" -#include "cogl1-context.h" -#include "cogl-gtype-private.h" - -#include <glib.h> -#include <glib/gprintf.h> -#include <string.h> - -static void _cogl_pipeline_free (CoglPipeline *tex); -static void recursively_free_layer_caches (CoglPipeline *pipeline); -static gboolean _cogl_pipeline_is_weak (CoglPipeline *pipeline); - -const CoglPipelineFragend *_cogl_pipeline_fragend; -const CoglPipelineVertend *_cogl_pipeline_vertend; -const CoglPipelineProgend *_cogl_pipeline_progend; - -#include "driver/gl/cogl-pipeline-fragend-glsl-private.h" -#include "driver/gl/cogl-pipeline-vertend-glsl-private.h" -#include "driver/gl/cogl-pipeline-progend-glsl-private.h" - -COGL_OBJECT_DEFINE (Pipeline, pipeline); -COGL_GTYPE_DEFINE_CLASS (Pipeline, pipeline); - -/* - * This initializes the first pipeline owned by the Cogl context. All - * subsequently instantiated pipelines created via the cogl_pipeline_new() - * API will initially be a copy of this pipeline. - * - * The default pipeline is the topmost ancester for all pipelines. - */ -void -_cogl_pipeline_init_default_pipeline (void) -{ - /* Create new - blank - pipeline */ - CoglPipeline *pipeline = g_new0 (CoglPipeline, 1); - /* XXX: NB: It's important that we zero this to avoid polluting - * pipeline hash values with un-initialized data */ - CoglPipelineBigState *big_state = g_new0 (CoglPipelineBigState, 1); - CoglPipelineAlphaFuncState *alpha_state = &big_state->alpha_state; - CoglPipelineBlendState *blend_state = &big_state->blend_state; - CoglPipelineCullFaceState *cull_face_state = &big_state->cull_face_state; - CoglPipelineUniformsState *uniforms_state = &big_state->uniforms_state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Take this opportunity to setup the backends... */ - _cogl_pipeline_fragend = &_cogl_pipeline_glsl_fragend; - _cogl_pipeline_progend = &_cogl_pipeline_glsl_progend; - _cogl_pipeline_vertend = &_cogl_pipeline_glsl_vertend; - - _cogl_pipeline_node_init (COGL_NODE (pipeline)); - - pipeline->is_weak = FALSE; - pipeline->journal_ref_count = 0; - pipeline->differences = COGL_PIPELINE_STATE_ALL_SPARSE; - - pipeline->real_blend_enable = FALSE; - - pipeline->layer_differences = NULL; - pipeline->n_layers = 0; - - pipeline->big_state = big_state; - pipeline->has_big_state = TRUE; - - pipeline->static_breadcrumb = "default pipeline"; - pipeline->has_static_breadcrumb = TRUE; - - pipeline->age = 0; - - /* Use the same defaults as the GL spec... */ - cogl_color_init_from_4ub (&pipeline->color, 0xff, 0xff, 0xff, 0xff); - - /* Use the same defaults as the GL spec... */ - alpha_state->alpha_func = COGL_PIPELINE_ALPHA_FUNC_ALWAYS; - alpha_state->alpha_func_reference = 0.0; - - /* Not the same as the GL default, but seems saner... */ -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - blend_state->blend_equation_rgb = GL_FUNC_ADD; - blend_state->blend_equation_alpha = GL_FUNC_ADD; - blend_state->blend_src_factor_alpha = GL_ONE; - blend_state->blend_dst_factor_alpha = GL_ONE_MINUS_SRC_ALPHA; - cogl_color_init_from_4ub (&blend_state->blend_constant, - 0x00, 0x00, 0x00, 0x00); -#endif - blend_state->blend_src_factor_rgb = GL_ONE; - blend_state->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA; - - big_state->user_program = NULL; - - cogl_depth_state_init (&big_state->depth_state); - - big_state->point_size = 0.0f; - - cull_face_state->mode = COGL_PIPELINE_CULL_FACE_MODE_NONE; - cull_face_state->front_winding = COGL_WINDING_COUNTER_CLOCKWISE; - - _cogl_bitmask_init (&uniforms_state->override_mask); - _cogl_bitmask_init (&uniforms_state->changed_mask); - uniforms_state->override_values = NULL; - - ctx->default_pipeline = _cogl_pipeline_object_new (pipeline); -} - -static void -_cogl_pipeline_unparent (CoglNode *pipeline) -{ - /* Chain up */ - _cogl_pipeline_node_unparent_real (pipeline); -} - -static gboolean -recursively_free_layer_caches_cb (CoglNode *node, - void *user_data) -{ - recursively_free_layer_caches (COGL_PIPELINE (node)); - return TRUE; -} - -/* This recursively frees the layers_cache of a pipeline and all of - * its descendants. - * - * For instance if we change a pipelines ->layer_differences list - * then that pipeline and all of its descendants may now have - * incorrect layer caches. */ -static void -recursively_free_layer_caches (CoglPipeline *pipeline) -{ - /* Note: we maintain the invariable that if a pipeline already has a - * dirty layers_cache then so do all of its descendants. */ - if (pipeline->layers_cache_dirty) - return; - - if (G_UNLIKELY (pipeline->layers_cache != pipeline->short_layers_cache)) - g_free (pipeline->layers_cache); - pipeline->layers_cache_dirty = TRUE; - - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - recursively_free_layer_caches_cb, - NULL); -} - -static void -_cogl_pipeline_set_parent (CoglPipeline *pipeline, - CoglPipeline *parent, - gboolean take_strong_reference) -{ - /* Chain up */ - _cogl_pipeline_node_set_parent_real (COGL_NODE (pipeline), - COGL_NODE (parent), - _cogl_pipeline_unparent, - take_strong_reference); - - /* Since we just changed the ancestry of the pipeline its cache of - * layers could now be invalid so free it... */ - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - recursively_free_layer_caches (pipeline); -} - -static void -_cogl_pipeline_promote_weak_ancestors (CoglPipeline *strong) -{ - CoglNode *n; - - g_return_if_fail (!strong->is_weak); - - /* If the parent of strong is weak, then we want to promote it by - taking a reference on strong's grandparent. We don't need to take - a reference on strong's direct parent */ - - if (COGL_NODE (strong)->parent == NULL) - return; - - for (n = COGL_NODE (strong)->parent; - /* We can assume that all weak pipelines have a parent */ - COGL_PIPELINE (n)->is_weak; - n = n->parent) - /* 'n' is weak so we take a reference on its parent */ - cogl_object_ref (n->parent); -} - -static void -_cogl_pipeline_revert_weak_ancestors (CoglPipeline *strong) -{ - CoglNode *n; - - g_return_if_fail (!strong->is_weak); - - /* This reverts the effect of calling - _cogl_pipeline_promote_weak_ancestors */ - - if (COGL_NODE (strong)->parent == NULL) - return; - - for (n = COGL_NODE (strong)->parent; - /* We can assume that all weak pipelines have a parent */ - COGL_PIPELINE (n)->is_weak; - n = n->parent) - /* 'n' is weak so we unref its parent */ - cogl_object_unref (n->parent); -} - -/* XXX: Always have an eye out for opportunities to lower the cost of - * cogl_pipeline_copy. */ -static CoglPipeline * -_cogl_pipeline_copy (CoglPipeline *src, gboolean is_weak) -{ - CoglPipeline *pipeline = g_new0 (CoglPipeline, 1); - - _cogl_pipeline_node_init (COGL_NODE (pipeline)); - - pipeline->is_weak = is_weak; - - pipeline->journal_ref_count = 0; - - pipeline->differences = 0; - - pipeline->has_big_state = FALSE; - - /* NB: real_blend_enable isn't a sparse property, it's valid for - * every pipeline node so we have fast access to it. */ - pipeline->real_blend_enable = src->real_blend_enable; - pipeline->dirty_real_blend_enable = src->dirty_real_blend_enable; - pipeline->unknown_color_alpha = src->unknown_color_alpha; - - /* XXX: - * consider generalizing the idea of "cached" properties. These - * would still have an authority like other sparse properties but - * you wouldn't have to walk up the ancestry to find the authority - * because the value would be cached directly in each pipeline. - */ - - pipeline->layers_cache_dirty = TRUE; - - pipeline->has_static_breadcrumb = FALSE; - - pipeline->age = 0; - - _cogl_pipeline_set_parent (pipeline, src, !is_weak); - - /* The semantics for copying a weak pipeline are that we promote all - * weak ancestors to temporarily become strong pipelines until the - * copy is freed. */ - if (!is_weak) - _cogl_pipeline_promote_weak_ancestors (pipeline); - - return _cogl_pipeline_object_new (pipeline); -} - -CoglPipeline * -cogl_pipeline_copy (CoglPipeline *src) -{ - return _cogl_pipeline_copy (src, FALSE); -} - -CoglPipeline * -_cogl_pipeline_weak_copy (CoglPipeline *pipeline, - CoglPipelineDestroyCallback callback, - void *user_data) -{ - CoglPipeline *copy; - CoglPipeline *copy_pipeline; - - copy = _cogl_pipeline_copy (pipeline, TRUE); - copy_pipeline = COGL_PIPELINE (copy); - copy_pipeline->destroy_callback = callback; - copy_pipeline->destroy_data = user_data; - - return copy; -} - -CoglPipeline * -cogl_pipeline_new (CoglContext *context) -{ - CoglPipeline *new; - - new = cogl_pipeline_copy (context->default_pipeline); -#ifdef COGL_DEBUG_ENABLED - _cogl_pipeline_set_static_breadcrumb (new, "new"); -#endif - return new; -} - -static gboolean -destroy_weak_children_cb (CoglNode *node, - void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - - if (_cogl_pipeline_is_weak (pipeline)) - { - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - pipeline->destroy_callback (pipeline, pipeline->destroy_data); - _cogl_pipeline_unparent (COGL_NODE (pipeline)); - } - - return TRUE; -} - -static void -_cogl_pipeline_free (CoglPipeline *pipeline) -{ - if (!pipeline->is_weak) - _cogl_pipeline_revert_weak_ancestors (pipeline); - - /* Weak pipelines don't take a reference on their parent */ - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - g_assert (_cogl_list_empty (&COGL_NODE (pipeline)->children)); - - _cogl_pipeline_unparent (COGL_NODE (pipeline)); - - if (pipeline->differences & COGL_PIPELINE_STATE_USER_SHADER && - pipeline->big_state->user_program) - cogl_object_unref (pipeline->big_state->user_program); - - if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) - { - CoglPipelineUniformsState *uniforms_state - = &pipeline->big_state->uniforms_state; - int n_overrides = _cogl_bitmask_popcount (&uniforms_state->override_mask); - int i; - - for (i = 0; i < n_overrides; i++) - _cogl_boxed_value_destroy (uniforms_state->override_values + i); - g_free (uniforms_state->override_values); - - _cogl_bitmask_destroy (&uniforms_state->override_mask); - _cogl_bitmask_destroy (&uniforms_state->changed_mask); - } - - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - g_list_free_full (pipeline->layer_differences, cogl_object_unref); - - if (pipeline->differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) - _cogl_pipeline_snippet_list_free (&pipeline->big_state->vertex_snippets); - - if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - _cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets); - - if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - g_free (pipeline->big_state); - - recursively_free_layer_caches (pipeline); - - g_free (pipeline); -} - -gboolean -_cogl_pipeline_get_real_blend_enabled (CoglPipeline *pipeline) -{ - g_return_val_if_fail (cogl_is_pipeline (pipeline), FALSE); - - return pipeline->real_blend_enable; -} - -static void -_cogl_pipeline_update_layers_cache (CoglPipeline *pipeline) -{ - /* Note: we assume this pipeline is a _LAYERS authority */ - int n_layers; - CoglPipeline *current; - int layers_found; - - if (G_LIKELY (!pipeline->layers_cache_dirty) || - pipeline->n_layers == 0) - return; - - pipeline->layers_cache_dirty = FALSE; - - n_layers = pipeline->n_layers; - if (G_LIKELY (n_layers < G_N_ELEMENTS (pipeline->short_layers_cache))) - { - pipeline->layers_cache = pipeline->short_layers_cache; - memset (pipeline->layers_cache, 0, - sizeof (CoglPipelineLayer *) * - G_N_ELEMENTS (pipeline->short_layers_cache)); - } - else - { - pipeline->layers_cache = - g_malloc0 (sizeof (CoglPipelineLayer *) * n_layers); - } - - /* Notes: - * - * Each pipeline doesn't have to contain a complete list of the layers - * it depends on, some of them are indirectly referenced through the - * pipeline's ancestors. - * - * pipeline->layer_differences only contains a list of layers that - * have changed in relation to its parent. - * - * pipeline->layer_differences is not maintained sorted, but it - * won't contain multiple layers corresponding to a particular - * ->unit_index. - * - * Some of the ancestor pipelines may reference layers with - * ->unit_index values >= n_layers so we ignore them. - * - * As we ascend through the ancestors we are searching for any - * CoglPipelineLayers corresponding to the texture ->unit_index - * values in the range [0,n_layers-1]. As soon as a pointer is found - * we ignore layers of further ancestors with the same ->unit_index - * values. - */ - - layers_found = 0; - for (current = pipeline; - _cogl_pipeline_get_parent (current); - current = _cogl_pipeline_get_parent (current)) - { - GList *l; - - if (!(current->differences & COGL_PIPELINE_STATE_LAYERS)) - continue; - - for (l = current->layer_differences; l; l = l->next) - { - CoglPipelineLayer *layer = l->data; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - if (unit_index < n_layers && !pipeline->layers_cache[unit_index]) - { - pipeline->layers_cache[unit_index] = layer; - layers_found++; - if (layers_found == n_layers) - return; - } - } - } - - g_warn_if_reached (); -} - -/* XXX: Be careful when using this API that the callback given doesn't result - * in the layer cache being invalidated during the iteration! */ -void -_cogl_pipeline_foreach_layer_internal (CoglPipeline *pipeline, - CoglPipelineInternalLayerCallback callback, - void *user_data) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - int n_layers; - int i; - gboolean cont; - - n_layers = authority->n_layers; - if (n_layers == 0) - return; - - _cogl_pipeline_update_layers_cache (authority); - - for (i = 0, cont = TRUE; i < n_layers && cont == TRUE; i++) - { - g_return_if_fail (authority->layers_cache_dirty == FALSE); - cont = callback (authority->layers_cache[i], user_data); - } -} - -gboolean -_cogl_pipeline_layer_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - CoglPipeline *authority0 = - _cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS); - CoglPipeline *authority1 = - _cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS); - int n_layers = authority0->n_layers; - int i; - - if (authority1->n_layers != n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer0 = authority0->layers_cache[i]; - CoglPipelineLayer *layer1 = authority1->layers_cache[i]; - - if (layer0->index != layer1->index) - return FALSE; - } - - return TRUE; -} - -gboolean -_cogl_pipeline_layer_and_unit_numbers_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - CoglPipeline *authority0 = - _cogl_pipeline_get_authority (pipeline0, COGL_PIPELINE_STATE_LAYERS); - CoglPipeline *authority1 = - _cogl_pipeline_get_authority (pipeline1, COGL_PIPELINE_STATE_LAYERS); - int n_layers = authority0->n_layers; - int i; - - if (authority1->n_layers != n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer0 = authority0->layers_cache[i]; - CoglPipelineLayer *layer1 = authority1->layers_cache[i]; - int unit0, unit1; - - if (layer0->index != layer1->index) - return FALSE; - - unit0 = _cogl_pipeline_layer_get_unit_index (layer0); - unit1 = _cogl_pipeline_layer_get_unit_index (layer1); - if (unit0 != unit1) - return FALSE; - } - - return TRUE; -} - -typedef struct -{ - int i; - int *indices; -} AppendLayerIndexState; - -static gboolean -append_layer_index_cb (CoglPipelineLayer *layer, - void *user_data) -{ - AppendLayerIndexState *state = user_data; - state->indices[state->i++] = layer->index; - return TRUE; -} - -void -cogl_pipeline_foreach_layer (CoglPipeline *pipeline, - CoglPipelineLayerCallback callback, - void *user_data) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - AppendLayerIndexState state; - gboolean cont; - int i; - - /* XXX: We don't know what the user is going to want to do to the layers - * but any modification of layers can result in the layer graph changing - * which could confuse _cogl_pipeline_foreach_layer_internal(). We first - * get a list of layer indices which will remain valid so long as the - * user doesn't remove layers. */ - - state.i = 0; - state.indices = g_alloca (authority->n_layers * sizeof (int)); - - _cogl_pipeline_foreach_layer_internal (pipeline, - append_layer_index_cb, - &state); - - for (i = 0, cont = TRUE; i < authority->n_layers && cont; i++) - cont = callback (pipeline, state.indices[i], user_data); -} - -static gboolean -layer_has_alpha_cb (CoglPipelineLayer *layer, void *data) -{ - gboolean *has_alpha = data; - *has_alpha = _cogl_pipeline_layer_has_alpha (layer); - - /* return FALSE to stop iterating layers if we find any layer - * has alpha ... - * - * FIXME: actually we should never be bailing out because it's - * always possible that a later layer could discard any previous - * alpha! - */ - - return !(*has_alpha); -} - -/* NB: If this pipeline returns FALSE that doesn't mean that the - * pipeline is definitely opaque, it just means that that the - * given changes dont imply transparency. - * - * If you want to find out of the pipeline is opaque then assuming - * this returns FALSE for a set of changes then you can follow - * up - */ -static gboolean -_cogl_pipeline_change_implies_transparency (CoglPipeline *pipeline, - unsigned int changes, - const CoglColor *override_color, - gboolean unknown_color_alpha) -{ - /* In the case of a layer state change we need to check everything - * else first since they contribute to the has_alpha status of the - * "PREVIOUS" layer. */ - if (changes & COGL_PIPELINE_STATE_LAYERS) - changes = COGL_PIPELINE_STATE_AFFECTS_BLENDING; - - if (unknown_color_alpha) - return TRUE; - - if ((override_color && cogl_color_get_alpha_byte (override_color) != 0xff)) - return TRUE; - - if (changes & COGL_PIPELINE_STATE_COLOR) - { - CoglColor tmp; - cogl_pipeline_get_color (pipeline, &tmp); - if (cogl_color_get_alpha_byte (&tmp) != 0xff) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_USER_SHADER) - { - /* We can't make any assumptions about the alpha channel if the user - * is using an unknown fragment shader. - * - * TODO: check that it isn't just a vertex shader! - */ - if (_cogl_pipeline_get_user_program (pipeline) != NULL) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - { - if (_cogl_pipeline_has_non_layer_fragment_snippets (pipeline)) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) - { - if (_cogl_pipeline_has_non_layer_vertex_snippets (pipeline)) - return TRUE; - } - - if (changes & COGL_PIPELINE_STATE_LAYERS) - { - /* has_alpha tracks the alpha status of the GL_PREVIOUS layer. - * To start with that's defined by the pipeline color which - * must be fully opaque if we got this far. */ - gboolean has_alpha = FALSE; - _cogl_pipeline_foreach_layer_internal (pipeline, - layer_has_alpha_cb, - &has_alpha); - if (has_alpha) - return TRUE; - } - - return FALSE; -} - -static gboolean -_cogl_pipeline_needs_blending_enabled (CoglPipeline *pipeline, - unsigned int changes, - const CoglColor *override_color, - gboolean unknown_color_alpha) -{ - CoglPipeline *blend_authority; - CoglPipelineBlendState *blend_state; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BLENDING))) - return FALSE; - - blend_authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); - - blend_state = &blend_authority->big_state->blend_state; - - /* We are trying to identify some cases that are equivalent to - * blending being disable, where the output is simply GL_SRC_COLOR. - * - * Note: we currently only consider a few cases that can be - * optimized but there could be opportunities to special case more - * blend functions later. - */ - - /* As the most common way that we currently use to effectively - * disable blending is to use an equation of - * "RGBA=ADD(SRC_COLOR, 0)" that's the first thing we check - * for... */ - if (blend_state->blend_equation_rgb == GL_FUNC_ADD && - blend_state->blend_equation_alpha == GL_FUNC_ADD && - blend_state->blend_src_factor_alpha == GL_ONE && - blend_state->blend_dst_factor_alpha == GL_ZERO) - { - return FALSE; - } - - /* NB: The default blending equation for Cogl is - * "RGBA=ADD(SRC_COLOR, DST_COLOR * (1-SRC_COLOR[A]))" - * - * Next we check if the default blending equation is being used. If - * so then we follow that by looking for cases where SRC_COLOR[A] == - * 1 since that simplifies "DST_COLOR * (1-SRC_COLOR[A])" to 0 which - * also effectively requires no blending. - */ - - if (blend_state->blend_equation_rgb != GL_FUNC_ADD || - blend_state->blend_equation_alpha != GL_FUNC_ADD) - return TRUE; - - if (blend_state->blend_src_factor_alpha != GL_ONE || - blend_state->blend_dst_factor_alpha != GL_ONE_MINUS_SRC_ALPHA) - return TRUE; - - if (blend_state->blend_src_factor_rgb != GL_ONE || - blend_state->blend_dst_factor_rgb != GL_ONE_MINUS_SRC_ALPHA) - return TRUE; - - /* Given the above constraints, it's now a case of finding any - * SRC_ALPHA that != 1 */ - - if (_cogl_pipeline_change_implies_transparency (pipeline, changes, - override_color, - unknown_color_alpha)) - return TRUE; - - /* At this point, considering just the state that has changed it - * looks like blending isn't needed. If blending was previously - * enabled though it could be that some other state still requires - * that we have blending enabled because it implies transparency. - * In this case we still need to go and check the other state... - * - * XXX: We could explicitly keep track of the mask of state groups - * that are currently causing blending to be enabled so that we - * never have to resort to checking *all* the state and can instead - * always limit the check to those in the mask. - */ - if (pipeline->real_blend_enable) - { - unsigned int other_state = - COGL_PIPELINE_STATE_AFFECTS_BLENDING & ~changes; - if (other_state && - _cogl_pipeline_change_implies_transparency (pipeline, other_state, NULL, FALSE)) - return TRUE; - } - - return FALSE; -} - -static void -_cogl_pipeline_copy_differences (CoglPipeline *dest, - CoglPipeline *src, - unsigned long differences) -{ - CoglPipelineBigState *big_state; - - if (differences & COGL_PIPELINE_STATE_COLOR) - dest->color = src->color; - - if (differences & COGL_PIPELINE_STATE_LAYERS) - { - GList *l; - - if (dest->differences & COGL_PIPELINE_STATE_LAYERS && - dest->layer_differences) - g_list_free_full (dest->layer_differences, cogl_object_unref); - - for (l = src->layer_differences; l; l = l->next) - { - /* NB: a layer can't have more than one ->owner so we can't - * simply take a references on each of the original - * layer_differences, we have to derive new layers from the - * originals instead. */ - CoglPipelineLayer *copy = _cogl_pipeline_layer_copy (l->data); - _cogl_pipeline_add_layer_difference (dest, copy, FALSE); - cogl_object_unref (copy); - } - - /* Note: we initialize n_layers after adding the layer differences - * since the act of adding the layers will initialize n_layers to 0 - * because dest isn't initially a STATE_LAYERS authority. */ - dest->n_layers = src->n_layers; - } - - if (differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE) - { - if (!dest->has_big_state) - { - dest->big_state = g_new0 (CoglPipelineBigState, 1); - dest->has_big_state = TRUE; - } - big_state = dest->big_state; - } - else - goto check_for_blending_change; - - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC) - big_state->alpha_state.alpha_func = - src->big_state->alpha_state.alpha_func; - - if (differences & COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE) - big_state->alpha_state.alpha_func_reference = - src->big_state->alpha_state.alpha_func_reference; - - if (differences & COGL_PIPELINE_STATE_BLEND) - { - memcpy (&big_state->blend_state, - &src->big_state->blend_state, - sizeof (CoglPipelineBlendState)); - } - - if (differences & COGL_PIPELINE_STATE_USER_SHADER) - { - if (src->big_state->user_program) - big_state->user_program = - cogl_object_ref (src->big_state->user_program); - else - big_state->user_program = NULL; - } - - if (differences & COGL_PIPELINE_STATE_DEPTH) - { - memcpy (&big_state->depth_state, - &src->big_state->depth_state, - sizeof (CoglDepthState)); - } - - if (differences & COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE) - big_state->non_zero_point_size = src->big_state->non_zero_point_size; - - if (differences & COGL_PIPELINE_STATE_POINT_SIZE) - big_state->point_size = src->big_state->point_size; - - if (differences & COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE) - big_state->per_vertex_point_size = src->big_state->per_vertex_point_size; - - if (differences & COGL_PIPELINE_STATE_CULL_FACE) - { - memcpy (&big_state->cull_face_state, - &src->big_state->cull_face_state, - sizeof (CoglPipelineCullFaceState)); - } - - if (differences & COGL_PIPELINE_STATE_UNIFORMS) - { - int n_overrides = - _cogl_bitmask_popcount (&src->big_state->uniforms_state.override_mask); - int i; - - big_state->uniforms_state.override_values = - g_malloc (n_overrides * sizeof (CoglBoxedValue)); - - for (i = 0; i < n_overrides; i++) - { - CoglBoxedValue *dst_bv = - big_state->uniforms_state.override_values + i; - const CoglBoxedValue *src_bv = - src->big_state->uniforms_state.override_values + i; - - _cogl_boxed_value_copy (dst_bv, src_bv); - } - - _cogl_bitmask_init (&big_state->uniforms_state.override_mask); - _cogl_bitmask_set_bits (&big_state->uniforms_state.override_mask, - &src->big_state->uniforms_state.override_mask); - - _cogl_bitmask_init (&big_state->uniforms_state.changed_mask); - } - - if (differences & COGL_PIPELINE_STATE_VERTEX_SNIPPETS) - _cogl_pipeline_snippet_list_copy (&big_state->vertex_snippets, - &src->big_state->vertex_snippets); - - if (differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS) - _cogl_pipeline_snippet_list_copy (&big_state->fragment_snippets, - &src->big_state->fragment_snippets); - - /* XXX: we shouldn't bother doing this in most cases since - * _copy_differences is typically used to initialize pipeline state - * by copying it from the current authority, so it's not actually - * *changing* anything. - */ -check_for_blending_change: - if (differences & COGL_PIPELINE_STATE_AFFECTS_BLENDING) - dest->dirty_real_blend_enable = TRUE; - - dest->differences |= differences; -} - -static void -_cogl_pipeline_init_multi_property_sparse_state (CoglPipeline *pipeline, - CoglPipelineState change) -{ - CoglPipeline *authority; - - g_return_if_fail (change & COGL_PIPELINE_STATE_ALL_SPARSE); - - if (!(change & COGL_PIPELINE_STATE_MULTI_PROPERTY)) - return; - - authority = _cogl_pipeline_get_authority (pipeline, change); - - switch (change) - { - /* XXX: avoid using a default: label so we get a warning if we - * don't explicitly handle a newly defined state-group here. */ - case COGL_PIPELINE_STATE_COLOR: - case COGL_PIPELINE_STATE_ALPHA_FUNC: - case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE: - case COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE: - case COGL_PIPELINE_STATE_POINT_SIZE: - case COGL_PIPELINE_STATE_USER_SHADER: - case COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE: - case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE: - g_return_if_reached (); - - case COGL_PIPELINE_STATE_LAYERS: - pipeline->n_layers = authority->n_layers; - pipeline->layer_differences = NULL; - break; - case COGL_PIPELINE_STATE_BLEND: - { - memcpy (&pipeline->big_state->blend_state, - &authority->big_state->blend_state, - sizeof (CoglPipelineBlendState)); - break; - } - case COGL_PIPELINE_STATE_DEPTH: - { - memcpy (&pipeline->big_state->depth_state, - &authority->big_state->depth_state, - sizeof (CoglDepthState)); - break; - } - case COGL_PIPELINE_STATE_CULL_FACE: - { - memcpy (&pipeline->big_state->cull_face_state, - &authority->big_state->cull_face_state, - sizeof (CoglPipelineCullFaceState)); - break; - } - case COGL_PIPELINE_STATE_UNIFORMS: - { - CoglPipelineUniformsState *uniforms_state = - &pipeline->big_state->uniforms_state; - _cogl_bitmask_init (&uniforms_state->override_mask); - _cogl_bitmask_init (&uniforms_state->changed_mask); - uniforms_state->override_values = NULL; - break; - } - case COGL_PIPELINE_STATE_VERTEX_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&pipeline->big_state->vertex_snippets, - &authority->big_state->vertex_snippets); - break; - - case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS: - _cogl_pipeline_snippet_list_copy (&pipeline->big_state->fragment_snippets, - &authority->big_state-> - fragment_snippets); - break; - } -} - -static gboolean -check_if_strong_cb (CoglNode *node, void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - gboolean *has_strong_child = user_data; - - if (!_cogl_pipeline_is_weak (pipeline)) - { - *has_strong_child = TRUE; - return FALSE; - } - - return TRUE; -} - -static gboolean -has_strong_children (CoglPipeline *pipeline) -{ - gboolean has_strong_child = FALSE; - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - check_if_strong_cb, - &has_strong_child); - return has_strong_child; -} - -static gboolean -_cogl_pipeline_is_weak (CoglPipeline *pipeline) -{ - if (pipeline->is_weak && !has_strong_children (pipeline)) - return TRUE; - else - return FALSE; -} - -static gboolean -reparent_children_cb (CoglNode *node, - void *user_data) -{ - CoglPipeline *pipeline = COGL_PIPELINE (node); - CoglPipeline *parent = user_data; - - _cogl_pipeline_set_parent (pipeline, parent, TRUE); - - return TRUE; -} - -void -_cogl_pipeline_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color, - gboolean from_layer_change) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If primitives have been logged in the journal referencing the - * current state of this pipeline we need to flush the journal - * before we can modify it... */ - if (pipeline->journal_ref_count) - { - gboolean skip_journal_flush = FALSE; - - /* XXX: We don't usually need to flush the journal just due to - * color changes since pipeline colors are logged in the - * journal's vertex buffer. The exception is when the change in - * color enables or disables the need for blending. */ - if (change == COGL_PIPELINE_STATE_COLOR) - { - gboolean will_need_blending = - _cogl_pipeline_needs_blending_enabled (pipeline, - change, - new_color, - FALSE); - gboolean blend_enable = pipeline->real_blend_enable ? TRUE : FALSE; - - if (will_need_blending == blend_enable) - skip_journal_flush = TRUE; - } - - if (!skip_journal_flush) - { - /* XXX: note we use cogl_flush() not _cogl_flush_journal() so - * we will flush *all* known journals that might reference the - * current pipeline. */ - cogl_flush (); - } - } - - /* XXX: - * To simplify things for the vertex, fragment and program backends - * we are careful about how we report STATE_LAYERS changes. - * - * All STATE_LAYERS change notifications with the exception of - * ->n_layers will also result in layer_pre_change_notifications. - * - * For backends that perform code generation for fragment processing - * they typically need to understand the details of how layers get - * changed to determine if they need to repeat codegen. It doesn't - * help them to report a pipeline STATE_LAYERS change for all layer - * changes since it's so broad, they really need to wait for the - * specific layer change to be notified. What does help though is - * to report a STATE_LAYERS change for a change in ->n_layers - * because they typically do need to repeat codegen in that case. - * - * Here we ensure that change notifications against a pipeline or - * against a layer are mutually exclusive as far as fragment, vertex - * and program backends are concerned. - * - * NB: A pipeline can potentially have private state from multiple - * backends associated with it because descendants may cache state - * with an ancestor to maximize the chance that it can later be - * re-used by other descendants and a descendent can require a - * different backend to an ancestor. - */ - if (!from_layer_change) - { - const CoglPipelineProgend *progend = _cogl_pipeline_progend; - const CoglPipelineVertend *vertend = _cogl_pipeline_vertend; - const CoglPipelineFragend *fragend = _cogl_pipeline_fragend; - - if (vertend->pipeline_pre_change_notify) - vertend->pipeline_pre_change_notify (pipeline, change, new_color); - - /* TODO: make the vertend and fragend implementation details - * of the progend */ - - if (fragend->pipeline_pre_change_notify) - fragend->pipeline_pre_change_notify (pipeline, change, new_color); - - if (progend->pipeline_pre_change_notify) - progend->pipeline_pre_change_notify (pipeline, change, new_color); - } - - /* There may be an arbitrary tree of descendants of this pipeline; - * any of which may indirectly depend on this pipeline as the - * authority for some set of properties. (Meaning for example that - * one of its descendants derives its color or blending state from - * this pipeline.) - * - * We can't modify any property that this pipeline is the authority - * for unless we create another pipeline to take its place first and - * make sure descendants reference this new pipeline instead. - */ - - /* The simplest descendants to handle are weak pipelines; we simply - * destroy them if we are modifying a pipeline they depend on. This - * means weak pipelines never cause us to do a copy-on-write. */ - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - destroy_weak_children_cb, - NULL); - - /* If there are still children remaining though we'll need to - * perform a copy-on-write and reparent the dependants as children - * of the copy. */ - if (!_cogl_list_empty (&COGL_NODE (pipeline)->children)) - { - CoglPipeline *new_authority; - - COGL_STATIC_COUNTER (pipeline_copy_on_write_counter, - "pipeline copy on write counter", - "Increments each time a pipeline " - "must be copied to allow modification", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, pipeline_copy_on_write_counter); - - new_authority = - cogl_pipeline_copy (_cogl_pipeline_get_parent (pipeline)); -#ifdef COGL_DEBUG_ENABLED - _cogl_pipeline_set_static_breadcrumb (new_authority, - "pre_change_notify:copy-on-write"); -#endif - - /* We could explicitly walk the descendants, OR together the set - * of differences that we determine this pipeline is the - * authority on and only copy those differences copied across. - * - * Or, if we don't explicitly walk the descendants we at least - * know that pipeline->differences represents the largest set of - * differences that this pipeline could possibly be an authority - * on. - * - * We do the later just because it's simplest, but we might need - * to come back to this later... - */ - _cogl_pipeline_copy_differences (new_authority, pipeline, - pipeline->differences); - - /* Reparent the dependants of pipeline to be children of - * new_authority instead... */ - _cogl_pipeline_node_foreach_child (COGL_NODE (pipeline), - reparent_children_cb, - new_authority); - - /* The children will keep the new authority alive so drop the - * reference we got when copying... */ - cogl_object_unref (new_authority); - } - - /* At this point we know we have a pipeline with no strong - * dependants (though we may have some weak children) so we are now - * free to modify the pipeline. */ - - pipeline->age++; - - if (change & COGL_PIPELINE_STATE_NEEDS_BIG_STATE && - !pipeline->has_big_state) - { - pipeline->big_state = g_new0 (CoglPipelineBigState, 1); - pipeline->has_big_state = TRUE; - } - - /* Note: conceptually we have just been notified that a single - * property value is about to change, but since some state-groups - * contain multiple properties and 'pipeline' is about to take over - * being the authority for the property's corresponding state-group - * we need to maintain the integrity of the other property values - * too. - * - * To ensure this we handle multi-property state-groups by copying - * all the values from the old-authority to the new... - * - * We don't have to worry about non-sparse property groups since - * we never take over being an authority for such properties so - * they automatically maintain integrity. - */ - if (change & COGL_PIPELINE_STATE_ALL_SPARSE && - !(pipeline->differences & change)) - { - _cogl_pipeline_init_multi_property_sparse_state (pipeline, change); - pipeline->differences |= change; - } - - /* Each pipeline has a sorted cache of the layers it depends on - * which will need updating via _cogl_pipeline_update_layers_cache - * if a pipeline's layers are changed. */ - if (change == COGL_PIPELINE_STATE_LAYERS) - recursively_free_layer_caches (pipeline); - - /* If the pipeline being changed is the same as the last pipeline we - * flushed then we keep a track of the changes so we can try to - * minimize redundant OpenGL calls if the same pipeline is flushed - * again. - */ - if (ctx->current_pipeline == pipeline) - ctx->current_pipeline_changes_since_flush |= change; -} - - -void -_cogl_pipeline_add_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean inc_n_layers) -{ - g_return_if_fail (layer->owner == NULL); - - layer->owner = pipeline; - cogl_object_ref (layer); - - /* - 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. - */ - /* Note: the last argument to _cogl_pipeline_pre_change_notify is - * needed to differentiate STATE_LAYER changes which don't affect - * the number of layers from those that do. NB: Layer change - * notifications that don't change the number of layers don't get - * forwarded to the fragend. */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - !inc_n_layers); - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - - pipeline->layer_differences = - g_list_prepend (pipeline->layer_differences, layer); - - if (inc_n_layers) - pipeline->n_layers++; - - /* Adding a layer difference may mean this pipeline now overrides - * all of the layers of its parent which might make the parent - * redundant so we should try to prune the hierarchy */ - _cogl_pipeline_prune_redundant_ancestry (pipeline); -} - -void -_cogl_pipeline_remove_layer_difference (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - gboolean dec_n_layers) -{ - /* - 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. - */ - /* Note: the last argument to _cogl_pipeline_pre_change_notify is - * needed to differentiate STATE_LAYER changes which don't affect - * the number of layers from those that do. NB: Layer change - * notifications that don't change the number of layers don't get - * forwarded to the fragend. */ - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - !dec_n_layers); - - /* We only need to remove the layer difference if the pipeline is - * currently the owner. If it is not the owner then one of two - * things will happen to make sure this layer is replaced. If it is - * the last layer being removed then decrementing n_layers will - * ensure that the last layer is skipped. If it is any other layer - * then the subsequent layers will have been shifted down and cause - * it be replaced */ - if (layer->owner == pipeline) - { - layer->owner = NULL; - cogl_object_unref (layer); - - pipeline->layer_differences = - g_list_remove (pipeline->layer_differences, layer); - } - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - - if (dec_n_layers) - pipeline->n_layers--; -} - -static void -_cogl_pipeline_try_reverting_layers_authority (CoglPipeline *authority, - CoglPipeline *old_authority) -{ - if (authority->layer_differences == NULL && - _cogl_pipeline_get_parent (authority)) - { - /* If the previous _STATE_LAYERS authority has the same - * ->n_layers then we can revert to that being the authority - * again. */ - if (!old_authority) - { - old_authority = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority), - COGL_PIPELINE_STATE_LAYERS); - } - - if (old_authority->n_layers == authority->n_layers) - authority->differences &= ~COGL_PIPELINE_STATE_LAYERS; - } -} - -void -_cogl_pipeline_update_real_blend_enable (CoglPipeline *pipeline, - gboolean unknown_color_alpha) -{ - CoglPipeline *parent; - unsigned int differences; - - if (pipeline->dirty_real_blend_enable == FALSE && - pipeline->unknown_color_alpha == unknown_color_alpha) - return; - - if (pipeline->dirty_real_blend_enable) - { - differences = pipeline->differences; - - parent = _cogl_pipeline_get_parent (pipeline); - while (parent->dirty_real_blend_enable) - { - differences |= parent->differences; - parent = _cogl_pipeline_get_parent (parent); - } - - /* We initialize the pipeline's real_blend_enable with a known - * reference value from its nearest ancestor with clean state so - * we can then potentially reduce the work involved in checking - * if the pipeline really needs blending itself because we can - * just look at the things that differ between the ancestor and - * this pipeline. - */ - pipeline->real_blend_enable = parent->real_blend_enable; - } - else /* pipeline->unknown_color_alpha != unknown_color_alpha */ - differences = 0; - - /* Note we don't call _cogl_pipeline_pre_change_notify() for this - * state change because ->real_blend_enable is lazily derived from - * other state while flushing the pipeline and we'd need to avoid - * recursion problems in cases where _pre_change_notify() flushes - * the journal if the pipeline is referenced by a journal. - */ - pipeline->real_blend_enable = - _cogl_pipeline_needs_blending_enabled (pipeline, differences, - NULL, unknown_color_alpha); - pipeline->dirty_real_blend_enable = FALSE; - pipeline->unknown_color_alpha = unknown_color_alpha; -} - -typedef struct -{ - int keep_n; - int current_pos; - int first_index_to_prune; -} CoglPipelinePruneLayersInfo; - -static gboolean -update_prune_layers_info_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelinePruneLayersInfo *state = user_data; - - if (state->current_pos == state->keep_n) - { - state->first_index_to_prune = layer->index; - return FALSE; - } - state->current_pos++; - return TRUE; -} - -void -_cogl_pipeline_prune_to_n_layers (CoglPipeline *pipeline, int n) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - CoglPipelinePruneLayersInfo state; - GList *l; - GList *next; - - if (authority->n_layers <= n) - return; - - /* This call to foreach_layer_internal needs to be done before - * calling pre_change_notify because it recreates the layer cache. - * We are relying on pre_change_notify to clear the layer cache - * before we change the number of layers */ - state.keep_n = n; - state.current_pos = 0; - _cogl_pipeline_foreach_layer_internal (pipeline, - update_prune_layers_info_cb, - &state); - - _cogl_pipeline_pre_change_notify (pipeline, - COGL_PIPELINE_STATE_LAYERS, - NULL, - FALSE); - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; - pipeline->n_layers = n; - - /* It's possible that this pipeline owns some of the layers being - * discarded, so we'll need to unlink them... */ - for (l = pipeline->layer_differences; l; l = next) - { - CoglPipelineLayer *layer = l->data; - next = l->next; /* we're modifying the list we're iterating */ - - if (layer->index >= state.first_index_to_prune) - _cogl_pipeline_remove_layer_difference (pipeline, layer, FALSE); - } - - pipeline->differences |= COGL_PIPELINE_STATE_LAYERS; -} - -typedef struct -{ - /* The layer we are trying to find */ - int layer_index; - - /* The layer we find or untouched if not found */ - CoglPipelineLayer *layer; - - /* If the layer can't be found then a new layer should be - * inserted after this texture unit index... */ - int insert_after; - - /* When adding a layer we need the list of layers to shift up - * to a new texture unit. When removing we need the list of - * layers to shift down. - * - * Note: the list isn't sorted */ - CoglPipelineLayer **layers_to_shift; - int n_layers_to_shift; - - /* When adding a layer we don't need a complete list of - * layers_to_shift if we find a layer already corresponding to the - * layer_index. */ - gboolean ignore_shift_layers_if_found; - -} CoglPipelineLayerInfo; - -/* Returns TRUE once we know there is nothing more to update */ -static gboolean -update_layer_info (CoglPipelineLayer *layer, - CoglPipelineLayerInfo *layer_info) -{ - if (layer->index == layer_info->layer_index) - { - layer_info->layer = layer; - if (layer_info->ignore_shift_layers_if_found) - return TRUE; - } - else if (layer->index < layer_info->layer_index) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - layer_info->insert_after = unit_index; - } - else - layer_info->layers_to_shift[layer_info->n_layers_to_shift++] = - layer; - - return FALSE; -} - -/* Returns FALSE to break out of a _foreach_layer () iteration */ -static gboolean -update_layer_info_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineLayerInfo *layer_info = user_data; - - if (update_layer_info (layer, layer_info)) - return FALSE; /* break */ - else - return TRUE; /* continue */ -} - -static void -_cogl_pipeline_get_layer_info (CoglPipeline *pipeline, - CoglPipelineLayerInfo *layer_info) -{ - /* Note: we are assuming this pipeline is a _STATE_LAYERS authority */ - int n_layers = pipeline->n_layers; - int i; - - /* FIXME: _cogl_pipeline_foreach_layer_internal now calls - * _cogl_pipeline_update_layers_cache anyway so this codepath is - * pointless! */ - if (layer_info->ignore_shift_layers_if_found && - pipeline->layers_cache_dirty) - { - /* The expectation is that callers of - * _cogl_pipeline_get_layer_info are likely to be modifying the - * list of layers associated with a pipeline so in this case - * where we don't have a cache of the layers and we don't - * necessarily have to iterate all the layers of the pipeline we - * use a foreach_layer callback instead of updating the cache - * and iterating that as below. */ - _cogl_pipeline_foreach_layer_internal (pipeline, - update_layer_info_cb, - layer_info); - return; - } - - _cogl_pipeline_update_layers_cache (pipeline); - for (i = 0; i < n_layers; i++) - { - CoglPipelineLayer *layer = pipeline->layers_cache[i]; - - if (update_layer_info (layer, layer_info)) - return; - } -} - -CoglPipelineLayer * -_cogl_pipeline_get_layer_with_flags (CoglPipeline *pipeline, - int layer_index, - CoglPipelineGetLayerFlags flags) -{ - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - CoglPipelineLayerInfo layer_info; - CoglPipelineLayer *layer; - int unit_index; - int i; - CoglContext *ctx; - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer_index; - - /* If a layer already exists with the given index this will be - * updated. */ - layer_info.layer = NULL; - - /* If a layer isn't found for the given index we'll need to know - * where to insert a new layer. */ - layer_info.insert_after = -1; - - /* If a layer can't be found then we'll need to insert a new layer - * and bump up the texture unit for all layers with an index - * > layer_index. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* If an exact match is found though we don't need a complete - * list of layers with indices > layer_index... */ - layer_info.ignore_shift_layers_if_found = TRUE; - - _cogl_pipeline_get_layer_info (authority, &layer_info); - - if (layer_info.layer || (flags & COGL_PIPELINE_GET_LAYER_NO_CREATE)) - return layer_info.layer; - - ctx = _cogl_context_get_default (); - - unit_index = layer_info.insert_after + 1; - if (unit_index == 0) - layer = _cogl_pipeline_layer_copy (ctx->default_layer_0); - else - { - CoglPipelineLayer *new; - layer = _cogl_pipeline_layer_copy (ctx->default_layer_n); - new = _cogl_pipeline_set_layer_unit (NULL, layer, unit_index); - /* Since we passed a newly allocated layer we wouldn't expect - * _set_layer_unit() to have to allocate *another* layer. */ - g_assert (new == layer); - } - layer->index = layer_index; - - for (i = 0; i < layer_info.n_layers_to_shift; i++) - { - CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i]; - - unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer); - _cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index + 1); - /* NB: shift_layer may not be writeable so _set_layer_unit() - * will allocate a derived layer internally which will become - * owned by pipeline. Check the return value if we need to do - * anything else with this layer. */ - } - - _cogl_pipeline_add_layer_difference (pipeline, layer, TRUE); - - cogl_object_unref (layer); - - return layer; -} - -void -_cogl_pipeline_prune_empty_layer_difference (CoglPipeline *layers_authority, - CoglPipelineLayer *layer) -{ - /* Find the GList link that references the empty layer */ - GList *link = g_list_find (layers_authority->layer_differences, layer); - /* No pipeline directly owns the root node layer so this is safe... */ - CoglPipelineLayer *layer_parent = _cogl_pipeline_layer_get_parent (layer); - CoglPipelineLayerInfo layer_info; - CoglPipeline *old_layers_authority; - - g_return_if_fail (link != NULL); - - /* If the layer's parent doesn't have an owner then we can simply - * take ownership ourselves and drop our reference on the empty - * layer. We don't want to take ownership of the root node layer so - * we also need to verify that the parent has a parent - */ - if (layer_parent->index == layer->index && layer_parent->owner == NULL && - _cogl_pipeline_layer_get_parent (layer_parent) != NULL) - { - cogl_object_ref (layer_parent); - layer_parent->owner = layers_authority; - link->data = layer_parent; - cogl_object_unref (layer); - recursively_free_layer_caches (layers_authority); - return; - } - - /* Now we want to find the layer that would become the authority for - * layer->index if we were to remove layer from - * layers_authority->layer_differences - */ - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer->index; - - /* If a layer already exists with the given index this will be - * updated. */ - layer_info.layer = NULL; - - /* If a layer can't be found then we'll need to insert a new layer - * and bump up the texture unit for all layers with an index - * > layer_index. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * layers_authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* If an exact match is found though we don't need a complete - * list of layers with indices > layer_index... */ - layer_info.ignore_shift_layers_if_found = TRUE; - - /* We know the default/root pipeline isn't a LAYERS authority so it's - * safe to use the result of _cogl_pipeline_get_parent (layers_authority) - * without checking it. - */ - old_layers_authority = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (layers_authority), - COGL_PIPELINE_STATE_LAYERS); - - _cogl_pipeline_get_layer_info (old_layers_authority, &layer_info); - - /* If layer is the defining layer for the corresponding ->index then - * we can't get rid of it. */ - if (!layer_info.layer) - return; - - /* If the layer that would become the authority for layer->index is - * _cogl_pipeline_layer_get_parent (layer) then we can simply remove the - * layer difference. */ - if (layer_info.layer == _cogl_pipeline_layer_get_parent (layer)) - { - _cogl_pipeline_remove_layer_difference (layers_authority, layer, FALSE); - _cogl_pipeline_try_reverting_layers_authority (layers_authority, - old_layers_authority); - } -} - -typedef struct -{ - int i; - CoglPipeline *pipeline; - unsigned long fallback_layers; -} CoglPipelineFallbackState; - -static gboolean -fallback_layer_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineFallbackState *state = user_data; - CoglPipeline *pipeline = state->pipeline; - CoglTexture *texture = NULL; - COGL_STATIC_COUNTER (layer_fallback_counter, - "layer fallback counter", - "Increments each time a layer's texture is " - "forced to a fallback texture", - 0 /* no application private data */); - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (!(state->fallback_layers & 1<<state->i)) - return TRUE; - - COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter); - - texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); - - if (texture == NULL) - { - g_warning ("We don't have a fallback texture we can use to fill " - "in for an invalid pipeline layer, since it was " - "using an unsupported texture target "); - /* might get away with this... */ - texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); - } - - cogl_pipeline_set_layer_texture (pipeline, layer->index, texture); - - state->i++; - - return TRUE; -} - -typedef struct -{ - CoglPipeline *pipeline; - CoglTexture *texture; -} CoglPipelineOverrideLayerState; - -static gboolean -override_layer_texture_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineOverrideLayerState *state = user_data; - - cogl_pipeline_set_layer_texture (state->pipeline, - layer->index, - state->texture); - - return TRUE; -} - -void -_cogl_pipeline_apply_overrides (CoglPipeline *pipeline, - CoglPipelineFlushOptions *options) -{ - COGL_STATIC_COUNTER (apply_overrides_counter, - "pipeline overrides counter", - "Increments each time we have to apply " - "override options to a pipeline", - 0 /* no application private data */); - - COGL_COUNTER_INC (_cogl_uprof_context, apply_overrides_counter); - - if (options->flags & COGL_PIPELINE_FLUSH_DISABLE_MASK) - { - int i; - - /* NB: we can assume that once we see one bit to disable - * a layer, all subsequent layers are also disabled. */ - for (i = 0; i < 32 && options->disable_layers & (1<<i); i++) - ; - - _cogl_pipeline_prune_to_n_layers (pipeline, i); - } - - if (options->flags & COGL_PIPELINE_FLUSH_FALLBACK_MASK) - { - CoglPipelineFallbackState state; - - state.i = 0; - state.pipeline = pipeline; - state.fallback_layers = options->fallback_layers; - - _cogl_pipeline_foreach_layer_internal (pipeline, - fallback_layer_cb, - &state); - } - - if (options->flags & COGL_PIPELINE_FLUSH_LAYER0_OVERRIDE) - { - CoglPipelineOverrideLayerState state; - - _cogl_pipeline_prune_to_n_layers (pipeline, 1); - - /* NB: we are overriding the first layer, but we don't know - * the user's given layer_index, which is why we use - * _cogl_pipeline_foreach_layer_internal() here even though we know - * there's only one layer. */ - state.pipeline = pipeline; - state.texture = options->layer0_override_texture; - _cogl_pipeline_foreach_layer_internal (pipeline, - override_layer_texture_cb, - &state); - } -} - -static gboolean -_cogl_pipeline_layers_equal (CoglPipeline *authority0, - CoglPipeline *authority1, - unsigned long differences, - CoglPipelineEvalFlags flags) -{ - int i; - - if (authority0->n_layers != authority1->n_layers) - return FALSE; - - _cogl_pipeline_update_layers_cache (authority0); - _cogl_pipeline_update_layers_cache (authority1); - - for (i = 0; i < authority0->n_layers; i++) - { - if (!_cogl_pipeline_layer_equal (authority0->layers_cache[i], - authority1->layers_cache[i], - differences, - flags)) - return FALSE; - } - return TRUE; -} - -/* Determine the mask of differences between two pipelines */ -unsigned long -_cogl_pipeline_compare_differences (CoglPipeline *pipeline0, - CoglPipeline *pipeline1) -{ - GSList *head0 = NULL; - GSList *head1 = NULL; - CoglPipeline *node0; - CoglPipeline *node1; - int len0 = 0; - int len1 = 0; - int count; - GSList *common_ancestor0; - GSList *common_ancestor1; - unsigned long pipelines_difference = 0; - - /* Algorithm: - * - * 1) Walk the ancestors of each pipeline to the root node, adding a - * pointer to each ancester node to two linked lists - * - * 2) Compare the lists to find the nodes where they start to - * differ marking the common_ancestor node for each list. - * - * 3) For each list now iterate starting after the common_ancestor - * nodes ORing each nodes ->difference mask into the final - * differences mask. - */ - - for (node0 = pipeline0; node0; node0 = _cogl_pipeline_get_parent (node0)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head0; - link->data = node0; - head0 = link; - len0++; - } - for (node1 = pipeline1; node1; node1 = _cogl_pipeline_get_parent (node1)) - { - GSList *link = alloca (sizeof (GSList)); - link->next = head1; - link->data = node1; - head1 = link; - len1++; - } - - /* NB: There's no point looking at the head entries since we know both - * pipelines must have the same default pipeline as their root node. */ - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - count = MIN (len0, len1) - 1; - while (count--) - { - if (head0->data != head1->data) - break; - common_ancestor0 = head0; - common_ancestor1 = head1; - head0 = head0->next; - head1 = head1->next; - } - - for (head0 = common_ancestor0->next; head0; head0 = head0->next) - { - node0 = head0->data; - pipelines_difference |= node0->differences; - } - for (head1 = common_ancestor1->next; head1; head1 = head1->next) - { - node1 = head1->data; - pipelines_difference |= node1->differences; - } - - return pipelines_difference; -} - -static void -_cogl_pipeline_resolve_authorities (CoglPipeline *pipeline, - unsigned long differences, - CoglPipeline **authorities) -{ - unsigned long remaining = differences; - CoglPipeline *authority = pipeline; - - do - { - unsigned long found = authority->differences & remaining; - int i; - - if (found == 0) - continue; - - for (i = 0; TRUE; i++) - { - unsigned long state = (1L<<i); - - if (state & found) - authorities[i] = authority; - else if (state > found) - break; - } - - remaining &= ~found; - if (remaining == 0) - return; - } - while ((authority = _cogl_pipeline_get_parent (authority))); - - g_assert (remaining == 0); -} - -/* Comparison of two arbitrary pipelines is done by: - * 1) walking up the parents of each pipeline until a common - * ancestor is found, and at each step ORing together the - * difference masks. - * - * 2) using the final difference mask to determine which state - * groups to compare. - * - * This is used, for example, by the Cogl journal to compare pipelines so that - * it can split up geometry that needs different OpenGL state. - * - * XXX: When comparing texture layers, _cogl_pipeline_equal will actually - * compare the underlying GL texture handle that the Cogl texture uses so that - * atlas textures and sub textures will be considered equal if they point to - * the same texture. This is useful for comparing pipelines in the journal but - * it means that _cogl_pipeline_equal doesn't strictly compare whether the - * pipelines are the same. If we needed those semantics we could perhaps add - * another function or some flags to control the behaviour. - * - * XXX: Similarly when comparing the wrap modes, - * COGL_PIPELINE_WRAP_MODE_AUTOMATIC is considered to be the same as - * COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE because once they get to the - * journal stage they act exactly the same. - */ -gboolean -_cogl_pipeline_equal (CoglPipeline *pipeline0, - CoglPipeline *pipeline1, - unsigned int differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags) -{ - unsigned long pipelines_difference; - CoglPipeline *authorities0[COGL_PIPELINE_STATE_SPARSE_COUNT]; - CoglPipeline *authorities1[COGL_PIPELINE_STATE_SPARSE_COUNT]; - int bit; - gboolean ret; - - COGL_STATIC_TIMER (pipeline_equal_timer, - "Mainloop", /* parent */ - "_cogl_pipeline_equal", - "The time spent comparing cogl pipelines", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, pipeline_equal_timer); - - if (pipeline0 == pipeline1) - { - ret = TRUE; - goto done; - } - - ret = FALSE; - - _cogl_pipeline_update_real_blend_enable (pipeline0, FALSE); - _cogl_pipeline_update_real_blend_enable (pipeline1, FALSE); - - /* First check non-sparse properties */ - - if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE && - pipeline0->real_blend_enable != pipeline1->real_blend_enable) - goto done; - - /* Then check sparse properties */ - - pipelines_difference = - _cogl_pipeline_compare_differences (pipeline0, pipeline1); - - /* Only compare the sparse state groups requested by the caller... */ - pipelines_difference &= differences; - - _cogl_pipeline_resolve_authorities (pipeline0, - pipelines_difference, - authorities0); - _cogl_pipeline_resolve_authorities (pipeline1, - pipelines_difference, - authorities1); - - COGL_FLAGS_FOREACH_START (&pipelines_difference, 1, bit) - { - /* XXX: We considered having an array of callbacks for each state index - * that we'd call here but decided that this way the compiler is more - * likely going to be able to in-line the comparison functions and use - * the index to jump straight to the required code. */ - switch ((CoglPipelineStateIndex)bit) - { - case COGL_PIPELINE_STATE_COLOR_INDEX: - if (!cogl_color_equal (&authorities0[bit]->color, - &authorities1[bit]->color)) - goto done; - break; - case COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX: - if (!_cogl_pipeline_alpha_func_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX: - if (!_cogl_pipeline_alpha_func_reference_state_equal ( - authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_BLEND_INDEX: - /* We don't need to compare the detailed blending state if we know - * blending is disabled for both pipelines. */ - if (pipeline0->real_blend_enable) - { - if (!_cogl_pipeline_blend_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - } - break; - case COGL_PIPELINE_STATE_DEPTH_INDEX: - if (!_cogl_pipeline_depth_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_CULL_FACE_INDEX: - if (!_cogl_pipeline_cull_face_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX: - if (!_cogl_pipeline_non_zero_point_size_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_POINT_SIZE_INDEX: - if (!_cogl_pipeline_point_size_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX: - if (!_cogl_pipeline_per_vertex_point_size_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_USER_SHADER_INDEX: - if (!_cogl_pipeline_user_shader_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_UNIFORMS_INDEX: - if (!_cogl_pipeline_uniforms_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX: - if (!_cogl_pipeline_vertex_snippets_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX: - if (!_cogl_pipeline_fragment_snippets_state_equal (authorities0[bit], - authorities1[bit])) - goto done; - break; - case COGL_PIPELINE_STATE_LAYERS_INDEX: - { - if (!_cogl_pipeline_layers_equal (authorities0[bit], - authorities1[bit], - layer_differences, - flags)) - goto done; - break; - } - - case COGL_PIPELINE_STATE_REAL_BLEND_ENABLE_INDEX: - case COGL_PIPELINE_STATE_COUNT: - g_warn_if_reached (); - } - } - COGL_FLAGS_FOREACH_END; - - ret = TRUE; -done: - COGL_TIMER_STOP (_cogl_uprof_context, pipeline_equal_timer); - return ret; -} - -void -_cogl_pipeline_prune_redundant_ancestry (CoglPipeline *pipeline) -{ - CoglPipeline *new_parent = _cogl_pipeline_get_parent (pipeline); - - /* Before considering pruning redundant ancestry we check if this - * pipeline is an authority for layer state and if so only consider - * reparenting if it *owns* all the layers it depends on. NB: A - * pipeline can be be a STATE_LAYERS authority but it may still - * defer to its ancestors to define the state for some of its - * layers. - * - * For example a pipeline that derives from a parent with 5 layers - * can become a STATE_LAYERS authority by simply changing it's - * ->n_layers count to 4 and in that case it can still defer to its - * ancestors to define the state of those 4 layers. - * - * If a pipeline depends on any ancestors for layer state then we - * immediately bail out. - */ - if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS) - { - if (pipeline->n_layers != g_list_length (pipeline->layer_differences)) - return; - } - - /* walk up past ancestors that are now redundant and potentially - * reparent the pipeline. */ - while (_cogl_pipeline_get_parent (new_parent) && - (new_parent->differences | pipeline->differences) == - pipeline->differences) - new_parent = _cogl_pipeline_get_parent (new_parent); - - if (new_parent != _cogl_pipeline_get_parent (pipeline)) - { - gboolean is_weak = _cogl_pipeline_is_weak (pipeline); - _cogl_pipeline_set_parent (pipeline, new_parent, is_weak ? FALSE : TRUE); - } -} - -void -_cogl_pipeline_update_authority (CoglPipeline *pipeline, - CoglPipeline *authority, - CoglPipelineState state, - CoglPipelineStateComparator comparator) -{ - /* If we are the current authority see if we can revert to one of - * our ancestors being the authority */ - if (pipeline == authority && - _cogl_pipeline_get_parent (authority) != NULL) - { - CoglPipeline *parent = _cogl_pipeline_get_parent (authority); - CoglPipeline *old_authority = - _cogl_pipeline_get_authority (parent, state); - - if (comparator (authority, old_authority)) - pipeline->differences &= ~state; - } - else if (pipeline != authority) - { - /* If we weren't previously the authority on this state then we - * need to extended our differences mask and so it's possible - * that some of our ancestry will now become redundant, so we - * aim to reparent ourselves if that's true... */ - pipeline->differences |= state; - _cogl_pipeline_prune_redundant_ancestry (pipeline); - } -} - -unsigned long -_cogl_pipeline_get_age (CoglPipeline *pipeline) -{ - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - return pipeline->age; -} - -void -cogl_pipeline_remove_layer (CoglPipeline *pipeline, int layer_index) -{ - CoglPipeline *authority; - CoglPipelineLayerInfo layer_info; - int i; - - g_return_if_fail (cogl_is_pipeline (pipeline)); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - - /* The layer index of the layer we want info about */ - layer_info.layer_index = layer_index; - - /* This will be updated with a reference to the layer being removed - * if it can be found. */ - layer_info.layer = NULL; - - /* This will be filled in with a list of layers that need to be - * dropped down to a lower texture unit to fill the gap of the - * removed layer. */ - layer_info.layers_to_shift = - g_alloca (sizeof (CoglPipelineLayer *) * authority->n_layers); - layer_info.n_layers_to_shift = 0; - - /* Unlike when we query layer info when adding a layer we must - * always have a complete layers_to_shift list... */ - layer_info.ignore_shift_layers_if_found = FALSE; - - _cogl_pipeline_get_layer_info (authority, &layer_info); - - if (layer_info.layer == NULL) - return; - - for (i = 0; i < layer_info.n_layers_to_shift; i++) - { - CoglPipelineLayer *shift_layer = layer_info.layers_to_shift[i]; - int unit_index = _cogl_pipeline_layer_get_unit_index (shift_layer); - _cogl_pipeline_set_layer_unit (pipeline, shift_layer, unit_index - 1); - /* NB: shift_layer may not be writeable so _set_layer_unit() - * will allocate a derived layer internally which will become - * owned by pipeline. Check the return value if we need to do - * anything else with this layer. */ - } - - _cogl_pipeline_remove_layer_difference (pipeline, layer_info.layer, TRUE); - _cogl_pipeline_try_reverting_layers_authority (pipeline, NULL); - - pipeline->dirty_real_blend_enable = TRUE; -} - -int -cogl_pipeline_get_n_layers (CoglPipeline *pipeline) -{ - CoglPipeline *authority; - - g_return_val_if_fail (cogl_is_pipeline (pipeline), 0); - - authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_LAYERS); - - return authority->n_layers; -} - -void -_cogl_pipeline_pre_paint_for_layer (CoglPipeline *pipeline, - int layer_id) -{ - CoglPipelineLayer *layer = _cogl_pipeline_get_layer (pipeline, layer_id); - _cogl_pipeline_layer_pre_paint (layer); -} - -/* While a pipeline is referenced by the Cogl journal we can not allow - * modifications, so this gives us a mechanism to track journal - * references separately */ -CoglPipeline * -_cogl_pipeline_journal_ref (CoglPipeline *pipeline) -{ - pipeline->journal_ref_count++; - return cogl_object_ref (pipeline); -} - -void -_cogl_pipeline_journal_unref (CoglPipeline *pipeline) -{ - pipeline->journal_ref_count--; - cogl_object_unref (pipeline); -} - -#ifdef COGL_DEBUG_ENABLED -void -_cogl_pipeline_set_static_breadcrumb (CoglPipeline *pipeline, - const char *breadcrumb) -{ - pipeline->has_static_breadcrumb = TRUE; - pipeline->static_breadcrumb = breadcrumb; -} -#endif - -typedef void (*LayerStateHashFunction) (CoglPipelineLayer *authority, - CoglPipelineLayer **authorities, - CoglPipelineHashState *state); - -static LayerStateHashFunction -layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT]; - -/* XXX: We don't statically initialize the array of hash functions, so - * we won't get caught out by later re-indexing the groups for some - * reason. */ -void -_cogl_pipeline_init_layer_state_hash_functions (void) -{ - CoglPipelineLayerStateIndex _index; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] = - _cogl_pipeline_layer_hash_unit_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] = - _cogl_pipeline_layer_hash_texture_data_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX] = - _cogl_pipeline_layer_hash_sampler_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX] = - _cogl_pipeline_layer_hash_combine_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX] = - _cogl_pipeline_layer_hash_combine_constant_state; - layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_USER_MATRIX_INDEX] = - _cogl_pipeline_layer_hash_user_matrix_state; - _index = COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_point_sprite_state; - _index = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_point_sprite_state; - _index = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX; - layer_state_hash_functions[_index] = - _cogl_pipeline_layer_hash_fragment_snippets_state; - - { - /* So we get a big error if we forget to update this code! */ - _COGL_STATIC_ASSERT (COGL_PIPELINE_LAYER_STATE_SPARSE_COUNT == 9, - "Don't forget to install a hash function for new " - "pipeline state and update assert at end of " - "_cogl_pipeline_init_state_hash_functions"); - } -} - -static gboolean -_cogl_pipeline_hash_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineHashState *state = user_data; - unsigned long differences = state->layer_differences; - CoglPipelineLayer *authorities[COGL_PIPELINE_LAYER_STATE_COUNT]; - unsigned long mask; - int i; - - /* Theoretically we would hash non-sparse layer state here but - * currently layers don't have any. */ - - /* XXX: we resolve all the authorities here - not just those - * corresponding to hash_state->layer_differences - because - * the hashing of some state groups actually depends on the values - * in other groups. For example we don't hash layer combine - * constants if they are aren't referenced by the current layer - * combine function. - */ - mask = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - _cogl_pipeline_layer_resolve_authorities (layer, - mask, - authorities); - - /* So we go right ahead and hash the sparse state... */ - for (i = 0; i < COGL_PIPELINE_LAYER_STATE_COUNT; i++) - { - unsigned long current_state = (1L<<i); - - /* XXX: we are hashing the un-mixed hash values of all the - * individual state groups; we should provide a means to test - * the quality of the final hash values we are getting with this - * approach... */ - if (differences & current_state) - { - CoglPipelineLayer *authority = authorities[i]; - layer_state_hash_functions[i] (authority, authorities, state); - } - - if (current_state > differences) - break; - } - - return TRUE; -} - -void -_cogl_pipeline_hash_layers_state (CoglPipeline *authority, - CoglPipelineHashState *state) -{ - state->hash = - _cogl_util_one_at_a_time_hash (state->hash, &authority->n_layers, - sizeof (authority->n_layers)); - _cogl_pipeline_foreach_layer_internal (authority, - _cogl_pipeline_hash_layer_cb, - state); -} - -typedef void (*StateHashFunction) (CoglPipeline *authority, CoglPipelineHashState *state); - -static StateHashFunction -state_hash_functions[COGL_PIPELINE_STATE_SPARSE_COUNT]; - -/* We don't statically initialize the array of hash functions - * so we won't get caught out by later re-indexing the groups for - * some reason. */ -void -_cogl_pipeline_init_state_hash_functions (void) -{ - state_hash_functions[COGL_PIPELINE_STATE_COLOR_INDEX] = - _cogl_pipeline_hash_color_state; - state_hash_functions[COGL_PIPELINE_STATE_LAYERS_INDEX] = - _cogl_pipeline_hash_layers_state; - state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_INDEX] = - _cogl_pipeline_hash_alpha_func_state; - state_hash_functions[COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE_INDEX] = - _cogl_pipeline_hash_alpha_func_reference_state; - state_hash_functions[COGL_PIPELINE_STATE_BLEND_INDEX] = - _cogl_pipeline_hash_blend_state; - state_hash_functions[COGL_PIPELINE_STATE_USER_SHADER_INDEX] = - _cogl_pipeline_hash_user_shader_state; - state_hash_functions[COGL_PIPELINE_STATE_DEPTH_INDEX] = - _cogl_pipeline_hash_depth_state; - state_hash_functions[COGL_PIPELINE_STATE_CULL_FACE_INDEX] = - _cogl_pipeline_hash_cull_face_state; - state_hash_functions[COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_non_zero_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE_INDEX] = - _cogl_pipeline_hash_per_vertex_point_size_state; - state_hash_functions[COGL_PIPELINE_STATE_UNIFORMS_INDEX] = - _cogl_pipeline_hash_uniforms_state; - state_hash_functions[COGL_PIPELINE_STATE_VERTEX_SNIPPETS_INDEX] = - _cogl_pipeline_hash_vertex_snippets_state; - state_hash_functions[COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS_INDEX] = - _cogl_pipeline_hash_fragment_snippets_state; - - { - /* So we get a big error if we forget to update this code! */ - _COGL_STATIC_ASSERT (COGL_PIPELINE_STATE_SPARSE_COUNT == 14, - "Make sure to install a hash function for " - "newly added pipeline state and update assert " - "in _cogl_pipeline_init_state_hash_functions"); - } -} - -unsigned int -_cogl_pipeline_hash (CoglPipeline *pipeline, - unsigned int differences, - unsigned long layer_differences, - CoglPipelineEvalFlags flags) -{ - CoglPipeline *authorities[COGL_PIPELINE_STATE_SPARSE_COUNT]; - unsigned int mask; - int i; - CoglPipelineHashState state; - unsigned int final_hash = 0; - - state.hash = 0; - state.layer_differences = layer_differences; - state.flags = flags; - - _cogl_pipeline_update_real_blend_enable (pipeline, FALSE); - - /* hash non-sparse state */ - - if (differences & COGL_PIPELINE_STATE_REAL_BLEND_ENABLE) - { - gboolean enable = pipeline->real_blend_enable; - state.hash = - _cogl_util_one_at_a_time_hash (state.hash, &enable, sizeof (enable)); - } - - /* hash sparse state */ - - mask = differences & COGL_PIPELINE_STATE_ALL_SPARSE; - _cogl_pipeline_resolve_authorities (pipeline, mask, authorities); - - for (i = 0; i < COGL_PIPELINE_STATE_SPARSE_COUNT; i++) - { - unsigned int current_state = (1<<i); - - /* XXX: we are hashing the un-mixed hash values of all the - * individual state groups; we should provide a means to test - * the quality of the final hash values we are getting with this - * approach... */ - if (differences & current_state) - { - CoglPipeline *authority = authorities[i]; - state_hash_functions[i] (authority, &state); - final_hash = _cogl_util_one_at_a_time_hash (final_hash, &state.hash, - sizeof (state.hash)); - } - - if (current_state > differences) - break; - } - - return _cogl_util_one_at_a_time_mix (final_hash); -} - -typedef struct -{ - CoglContext *context; - CoglPipeline *src_pipeline; - CoglPipeline *dst_pipeline; - unsigned int layer_differences; -} DeepCopyData; - -static gboolean -deep_copy_layer_cb (CoglPipelineLayer *src_layer, - void *user_data) -{ - DeepCopyData *data = user_data; - CoglPipelineLayer *dst_layer; - unsigned int differences = data->layer_differences; - - dst_layer = _cogl_pipeline_get_layer (data->dst_pipeline, src_layer->index); - - while (src_layer != data->context->default_layer_n && - src_layer != data->context->default_layer_0 && - differences) - { - unsigned long to_copy = differences & src_layer->differences; - - if (to_copy) - { - _cogl_pipeline_layer_copy_differences (dst_layer, src_layer, to_copy); - differences ^= to_copy; - } - - src_layer = COGL_PIPELINE_LAYER (COGL_NODE (src_layer)->parent); - } - - return TRUE; -} - -CoglPipeline * -_cogl_pipeline_deep_copy (CoglPipeline *pipeline, - unsigned long differences, - unsigned long layer_differences) -{ - CoglPipeline *new, *authority; - gboolean copy_layer_state; - - _COGL_GET_CONTEXT (ctx, NULL); - - if ((differences & COGL_PIPELINE_STATE_LAYERS)) - { - copy_layer_state = TRUE; - differences &= ~COGL_PIPELINE_STATE_LAYERS; - } - else - copy_layer_state = FALSE; - - new = cogl_pipeline_new (ctx); - - for (authority = pipeline; - authority != ctx->default_pipeline && differences; - authority = COGL_PIPELINE (COGL_NODE (authority)->parent)) - { - unsigned long to_copy = differences & authority->differences; - - if (to_copy) - { - _cogl_pipeline_copy_differences (new, authority, to_copy); - differences ^= to_copy; - } - } - - if (copy_layer_state) - { - DeepCopyData data; - - /* The unit index doesn't need to be copied because it should - * end up with the same values anyway because the new pipeline - * will have the same indices as the source pipeline */ - layer_differences &= ~COGL_PIPELINE_LAYER_STATE_UNIT; - - data.context = ctx; - data.src_pipeline = pipeline; - data.dst_pipeline = new; - data.layer_differences = layer_differences; - - _cogl_pipeline_foreach_layer_internal (pipeline, - deep_copy_layer_cb, - &data); - } - - return new; -} - -typedef struct -{ - int i; - CoglPipelineLayer **layers; -} AddLayersToArrayState; - -static gboolean -add_layer_to_array_cb (CoglPipelineLayer *layer, - void *user_data) -{ - AddLayersToArrayState *state = user_data; - state->layers[state->i++] = layer; - return TRUE; -} - -/* This tries to find the oldest ancestor whose pipeline and layer - state matches the given flags. This is mostly used to detect code - gen authorities so that we can reduce the number of programs - generated */ -CoglPipeline * -_cogl_pipeline_find_equivalent_parent (CoglPipeline *pipeline, - CoglPipelineState pipeline_state, - CoglPipelineLayerState layer_state) -{ - CoglPipeline *authority0; - CoglPipeline *authority1; - int n_layers; - CoglPipelineLayer **authority0_layers; - CoglPipelineLayer **authority1_layers; - - /* Find the first pipeline that modifies state that affects the - * state or any layer state... */ - authority0 = _cogl_pipeline_get_authority (pipeline, - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - - /* Find the next ancestor after that, that also modifies the - * state... */ - if (_cogl_pipeline_get_parent (authority0)) - { - authority1 = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority0), - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - } - else - return authority0; - - n_layers = cogl_pipeline_get_n_layers (authority0); - - for (;;) - { - AddLayersToArrayState state; - int i; - - if (n_layers != cogl_pipeline_get_n_layers (authority1)) - return authority0; - - /* If the programs differ by anything that isn't part of the - layer state then we can't continue */ - if (pipeline_state && - (_cogl_pipeline_compare_differences (authority0, authority1) & - pipeline_state)) - return authority0; - - authority0_layers = - g_alloca (sizeof (CoglPipelineLayer *) * n_layers); - state.i = 0; - state.layers = authority0_layers; - _cogl_pipeline_foreach_layer_internal (authority0, - add_layer_to_array_cb, - &state); - - authority1_layers = - g_alloca (sizeof (CoglPipelineLayer *) * n_layers); - state.i = 0; - state.layers = authority1_layers; - _cogl_pipeline_foreach_layer_internal (authority1, - add_layer_to_array_cb, - &state); - - for (i = 0; i < n_layers; i++) - { - unsigned long layer_differences; - - if (authority0_layers[i] == authority1_layers[i]) - continue; - - layer_differences = - _cogl_pipeline_layer_compare_differences (authority0_layers[i], - authority1_layers[i]); - - if (layer_differences & layer_state) - return authority0; - } - - /* Find the next ancestor after that, that also modifies state - * affecting codegen... */ - - if (!_cogl_pipeline_get_parent (authority1)) - break; - - authority0 = authority1; - authority1 = - _cogl_pipeline_get_authority (_cogl_pipeline_get_parent (authority1), - pipeline_state | - COGL_PIPELINE_STATE_LAYERS); - if (authority1 == authority0) - break; - } - - return authority1; -} - -CoglPipelineState -_cogl_pipeline_get_state_for_vertex_codegen (CoglContext *context) -{ - CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS | - COGL_PIPELINE_STATE_USER_SHADER | - COGL_PIPELINE_STATE_PER_VERTEX_POINT_SIZE | - COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - state |= COGL_PIPELINE_STATE_NON_ZERO_POINT_SIZE; - - return state; -} - -CoglPipelineLayerState -_cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context) -{ - CoglPipelineLayerState state = - (COGL_PIPELINE_LAYER_STATE_COMBINE | - COGL_PIPELINE_LAYER_STATE_UNIT | - COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); - - /* Since the driver supports GLSL then we might be using gl_PointCoord - * to implement the sprite coords. In that case the generated code - * depends on the point sprite state */ - state |= COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS; - - return state; -} - -CoglPipelineState -_cogl_pipeline_get_state_for_fragment_codegen (CoglContext *context) -{ - CoglPipelineState state = (COGL_PIPELINE_STATE_LAYERS | - COGL_PIPELINE_STATE_USER_SHADER | - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS | - COGL_PIPELINE_STATE_ALPHA_FUNC); - - return state; -} - -int -cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, - const char *uniform_name) -{ - void *location_ptr; - char *uniform_name_copy; - - _COGL_GET_CONTEXT (ctx, -1); - - /* This API is designed as if the uniform locations are specific to - a pipeline but they are actually unique across a whole - CoglContext. Potentially this could just be - cogl_context_get_uniform_location but it seems to make sense to - keep the API this way so that we can change the internals if need - be. */ - - /* Look for an existing uniform with this name */ - if (g_hash_table_lookup_extended (ctx->uniform_name_hash, - uniform_name, - NULL, - &location_ptr)) - return GPOINTER_TO_INT (location_ptr); - - uniform_name_copy = g_strdup (uniform_name); - g_ptr_array_add (ctx->uniform_names, uniform_name_copy); - g_hash_table_insert (ctx->uniform_name_hash, - uniform_name_copy, - GINT_TO_POINTER (ctx->n_uniform_names)); - - return ctx->n_uniform_names++; -} diff --git a/cogl/cogl/cogl-pipeline.h b/cogl/cogl/cogl-pipeline.h deleted file mode 100644 index f420a5a84..000000000 --- a/cogl/cogl/cogl-pipeline.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PIPELINE_H__ -#define __COGL_PIPELINE_H__ - -/* We forward declare the CoglPipeline type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglPipeline CoglPipeline; - -#include <cogl/cogl-types.h> -#include <cogl/cogl-context.h> -#include <cogl/cogl-snippet.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-pipeline - * @short_description: Functions for creating and manipulating the GPU - * pipeline - * - * Cogl allows creating and manipulating objects representing the full - * configuration of the GPU pipeline. In simplified terms the GPU - * pipeline takes primitive geometry as the input, it first performs - * vertex processing, allowing you to deform your geometry, then - * rasterizes that (turning it from pure geometry into fragments) then - * performs fragment processing including depth testing and texture - * mapping. Finally it blends the result with the framebuffer. - */ - -#define COGL_PIPELINE(OBJECT) ((CoglPipeline *)OBJECT) - -/** - * cogl_pipeline_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_pipeline_get_gtype (void); - -/** - * cogl_pipeline_new: (constructor) - * @context: a #CoglContext - * - * Allocates and initializes a default simple pipeline that will color - * a primitive white. - * - * Return value: (transfer full): a pointer to a new #CoglPipeline - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT CoglPipeline * -cogl_pipeline_new (CoglContext *context); - -/** - * cogl_pipeline_copy: - * @source: a #CoglPipeline object to copy - * - * Creates a new pipeline with the configuration copied from the - * source pipeline. - * - * We would strongly advise developers to always aim to use - * cogl_pipeline_copy() instead of cogl_pipeline_new() whenever there will - * be any similarity between two pipelines. Copying a pipeline helps Cogl - * keep track of a pipelines ancestry which we may use to help minimize GPU - * state changes. - * - * Return value: (transfer full): a pointer to the newly allocated #CoglPipeline - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT CoglPipeline * -cogl_pipeline_copy (CoglPipeline *source); - -/** - * cogl_is_pipeline: - * @object: A #CoglObject - * - * Gets whether the given @object references an existing pipeline object. - * - * Return value: %TRUE if the @object references a #CoglPipeline, - * %FALSE otherwise - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_pipeline (void *object); - -/** - * CoglPipelineLayerCallback: - * @pipeline: The #CoglPipeline whose layers are being iterated - * @layer_index: The current layer index - * @user_data: The private data passed to cogl_pipeline_foreach_layer() - * - * The callback prototype used with cogl_pipeline_foreach_layer() for - * iterating all the layers of a @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -typedef gboolean (*CoglPipelineLayerCallback) (CoglPipeline *pipeline, - int layer_index, - void *user_data); - -/** - * cogl_pipeline_foreach_layer: - * @pipeline: A #CoglPipeline object - * @callback: (scope call): A #CoglPipelineLayerCallback to be - * called for each layer index - * @user_data: (closure): Private data that will be passed to the - * callback - * - * Iterates all the layer indices of the given @pipeline. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_pipeline_foreach_layer (CoglPipeline *pipeline, - CoglPipelineLayerCallback callback, - void *user_data); - -/** - * cogl_pipeline_get_uniform_location: - * @pipeline: A #CoglPipeline object - * @uniform_name: The name of a uniform - * - * This is used to get an integer representing the uniform with the - * name @uniform_name. The integer can be passed to functions such as - * cogl_pipeline_set_uniform_1f() to set the value of a uniform. - * - * This function will always return a valid integer. Ie, unlike - * OpenGL, it does not return -1 if the uniform is not available in - * this pipeline so it can not be used to test whether uniforms are - * present. It is not necessary to set the program on the pipeline - * before calling this function. - * - * Return value: A integer representing the location of the given uniform. - * - * Since: 2.0 - * Stability: Unstable - */ -COGL_EXPORT int -cogl_pipeline_get_uniform_location (CoglPipeline *pipeline, - const char *uniform_name); - -G_END_DECLS - -#endif /* __COGL_PIPELINE_H__ */ diff --git a/cogl/cogl/cogl-pixel-buffer-private.h b/cogl/cogl/cogl-pixel-buffer-private.h deleted file mode 100644 index 3e5100336..000000000 --- a/cogl/cogl/cogl-pixel-buffer-private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIXEL_BUFFER_PRIVATE_H__ -#define __COGL_PIXEL_BUFFER_PRIVATE_H__ - -#include "cogl-object-private.h" -#include "cogl-buffer-private.h" - -#include <glib.h> - -G_BEGIN_DECLS - -struct _CoglPixelBuffer -{ - CoglBuffer _parent; -}; - -G_END_DECLS - -#endif /* __COGL_PIXEL_BUFFER_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-pixel-buffer.c b/cogl/cogl/cogl-pixel-buffer.c deleted file mode 100644 index f7dc0c70c..000000000 --- a/cogl/cogl/cogl-pixel-buffer.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -/* For an overview of the functionality implemented here, please see - * cogl-buffer-array.h, which contains the gtk-doc section overview for the - * Pixel Buffers API. - */ - -#include "cogl-config.h" - -#include <stdio.h> -#include <string.h> -#include <glib.h> - -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-object.h" -#include "cogl-pixel-buffer-private.h" -#include "cogl-pixel-buffer.h" -#include "cogl-gtype-private.h" - -static void -_cogl_pixel_buffer_free (CoglPixelBuffer *buffer); - -COGL_BUFFER_DEFINE (PixelBuffer, pixel_buffer) -COGL_GTYPE_DEFINE_CLASS (PixelBuffer, pixel_buffer) - -static CoglPixelBuffer * -_cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data, - GError **error) -{ - CoglPixelBuffer *pixel_buffer = g_new0 (CoglPixelBuffer, 1); - CoglBuffer *buffer = COGL_BUFFER (pixel_buffer); - - /* parent's constructor */ - _cogl_buffer_initialize (buffer, - context, - size, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - COGL_BUFFER_USAGE_HINT_TEXTURE, - COGL_BUFFER_UPDATE_HINT_STATIC); - - _cogl_pixel_buffer_object_new (pixel_buffer); - - if (data) - { - if (!_cogl_buffer_set_data (COGL_BUFFER (pixel_buffer), - 0, - data, - size, - error)) - { - cogl_object_unref (pixel_buffer); - return NULL; - } - } - - return pixel_buffer; -} - -CoglPixelBuffer * -cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data) -{ - GError *ignore_error = NULL; - CoglPixelBuffer *buffer = - _cogl_pixel_buffer_new (context, size, data, &ignore_error); - - g_clear_error (&ignore_error); - return buffer; -} - -static void -_cogl_pixel_buffer_free (CoglPixelBuffer *buffer) -{ - /* parent's destructor */ - _cogl_buffer_fini (COGL_BUFFER (buffer)); - - g_free (buffer); -} - diff --git a/cogl/cogl/cogl-pixel-buffer.h b/cogl/cogl/cogl-pixel-buffer.h deleted file mode 100644 index 79d03c83c..000000000 --- a/cogl/cogl/cogl-pixel-buffer.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PIXEL_BUFFER_H__ -#define __COGL_PIXEL_BUFFER_H__ - -/* XXX: We forward declare CoglPixelBuffer here to allow for circular - * dependencies between some headers */ -typedef struct _CoglPixelBuffer CoglPixelBuffer; - -#include <cogl/cogl-types.h> -#include <cogl/cogl-context.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define COGL_PIXEL_BUFFER(buffer) ((CoglPixelBuffer *)(buffer)) - -/** - * CoglPixelBuffer: (skip) - */ - -/** - * cogl_pixel_buffer_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_pixel_buffer_get_gtype (void); - -/** - * cogl_pixel_buffer_new: - * @context: A #CoglContext - * @size: The number of bytes to allocate for the pixel data. - * @data: An optional pointer to vertex data to upload immediately - * - * Declares a new #CoglPixelBuffer of @size bytes to contain arrays of - * pixels. Once declared, data can be set using cogl_buffer_set_data() - * or by mapping it into the application's address space using - * cogl_buffer_map(). - * - * If @data isn't %NULL then @size bytes will be read from @data and - * immediately copied into the new buffer. - * - * Return value: (transfer full): a newly allocated #CoglPixelBuffer - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglPixelBuffer * -cogl_pixel_buffer_new (CoglContext *context, - size_t size, - const void *data); - -/** - * cogl_is_pixel_buffer: - * @object: a #CoglObject to test - * - * Checks whether @object is a pixel buffer. - * - * Return value: %TRUE if the @object is a pixel buffer, and %FALSE - * otherwise - * - * Since: 1.2 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_pixel_buffer (void *object); - -G_END_DECLS - -#endif /* __COGL_PIXEL_BUFFER_H__ */ diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c deleted file mode 100644 index 05169b955..000000000 --- a/cogl/cogl/cogl-pixel-format.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> -#include <math.h> -#include <stdlib.h> - -#include "cogl-pixel-format.h" - -/* An entry to map CoglPixelFormats to their respective properties */ -typedef struct _CoglPixelFormatInfo -{ - CoglPixelFormat cogl_format; - const char *format_str; - int aligned; /* Aligned components? (-1 if n/a) */ - uint8_t n_planes; - - /* Per-plane information */ - uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES]; /* Bytes per pixel */ -} CoglPixelFormatInfo; - -static const CoglPixelFormatInfo format_info_table[] = { - { - .cogl_format = COGL_PIXEL_FORMAT_ANY, - .format_str = "ANY", - .n_planes = 0, - .aligned = -1, - .bpp = { 0 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_A_8, - .format_str = "A_8", - .n_planes = 1, - .aligned = 1, - .bpp = { 1 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGB_565, - .format_str = "RGB_565", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444, - .format_str = "RGBA_4444", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551, - .format_str = "RGBA_5551", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_YUV, - .format_str = "YUV", - .n_planes = 1, - .aligned = -1, - .bpp = { 0 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_G_8, - .format_str = "G_8", - .n_planes = 1, - .aligned = 1, - .bpp = { 1 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RG_88, - .format_str = "RG_88", - .n_planes = 1, - .aligned = 1, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGB_888, - .format_str = "RGB_888", - .n_planes = 1, - .aligned = 1, - .bpp = { 3 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGR_888, - .format_str = "BGR_888", - .n_planes = 1, - .aligned = 1, - .bpp = { 3 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888, - .format_str = "RGBA_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888, - .format_str = "BGRA_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888, - .format_str = "ARGB_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888, - .format_str = "ABGR_8888", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102, - .format_str = "RGBA_1010102", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102, - .format_str = "BGRA_1010102", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010, - .format_str = "ARGB_2101010", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010, - .format_str = "ABGR_2101010", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE, - .format_str = "RGBA_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE, - .format_str = "BGRA_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE, - .format_str = "ARGB_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE, - .format_str = "ABGR_8888_PRE", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE, - .format_str = "RGBA_4444_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE, - .format_str = "RGBA_5551_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE, - .format_str = "RGBA_1010102_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE, - .format_str = "BGRA_1010102_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE, - .format_str = "ARGB_2101010_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE, - .format_str = "ABGR_2101010_PRE", - .n_planes = 1, - .aligned = 0, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616, - .format_str = "RGBA_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616, - .format_str = "BGRA_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616, - .format_str = "ARGB_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616, - .format_str = "ABGR_FP_16161616", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE, - .format_str = "RGBA_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE, - .format_str = "BGRA_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE, - .format_str = "ARGB_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE, - .format_str = "ABGR_FP_16161616_PRE", - .n_planes = 1, - .bpp = { 8 }, - .aligned = 1 - }, - { - .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16, - .format_str = "DEPTH_16", - .n_planes = 1, - .aligned = 1, - .bpp = { 2 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_DEPTH_32, - .format_str = "DEPTH_32", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, - { - .cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, - .format_str = "DEPTH_24_STENCIL_8", - .n_planes = 1, - .aligned = 1, - .bpp = { 4 }, - }, -}; - -int -cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, - int plane) -{ - size_t i; - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - { - g_return_val_if_fail (plane < format_info_table[i].n_planes, 0); - - return format_info_table[i].bpp[plane]; - } - } - - g_assert_not_reached (); -} - -/* Note: this also refers to the mapping defined above for - * cogl_pixel_format_get_bytes_per_pixel() */ -gboolean -_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) -{ - int aligned = -1; - size_t i; - - /* NB: currently checking whether the format components are aligned - * or not determines whether the format is endian dependent or not. - * In the future though we might consider adding formats with - * aligned components that are also endian independent. */ - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - { - aligned = format_info_table[i].aligned; - break; - } - } - - g_return_val_if_fail (aligned != -1, FALSE); - - return aligned; -} - -int -cogl_pixel_format_get_n_planes (CoglPixelFormat format) -{ - size_t i; - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - return format_info_table[i].n_planes; - } - - g_assert_not_reached (); -} - -const char * -cogl_pixel_format_to_string (CoglPixelFormat format) -{ - size_t i; - - for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) - { - if (format_info_table[i].cogl_format == format) - return format_info_table[i].format_str; - } - - g_assert_not_reached (); -} diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h deleted file mode 100644 index 7ef03d3fd..000000000 --- a/cogl/cogl/cogl-pixel-format.h +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PIXEL_FORMAT_H__ -#define __COGL_PIXEL_FORMAT_H__ - -#include <stdint.h> -#include <stddef.h> - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-macros.h> - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-pixel-format - * @short_description: Pixel formats supported by Cogl - * - * The pixel format of an image descrbes how the bits of each pixel are - * represented in memory. For example: an image can be laid out as one long - * sequence of pixels, where each pixel is a sequence of 8 bits of Red, Green - * and Blue. The amount of bits that are used can be different for each pixel - * format, as well as the components (for example an Alpha layer to include - * transparency, or non_RGBA). - * - * Other examples of factors that can influence the layout in memory are the - * system's endianness. - */ - -#define COGL_A_BIT (1 << 4) -#define COGL_BGR_BIT (1 << 5) -#define COGL_AFIRST_BIT (1 << 6) -#define COGL_PREMULT_BIT (1 << 7) -#define COGL_DEPTH_BIT (1 << 8) -#define COGL_STENCIL_BIT (1 << 9) - -/* XXX: Notes to those adding new formats here... - * - * First this diagram outlines how we allocate the 32bits of a - * CoglPixelFormat currently... - * - * 6 bits for flags - * |-----| - * enum unused 4 bits for the bytes-per-pixel - * and component alignment info - * |------| |-------------| |--| - * 00000000 xxxxxxxx xxxxxxSD PFBA0000 - * ^ stencil - * ^ depth - * ^ premult - * ^ alpha first - * ^ bgr order - * ^ has alpha - * - * The most awkward part about the formats is how we use the last 4 - * bits to encode the bytes per pixel and component alignment - * information. Ideally we should have had 3 bits for the bpp and a - * flag for alignment but we didn't plan for that in advance so we - * instead use a small lookup table to query the bpp and whether the - * components are byte aligned or not. - * - * The mapping is the following (see discussion on bug #660188): - * - * 0 = undefined - * 1, 8 = 1 bpp (e.g. A_8, G_8) - * 2 = 3 bpp, aligned (e.g. 888) - * 3 = 4 bpp, aligned (e.g. 8888) - * 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551) - * 7 = YUV: undefined bpp, undefined alignment - * 9 = 2 bpp, aligned - * 10 = depth, aligned (8, 16, 24, 32, 32f) - * 11 = 8 bpp fp16 - * 12 = 3 bpp, not aligned - * 13 = 4 bpp, not aligned (e.g. 2101010) - * 14-15 = undefined - * - * Note: the gap at 10-11 is just because we wanted to maintain that - * all non-aligned formats have the third bit set in case that's - * useful later. - * - * Since we don't want to waste bits adding more and more flags, we'd - * like to see most new pixel formats that can't be represented - * uniquely with the existing flags in the least significant byte - * simply be enumerated with sequential values in the most significant - * enum byte. - * - * Note: Cogl avoids exposing any padded XRGB or RGBX formats and - * instead we leave it up to applications to decided whether they - * consider the A component as padding or valid data. We shouldn't - * change this policy without good reasoning. - * - * So to add a new format: - * 1) Use the mapping table above to figure out what to but in - * the lowest nibble. - * 2) OR in the COGL_PREMULT_BIT, COGL_AFIRST_BIT, COGL_A_BIT and - * COGL_BGR_BIT flags as appropriate. - * 3) If the result is not yet unique then also combine with an - * increment of the last sequence number in the most significant - * byte. - * - * The last sequence number used was 0 (i.e. no formats currently need - * a sequence number) - * Update this note whenever a new sequence number is used. - */ -/** - * CoglPixelFormat: - * @COGL_PIXEL_FORMAT_ANY: Any format - * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask - * @COGL_PIXEL_FORMAT_RG_88: RG, 16 bits. Note that red-green textures - * are only available if %COGL_FEATURE_ID_TEXTURE_RG is advertised. - * See cogl_texture_set_components() for details. - * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_YUV: Not currently supported - * @COGL_PIXEL_FORMAT_G_8: Single luminance component - * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits - * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits - * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_1010102 : RGBA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_BGRA_1010102 : BGRA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ARGB_2101010 : ARGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ABGR_2101010 : ABGR, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits - * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits - * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits - * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits - * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits - * @COGL_PIXEL_FORMAT_RGBA_1010102_PRE: Premultiplied RGBA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc - * @COGL_PIXEL_FORMAT_RGBA_FP_16161616: RGBA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_BGRA_FP_16161616: BGRA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ARGB_FP_16161616: ARGB half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ABGR_FP_16161616: ABGR half floating point, 64 bit - * @COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: Premultiplied RGBA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: Premultiplied BGRA half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: Premultiplied ARGB half floating point, 64 bit - * @COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: Premultiplied ABGR half floating point, 64 bit - * - * Pixel formats used by Cogl. For the formats with a byte per - * component, the order of the components specify the order in - * increasing memory addresses. So for example - * %COGL_PIXEL_FORMAT_RGB_888 would have the red component in the - * lowest address, green in the next address and blue after that - * regardless of the endianness of the system. - * - * For the formats with non byte aligned components the component - * order specifies the order within a 16-bit or 32-bit number from - * most significant bit to least significant. So for - * %COGL_PIXEL_FORMAT_RGB_565, the red component would be in bits - * 11-15, the green component would be in 6-11 and the blue component - * would be in 1-5. Therefore the order in memory depends on the - * endianness of the system. - * - * When uploading a texture %COGL_PIXEL_FORMAT_ANY can be used as the - * internal format. Cogl will try to pick the best format to use - * internally and convert the texture data if necessary. - * - * Since: 0.8 - */ -typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ -{ - COGL_PIXEL_FORMAT_ANY = 0, - COGL_PIXEL_FORMAT_A_8 = 1 | COGL_A_BIT, - - COGL_PIXEL_FORMAT_RGB_565 = 4, - COGL_PIXEL_FORMAT_RGBA_4444 = 5 | COGL_A_BIT, - COGL_PIXEL_FORMAT_RGBA_5551 = 6 | COGL_A_BIT, - COGL_PIXEL_FORMAT_YUV = 7, - COGL_PIXEL_FORMAT_G_8 = 8, - - COGL_PIXEL_FORMAT_RG_88 = 9, - - COGL_PIXEL_FORMAT_RGB_888 = 2, - COGL_PIXEL_FORMAT_BGR_888 = (2 | COGL_BGR_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888 = (3 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888 = (3 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888 = (3 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_1010102 = (13 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_1010102 = (13 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_2101010 = (13 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_2101010 = (13 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_FP_16161616 = (11 | COGL_A_BIT), - COGL_PIXEL_FORMAT_BGRA_FP_16161616 = (11 | COGL_A_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_FP_16161616 = (11 | COGL_A_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_FP_16161616 = (11 | COGL_A_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_RGBA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_8888_PRE = (3 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_RGBA_4444_PRE = (COGL_PIXEL_FORMAT_RGBA_4444 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_RGBA_5551_PRE = (COGL_PIXEL_FORMAT_RGBA_5551 | COGL_A_BIT | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT), - - COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT), - COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT), - COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_AFIRST_BIT), - COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE = (11 | COGL_A_BIT | COGL_PREMULT_BIT | COGL_BGR_BIT | COGL_AFIRST_BIT), - - COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT), - COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT), - - COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT) -} CoglPixelFormat; - -/** - * COGL_PIXEL_FORMAT_MAX_PLANES: - * - * The maximum number of planes of a pixel format (see also - * cogl_pixel_format_get_planes()). - */ -#define COGL_PIXEL_FORMAT_MAX_PLANES (4) - -/** - * cogl_pixel_format_get_bytes_per_pixel: - * @format: The pixel format - * @plane: The index of the plane (should not be more than the number of planes - * in the given format). - * - * Queries the number of bytes per pixel for a given format in the given plane. - * - * Returns: The number of bytes per pixel in the given format's given plane. - */ -COGL_EXPORT int -cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, - int plane); - -/* - * _cogl_pixel_format_has_aligned_components: - * @format: a #CoglPixelFormat - * - * Queries whether the ordering of the components for the given - * @format depend on the endianness of the host CPU or if the - * components can be accessed using bit shifting and bitmasking by - * loading a whole pixel into a word. - * - * XXX: If we ever consider making something like this public we - * should really try to think of a better name and come up with - * much clearer documentation since it really depends on what - * point of view you consider this from whether a format like - * COGL_PIXEL_FORMAT_RGBA_8888 is endian dependent. E.g. If you - * read an RGBA_8888 pixel into a uint32 - * it's endian dependent how you mask out the different channels. - * But If you already have separate color components and you want - * to write them to an RGBA_8888 pixel then the bytes can be - * written sequentially regardless of the endianness. - * - * Return value: %TRUE if you need to consider the host CPU - * endianness when dealing with the given @format - * else %FALSE. - */ -gboolean -_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); - -/* - * COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format): - * @format: a #CoglPixelFormat - * - * Returns TRUE if the pixel format can take a premult bit. This is - * currently true for all formats that have an alpha channel except - * COGL_PIXEL_FORMAT_A_8 (because that doesn't have any other - * components to multiply by the alpha). - */ -#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \ - (((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8) - -/** - * cogl_pixel_format_get_n_planes: - * @format: The format for which to get the number of planes - * - * Returns the number of planes the given CoglPixelFormat specifies. - * - * Returns: The no. of planes of @format (at most %COGL_PIXEL_FORMAT_MAX_PLANES) - */ -COGL_EXPORT int -cogl_pixel_format_get_n_planes (CoglPixelFormat format); - -/** - * cogl_pixel_format_to_string: - * @format: a #CoglPixelFormat - * - * Returns a string representation of @format, useful for debugging purposes. - * - * Returns: (transfer none): A string representation of @format. - */ -COGL_EXPORT const char * -cogl_pixel_format_to_string (CoglPixelFormat format); - -G_END_DECLS - -#endif /* __COGL_PIXEL_FORMAT_H__ */ diff --git a/cogl/cogl/cogl-point-in-poly-private.h b/cogl/cogl/cogl-point-in-poly-private.h deleted file mode 100644 index 9b6b21953..000000000 --- a/cogl/cogl/cogl-point-in-poly-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __COGL_POINT_INT_POLYGON_PRIVATE_H -#define __COGL_POINT_INT_POLYGON_PRIVATE_H - -#include <glib.h> - -G_BEGIN_DECLS - -int -_cogl_util_point_in_screen_poly (float point_x, - float point_y, - void *vertices, - size_t stride, - int n_vertices); - -G_END_DECLS - -#endif /* __COGL_POINT_INT_POLYGON_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-point-in-poly.c b/cogl/cogl/cogl-point-in-poly.c deleted file mode 100644 index c80fcbaca..000000000 --- a/cogl/cogl/cogl-point-in-poly.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Point Inclusion in Polygon Test - * - * Copyright (c) 1970-2003, Wm. Randolph Franklin - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimers. - * 2. Redistributions in binary form must reproduce the above - * copyright notice in the documentation and/or other materials - * provided with the distribution. - * 3. The name of W. Randolph Franklin may not be used to endorse or - * promote products derived from this Software without specific - * prior written permission. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Note: - * The algorithm for this point_in_poly() function was learnt from: - * http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-point-in-poly-private.h" - -#include <glib.h> - -/* We've made a notable change to the original algorithm referenced - * above to make sure we have reliable results for screen aligned - * rectangles even though there may be some numerical in-precision in - * how the vertices of the polygon were calculated. - * - * We've avoided introducing an epsilon factor to the comparisons - * since we feel there's a risk of changing some semantics in ways that - * might not be desirable. One of those is that if you transform two - * polygons which share an edge and test a point close to that edge - * then this algorithm will currently give a positive result for only - * one polygon. - * - * Another concern is the way this algorithm resolves the corner case - * where the horizontal ray being cast to count edge crossings may - * cross directly through a vertex. The solution is based on the "idea - * of Simulation of Simplicity" and "pretends to shift the ray - * infinitesimally down so that it either clearly intersects, or - * clearly doesn't touch". I'm not familiar with the idea myself so I - * expect a misplaced epsilon is likely to break that aspect of the - * algorithm. - * - * The simple solution we've gone for is to pixel align the polygon - * vertices which should eradicate most noise due to in-precision. - */ -int -_cogl_util_point_in_screen_poly (float point_x, - float point_y, - void *vertices, - size_t stride, - int n_vertices) -{ - int i, j, c = 0; - - for (i = 0, j = n_vertices - 1; i < n_vertices; j = i++) - { - float vert_xi = *(float *)((uint8_t *)vertices + i * stride); - float vert_xj = *(float *)((uint8_t *)vertices + j * stride); - float vert_yi = *(float *)((uint8_t *)vertices + i * stride + - sizeof (float)); - float vert_yj = *(float *)((uint8_t *)vertices + j * stride + - sizeof (float)); - - vert_xi = COGL_UTIL_NEARBYINT (vert_xi); - vert_xj = COGL_UTIL_NEARBYINT (vert_xj); - vert_yi = COGL_UTIL_NEARBYINT (vert_yi); - vert_yj = COGL_UTIL_NEARBYINT (vert_yj); - - if (((vert_yi > point_y) != (vert_yj > point_y)) && - (point_x < (vert_xj - vert_xi) * (point_y - vert_yi) / - (vert_yj - vert_yi) + vert_xi) ) - c = !c; - } - - return c; -} - diff --git a/cogl/cogl/cogl-poll-private.h b/cogl/cogl/cogl-poll-private.h deleted file mode 100644 index 55021926e..000000000 --- a/cogl/cogl/cogl-poll-private.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_POLL_PRIVATE_H__ -#define __COGL_POLL_PRIVATE_H__ - -#include "cogl-poll.h" -#include "cogl-renderer.h" -#include "cogl-closure-list-private.h" - -void -_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd); - -typedef int64_t (*CoglPollPrepareCallback) (void *user_data); -typedef void (*CoglPollDispatchCallback) (void *user_data, int revents); - -COGL_EXPORT void -_cogl_poll_renderer_add_fd (CoglRenderer *renderer, - int fd, - CoglPollFDEvent events, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data); - -void -_cogl_poll_renderer_modify_fd (CoglRenderer *renderer, - int fd, - CoglPollFDEvent events); - -typedef struct _CoglPollSource CoglPollSource; - -CoglPollSource * -_cogl_poll_renderer_add_source (CoglRenderer *renderer, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data); - -void -_cogl_poll_renderer_remove_source (CoglRenderer *renderer, - CoglPollSource *source); - -typedef void (*CoglIdleCallback) (void *user_data); - -COGL_EXPORT CoglClosure * -_cogl_poll_renderer_add_idle (CoglRenderer *renderer, - CoglIdleCallback idle_cb, - void *user_data, - CoglUserDataDestroyCallback destroy_cb); - -#endif /* __COGL_POLL_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-poll.c b/cogl/cogl/cogl-poll.c deleted file mode 100644 index f9818a811..000000000 --- a/cogl/cogl/cogl-poll.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-poll.h" -#include "cogl-poll-private.h" -#include "cogl-renderer-private.h" -#include "winsys/cogl-winsys-private.h" - -struct _CoglPollSource -{ - int fd; - CoglPollPrepareCallback prepare; - CoglPollDispatchCallback dispatch; - void *user_data; -}; - -int -cogl_poll_renderer_get_info (CoglRenderer *renderer, - CoglPollFD **poll_fds, - int *n_poll_fds, - int64_t *timeout) -{ - GList *l, *next; - - g_return_val_if_fail (cogl_is_renderer (renderer), 0); - g_return_val_if_fail (poll_fds != NULL, 0); - g_return_val_if_fail (n_poll_fds != NULL, 0); - g_return_val_if_fail (timeout != NULL, 0); - - *timeout = -1; - - if (!_cogl_list_empty (&renderer->idle_closures)) - *timeout = 0; - - /* This loop needs to cope with the prepare callback removing its - * own fd */ - for (l = renderer->poll_sources; l; l = next) - { - CoglPollSource *source = l->data; - - next = l->next; - - if (source->prepare) - { - int64_t source_timeout = source->prepare (source->user_data); - if (source_timeout >= 0 && - (*timeout == -1 || *timeout > source_timeout)) - *timeout = source_timeout; - } - } - - /* This is deliberately set after calling the prepare callbacks in - * case one of them removes its fd */ - *poll_fds = (void *)renderer->poll_fds->data; - *n_poll_fds = renderer->poll_fds->len; - - return renderer->poll_fds_age; -} - -void -cogl_poll_renderer_dispatch (CoglRenderer *renderer, - const CoglPollFD *poll_fds, - int n_poll_fds) -{ - GList *l, *next; - - g_return_if_fail (cogl_is_renderer (renderer)); - - _cogl_closure_list_invoke_no_args (&renderer->idle_closures); - - /* This loop needs to cope with the dispatch callback removing its - * own fd */ - for (l = renderer->poll_sources; l; l = next) - { - CoglPollSource *source = l->data; - int i; - - next = l->next; - - if (source->fd == -1) - { - source->dispatch (source->user_data, 0); - continue; - } - - for (i = 0; i < n_poll_fds; i++) - { - const CoglPollFD *pollfd = &poll_fds[i]; - - if (pollfd->fd == source->fd) - { - source->dispatch (source->user_data, pollfd->revents); - break; - } - } - } -} - -static int -find_pollfd (CoglRenderer *renderer, int fd) -{ - int i; - - for (i = 0; i < renderer->poll_fds->len; i++) - { - CoglPollFD *pollfd = &g_array_index (renderer->poll_fds, CoglPollFD, i); - - if (pollfd->fd == fd) - return i; - } - - return -1; -} - -void -_cogl_poll_renderer_remove_fd (CoglRenderer *renderer, int fd) -{ - int i = find_pollfd (renderer, fd); - GList *l; - - if (i < 0) - return; - - g_array_remove_index_fast (renderer->poll_fds, i); - renderer->poll_fds_age++; - - for (l = renderer->poll_sources; l; l = l->next) - { - CoglPollSource *source = l->data; - if (source->fd == fd) - { - renderer->poll_sources = - g_list_delete_link (renderer->poll_sources, l); - g_free (source); - break; - } - } -} - -void -_cogl_poll_renderer_modify_fd (CoglRenderer *renderer, - int fd, - CoglPollFDEvent events) -{ - int fd_index = find_pollfd (renderer, fd); - - if (fd_index == -1) - g_warn_if_reached (); - else - { - CoglPollFD *pollfd = - &g_array_index (renderer->poll_sources, CoglPollFD, fd_index); - - pollfd->events = events; - renderer->poll_fds_age++; - } -} - -void -_cogl_poll_renderer_add_fd (CoglRenderer *renderer, - int fd, - CoglPollFDEvent events, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data) -{ - CoglPollFD pollfd = { - fd, - events - }; - CoglPollSource *source; - - _cogl_poll_renderer_remove_fd (renderer, fd); - - source = g_new0 (CoglPollSource, 1); - source->fd = fd; - source->prepare = prepare; - source->dispatch = dispatch; - source->user_data = user_data; - - renderer->poll_sources = g_list_prepend (renderer->poll_sources, source); - - g_array_append_val (renderer->poll_fds, pollfd); - renderer->poll_fds_age++; -} - -CoglPollSource * -_cogl_poll_renderer_add_source (CoglRenderer *renderer, - CoglPollPrepareCallback prepare, - CoglPollDispatchCallback dispatch, - void *user_data) -{ - CoglPollSource *source; - - source = g_new0 (CoglPollSource, 1); - source->fd = -1; - source->prepare = prepare; - source->dispatch = dispatch; - source->user_data = user_data; - - renderer->poll_sources = g_list_prepend (renderer->poll_sources, source); - - return source; -} - -void -_cogl_poll_renderer_remove_source (CoglRenderer *renderer, - CoglPollSource *source) -{ - GList *l; - - for (l = renderer->poll_sources; l; l = l->next) - { - if (l->data == source) - { - renderer->poll_sources = - g_list_delete_link (renderer->poll_sources, l); - g_free (source); - break; - } - } -} - -CoglClosure * -_cogl_poll_renderer_add_idle (CoglRenderer *renderer, - CoglIdleCallback idle_cb, - void *user_data, - CoglUserDataDestroyCallback destroy_cb) -{ - return _cogl_closure_list_add (&renderer->idle_closures, - idle_cb, - user_data, - destroy_cb); -} diff --git a/cogl/cogl/cogl-poll.h b/cogl/cogl/cogl-poll.h deleted file mode 100644 index 5afed9089..000000000 --- a/cogl/cogl/cogl-poll.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_POLL_H__ -#define __COGL_POLL_H__ - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-context.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-poll - * @short_description: Functions for integrating Cogl with an - * application's main loop - * - * Cogl needs to integrate with the application's main loop so that it - * can internally handle some events from the driver. All Cogl - * applications must use these functions. They provide enough - * information to describe the state that Cogl will need to wake up - * on. An application using the GLib main loop can instead use - * cogl_glib_source_new() which provides a #GSource ready to be added - * to the main loop. - */ - -/** - * CoglPollFDEvent: - * @COGL_POLL_FD_EVENT_IN: there is data to read - * @COGL_POLL_FD_EVENT_PRI: data can be written (without blocking) - * @COGL_POLL_FD_EVENT_OUT: there is urgent data to read. - * @COGL_POLL_FD_EVENT_ERR: error condition - * @COGL_POLL_FD_EVENT_HUP: hung up (the connection has been broken, usually - * for pipes and sockets). - * @COGL_POLL_FD_EVENT_NVAL: invalid request. The file descriptor is not open. - * - * A bitmask of events that Cogl may need to wake on for a file - * descriptor. Note that these all have the same values as the - * corresponding defines for the poll function call on Unix so they - * may be directly passed to poll. - * - * Since: 1.10 - * Stability: unstable - */ -typedef enum -{ - COGL_POLL_FD_EVENT_IN = COGL_SYSDEF_POLLIN, - COGL_POLL_FD_EVENT_PRI = COGL_SYSDEF_POLLPRI, - COGL_POLL_FD_EVENT_OUT = COGL_SYSDEF_POLLOUT, - COGL_POLL_FD_EVENT_ERR = COGL_SYSDEF_POLLERR, - COGL_POLL_FD_EVENT_HUP = COGL_SYSDEF_POLLHUP, - COGL_POLL_FD_EVENT_NVAL = COGL_SYSDEF_POLLNVAL -} CoglPollFDEvent; - -/** - * CoglPollFD: - * @fd: The file descriptor to block on - * @events: A bitmask of events to block on - * @revents: A bitmask of returned events - * - * A struct for describing the state of a file descriptor that Cogl - * needs to block on. The @events field contains a bitmask of - * #CoglPollFDEvent<!-- -->s that should cause the application to wake - * up. After the application is woken up from idle it should pass back - * an array of #CoglPollFD<!-- -->s to Cogl and update the @revents - * mask to the actual events that occurred on the file descriptor. - * - * Note that CoglPollFD is deliberately exactly the same as struct - * pollfd on Unix so that it can simply be cast when calling poll. - * - * Since: 1.10 - * Stability: unstable - */ -typedef struct { - int fd; - short int events; - short int revents; -} CoglPollFD; - -/** - * cogl_poll_renderer_get_info: - * @renderer: A #CoglRenderer - * @poll_fds: A return location for a pointer to an array - * of #CoglPollFD<!-- -->s - * @n_poll_fds: A return location for the number of entries in *@poll_fds - * @timeout: A return location for the maximum length of time to wait - * in microseconds, or -1 to wait indefinitely. - * - * Is used to integrate Cogl with an application mainloop that is based - * on the unix poll(2) api (or select() or something equivalent). This - * api should be called whenever an application is about to go idle so - * that Cogl has a chance to describe what file descriptor events it - * needs to be woken up for. - * - * <note>If your application is using the Glib mainloop then you - * should jump to the cogl_glib_source_new() api as a more convenient - * way of integrating Cogl with the mainloop.</note> - * - * After the function is called *@poll_fds will contain a pointer to - * an array of #CoglPollFD structs describing the file descriptors - * that Cogl expects. The fd and events members will be updated - * accordingly. After the application has completed its idle it is - * expected to either update the revents members directly in this - * array or to create a copy of the array and update them - * there. - * - * When the application mainloop returns from calling poll(2) (or its - * equivalent) then it should call cogl_poll_renderer_dispatch() - * passing a pointer the array of CoglPollFD<!-- -->s with updated - * revent values. - * - * @timeout will contain a maximum amount of time to wait in - * microseconds before the application should wake up or -1 if the - * application should wait indefinitely. This can also be 0 if - * Cogl needs to be woken up immediately. - * - * Return value: A "poll fd state age" that changes whenever the set - * of poll_fds has changed. If this API is being used to - * integrate with another system mainloop api then - * knowing if the set of file descriptors and events has - * really changed can help avoid redundant work - * depending the api. The age isn't guaranteed to change - * when the timeout changes. - * - * Stability: unstable - * Since: 1.16 - */ -COGL_EXPORT int -cogl_poll_renderer_get_info (CoglRenderer *renderer, - CoglPollFD **poll_fds, - int *n_poll_fds, - int64_t *timeout); - -/** - * cogl_poll_renderer_dispatch: - * @renderer: A #CoglRenderer - * @poll_fds: An array of #CoglPollFD<!-- -->s describing the events - * that have occurred since the application went idle. - * @n_poll_fds: The length of the @poll_fds array. - * - * This should be called whenever an application is woken up from - * going idle in its main loop. The @poll_fds array should contain a - * list of file descriptors matched with the events that occurred in - * revents. The events field is ignored. It is safe to pass in extra - * file descriptors that Cogl didn't request when calling - * cogl_poll_renderer_get_info() or a shorter array missing some file - * descriptors that Cogl requested. - * - * <note>If your application didn't originally create a #CoglRenderer - * manually then you can easily get a #CoglRenderer pointer by calling - * cogl_get_renderer().</note> - * - * Stability: unstable - * Since: 1.16 - */ -COGL_EXPORT void -cogl_poll_renderer_dispatch (CoglRenderer *renderer, - const CoglPollFD *poll_fds, - int n_poll_fds); - -G_END_DECLS - -#endif /* __COGL_POLL_H__ */ diff --git a/cogl/cogl/cogl-primitive-private.h b/cogl/cogl/cogl-primitive-private.h deleted file mode 100644 index 072812148..000000000 --- a/cogl/cogl/cogl-primitive-private.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PRIMITIVE_PRIVATE_H -#define __COGL_PRIMITIVE_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-attribute-buffer-private.h" -#include "cogl-attribute-private.h" -#include "cogl-framebuffer.h" - -struct _CoglPrimitive -{ - CoglObject _parent; - - CoglIndices *indices; - CoglVerticesMode mode; - int first_vertex; - int n_vertices; - - int immutable_ref; - - CoglAttribute **attributes; - int n_attributes; - - int n_embedded_attributes; - CoglAttribute *embedded_attribute; -}; - -CoglPrimitive * -_cogl_primitive_immutable_ref (CoglPrimitive *primitive); - -void -_cogl_primitive_immutable_unref (CoglPrimitive *primitive); - -COGL_EXPORT void -_cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags); - -#endif /* __COGL_PRIMITIVE_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-primitive-texture.c b/cogl/cogl/cogl-primitive-texture.c deleted file mode 100644 index f7f0aabd8..000000000 --- a/cogl/cogl/cogl-primitive-texture.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-primitive-texture.h" -#include "cogl-texture-private.h" - -gboolean -cogl_is_primitive_texture (void *object) -{ - return (cogl_is_texture (object) && - COGL_TEXTURE (object)->vtable->is_primitive); -} - -void -cogl_primitive_texture_set_auto_mipmap (CoglPrimitiveTexture *primitive_texture, - gboolean value) -{ - CoglTexture *texture; - - g_return_if_fail (cogl_is_primitive_texture (primitive_texture)); - - texture = COGL_TEXTURE (primitive_texture); - - g_assert (texture->vtable->set_auto_mipmap != NULL); - - texture->vtable->set_auto_mipmap (texture, value); -} diff --git a/cogl/cogl/cogl-primitive-texture.h b/cogl/cogl/cogl-primitive-texture.h deleted file mode 100644 index 8d6efe9dc..000000000 --- a/cogl/cogl/cogl-primitive-texture.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PRIMITIVE_TEXTURE_H__ -#define __COGL_PRIMITIVE_TEXTURE_H__ - -#include "cogl-types.h" - -G_BEGIN_DECLS - -/** - * SECTION:cogl-primitive-texture - * @short_description: Interface for low-level textures like - * #CoglTexture2D. - * - * A #CoglPrimitiveTexture is a texture that is directly represented - * by a single texture on the GPU. For example this could be a - * #CoglTexture2D. This is opposed to high level meta textures which - * may be composed of multiple primitive textures or a sub-region of - * another texture such as #CoglAtlasTexture and #CoglTexture2DSliced. - * - * A texture that implements this interface can be directly used with - * the low level cogl_primitive_draw() API. Other types of textures - * need to be first resolved to primitive textures using the - * #CoglMetaTexture interface. - * - * <note>Most developers won't need to use this interface directly but - * still it is worth understanding the distinction between high-level - * and primitive textures because you may find other references in the - * documentation that detail limitations of using - * primitive textures.</note> - */ - -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ - !defined(COGL_GIR_SCANNING) -/* For the public C api we typedef interface types as void to avoid needing - * lots of casting in code and instead we will rely on runtime type checking - * for these objects. */ -typedef void CoglPrimitiveTexture; -#else -typedef struct _CoglPrimitiveTexture CoglPrimitiveTexture; -#define COGL_PRIMITIVE_TEXTURE(X) ((CoglPrimitiveTexture *)X) -#endif - -/** - * cogl_is_primitive_texture: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a primitive texture object. - * - * Return value: %TRUE if the pointer references a primitive texture, and - * %FALSE otherwise - * Since: 2.0 - * Stability: unstable - */ -gboolean -cogl_is_primitive_texture (void *object); - -/** - * cogl_primitive_texture_set_auto_mipmap: - * @primitive_texture: A #CoglPrimitiveTexture - * @value: The new value for whether to auto mipmap - * - * Sets whether the texture will automatically update the smaller - * mipmap levels after any part of level 0 is updated. The update will - * only occur whenever the texture is used for drawing with a texture - * filter that requires the lower mipmap levels. An application should - * disable this if it wants to upload its own data for the other - * levels. By default auto mipmapping is enabled. - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT void -cogl_primitive_texture_set_auto_mipmap (CoglPrimitiveTexture *primitive_texture, - gboolean value); - -G_END_DECLS - -#endif /* __COGL_PRIMITIVE_TEXTURE_H__ */ diff --git a/cogl/cogl/cogl-primitive.c b/cogl/cogl/cogl-primitive.c deleted file mode 100644 index 7da4a3fa9..000000000 --- a/cogl/cogl/cogl-primitive.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-object-private.h" -#include "cogl-primitive.h" -#include "cogl-primitive-private.h" -#include "cogl-attribute-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-gtype-private.h" - -#include <stdarg.h> -#include <string.h> - -static void _cogl_primitive_free (CoglPrimitive *primitive); - -COGL_OBJECT_DEFINE (Primitive, primitive); -COGL_GTYPE_DEFINE_CLASS (Primitive, primitive); - -CoglPrimitive * -cogl_primitive_new_with_attributes (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes, - int n_attributes) -{ - CoglPrimitive *primitive; - int i; - - primitive = g_malloc0 (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); - - g_return_val_if_fail (cogl_is_attribute (attribute), NULL); - - primitive->attributes[i] = attribute; - } - - return _cogl_primitive_object_new (primitive); -} - -/* This is just an internal convenience wrapper around - new_with_attributes that also unrefs the attributes. It is just - used for the builtin struct constructors */ -static CoglPrimitive * -_cogl_primitive_new_with_attributes_unref (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes, - int n_attributes) -{ - CoglPrimitive *primitive; - int i; - - primitive = cogl_primitive_new_with_attributes (mode, - n_vertices, - attributes, - n_attributes); - - for (i = 0; i < n_attributes; i++) - cogl_object_unref (attributes[i]); - - return primitive; -} - -CoglPrimitive * -cogl_primitive_new (CoglVerticesMode mode, - int n_vertices, - ...) -{ - va_list ap; - int n_attributes; - CoglAttribute **attributes; - int i; - CoglAttribute *attribute; - - va_start (ap, n_vertices); - for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++) - ; - va_end (ap); - - attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes); - - va_start (ap, n_vertices); - for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++) - attributes[i] = attribute; - va_end (ap); - - return cogl_primitive_new_with_attributes (mode, n_vertices, - attributes, - i); -} - -CoglPrimitive * -cogl_primitive_new_p2 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP2), data); - CoglAttribute *attributes[1]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2), - offsetof (CoglVertexP2, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 1); -} - -CoglPrimitive * -cogl_primitive_new_p3 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3), data); - CoglAttribute *attributes[1]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3), - offsetof (CoglVertexP3, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 1); -} - -CoglPrimitive * -cogl_primitive_new_p2c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP2C4), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2C4), - offsetof (CoglVertexP2C4, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP2C4), - offsetof (CoglVertexP2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p3c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3C4), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3C4), - offsetof (CoglVertexP3C4, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP3C4), - offsetof (CoglVertexP3C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p2t2 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP2T2), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2T2), - offsetof (CoglVertexP2T2, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2), - offsetof (CoglVertexP2T2, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p3t2 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3T2), data); - CoglAttribute *attributes[2]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3T2), - offsetof (CoglVertexP3T2, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2), - offsetof (CoglVertexP3T2, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 2); -} - -CoglPrimitive * -cogl_primitive_new_p2t2c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, - n_vertices * sizeof (CoglVertexP2T2C4), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, x), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP2T2C4), - offsetof (CoglVertexP2T2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 3); -} - -CoglPrimitive * -cogl_primitive_new_p3t2c4 (CoglContext *ctx, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2C4 *data) -{ - CoglAttributeBuffer *attribute_buffer = - cogl_attribute_buffer_new (ctx, - n_vertices * sizeof (CoglVertexP3T2C4), data); - CoglAttribute *attributes[3]; - - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, x), - 3, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[1] = cogl_attribute_new (attribute_buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, s), - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - attributes[2] = cogl_attribute_new (attribute_buffer, - "cogl_color_in", - sizeof (CoglVertexP3T2C4), - offsetof (CoglVertexP3T2C4, r), - 4, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); - - cogl_object_unref (attribute_buffer); - - return _cogl_primitive_new_with_attributes_unref (mode, n_vertices, - attributes, - 3); -} - -static void -_cogl_primitive_free (CoglPrimitive *primitive) -{ - int i; - - for (i = 0; i < primitive->n_attributes; i++) - cogl_object_unref (primitive->attributes[i]); - - if (primitive->attributes != &primitive->embedded_attribute) - g_free (primitive->attributes); - - if (primitive->indices) - cogl_object_unref (primitive->indices); - - g_free (primitive); -} - -static void -warn_about_midscene_changes (void) -{ - static gboolean seen = FALSE; - if (!seen) - { - g_warning ("Mid-scene modification of primitives has " - "undefined results\n"); - seen = TRUE; - } -} - -void -cogl_primitive_set_attributes (CoglPrimitive *primitive, - CoglAttribute **attributes, - int n_attributes) -{ - int i; - - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - /* NB: we don't unref the previous attributes before refing the new - * in case we would end up releasing the last reference for an - * attribute that's actually in the new list too. */ - for (i = 0; i < n_attributes; i++) - { - g_return_if_fail (cogl_is_attribute (attributes[i])); - cogl_object_ref (attributes[i]); - } - - for (i = 0; i < primitive->n_attributes; i++) - cogl_object_unref (primitive->attributes[i]); - - /* First try to use the embedded storage associated with the - * primitive, else fallback to slice allocating separate storage for - * the attribute pointers... */ - - if (n_attributes <= primitive->n_embedded_attributes) - { - if (primitive->attributes != &primitive->embedded_attribute) - g_free (primitive->attributes); - primitive->attributes = &primitive->embedded_attribute; - } - else - { - if (primitive->attributes != &primitive->embedded_attribute) - g_free (primitive->attributes); - primitive->attributes = - g_malloc0 (sizeof (CoglAttribute *) * n_attributes); - } - - memcpy (primitive->attributes, attributes, - sizeof (CoglAttribute *) * n_attributes); - - primitive->n_attributes = n_attributes; -} - -int -cogl_primitive_get_first_vertex (CoglPrimitive *primitive) -{ - g_return_val_if_fail (cogl_is_primitive (primitive), 0); - - return primitive->first_vertex; -} - -void -cogl_primitive_set_first_vertex (CoglPrimitive *primitive, - int first_vertex) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - primitive->first_vertex = first_vertex; -} - -int -cogl_primitive_get_n_vertices (CoglPrimitive *primitive) -{ - g_return_val_if_fail (cogl_is_primitive (primitive), 0); - - return primitive->n_vertices; -} - -void -cogl_primitive_set_n_vertices (CoglPrimitive *primitive, - int n_vertices) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - primitive->n_vertices = n_vertices; -} - -CoglVerticesMode -cogl_primitive_get_mode (CoglPrimitive *primitive) -{ - g_return_val_if_fail (cogl_is_primitive (primitive), 0); - - return primitive->mode; -} - -void -cogl_primitive_set_mode (CoglPrimitive *primitive, - CoglVerticesMode mode) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - primitive->mode = mode; -} - -void -cogl_primitive_set_indices (CoglPrimitive *primitive, - CoglIndices *indices, - int n_indices) -{ - g_return_if_fail (cogl_is_primitive (primitive)); - - if (G_UNLIKELY (primitive->immutable_ref)) - { - warn_about_midscene_changes (); - return; - } - - if (indices) - cogl_object_ref (indices); - if (primitive->indices) - cogl_object_unref (primitive->indices); - primitive->indices = indices; - primitive->n_vertices = n_indices; -} - -CoglIndices * -cogl_primitive_get_indices (CoglPrimitive *primitive) -{ - return primitive->indices; -} - -CoglPrimitive * -cogl_primitive_copy (CoglPrimitive *primitive) -{ - CoglPrimitive *copy; - - copy = cogl_primitive_new_with_attributes (primitive->mode, - primitive->n_vertices, - primitive->attributes, - primitive->n_attributes); - - cogl_primitive_set_indices (copy, primitive->indices, primitive->n_vertices); - cogl_primitive_set_first_vertex (copy, primitive->first_vertex); - - return copy; -} - -CoglPrimitive * -_cogl_primitive_immutable_ref (CoglPrimitive *primitive) -{ - int i; - - g_return_val_if_fail (cogl_is_primitive (primitive), NULL); - - primitive->immutable_ref++; - - for (i = 0; i < primitive->n_attributes; i++) - _cogl_attribute_immutable_ref (primitive->attributes[i]); - - return primitive; -} - -void -_cogl_primitive_immutable_unref (CoglPrimitive *primitive) -{ - int i; - - g_return_if_fail (cogl_is_primitive (primitive)); - g_return_if_fail (primitive->immutable_ref > 0); - - primitive->immutable_ref--; - - for (i = 0; i < primitive->n_attributes; i++) - _cogl_attribute_immutable_unref (primitive->attributes[i]); -} - -void -cogl_primitive_foreach_attribute (CoglPrimitive *primitive, - CoglPrimitiveAttributeCallback callback, - void *user_data) -{ - int i; - - for (i = 0; i < primitive->n_attributes; i++) - if (!callback (primitive, primitive->attributes[i], user_data)) - break; -} - -void -_cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglDrawFlags flags) -{ - if (primitive->indices) - _cogl_framebuffer_draw_indexed_attributes (framebuffer, - pipeline, - primitive->mode, - primitive->first_vertex, - primitive->n_vertices, - primitive->indices, - primitive->attributes, - primitive->n_attributes, - flags); - else - _cogl_framebuffer_draw_attributes (framebuffer, - pipeline, - primitive->mode, - primitive->first_vertex, - primitive->n_vertices, - primitive->attributes, - primitive->n_attributes, - flags); -} - -void -cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline) -{ - _cogl_primitive_draw (primitive, framebuffer, pipeline, 0 /* flags */); -} diff --git a/cogl/cogl/cogl-primitive.h b/cogl/cogl/cogl-primitive.h deleted file mode 100644 index 5b3a70c88..000000000 --- a/cogl/cogl/cogl-primitive.h +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_PRIMITIVE_H__ -#define __COGL_PRIMITIVE_H__ - -/* We forward declare the CoglPrimitive type here to avoid some circular - * dependency issues with the following headers. - */ -typedef struct _CoglPrimitive CoglPrimitive; - -#include <cogl/cogl-types.h> /* for CoglVerticesMode */ -#include <cogl/cogl-attribute.h> -#include <cogl/cogl-framebuffer.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-primitive - * @short_description: Functions for creating, manipulating and drawing - * primitives - * - * FIXME - */ - -/** - * CoglPrimitive: (ref-func cogl_object_ref) (unref-func cogl_object_unref) - * (set-value-func cogl_object_value_set_object) - * (get-value-func cogl_object_value_get_object) - */ - -/** - * cogl_primitive_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_primitive_get_gtype (void); - -/** - * CoglVertexP2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p2(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y; -} CoglVertexP2; - -/** - * CoglVertexP3: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y, z; -} CoglVertexP3; - -/** - * CoglVertexP2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p2c4(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y; - uint8_t r, g, b, a; -} CoglVertexP2C4; - -/** - * CoglVertexP3C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3c4(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y, z; - uint8_t r, g, b, a; -} CoglVertexP3C4; - -/** - * CoglVertexP2T2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p2t2(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y; - float s, t; -} CoglVertexP2T2; - -/** - * CoglVertexP3T2: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3t2(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y, z; - float s, t; -} CoglVertexP3T2; - - -/** - * CoglVertexP2T2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3t2c4(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y; - float s, t; - uint8_t r, g, b, a; -} CoglVertexP2T2C4; - -/** - * CoglVertexP3T2C4: - * @x: The x component of a position attribute - * @y: The y component of a position attribute - * @z: The z component of a position attribute - * @s: The s component of a texture coordinate attribute - * @t: The t component of a texture coordinate attribute - * @r: The red component of a color attribute - * @b: The green component of a color attribute - * @g: The blue component of a color attribute - * @a: The alpha component of a color attribute - * - * A convenience vertex definition that can be used with - * cogl_primitive_new_p3t2c4(). - * - * Since: 1.6 - * Stability: Unstable - */ -typedef struct { - float x, y, z; - float s, t; - uint8_t r, g, b, a; -} CoglVertexP3T2C4; - -/** - * cogl_primitive_new: - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @...: A %NULL terminated list of attributes - * - * Combines a set of #CoglAttribute<!-- -->s with a specific draw @mode - * and defines a vertex count so a #CoglPrimitive object can be retained and - * drawn later with no addition information required. - * - * The value passed as @n_vertices will simply update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - * - * Return value: (transfer full): A newly allocated #CoglPrimitive object - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new (CoglVerticesMode mode, - int n_vertices, - ...); - -/** - * cogl_primitive_new_with_attributes: (skip) - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to process when drawing - * @attributes: An array of CoglAttribute - * @n_attributes: The number of attributes - * - * Combines a set of #CoglAttribute<!-- -->s with a specific draw @mode - * and defines a vertex count so a #CoglPrimitive object can be retained and - * drawn later with no addition information required. - * - * The value passed as @n_vertices will simply update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - * - * Return value: (transfer full): A newly allocated #CoglPrimitive object - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_with_attributes (CoglVerticesMode mode, - int n_vertices, - CoglAttribute **attributes, - int n_attributes); - -/** - * cogl_primitive_new_p2: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP2): An array - * of #CoglVertexP2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * attribute with a #CoglAttribute and upload your data. - * - * For example to draw a convex polygon you can do: - * |[ - * CoglVertexP2 triangle[] = - * { - * { 0, 300 }, - * { 150, 0, }, - * { 300, 300 } - * }; - * prim = cogl_primitive_new_p2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2 *data); - -/** - * cogl_primitive_new_p3: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP3): An array of - * #CoglVertexP3 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * attribute with a #CoglAttribute and upload your data. - * - * For example to draw a convex polygon you can do: - * |[ - * CoglVertexP3 triangle[] = - * { - * { 0, 300, 0 }, - * { 150, 0, 0 }, - * { 300, 300, 0 } - * }; - * prim = cogl_primitive_new_p3 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3 *data); - -/** - * cogl_primitive_new_p2c4: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP2C4): An array - * of #CoglVertexP2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * and color attributes with #CoglAttribute<!-- -->s and upload - * your data. - * - * For example to draw a convex polygon with a linear gradient you - * can do: - * |[ - * CoglVertexP2C4 triangle[] = - * { - * { 0, 300, 0xff, 0x00, 0x00, 0xff }, - * { 150, 0, 0x00, 0xff, 0x00, 0xff }, - * { 300, 300, 0xff, 0x00, 0x00, 0xff } - * }; - * prim = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2C4 *data); - -/** - * cogl_primitive_new_p3c4: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP3C4): An array - * of #CoglVertexP3C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position - * and color attributes with #CoglAttribute<!-- -->s and upload - * your data. - * - * For example to draw a convex polygon with a linear gradient you - * can do: - * |[ - * CoglVertexP3C4 triangle[] = - * { - * { 0, 300, 0, 0xff, 0x00, 0x00, 0xff }, - * { 150, 0, 0, 0x00, 0xff, 0x00, 0xff }, - * { 300, 300, 0, 0xff, 0x00, 0x00, 0xff } - * }; - * prim = cogl_primitive_new_p3c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3C4 *data); - -/** - * cogl_primitive_new_p2t2: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP2T2): An array - * of #CoglVertexP2T2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position and - * texture coordinate attributes with #CoglAttribute<!-- -->s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping you can - * do: - * |[ - * CoglVertexP2T2 triangle[] = - * { - * { 0, 300, 0.0, 1.0}, - * { 150, 0, 0.5, 0.0}, - * { 300, 300, 1.0, 1.0} - * }; - * prim = cogl_primitive_new_p2t2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2t2 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2 *data); - -/** - * cogl_primitive_new_p3t2: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP3T2): An array - * of #CoglVertexP3T2 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position and - * texture coordinate attributes with #CoglAttribute<!-- -->s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping you can - * do: - * |[ - * CoglVertexP3T2 triangle[] = - * { - * { 0, 300, 0, 0.0, 1.0}, - * { 150, 0, 0, 0.5, 0.0}, - * { 300, 300, 0, 1.0, 1.0} - * }; - * prim = cogl_primitive_new_p3t2 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3t2 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2 *data); - -/** - * cogl_primitive_new_p2t2c4: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP2T2C4): An - * array of #CoglVertexP2T2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position, texture - * coordinate and color attributes with #CoglAttribute<!-- -->s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping and a - * linear gradient you can do: - * |[ - * CoglVertexP2T2C4 triangle[] = - * { - * { 0, 300, 0.0, 1.0, 0xff, 0x00, 0x00, 0xff}, - * { 150, 0, 0.5, 0.0, 0x00, 0xff, 0x00, 0xff}, - * { 300, 300, 1.0, 1.0, 0xff, 0x00, 0x00, 0xff} - * }; - * prim = cogl_primitive_new_p2t2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p2t2c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP2T2C4 *data); - -/** - * cogl_primitive_new_p3t2c4: (skip) - * @context: A #CoglContext - * @mode: A #CoglVerticesMode defining how to draw the vertices - * @n_vertices: The number of vertices to read from @data and also - * the number of vertices to read when later drawing. - * @data: (array length=n_vertices): (type Cogl.VertexP3T2C4): An - * array of #CoglVertexP3T2C4 vertices - * - * Provides a convenient way to describe a primitive, such as a single - * triangle strip or a triangle fan, that will internally allocate the - * necessary #CoglAttributeBuffer storage, describe the position, texture - * coordinate and color attributes with #CoglAttribute<!-- -->s and - * upload your data. - * - * For example to draw a convex polygon with texture mapping and a - * linear gradient you can do: - * |[ - * CoglVertexP3T2C4 triangle[] = - * { - * { 0, 300, 0, 0.0, 1.0, 0xff, 0x00, 0x00, 0xff}, - * { 150, 0, 0, 0.5, 0.0, 0x00, 0xff, 0x00, 0xff}, - * { 300, 300, 0, 1.0, 1.0, 0xff, 0x00, 0x00, 0xff} - * }; - * prim = cogl_primitive_new_p3t2c4 (COGL_VERTICES_MODE_TRIANGLE_FAN, - * 3, triangle); - * cogl_primitive_draw (prim); - * ]| - * - * The value passed as @n_vertices is initially used to determine how - * much can be read from @data but it will also be used to update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to read when drawing. - - * <note>The primitive API doesn't support drawing with sliced - * textures (since switching between slices implies changing state and - * so that implies multiple primitives need to be submitted). You - * should pass the %COGL_TEXTURE_NO_SLICING flag to all textures that - * might be used while drawing with this API. If your hardware doesn't - * support non-power of two textures (For example you are using GLES - * 1.1) then you will need to make sure your assets are resized to a - * power-of-two size (though they don't have to be square)</note> - * - * Return value: (transfer full): A newly allocated #CoglPrimitive - * with a reference of 1. This can be freed using cogl_object_unref(). - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_new_p3t2c4 (CoglContext *context, - CoglVerticesMode mode, - int n_vertices, - const CoglVertexP3T2C4 *data); -COGL_EXPORT int -cogl_primitive_get_first_vertex (CoglPrimitive *primitive); - -COGL_EXPORT void -cogl_primitive_set_first_vertex (CoglPrimitive *primitive, - int first_vertex); - -/** - * cogl_primitive_get_n_vertices: - * @primitive: A #CoglPrimitive object - * - * Queries the number of vertices to read when drawing the given - * @primitive. Usually this value is implicitly set when associating - * vertex data or indices with a #CoglPrimitive. - * - * If cogl_primitive_set_indices() has been used to associate a - * sequence of #CoglIndices with the given @primitive then the - * number of vertices to read can also be phrased as the number - * of indices to read. - * - * <note>To be clear; it doesn't refer to the number of vertices - in - * terms of data - associated with the primitive it's just the number - * of vertices to read and draw.</note> - * - * Returns: The number of vertices to read when drawing. - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT int -cogl_primitive_get_n_vertices (CoglPrimitive *primitive); - -/** - * cogl_primitive_set_n_vertices: - * @primitive: A #CoglPrimitive object - * @n_vertices: The number of vertices to read when drawing. - * - * Specifies how many vertices should be read when drawing the given - * @primitive. - * - * Usually this value is set implicitly when associating vertex data - * or indices with a #CoglPrimitive. - * - * <note>To be clear; it doesn't refer to the number of vertices - in - * terms of data - associated with the primitive it's just the number - * of vertices to read and draw.</note> - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT void -cogl_primitive_set_n_vertices (CoglPrimitive *primitive, - int n_vertices); - -COGL_EXPORT CoglVerticesMode -cogl_primitive_get_mode (CoglPrimitive *primitive); - -COGL_EXPORT void -cogl_primitive_set_mode (CoglPrimitive *primitive, - CoglVerticesMode mode); - -/** - * cogl_primitive_set_attributes: (skip) - * @primitive: A #CoglPrimitive object - * @attributes: an array of #CoglAttribute pointers - * @n_attributes: the number of elements in @attributes - * - * Replaces all the attributes of the given #CoglPrimitive object. - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_primitive_set_attributes (CoglPrimitive *primitive, - CoglAttribute **attributes, - int n_attributes); - -/** - * cogl_primitive_set_indices: (skip) - * @primitive: A #CoglPrimitive - * @indices: A #CoglIndices array - * @n_indices: The number of indices to reference when drawing - * - * Associates a sequence of #CoglIndices with the given @primitive. - * - * #CoglIndices provide a way to virtualize your real vertex data by - * providing a sequence of indices that index into your real vertex - * data. The GPU will walk though the index values to indirectly - * lookup the data for each vertex instead of sequentially walking - * through the data directly. This lets you save memory by indexing - * shared data multiple times instead of duplicating the data. - * - * The value passed as @n_indices will simply update the - * #CoglPrimitive <structfield>n_vertices</structfield> property as if - * cogl_primitive_set_n_vertices() were called. This property defines - * the number of vertices to draw or, put another way, how many - * indices should be read from @indices when drawing. - * - * <note>The #CoglPrimitive <structfield>first_vertex</structfield> property - * also affects drawing with indices by defining the first entry of the - * indices to start drawing from.</note> - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_primitive_set_indices (CoglPrimitive *primitive, - CoglIndices *indices, - int n_indices); - -/** - * cogl_primitive_get_indices: (skip) - * @primitive: A #CoglPrimitive - * - * Return value: (transfer none): the indices that were set with - * cogl_primitive_set_indices() or %NULL if no indices were set. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglIndices * -cogl_primitive_get_indices (CoglPrimitive *primitive); - -/** - * cogl_primitive_copy: - * @primitive: A primitive copy - * - * Makes a copy of an existing #CoglPrimitive. Note that the primitive - * is a shallow copy which means it will use the same attributes and - * attribute buffers as the original primitive. - * - * Return value: (transfer full): the new primitive - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglPrimitive * -cogl_primitive_copy (CoglPrimitive *primitive); - -/** - * cogl_is_primitive: - * @object: A #CoglObject - * - * Gets whether the given object references a #CoglPrimitive. - * - * Returns: %TRUE if the @object references a #CoglPrimitive, - * %FALSE otherwise - * - * Since: 1.6 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_primitive (void *object); - -/** - * CoglPrimitiveAttributeCallback: - * @primitive: The #CoglPrimitive whose attributes are being iterated - * @attribute: The #CoglAttribute - * @user_data: The private data passed to cogl_primitive_foreach_attribute() - * - * The callback prototype used with cogl_primitive_foreach_attribute() - * for iterating all the attributes of a #CoglPrimitive. - * - * The function should return TRUE to continue iteration or FALSE to - * stop. - * - * Since: 1.10 - * Stability: Unstable - */ -typedef gboolean (* CoglPrimitiveAttributeCallback) (CoglPrimitive *primitive, - CoglAttribute *attribute, - void *user_data); - -/** - * cogl_primitive_foreach_attribute: - * @primitive: A #CoglPrimitive object - * @callback: (scope call): A #CoglPrimitiveAttributeCallback to be - * called for each attribute - * @user_data: (closure): Private data that will be passed to the - * callback - * - * Iterates all the attributes of the given #CoglPrimitive. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_primitive_foreach_attribute (CoglPrimitive *primitive, - CoglPrimitiveAttributeCallback callback, - void *user_data); - -/** - * cogl_primitive_draw: (skip) - * @primitive: A #CoglPrimitive geometry object - * @framebuffer: A destination #CoglFramebuffer - * @pipeline: A #CoglPipeline state object - * - * Draws the given @primitive geometry to the specified destination - * @framebuffer using the graphics processing state described by @pipeline. - * - * This drawing api doesn't support high-level meta texture types such - * as #CoglTexture2DSliced so it is the user's responsibility to - * ensure that only low-level textures that can be directly sampled by - * a GPU such as #CoglTexture2D are associated with layers of the given - * @pipeline. - * - * Stability: unstable - * Since: 1.16 - */ -COGL_EXPORT void -cogl_primitive_draw (CoglPrimitive *primitive, - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline); - - -G_END_DECLS - -#endif /* __COGL_PRIMITIVE_H__ */ - diff --git a/cogl/cogl/cogl-primitives-private.h b/cogl/cogl/cogl-primitives-private.h deleted file mode 100644 index 637c33eba..000000000 --- a/cogl/cogl/cogl-primitives-private.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PRIMITIVES_PRIVATE_H -#define __COGL_PRIMITIVES_PRIVATE_H - -#include <glib.h> - -G_BEGIN_DECLS - -/* Draws a rectangle without going through the journal so that it will - be flushed immediately. This should only be used in situations - where the code may be called while the journal is already being - flushed. In that case using the journal would go wrong */ -void -_cogl_rectangle_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2); - -void -cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - const CoglVertexP2 *vertices, - unsigned int n_vertices); - -typedef struct _CoglMultiTexturedRect -{ - const float *position; /* x0,y0,x1,y1 */ - const float *tex_coords; /* (tx0,ty0,tx1,ty1)(tx0,ty0,tx1,ty1)(... */ - int tex_coords_len; /* number of floats in tex_coords? */ -} CoglMultiTexturedRect; - -void -_cogl_framebuffer_draw_multitextured_rectangles ( - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglMultiTexturedRect *rects, - int n_rects); - -G_END_DECLS - -#endif /* __COGL_PRIMITIVES_PRIVATE_H */ diff --git a/cogl/cogl/cogl-primitives.c b/cogl/cogl/cogl-primitives.c deleted file mode 100644 index 03e1d54c4..000000000 --- a/cogl/cogl/cogl-primitives.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-context-private.h" -#include "cogl-journal-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-attribute-private.h" -#include "cogl-private.h" -#include "cogl-meta-texture.h" -#include "cogl-framebuffer-private.h" -#include "cogl1-context.h" -#include "cogl-primitives-private.h" - -#include <string.h> -#include <math.h> - -#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 - -typedef struct _TextureSlicedQuadState -{ - CoglFramebuffer *framebuffer; - CoglPipeline *pipeline; - CoglTexture *main_texture; - float tex_virtual_origin_x; - float tex_virtual_origin_y; - float quad_origin_x; - float quad_origin_y; - float v_to_q_scale_x; - float v_to_q_scale_y; - float quad_len_x; - float quad_len_y; - gboolean flipped_x; - gboolean flipped_y; -} TextureSlicedQuadState; - -typedef struct _TextureSlicedPolygonState -{ - const CoglTextureVertex *vertices; - int n_vertices; - int stride; - CoglAttribute **attributes; -} TextureSlicedPolygonState; - -static void -log_quad_sub_textures_cb (CoglTexture *texture, - const float *subtexture_coords, - const float *virtual_coords, - void *user_data) -{ - TextureSlicedQuadState *state = user_data; - CoglFramebuffer *framebuffer = state->framebuffer; - CoglTexture *texture_override; - float quad_coords[4]; - -#define TEX_VIRTUAL_TO_QUAD(V, Q, AXIS) \ - do { \ - Q = V - state->tex_virtual_origin_##AXIS; \ - Q *= state->v_to_q_scale_##AXIS; \ - if (state->flipped_##AXIS) \ - Q = state->quad_len_##AXIS - Q; \ - Q += state->quad_origin_##AXIS; \ - } while (0); - - TEX_VIRTUAL_TO_QUAD (virtual_coords[0], quad_coords[0], x); - TEX_VIRTUAL_TO_QUAD (virtual_coords[1], quad_coords[1], y); - - TEX_VIRTUAL_TO_QUAD (virtual_coords[2], quad_coords[2], x); - TEX_VIRTUAL_TO_QUAD (virtual_coords[3], quad_coords[3], y); - -#undef TEX_VIRTUAL_TO_QUAD - - COGL_NOTE (DRAW, - "~~~~~ slice\n" - "qx1: %f\t" - "qy1: %f\n" - "qx2: %f\t" - "qy2: %f\n" - "tx1: %f\t" - "ty1: %f\n" - "tx2: %f\t" - "ty2: %f\n", - quad_coords[0], quad_coords[1], - quad_coords[2], quad_coords[3], - subtexture_coords[0], subtexture_coords[1], - subtexture_coords[2], subtexture_coords[3]); - - /* We only need to override the texture if it's different from the - main texture */ - if (texture == state->main_texture) - texture_override = NULL; - else - texture_override = texture; - - _cogl_journal_log_quad (cogl_framebuffer_get_journal (framebuffer), - quad_coords, - state->pipeline, - 1, /* one layer */ - texture_override, /* replace the layer0 texture */ - subtexture_coords, - 4); -} - -typedef struct _ValidateFirstLayerState -{ - CoglPipeline *override_pipeline; -} ValidateFirstLayerState; - -static gboolean -validate_first_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateFirstLayerState *state = user_data; - CoglPipelineWrapMode clamp_to_edge = - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - CoglPipelineWrapMode wrap_s; - CoglPipelineWrapMode wrap_t; - - /* We can't use hardware repeat so we need to set clamp to edge - * otherwise it might pull in edge pixels from the other side. By - * default WRAP_MODE_AUTOMATIC becomes CLAMP_TO_EDGE so we only need - * to override if the wrap mode isn't already automatic or - * clamp_to_edge. - */ - wrap_s = cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index); - if (wrap_s != COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE && - wrap_s != COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline, - layer_index, clamp_to_edge); - } - - wrap_t = cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index); - if (wrap_t != COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE && - wrap_t != COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline, - layer_index, clamp_to_edge); - } - - return FALSE; -} - -/* This path doesn't currently support multitexturing but is used for - * CoglTextures that don't support repeating using the GPU so we need to - * manually emit extra geometry to fake the repeating. This includes: - * - * - CoglTexture2DSliced: when made of > 1 slice or if the users given - * texture coordinates require repeating, - * - CoglTexture2DAtlas: if the users given texture coordinates require - * repeating, - * - CoglTexturePixmap: if the users given texture coordinates require - * repeating - */ -/* TODO: support multitexturing */ -static void -_cogl_texture_quad_multiple_primitives (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglTexture *texture, - int layer_index, - const float *position, - float tx_1, - float ty_1, - float tx_2, - float ty_2) -{ - TextureSlicedQuadState state; - gboolean tex_virtual_flipped_x; - gboolean tex_virtual_flipped_y; - gboolean quad_flipped_x; - gboolean quad_flipped_y; - ValidateFirstLayerState validate_first_layer_state; - CoglPipelineWrapMode wrap_s, wrap_t; - - wrap_s = cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index); - wrap_t = cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index); - - validate_first_layer_state.override_pipeline = NULL; - cogl_pipeline_foreach_layer (pipeline, - validate_first_layer_cb, - &validate_first_layer_state); - - state.framebuffer = framebuffer; - state.main_texture = texture; - - if (validate_first_layer_state.override_pipeline) - state.pipeline = validate_first_layer_state.override_pipeline; - else - state.pipeline = pipeline; - - /* Get together the data we need to transform the virtual texture - * coordinates of each slice into quad coordinates... - * - * NB: We need to consider that the quad coordinates and the texture - * coordinates may be inverted along the x or y axis, and must preserve the - * inversions when we emit the final geometry. - */ - -#define X0 0 -#define Y0 1 -#define X1 2 -#define Y1 3 - - tex_virtual_flipped_x = (tx_1 > tx_2) ? TRUE : FALSE; - tex_virtual_flipped_y = (ty_1 > ty_2) ? TRUE : FALSE; - state.tex_virtual_origin_x = tex_virtual_flipped_x ? tx_2 : tx_1; - state.tex_virtual_origin_y = tex_virtual_flipped_y ? ty_2 : ty_1; - - quad_flipped_x = (position[X0] > position[X1]) ? TRUE : FALSE; - quad_flipped_y = (position[Y0] > position[Y1]) ? TRUE : FALSE; - state.quad_origin_x = quad_flipped_x ? position[X1] : position[X0]; - state.quad_origin_y = quad_flipped_y ? position[Y1] : position[Y0]; - - /* flatten the two forms of coordinate inversion into one... */ - state.flipped_x = tex_virtual_flipped_x ^ quad_flipped_x; - state.flipped_y = tex_virtual_flipped_y ^ quad_flipped_y; - - /* We use the _len_AXIS naming here instead of _width and _height because - * log_quad_slice_cb uses a macro with symbol concatenation to handle both - * axis, so this is more convenient... */ - state.quad_len_x = fabs (position[X1] - position[X0]); - state.quad_len_y = fabs (position[Y1] - position[Y0]); - -#undef X0 -#undef Y0 -#undef X1 -#undef Y1 - - state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1)); - state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1)); - - /* For backwards compatibility the default wrap mode for cogl_rectangle() is - * _REPEAT... */ - if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; - if (wrap_t == COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - wrap_t = COGL_PIPELINE_WRAP_MODE_REPEAT; - - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture), - tx_1, ty_1, tx_2, ty_2, - wrap_s, - wrap_t, - log_quad_sub_textures_cb, - &state); - - if (validate_first_layer_state.override_pipeline) - cogl_object_unref (validate_first_layer_state.override_pipeline); -} - -typedef struct _ValidateTexCoordsState -{ - int i; - int n_layers; - const float *user_tex_coords; - int user_tex_coords_len; - float *final_tex_coords; - CoglPipeline *override_pipeline; - gboolean needs_multiple_primitives; -} ValidateTexCoordsState; - -/* - * Validate the texture coordinates for this rectangle. - */ -static gboolean -validate_tex_coords_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateTexCoordsState *state = user_data; - CoglTexture *texture; - const float *in_tex_coords; - float *out_tex_coords; - float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0}; - CoglTransformResult transform_result; - - state->i++; - - /* FIXME: we should be able to avoid this copying when no - * transform is required by the texture backend and the user - * has supplied enough coordinates for all the layers. - */ - - /* If the user didn't supply texture coordinates for this layer - then use the default coords */ - if (state->i >= state->user_tex_coords_len / 4) - in_tex_coords = default_tex_coords; - else - in_tex_coords = &state->user_tex_coords[state->i * 4]; - - out_tex_coords = &state->final_tex_coords[state->i * 4]; - - memcpy (out_tex_coords, in_tex_coords, sizeof (float) * 4); - - texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); - - /* NB: NULL textures are handled by _cogl_pipeline_flush_gl_state */ - if (!texture) - return TRUE; - - /* Convert the texture coordinates to GL. - */ - transform_result = - _cogl_texture_transform_quad_coords_to_gl (texture, - out_tex_coords); - /* If the texture has waste or we are using GL_TEXTURE_RECT we - * can't handle texture repeating so we can't use the layer if - * repeating is required. - * - * NB: We already know that no texture matrix is being used if the - * texture doesn't support hardware repeat. - */ - if (transform_result == COGL_TRANSFORM_SOFTWARE_REPEAT) - { - if (state->i == 0) - { - if (state->n_layers > 1) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Skipping layers 1..n of your material since " - "the first layer doesn't support hardware " - "repeat (e.g. because of waste or use of " - "GL_TEXTURE_RECTANGLE_ARB) and you supplied " - "texture coordinates outside the range [0,1]." - "Falling back to software repeat assuming " - "layer 0 is the most important one keep"); - warning_seen = TRUE; - } - - if (state->override_pipeline) - cogl_object_unref (state->override_pipeline); - state->needs_multiple_primitives = TRUE; - return FALSE; - } - else - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("Skipping layer %d of your material " - "since you have supplied texture coords " - "outside the range [0,1] but the texture " - "doesn't support hardware repeat (e.g. " - "because of waste or use of " - "GL_TEXTURE_RECTANGLE_ARB). This isn't " - "supported with multi-texturing.", state->i); - warning_seen = TRUE; - - cogl_pipeline_set_layer_texture (pipeline, layer_index, NULL); - } - } - - /* By default WRAP_MODE_AUTOMATIC becomes to CLAMP_TO_EDGE. If - the texture coordinates need repeating then we'll override - this to GL_REPEAT. Otherwise we'll leave it at CLAMP_TO_EDGE - so that it won't blend in pixels from the opposite side when - the full texture is drawn with GL_LINEAR filter mode */ - if (transform_result == COGL_TRANSFORM_HARDWARE_REPEAT) - { - if (cogl_pipeline_get_layer_wrap_mode_s (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_s (state->override_pipeline, - layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - if (cogl_pipeline_get_layer_wrap_mode_t (pipeline, layer_index) == - COGL_PIPELINE_WRAP_MODE_AUTOMATIC) - { - if (!state->override_pipeline) - state->override_pipeline = cogl_pipeline_copy (pipeline); - cogl_pipeline_set_layer_wrap_mode_t (state->override_pipeline, - layer_index, - COGL_PIPELINE_WRAP_MODE_REPEAT); - } - } - - return TRUE; -} - -/* This path supports multitexturing but only when each of the layers is - * handled with a single GL texture. Also if repeating is necessary then - * _cogl_texture_can_hardware_repeat() must return TRUE. - * This includes layers made from: - * - * - CoglTexture2DSliced: if only comprised of a single slice with optional - * waste, assuming the users given texture coordinates don't require - * repeating. - * - CoglTexture{1D,2D}: always. - * - CoglTexture2DAtlas: assuming the users given texture coordinates don't - * require repeating. - * - CoglTexturePixmap: assuming the users given texture coordinates don't - * require repeating. - */ -static gboolean -_cogl_multitexture_quad_single_primitive (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - const float *position, - const float *user_tex_coords, - int user_tex_coords_len) -{ - int n_layers = cogl_pipeline_get_n_layers (pipeline); - ValidateTexCoordsState state; - float *final_tex_coords = alloca (sizeof (float) * 4 * n_layers); - - state.i = -1; - state.n_layers = n_layers; - state.user_tex_coords = user_tex_coords; - state.user_tex_coords_len = user_tex_coords_len; - state.final_tex_coords = final_tex_coords; - state.override_pipeline = NULL; - state.needs_multiple_primitives = FALSE; - - cogl_pipeline_foreach_layer (pipeline, - validate_tex_coords_cb, - &state); - - if (state.needs_multiple_primitives) - return FALSE; - - if (state.override_pipeline) - pipeline = state.override_pipeline; - - _cogl_journal_log_quad (cogl_framebuffer_get_journal (framebuffer), - position, - pipeline, - n_layers, - NULL, /* no texture override */ - final_tex_coords, - n_layers * 4); - - if (state.override_pipeline) - cogl_object_unref (state.override_pipeline); - - return TRUE; -} - -typedef struct _ValidateLayerState -{ - CoglContext *ctx; - int i; - int first_layer; - CoglPipeline *override_source; - gboolean all_use_sliced_quad_fallback; -} ValidateLayerState; - -static gboolean -_cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - ValidateLayerState *state = user_data; - CoglTexture *texture; - - state->i++; - - /* We need to ensure the mipmaps are ready before deciding - * anything else about the texture because the texture storage - * could completely change if it needs to be migrated out of the - * atlas and will affect how we validate the layer. - * - * FIXME: this needs to be generalized. There could be any - * number of things that might require a shuffling of the - * underlying texture storage. We could add two mechanisms to - * generalize this a bit... - * - * 1) add a _cogl_pipeline_layer_update_storage() function that - * would for instance consider if mipmapping is necessary and - * potentially migrate the texture from an atlas. - * - * 2) allow setting of transient primitive-flags on a pipeline - * that may affect the outcome of _update_storage(). One flag - * could indicate that we expect to sample beyond the bounds of - * the texture border. - * - * flags = COGL_PIPELINE_PRIMITIVE_FLAG_VALID_BORDERS; - * _cogl_pipeline_layer_assert_primitive_flags (layer, flags) - * _cogl_pipeline_layer_update_storage (layer) - * enqueue primitive in journal - * - * when the primitive is dequeued and drawn we should: - * _cogl_pipeline_flush_gl_state (pipeline) - * draw primitive - * _cogl_pipeline_unassert_primitive_flags (layer, flags); - * - * _cogl_pipeline_layer_update_storage should take into - * consideration all the asserted primitive requirements. (E.g. - * there could be multiple primitives in the journal - or in a - * renderlist in the future - that need mipmaps or that need - * valid contents beyond their borders (for cogl_polygon) - * meaning they can't work with textures in an atas, so - * _cogl_pipeline_layer_update_storage would pass on these - * requirements to the texture atlas backend which would make - * sure the referenced texture is migrated out of the atlas and - * mipmaps are generated.) - */ - _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); - - texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); - - /* NULL textures are handled by - * _cogl_pipeline_flush_gl_state */ - if (texture == NULL) - return TRUE; - - if (state->i == 0) - state->first_layer = layer_index; - - /* XXX: - * For now, if the first layer is sliced then all other layers are - * ignored since we currently don't support multi-texturing with - * sliced textures. If the first layer is not sliced then any other - * layers found to be sliced will be skipped. (with a warning) - * - * TODO: Add support for multi-texturing rectangles with sliced - * textures if no texture matrices are in use. - */ - if (cogl_texture_is_sliced (texture)) - { - if (state->i == 0) - { - if (cogl_pipeline_get_n_layers (pipeline) > 1) - { - static gboolean warning_seen = FALSE; - - if (!state->override_source) - state->override_source = cogl_pipeline_copy (pipeline); - _cogl_pipeline_prune_to_n_layers (state->override_source, 1); - - if (!warning_seen) - g_warning ("Skipping layers 1..n of your pipeline since " - "the first layer is sliced. We don't currently " - "support any multi-texturing with sliced " - "textures but assume layer 0 is the most " - "important to keep"); - warning_seen = TRUE; - } - - state->all_use_sliced_quad_fallback = TRUE; - - return FALSE; - } - else - { - static gboolean warning_seen = FALSE; - CoglTexture2D *tex_2d; - - if (!warning_seen) - g_warning ("Skipping layer %d of your pipeline consisting of " - "a sliced texture (unsupported for multi texturing)", - state->i); - warning_seen = TRUE; - - /* Note: currently only 2D textures can be sliced. */ - tex_2d = state->ctx->default_gl_texture_2d_tex; - cogl_pipeline_set_layer_texture (pipeline, layer_index, - COGL_TEXTURE (tex_2d)); - return TRUE; - } - } - -#ifdef COGL_ENABLE_DEBUG - /* If the texture can't be repeated with the GPU (e.g. because it has - * waste or if using GL_TEXTURE_RECTANGLE_ARB) then if a texture matrix - * is also in use we don't know if the result will end up trying - * to texture from the waste area. - * - * Note: we check can_hardware_repeat() first since it's cheaper. - * - * Note: cases where the texture coordinates will require repeating - * will be caught by later validation. - */ - if (!_cogl_texture_can_hardware_repeat (texture) && - _cogl_pipeline_layer_has_user_matrix (pipeline, layer_index)) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - g_warning ("layer %d of your pipeline uses a custom " - "texture matrix but because the texture doesn't " - "support hardware repeating you may see artefacts " - "due to sampling beyond the texture's bounds.", - state->i); - warning_seen = TRUE; - } -#endif - - return TRUE; -} - -void -_cogl_framebuffer_draw_multitextured_rectangles ( - CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglMultiTexturedRect *rects, - int n_rects) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglPipeline *original_pipeline; - ValidateLayerState state; - int i; - - original_pipeline = pipeline; - - /* - * Validate all the layers of the current source pipeline... - */ - state.ctx = ctx; - state.i = -1; - state.first_layer = 0; - state.override_source = NULL; - state.all_use_sliced_quad_fallback = FALSE; - cogl_pipeline_foreach_layer (pipeline, - _cogl_rectangles_validate_layer_cb, - &state); - - if (state.override_source) - pipeline = state.override_source; - - /* - * Emit geometry for each of the rectangles... - */ - - for (i = 0; i < n_rects; i++) - { - CoglTexture *texture; - const float default_tex_coords[4] = {0.0, 0.0, 1.0, 1.0}; - const float *tex_coords; - - if (!state.all_use_sliced_quad_fallback) - { - gboolean success = - _cogl_multitexture_quad_single_primitive (framebuffer, - pipeline, - rects[i].position, - rects[i].tex_coords, - rects[i].tex_coords_len); - - /* NB: If _cogl_multitexture_quad_single_primitive fails then it - * means the user tried to use texture repeat with a texture that - * can't be repeated by the GPU (e.g. due to waste or use of - * GL_TEXTURE_RECTANGLE_ARB) */ - if (success) - continue; - } - - /* If multitexturing failed or we are drawing with a sliced texture - * then we only support a single layer so we pluck out the texture - * from the first pipeline layer... */ - texture = cogl_pipeline_get_layer_texture (pipeline, state.first_layer); - - if (rects[i].tex_coords) - tex_coords = rects[i].tex_coords; - else - tex_coords = default_tex_coords; - - COGL_NOTE (DRAW, "Drawing Tex Quad (Multi-Prim Mode)"); - - _cogl_texture_quad_multiple_primitives (framebuffer, - pipeline, - texture, - state.first_layer, - rects[i].position, - tex_coords[0], - tex_coords[1], - tex_coords[2], - tex_coords[3]); - } - - if (pipeline != original_pipeline) - cogl_object_unref (pipeline); -} - -void -cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglVerticesMode mode, - const CoglVertexP2 *vertices, - unsigned int n_vertices) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglAttributeBuffer *attribute_buffer; - CoglAttribute *attributes[1]; - size_t vertices_size = sizeof (CoglVertexP2) * n_vertices; - - attribute_buffer = - cogl_attribute_buffer_new (ctx, vertices_size, vertices); - attributes[0] = cogl_attribute_new (attribute_buffer, - "cogl_position_in", - sizeof (CoglVertexP2), /* stride */ - 0, /* offset */ - 2, /* n_components */ - COGL_ATTRIBUTE_TYPE_FLOAT); - - _cogl_framebuffer_draw_attributes (framebuffer, - pipeline, - mode, - 0, /* first_index */ - n_vertices, - attributes, - 1, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); - - - cogl_object_unref (attributes[0]); - cogl_object_unref (attribute_buffer); -} - -void -_cogl_rectangle_immediate (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - float x_1, - float y_1, - float x_2, - float y_2) -{ - CoglVertexP2 vertices[4] = - { - {x_1, y_1}, - {x_1, y_2}, - {x_2, y_1}, - {x_2, y_2} - }; - - cogl_2d_primitives_immediate (framebuffer, - pipeline, - COGL_VERTICES_MODE_TRIANGLE_STRIP, - vertices, - 4); -} diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h deleted file mode 100644 index 2878a1640..000000000 --- a/cogl/cogl/cogl-private.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PRIVATE_H__ -#define __COGL_PRIVATE_H__ - -#include <cogl/cogl-pipeline.h> - -#include "cogl-context.h" -#include "cogl-flags.h" - -G_BEGIN_DECLS - -typedef enum -{ - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, - COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, - COGL_PRIVATE_FEATURE_PBOS, - COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, - COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, - COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT, - COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, - COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, - COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, - COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, - COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, - COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, - COGL_PRIVATE_FEATURE_OES_EGL_SYNC, - /* If this is set then the winsys is responsible for queueing dirty - * events. Otherwise a dirty event will be queued when the onscreen - * is first allocated or when it is shown or resized */ - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - /* This feature allows for explicitly selecting a GL-based backend, - * as opposed to nop or (in the future) Vulkan. - */ - COGL_PRIVATE_FEATURE_ANY_GL, - - COGL_N_PRIVATE_FEATURES -} CoglPrivateFeature; - -/* Sometimes when evaluating pipelines, either during comparisons or - * if calculating a hash value we need to tweak the evaluation - * semantics */ -typedef enum _CoglPipelineEvalFlags -{ - COGL_PIPELINE_EVAL_FLAG_NONE = 0 -} CoglPipelineEvalFlags; - -void -_cogl_transform_point (const graphene_matrix_t *matrix_mv, - const graphene_matrix_t *matrix_p, - const float *viewport, - float *x, - float *y); - -gboolean -_cogl_check_extension (const char *name, char * const *ext); - -void -_cogl_init (void); - -#define _cogl_has_private_feature(ctx, feature) \ - COGL_FLAGS_GET ((ctx)->private_features, (feature)) - -G_END_DECLS - -#endif /* __COGL_PRIVATE_H__ */ diff --git a/cogl/cogl/cogl-profile.c b/cogl/cogl/cogl-profile.c deleted file mode 100644 index c7ee7dca1..000000000 --- a/cogl/cogl/cogl-profile.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "cogl-config.h" - -#ifdef COGL_ENABLE_PROFILE - -#include "cogl-profile.h" -#include "cogl-debug.h" -#include "cogl-i18n-private.h" - -#include <stdlib.h> - -UProfContext *_cogl_uprof_context; - -static gboolean -debug_option_getter (void *user_data) -{ - unsigned int shift = GPOINTER_TO_UINT (user_data); - return COGL_DEBUG_ENABLED (shift); -} - -static void -debug_option_setter (gboolean value, void *user_data) -{ - unsigned int shift = GPOINTER_TO_UINT (user_data); - - if (value) - COGL_DEBUG_SET_FLAG (shift); - else - COGL_DEBUG_CLEAR_FLAG (shift); -} - -static void -print_exit_report (void) -{ - if (getenv ("COGL_PROFILE_OUTPUT_REPORT")) - { - UProfContext *mainloop_context; - UProfTimerResult *mainloop_timer; - UProfReport *report; - - /* NB: uprof provides a shared context for mainloop statistics - * which needs to be setup by the application which controls the - * mainloop. - * - * If no "Mainloop" timer has been setup then we print a warning - * since we can't provide a meaningful Cogl report without one. - */ - mainloop_context = uprof_get_mainloop_context (); - mainloop_timer = uprof_context_get_timer_result (mainloop_context, - "Mainloop"); - /* just bail out if the mainloop timer wasn't hit */ - if (!mainloop_timer) - { - g_warning ("\n\n" - "No UProf \"Mainloop\" timer was setup by the " - "application therefore we\ncan't provide a meaningful " - "profile report.\n" - "\n" - "This should be done automatically if you are using Clutter " - "(if\nbuilt with --enable-profile)\n" - "\n" - "If you aren't using Clutter then you can declare a " - "\"Mainloop\" UProf\ntimer in your application like this:\n\n" - " UPROF_STATIC_TIMER (mainloop_timer, \n" - " NULL,\n" - " \"Mainloop\",\n" - " \"Time in glib mainloop\",\n" - " 0);\n" - "\n" - "And start/stop it around your mainloop like this:\n" - "\n" - " UPROF_TIMER_START (uprof_get_mainloop_context (), mainloop_timer);\n" - " g_main_loop_run (loop);\n" - " UPROF_TIMER_STOP (uprof_get_mainloop_context (), mainloop_timer);\n"); - return; - } - - report = uprof_report_new ("Cogl report"); - uprof_report_add_context (report, _cogl_uprof_context); - uprof_report_print (report); - uprof_report_unref (report); - } - uprof_context_unref (_cogl_uprof_context); -} - -void -_cogl_uprof_init (void) -{ - _cogl_uprof_context = uprof_context_new ("Cogl"); - uprof_context_link (_cogl_uprof_context, uprof_get_mainloop_context ()); -#define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - G_STMT_START { \ - int shift = COGL_DEBUG_ ## MASK_NAME; \ - uprof_context_add_boolean_option (_cogl_uprof_context, \ - GROUP, \ - NAME, \ - NAME_FORMATTED, \ - DESCRIPTION, \ - debug_option_getter, \ - debug_option_setter, \ - GUINT_TO_POINTER (shift)); \ - } G_STMT_END; - -#include "cogl-debug-options.h" -#undef OPT - - atexit (print_exit_report); -} - -void -_cogl_profile_trace_message (const char *format, ...) -{ - va_list ap; - - va_start (ap, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, ap); - va_end (ap); - - if (_cogl_uprof_context) - uprof_context_vtrace_message (_cogl_uprof_context, format, ap); -} - -#endif diff --git a/cogl/cogl/cogl-profile.h b/cogl/cogl/cogl-profile.h deleted file mode 100644 index ad32a3f16..000000000 --- a/cogl/cogl/cogl-profile.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PROFILE_H__ -#define __COGL_PROFILE_H__ - - -#ifdef COGL_ENABLE_PROFILE - -#include <uprof.h> - -extern UProfContext *_cogl_uprof_context; - -#define COGL_STATIC_TIMER UPROF_STATIC_TIMER -#define COGL_STATIC_COUNTER UPROF_STATIC_COUNTER -#define COGL_COUNTER_INC UPROF_COUNTER_INC -#define COGL_COUNTER_DEC UPROF_COUNTER_DEC -#define COGL_TIMER_START UPROF_TIMER_START -#define COGL_TIMER_STOP UPROF_TIMER_STOP - -void -_cogl_uprof_init (void); - -COGL_EXPORT void -_cogl_profile_trace_message (const char *format, ...); - -#else - -#define COGL_STATIC_TIMER(A,B,C,D,E) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_STATIC_COUNTER(A,B,C,D) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_COUNTER_INC(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_COUNTER_DEC(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_TIMER_START(A,B) G_STMT_START{ (void)0; }G_STMT_END -#define COGL_TIMER_STOP(A,B) G_STMT_START{ (void)0; }G_STMT_END - -#define _cogl_profile_trace_message g_message - -#endif - -#endif /* __COGL_PROFILE_H__ */ - diff --git a/cogl/cogl/cogl-rectangle-map.c b/cogl/cogl/cogl-rectangle-map.c deleted file mode 100644 index 6285c8a7a..000000000 --- a/cogl/cogl/cogl-rectangle-map.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <glib.h> - -#include "cogl-util.h" -#include "cogl-rectangle-map.h" -#include "cogl-debug.h" - -/* Implements a data structure which keeps track of unused - sub-rectangles within a larger rectangle using a binary tree - structure. The algorithm for this is based on the description here: - - http://www.blackpawn.com/texts/lightmaps/default.html -*/ - -#ifdef COGL_ENABLE_DEBUG - -/* The cairo header is only used for debugging to generate an image of - the atlas */ -#include <cairo.h> - -static void _cogl_rectangle_map_dump_image (CoglRectangleMap *map); - -#endif /* COGL_ENABLE_DEBUG */ - -typedef struct _CoglRectangleMapNode CoglRectangleMapNode; -typedef struct _CoglRectangleMapStackEntry CoglRectangleMapStackEntry; - -typedef void (* CoglRectangleMapInternalForeachCb) (CoglRectangleMapNode *node, - void *data); - -typedef enum -{ - COGL_RECTANGLE_MAP_BRANCH, - COGL_RECTANGLE_MAP_FILLED_LEAF, - COGL_RECTANGLE_MAP_EMPTY_LEAF -} CoglRectangleMapNodeType; - -struct _CoglRectangleMap -{ - CoglRectangleMapNode *root; - - unsigned int n_rectangles; - - unsigned int space_remaining; - - GDestroyNotify value_destroy_func; - - /* Stack used for walking the structure. This is only used during - the lifetime of a single function call but it is kept here as an - optimisation to avoid reallocating it every time it is needed */ - GArray *stack; -}; - -struct _CoglRectangleMapNode -{ - CoglRectangleMapNodeType type; - - CoglRectangleMapEntry rectangle; - - unsigned int largest_gap; - - CoglRectangleMapNode *parent; - - union - { - /* Fields used when this is a branch */ - struct - { - CoglRectangleMapNode *left; - CoglRectangleMapNode *right; - } branch; - - /* Field used when this is a filled leaf */ - void *data; - } d; -}; - -struct _CoglRectangleMapStackEntry -{ - /* The node to search */ - CoglRectangleMapNode *node; - /* Index of next branch of this node to explore. Basically either 0 - to go left or 1 to go right */ - gboolean next_index; -}; - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_new (void) -{ - return g_new0 (CoglRectangleMapNode, 1); -} - -static void -_cogl_rectangle_map_node_free (CoglRectangleMapNode *node) -{ - g_free (node); -} - -CoglRectangleMap * -_cogl_rectangle_map_new (unsigned int width, - unsigned int height, - GDestroyNotify value_destroy_func) -{ - CoglRectangleMap *map = g_new (CoglRectangleMap, 1); - CoglRectangleMapNode *root = _cogl_rectangle_map_node_new (); - - root->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - root->parent = NULL; - root->rectangle.x = 0; - root->rectangle.y = 0; - root->rectangle.width = width; - root->rectangle.height = height; - root->largest_gap = width * height; - - map->root = root; - map->n_rectangles = 0; - map->value_destroy_func = value_destroy_func; - map->space_remaining = width * height; - - map->stack = g_array_new (FALSE, FALSE, sizeof (CoglRectangleMapStackEntry)); - - return map; -} - -static void -_cogl_rectangle_map_stack_push (GArray *stack, - CoglRectangleMapNode *node, - gboolean next_index) -{ - CoglRectangleMapStackEntry *new_entry; - - g_array_set_size (stack, stack->len + 1); - - new_entry = &g_array_index (stack, CoglRectangleMapStackEntry, - stack->len - 1); - - new_entry->node = node; - new_entry->next_index = next_index; -} - -static void -_cogl_rectangle_map_stack_pop (GArray *stack) -{ - g_array_set_size (stack, stack->len - 1); -} - -static CoglRectangleMapStackEntry * -_cogl_rectangle_map_stack_get_top (GArray *stack) -{ - return &g_array_index (stack, CoglRectangleMapStackEntry, - stack->len - 1); -} - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_split_horizontally (CoglRectangleMapNode *node, - unsigned int left_width) -{ - /* Splits the node horizontally (according to emacs' definition, not - vim) by converting it to a branch and adding two new leaf - nodes. The leftmost branch will have the width left_width and - will be returned. If the node is already just the right size it - won't do anything */ - - CoglRectangleMapNode *left_node, *right_node; - - if (node->rectangle.width == left_width) - return node; - - left_node = _cogl_rectangle_map_node_new (); - left_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - left_node->parent = node; - left_node->rectangle.x = node->rectangle.x; - left_node->rectangle.y = node->rectangle.y; - left_node->rectangle.width = left_width; - left_node->rectangle.height = node->rectangle.height; - left_node->largest_gap = (left_node->rectangle.width * - left_node->rectangle.height); - node->d.branch.left = left_node; - - right_node = _cogl_rectangle_map_node_new (); - right_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - right_node->parent = node; - right_node->rectangle.x = node->rectangle.x + left_width; - right_node->rectangle.y = node->rectangle.y; - right_node->rectangle.width = node->rectangle.width - left_width; - right_node->rectangle.height = node->rectangle.height; - right_node->largest_gap = (right_node->rectangle.width * - right_node->rectangle.height); - node->d.branch.right = right_node; - - node->type = COGL_RECTANGLE_MAP_BRANCH; - - return left_node; -} - -static CoglRectangleMapNode * -_cogl_rectangle_map_node_split_vertically (CoglRectangleMapNode *node, - unsigned int top_height) -{ - /* Splits the node vertically (according to emacs' definition, not - vim) by converting it to a branch and adding two new leaf - nodes. The topmost branch will have the height top_height and - will be returned. If the node is already just the right size it - won't do anything */ - - CoglRectangleMapNode *top_node, *bottom_node; - - if (node->rectangle.height == top_height) - return node; - - top_node = _cogl_rectangle_map_node_new (); - top_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - top_node->parent = node; - top_node->rectangle.x = node->rectangle.x; - top_node->rectangle.y = node->rectangle.y; - top_node->rectangle.width = node->rectangle.width; - top_node->rectangle.height = top_height; - top_node->largest_gap = (top_node->rectangle.width * - top_node->rectangle.height); - node->d.branch.left = top_node; - - bottom_node = _cogl_rectangle_map_node_new (); - bottom_node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - bottom_node->parent = node; - bottom_node->rectangle.x = node->rectangle.x; - bottom_node->rectangle.y = node->rectangle.y + top_height; - bottom_node->rectangle.width = node->rectangle.width; - bottom_node->rectangle.height = node->rectangle.height - top_height; - bottom_node->largest_gap = (bottom_node->rectangle.width * - bottom_node->rectangle.height); - node->d.branch.right = bottom_node; - - node->type = COGL_RECTANGLE_MAP_BRANCH; - - return top_node; -} - -#ifdef COGL_ENABLE_DEBUG - -static unsigned int -_cogl_rectangle_map_verify_recursive (CoglRectangleMapNode *node) -{ - /* This is just used for debugging the data structure. It - recursively walks the tree to verify that the largest gap values - all add up */ - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - { - int sum = - _cogl_rectangle_map_verify_recursive (node->d.branch.left) + - _cogl_rectangle_map_verify_recursive (node->d.branch.right); - g_assert (node->largest_gap == - MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap)); - return sum; - } - - case COGL_RECTANGLE_MAP_EMPTY_LEAF: - g_assert (node->largest_gap == - node->rectangle.width * node->rectangle.height); - return 0; - - case COGL_RECTANGLE_MAP_FILLED_LEAF: - g_assert (node->largest_gap == 0); - return 1; - } - - return 0; -} - -static unsigned int -_cogl_rectangle_map_get_space_remaining_recursive (CoglRectangleMapNode *node) -{ - /* This is just used for debugging the data structure. It - recursively walks the tree to verify that the remaining space - value adds up */ - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - { - CoglRectangleMapNode *l = node->d.branch.left; - CoglRectangleMapNode *r = node->d.branch.right; - - return (_cogl_rectangle_map_get_space_remaining_recursive (l) + - _cogl_rectangle_map_get_space_remaining_recursive (r)); - } - - case COGL_RECTANGLE_MAP_EMPTY_LEAF: - return node->rectangle.width * node->rectangle.height; - - case COGL_RECTANGLE_MAP_FILLED_LEAF: - return 0; - } - - return 0; -} - -static void -_cogl_rectangle_map_verify (CoglRectangleMap *map) -{ - unsigned int actual_n_rectangles = - _cogl_rectangle_map_verify_recursive (map->root); - unsigned int actual_space_remaining = - _cogl_rectangle_map_get_space_remaining_recursive (map->root); - - g_assert_cmpuint (actual_n_rectangles, ==, map->n_rectangles); - g_assert_cmpuint (actual_space_remaining, ==, map->space_remaining); -} - -#endif /* COGL_ENABLE_DEBUG */ - -gboolean -_cogl_rectangle_map_add (CoglRectangleMap *map, - unsigned int width, - unsigned int height, - void *data, - CoglRectangleMapEntry *rectangle) -{ - unsigned int rectangle_size = width * height; - /* Stack of nodes to search in */ - GArray *stack = map->stack; - CoglRectangleMapNode *found_node = NULL; - - /* Zero-sized rectangles break the algorithm for removing rectangles - so we'll disallow them */ - g_return_val_if_fail (width > 0 && height > 0, FALSE); - - /* Start with the root node */ - g_array_set_size (stack, 0); - _cogl_rectangle_map_stack_push (stack, map->root, FALSE); - - /* Depth-first search for an empty node that is big enough */ - while (stack->len > 0) - { - CoglRectangleMapStackEntry *stack_top; - CoglRectangleMapNode *node; - int next_index; - - /* Pop an entry off the stack */ - stack_top = _cogl_rectangle_map_stack_get_top (stack); - node = stack_top->node; - next_index = stack_top->next_index; - _cogl_rectangle_map_stack_pop (stack); - - /* Regardless of the type of the node, there's no point - descending any further if the new rectangle won't fit within - it */ - if (node->rectangle.width >= width && - node->rectangle.height >= height && - node->largest_gap >= rectangle_size) - { - if (node->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - /* We've found a node we can use */ - found_node = node; - break; - } - else if (node->type == COGL_RECTANGLE_MAP_BRANCH) - { - if (next_index) - /* Try the right branch */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.right, - 0); - else - { - /* Make sure we remember to try the right branch once - we've finished descending the left branch */ - _cogl_rectangle_map_stack_push (stack, - node, - 1); - /* Try the left branch */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.left, - 0); - } - } - } - } - - if (found_node) - { - CoglRectangleMapNode *node; - - /* Split according to whichever axis will leave us with the - largest space */ - if (found_node->rectangle.width - width > - found_node->rectangle.height - height) - { - found_node = - _cogl_rectangle_map_node_split_horizontally (found_node, width); - found_node = - _cogl_rectangle_map_node_split_vertically (found_node, height); - } - else - { - found_node = - _cogl_rectangle_map_node_split_vertically (found_node, height); - found_node = - _cogl_rectangle_map_node_split_horizontally (found_node, width); - } - - found_node->type = COGL_RECTANGLE_MAP_FILLED_LEAF; - found_node->d.data = data; - found_node->largest_gap = 0; - if (rectangle) - *rectangle = found_node->rectangle; - - /* Walk back up the tree and update the stored largest gap for - the node's sub tree */ - for (node = found_node->parent; node; node = node->parent) - { - /* This node is a parent so it should always be a branch */ - g_assert (node->type == COGL_RECTANGLE_MAP_BRANCH); - - node->largest_gap = MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap); - } - - /* There is now an extra rectangle in the map */ - map->n_rectangles++; - /* and less space */ - map->space_remaining -= rectangle_size; - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DUMP_ATLAS_IMAGE))) - { - _cogl_rectangle_map_dump_image (map); - /* Dumping the rectangle map is really slow so we might as well - verify the space remaining here as it is also quite slow */ - _cogl_rectangle_map_verify (map); - } -#endif - - return TRUE; - } - else - return FALSE; -} - -void -_cogl_rectangle_map_remove (CoglRectangleMap *map, - const CoglRectangleMapEntry *rectangle) -{ - CoglRectangleMapNode *node = map->root; - unsigned int rectangle_size = rectangle->width * rectangle->height; - - /* We can do a binary-chop down the search tree to find the rectangle */ - while (node->type == COGL_RECTANGLE_MAP_BRANCH) - { - CoglRectangleMapNode *left_node = node->d.branch.left; - - /* If and only if the rectangle is in the left node then the x,y - position of the rectangle will be within the node's - rectangle */ - if (rectangle->x < left_node->rectangle.x + left_node->rectangle.width && - rectangle->y < left_node->rectangle.y + left_node->rectangle.height) - /* Go left */ - node = left_node; - else - /* Go right */ - node = node->d.branch.right; - } - - /* Make sure we found the right node */ - if (node->type != COGL_RECTANGLE_MAP_FILLED_LEAF || - node->rectangle.x != rectangle->x || - node->rectangle.y != rectangle->y || - node->rectangle.width != rectangle->width || - node->rectangle.height != rectangle->height) - /* This should only happen if someone tried to remove a rectangle - that was not in the map so something has gone wrong */ - g_return_if_reached (); - else - { - /* Convert the node back to an empty node */ - if (map->value_destroy_func) - map->value_destroy_func (node->d.data); - node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - node->largest_gap = rectangle_size; - - /* Walk back up the tree combining branch nodes that have two - empty leaves back into a single empty leaf */ - for (node = node->parent; node; node = node->parent) - { - /* This node is a parent so it should always be a branch */ - g_assert (node->type == COGL_RECTANGLE_MAP_BRANCH); - - if (node->d.branch.left->type == COGL_RECTANGLE_MAP_EMPTY_LEAF && - node->d.branch.right->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - _cogl_rectangle_map_node_free (node->d.branch.left); - _cogl_rectangle_map_node_free (node->d.branch.right); - node->type = COGL_RECTANGLE_MAP_EMPTY_LEAF; - - node->largest_gap = (node->rectangle.width * - node->rectangle.height); - } - else - break; - } - - /* Reduce the amount of space remaining in all of the parents - further up the chain */ - for (; node; node = node->parent) - node->largest_gap = MAX (node->d.branch.left->largest_gap, - node->d.branch.right->largest_gap); - - /* There is now one less rectangle */ - g_assert (map->n_rectangles > 0); - map->n_rectangles--; - /* and more space */ - map->space_remaining += rectangle_size; - } - -#ifdef COGL_ENABLE_DEBUG - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DUMP_ATLAS_IMAGE))) - { - _cogl_rectangle_map_dump_image (map); - /* Dumping the rectangle map is really slow so we might as well - verify the space remaining here as it is also quite slow */ - _cogl_rectangle_map_verify (map); - } -#endif -} - -unsigned int -_cogl_rectangle_map_get_width (CoglRectangleMap *map) -{ - return map->root->rectangle.width; -} - -unsigned int -_cogl_rectangle_map_get_height (CoglRectangleMap *map) -{ - return map->root->rectangle.height; -} - -unsigned int -_cogl_rectangle_map_get_remaining_space (CoglRectangleMap *map) -{ - return map->space_remaining; -} - -unsigned int -_cogl_rectangle_map_get_n_rectangles (CoglRectangleMap *map) -{ - return map->n_rectangles; -} - -static void -_cogl_rectangle_map_internal_foreach (CoglRectangleMap *map, - CoglRectangleMapInternalForeachCb func, - void *data) -{ - /* Stack of nodes to search in */ - GArray *stack = map->stack; - - /* Start with the root node */ - g_array_set_size (stack, 0); - _cogl_rectangle_map_stack_push (stack, map->root, 0); - - /* Iterate all nodes depth-first */ - while (stack->len > 0) - { - CoglRectangleMapStackEntry *stack_top = - _cogl_rectangle_map_stack_get_top (stack); - CoglRectangleMapNode *node = stack_top->node; - - switch (node->type) - { - case COGL_RECTANGLE_MAP_BRANCH: - if (stack_top->next_index == 0) - { - /* Next time we come back to this node, go to the right */ - stack_top->next_index = 1; - - /* Explore the left branch next */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.left, - 0); - } - else if (stack_top->next_index == 1) - { - /* Next time we come back to this node, stop processing it */ - stack_top->next_index = 2; - - /* Explore the right branch next */ - _cogl_rectangle_map_stack_push (stack, - node->d.branch.right, - 0); - } - else - { - /* We're finished with this node so we can call the callback */ - func (node, data); - _cogl_rectangle_map_stack_pop (stack); - } - break; - - default: - /* Some sort of leaf node, just call the callback */ - func (node, data); - _cogl_rectangle_map_stack_pop (stack); - break; - } - } - - /* The stack should now be empty */ - g_assert (stack->len == 0); -} - -typedef struct _CoglRectangleMapForeachClosure -{ - CoglRectangleMapCallback callback; - void *data; -} CoglRectangleMapForeachClosure; - -static void -_cogl_rectangle_map_foreach_cb (CoglRectangleMapNode *node, void *data) -{ - CoglRectangleMapForeachClosure *closure = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF) - closure->callback (&node->rectangle, node->d.data, closure->data); -} - -void -_cogl_rectangle_map_foreach (CoglRectangleMap *map, - CoglRectangleMapCallback callback, - void *data) -{ - CoglRectangleMapForeachClosure closure; - - closure.callback = callback; - closure.data = data; - - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_foreach_cb, - &closure); -} - -static void -_cogl_rectangle_map_free_cb (CoglRectangleMapNode *node, void *data) -{ - CoglRectangleMap *map = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF && map->value_destroy_func) - map->value_destroy_func (node->d.data); - - _cogl_rectangle_map_node_free (node); -} - -void -_cogl_rectangle_map_free (CoglRectangleMap *map) -{ - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_free_cb, - map); - - g_array_free (map->stack, TRUE); - - g_free (map); -} - -#ifdef COGL_ENABLE_DEBUG - -static void -_cogl_rectangle_map_dump_image_cb (CoglRectangleMapNode *node, void *data) -{ - cairo_t *cr = data; - - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF || - node->type == COGL_RECTANGLE_MAP_EMPTY_LEAF) - { - /* Fill the rectangle using a different colour depending on - whether the rectangle is used */ - if (node->type == COGL_RECTANGLE_MAP_FILLED_LEAF) - cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); - else - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - - cairo_rectangle (cr, - node->rectangle.x, - node->rectangle.y, - node->rectangle.width, - node->rectangle.height); - - cairo_fill_preserve (cr); - - /* Draw a white outline around the rectangle */ - cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); - cairo_stroke (cr); - } -} - -static void -_cogl_rectangle_map_dump_image (CoglRectangleMap *map) -{ - /* This dumps a png to help visualize the map. Each leaf rectangle - is drawn with a white outline. Unused leaves are filled in black - and used leaves are blue */ - - cairo_surface_t *surface = - cairo_image_surface_create (CAIRO_FORMAT_RGB24, - _cogl_rectangle_map_get_width (map), - _cogl_rectangle_map_get_height (map)); - cairo_t *cr = cairo_create (surface); - - _cogl_rectangle_map_internal_foreach (map, - _cogl_rectangle_map_dump_image_cb, - cr); - - cairo_destroy (cr); - - cairo_surface_write_to_png (surface, "cogl-rectangle-map-dump.png"); - - cairo_surface_destroy (surface); -} - -#endif /* COGL_ENABLE_DEBUG */ diff --git a/cogl/cogl/cogl-rectangle-map.h b/cogl/cogl/cogl-rectangle-map.h deleted file mode 100644 index 613965d68..000000000 --- a/cogl/cogl/cogl-rectangle-map.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __COGL_RECTANGLE_MAP_H -#define __COGL_RECTANGLE_MAP_H - -#include <glib.h> -#include "cogl-types.h" - -typedef struct _CoglRectangleMap CoglRectangleMap; -typedef struct _CoglRectangleMapEntry CoglRectangleMapEntry; - -typedef void (* CoglRectangleMapCallback) (const CoglRectangleMapEntry *entry, - void *rectangle_data, - void *user_data); - -struct _CoglRectangleMapEntry -{ - unsigned int x, y; - unsigned int width, height; -}; - -CoglRectangleMap * -_cogl_rectangle_map_new (unsigned int width, - unsigned int height, - GDestroyNotify value_destroy_func); - -gboolean -_cogl_rectangle_map_add (CoglRectangleMap *map, - unsigned int width, - unsigned int height, - void *data, - CoglRectangleMapEntry *rectangle); - -void -_cogl_rectangle_map_remove (CoglRectangleMap *map, - const CoglRectangleMapEntry *rectangle); - -unsigned int -_cogl_rectangle_map_get_width (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_height (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_remaining_space (CoglRectangleMap *map); - -unsigned int -_cogl_rectangle_map_get_n_rectangles (CoglRectangleMap *map); - -void -_cogl_rectangle_map_foreach (CoglRectangleMap *map, - CoglRectangleMapCallback callback, - void *data); - -void -_cogl_rectangle_map_free (CoglRectangleMap *map); - -#endif /* __COGL_RECTANGLE_MAP_H */ diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h deleted file mode 100644 index 66634c075..000000000 --- a/cogl/cogl/cogl-renderer-private.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_RENDERER_PRIVATE_H -#define __COGL_RENDERER_PRIVATE_H - -#include <gmodule.h> - -#include "cogl-object-private.h" -#include "cogl-driver.h" -#include "cogl-texture-driver.h" -#include "cogl-context.h" -#include "cogl-closure-list-private.h" -#include "winsys/cogl-winsys-private.h" - -typedef const CoglWinsysVtable *(*CoglCustomWinsysVtableGetter) (CoglRenderer *renderer); - -struct _CoglRenderer -{ - CoglObject _parent; - gboolean connected; - CoglDriver driver_override; - const CoglDriverVtable *driver_vtable; - const CoglTextureDriver *texture_driver; - const CoglWinsysVtable *winsys_vtable; - void *custom_winsys_user_data; - CoglCustomWinsysVtableGetter custom_winsys_vtable_getter; - CoglWinsysID winsys_id_override; - GList *constraints; - - GArray *poll_fds; - int poll_fds_age; - GList *poll_sources; - - CoglList idle_closures; - - GList *outputs; - -#ifdef COGL_HAS_XLIB_SUPPORT - Display *foreign_xdpy; - gboolean xlib_enable_event_retrieval; - gboolean xlib_want_reset_on_video_memory_purge; -#endif - - CoglDriver driver; - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)]; - GModule *libgl_module; - - /* List of callback functions that will be given every native event */ - GSList *event_filters; - void *winsys; -}; - -typedef CoglFilterReturn (* CoglNativeFilterFunc) (void *native_event, - void *data); - -CoglFilterReturn -_cogl_renderer_handle_native_event (CoglRenderer *renderer, - void *event); - -void -_cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -void -_cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data); - -void * -_cogl_renderer_get_proc_address (CoglRenderer *renderer, - const char *name, - gboolean in_core); - -#endif /* __COGL_RENDERER_PRIVATE_H */ diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c deleted file mode 100644 index d815757a0..000000000 --- a/cogl/cogl/cogl-renderer.c +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <gio/gio.h> -#include <stdlib.h> -#include <string.h> - -#include "cogl-util.h" -#include "cogl-private.h" -#include "cogl-object.h" -#include "cogl-context-private.h" -#include "cogl-mutter.h" - -#include "cogl-renderer.h" -#include "cogl-renderer-private.h" -#include "cogl-display-private.h" -#include "cogl-gtype-private.h" - -#include "winsys/cogl-winsys-private.h" - -#ifdef COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT -#include "winsys/cogl-winsys-egl-x11-private.h" -#endif -#ifdef COGL_HAS_GLX_SUPPORT -#include "winsys/cogl-winsys-glx-private.h" -#endif - -#ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-xlib-renderer.h" -#endif - -#ifdef HAVE_COGL_GL -extern const CoglTextureDriver _cogl_texture_driver_gl; -extern const CoglDriverVtable _cogl_driver_gl; -#endif -#if defined (HAVE_COGL_GLES2) -extern const CoglTextureDriver _cogl_texture_driver_gles; -extern const CoglDriverVtable _cogl_driver_gles; -#endif - -extern const CoglDriverVtable _cogl_driver_nop; - -typedef struct _CoglDriverDescription -{ - CoglDriver id; - const char *name; - /* It would be nice to make this a pointer and then use a compound - * literal from C99 to initialise it but we probably can't get away - * with using C99 here. Instead we'll just use a fixed-size array. - * GCC should complain if someone adds an 8th feature to a - * driver. */ - const CoglPrivateFeature private_features[8]; - const CoglDriverVtable *vtable; - const CoglTextureDriver *texture_driver; - const char *libgl_name; -} CoglDriverDescription; - -static CoglDriverDescription _cogl_drivers[] = -{ -#ifdef HAVE_COGL_GL - { - COGL_DRIVER_GL, - "gl", - { COGL_PRIVATE_FEATURE_ANY_GL, - -1 }, - &_cogl_driver_gl, - &_cogl_texture_driver_gl, - COGL_GL_LIBNAME, - }, - { - COGL_DRIVER_GL3, - "gl3", - { COGL_PRIVATE_FEATURE_ANY_GL, - -1 }, - &_cogl_driver_gl, - &_cogl_texture_driver_gl, - COGL_GL_LIBNAME, - }, -#endif -#ifdef HAVE_COGL_GLES2 - { - COGL_DRIVER_GLES2, - "gles2", - { COGL_PRIVATE_FEATURE_ANY_GL, - -1 }, - &_cogl_driver_gles, - &_cogl_texture_driver_gles, - COGL_GLES2_LIBNAME, - }, -#endif - { - COGL_DRIVER_NOP, - "nop", - { -1 }, - &_cogl_driver_nop, - NULL, /* texture driver */ - NULL /* libgl_name */ - } -}; - -static CoglWinsysVtableGetter _cogl_winsys_vtable_getters[] = -{ -#ifdef COGL_HAS_GLX_SUPPORT - _cogl_winsys_glx_get_vtable, -#endif -#ifdef COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT - _cogl_winsys_egl_xlib_get_vtable, -#endif -}; - -static void _cogl_renderer_free (CoglRenderer *renderer); - -COGL_OBJECT_DEFINE (Renderer, renderer); -COGL_GTYPE_DEFINE_CLASS (Renderer, renderer); - -typedef struct _CoglNativeFilterClosure -{ - CoglNativeFilterFunc func; - void *data; -} CoglNativeFilterClosure; - -uint32_t -cogl_renderer_error_quark (void) -{ - return g_quark_from_static_string ("cogl-renderer-error-quark"); -} - -static const CoglWinsysVtable * -_cogl_renderer_get_winsys (CoglRenderer *renderer) -{ - return renderer->winsys_vtable; -} - -static void -native_filter_closure_free (CoglNativeFilterClosure *closure) -{ - g_free (closure); -} - -static void -_cogl_renderer_free (CoglRenderer *renderer) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - _cogl_closure_list_disconnect_all (&renderer->idle_closures); - - if (winsys) - winsys->renderer_disconnect (renderer); - - if (renderer->libgl_module) - g_module_close (renderer->libgl_module); - - g_slist_free_full (renderer->event_filters, - (GDestroyNotify) native_filter_closure_free); - - g_array_free (renderer->poll_fds, TRUE); - - g_free (renderer); -} - -CoglRenderer * -cogl_renderer_new (void) -{ - CoglRenderer *renderer = g_new0 (CoglRenderer, 1); - - _cogl_init (); - - renderer->connected = FALSE; - renderer->event_filters = NULL; - - renderer->poll_fds = g_array_new (FALSE, TRUE, sizeof (CoglPollFD)); - - _cogl_list_init (&renderer->idle_closures); - -#ifdef COGL_HAS_XLIB_SUPPORT - renderer->xlib_enable_event_retrieval = TRUE; -#endif - - return _cogl_renderer_object_new (renderer); -} - -#ifdef COGL_HAS_XLIB_SUPPORT -void -cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, - Display *xdisplay) -{ - g_return_if_fail (cogl_is_renderer (renderer)); - - /* NB: Renderers are considered immutable once connected */ - g_return_if_fail (!renderer->connected); - - renderer->foreign_xdpy = xdisplay; - - /* If the application is using a foreign display then we can assume - it will also do its own event retrieval */ - renderer->xlib_enable_event_retrieval = FALSE; -} - -Display * -cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer) -{ - g_return_val_if_fail (cogl_is_renderer (renderer), NULL); - - return renderer->foreign_xdpy; -} - -void -cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, - gboolean enable) -{ - g_return_if_fail (cogl_is_renderer (renderer)); - g_return_if_fail (!renderer->connected); - - renderer->xlib_want_reset_on_video_memory_purge = enable; -} -#endif /* COGL_HAS_XLIB_SUPPORT */ - -gboolean -cogl_renderer_check_onscreen_template (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template, - GError **error) -{ - CoglDisplay *display; - - if (!cogl_renderer_connect (renderer, error)) - return FALSE; - - display = cogl_display_new (renderer, onscreen_template); - if (!cogl_display_setup (display, error)) - { - cogl_object_unref (display); - return FALSE; - } - - cogl_object_unref (display); - - return TRUE; -} - -typedef gboolean (*CoglDriverCallback) (CoglDriverDescription *description, - void *user_data); - -static void -foreach_driver_description (CoglDriver driver_override, - CoglDriverCallback callback, - void *user_data) -{ -#ifdef COGL_DEFAULT_DRIVER - const CoglDriverDescription *default_driver = NULL; -#endif - int i; - - if (driver_override != COGL_DRIVER_ANY) - { - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - if (_cogl_drivers[i].id == driver_override) - { - callback (&_cogl_drivers[i], user_data); - return; - } - } - - g_warn_if_reached (); - return; - } - -#ifdef COGL_DEFAULT_DRIVER - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - const CoglDriverDescription *desc = &_cogl_drivers[i]; - if (g_ascii_strcasecmp (desc->name, COGL_DEFAULT_DRIVER) == 0) - { - default_driver = desc; - break; - } - } - - if (default_driver) - { - if (!callback (default_driver, user_data)) - return; - } -#endif - - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { -#ifdef COGL_DEFAULT_DRIVER - if (&_cogl_drivers[i] == default_driver) - continue; -#endif - - if (!callback (&_cogl_drivers[i], user_data)) - return; - } -} - -static CoglDriver -driver_name_to_id (const char *name) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - if (g_ascii_strcasecmp (_cogl_drivers[i].name, name) == 0) - return _cogl_drivers[i].id; - } - - return COGL_DRIVER_ANY; -} - -static const char * -driver_id_to_name (CoglDriver id) -{ - switch (id) - { - case COGL_DRIVER_GL: - return "gl"; - case COGL_DRIVER_GL3: - return "gl3"; - case COGL_DRIVER_GLES2: - return "gles2"; - case COGL_DRIVER_NOP: - return "nop"; - case COGL_DRIVER_ANY: - g_warn_if_reached (); - return "any"; - } - - g_warn_if_reached (); - return "unknown"; -} - -typedef struct _SatisfyConstraintsState -{ - const CoglDriverDescription *driver_description; -} SatisfyConstraintsState; - -/* XXX this is still uglier than it needs to be */ -static gboolean -satisfy_constraints (CoglDriverDescription *description, - void *user_data) -{ - SatisfyConstraintsState *state = user_data; - - state->driver_description = description; - - return FALSE; -} - -static gboolean -_cogl_renderer_choose_driver (CoglRenderer *renderer, - GError **error) -{ - const char *driver_name = g_getenv ("COGL_DRIVER"); - CoglDriver driver_override = COGL_DRIVER_ANY; - const char *invalid_override = NULL; - const char *libgl_name; - SatisfyConstraintsState state; - const CoglDriverDescription *desc; - int i; - - if (driver_name) - { - driver_override = driver_name_to_id (driver_name); - if (driver_override == COGL_DRIVER_ANY) - invalid_override = driver_name; - } - - if (renderer->driver_override != COGL_DRIVER_ANY) - { - if (driver_override != COGL_DRIVER_ANY && - renderer->driver_override != driver_override) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Application driver selection conflicts with driver " - "specified in configuration"); - return FALSE; - } - - driver_override = renderer->driver_override; - } - - if (driver_override != COGL_DRIVER_ANY) - { - gboolean found = FALSE; - int i; - - for (i = 0; i < G_N_ELEMENTS (_cogl_drivers); i++) - { - if (_cogl_drivers[i].id == driver_override) - { - found = TRUE; - break; - } - } - if (!found) - invalid_override = driver_id_to_name (driver_override); - } - - if (invalid_override) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Driver \"%s\" is not available", - invalid_override); - return FALSE; - } - - state.driver_description = NULL; - - foreach_driver_description (driver_override, - satisfy_constraints, - &state); - - if (!state.driver_description) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "No suitable driver found"); - return FALSE; - } - - desc = state.driver_description; - renderer->driver = desc->id; - renderer->driver_vtable = desc->vtable; - renderer->texture_driver = desc->texture_driver; - libgl_name = desc->libgl_name; - - memset(renderer->private_features, 0, sizeof (renderer->private_features)); - for (i = 0; desc->private_features[i] != -1; i++) - COGL_FLAGS_SET (renderer->private_features, - desc->private_features[i], TRUE); - - if (COGL_FLAGS_GET (renderer->private_features, - COGL_PRIVATE_FEATURE_ANY_GL)) - { - renderer->libgl_module = g_module_open (libgl_name, - G_MODULE_BIND_LAZY); - - if (renderer->libgl_module == NULL) - { - g_set_error (error, COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_FAILED_TO_LOAD_LIBRARY, - "Failed to dynamically open the GL library \"%s\"", - libgl_name); - return FALSE; - } - } - - return TRUE; -} - -/* Final connection API */ - -void -cogl_renderer_set_custom_winsys (CoglRenderer *renderer, - CoglCustomWinsysVtableGetter winsys_vtable_getter, - void *user_data) -{ - renderer->custom_winsys_user_data = user_data; - renderer->custom_winsys_vtable_getter = winsys_vtable_getter; -} - -static gboolean -connect_custom_winsys (CoglRenderer *renderer, - GError **error) -{ - const CoglWinsysVtable *winsys; - GError *tmp_error = NULL; - GString *error_message; - - winsys = renderer->custom_winsys_vtable_getter (renderer); - renderer->winsys_vtable = winsys; - - error_message = g_string_new (""); - if (!winsys->renderer_connect (renderer, &tmp_error)) - { - g_string_append_c (error_message, '\n'); - g_string_append (error_message, tmp_error->message); - g_error_free (tmp_error); - } - else - { - renderer->connected = TRUE; - g_string_free (error_message, TRUE); - return TRUE; - } - - renderer->winsys_vtable = NULL; - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", error_message->str); - g_string_free (error_message, TRUE); - return FALSE; -} - -gboolean -cogl_renderer_connect (CoglRenderer *renderer, GError **error) -{ - int i; - GString *error_message; - gboolean constraints_failed = FALSE; - - if (renderer->connected) - return TRUE; - - /* The driver needs to be chosen before connecting the renderer - because eglInitialize requires the library containing the GL API - to be loaded before its called */ - if (!_cogl_renderer_choose_driver (renderer, error)) - return FALSE; - - if (renderer->custom_winsys_vtable_getter) - return connect_custom_winsys (renderer, error); - - error_message = g_string_new (""); - for (i = 0; i < G_N_ELEMENTS (_cogl_winsys_vtable_getters); i++) - { - const CoglWinsysVtable *winsys = _cogl_winsys_vtable_getters[i](); - GError *tmp_error = NULL; - GList *l; - gboolean skip_due_to_constraints = FALSE; - - if (renderer->winsys_id_override != COGL_WINSYS_ID_ANY) - { - if (renderer->winsys_id_override != winsys->id) - continue; - } - else - { - char *user_choice = getenv ("COGL_RENDERER"); - if (user_choice && - g_ascii_strcasecmp (winsys->name, user_choice) != 0) - continue; - } - - for (l = renderer->constraints; l; l = l->next) - { - CoglRendererConstraint constraint = GPOINTER_TO_UINT (l->data); - if (!(winsys->constraints & constraint)) - { - skip_due_to_constraints = TRUE; - break; - } - } - if (skip_due_to_constraints) - { - constraints_failed |= TRUE; - continue; - } - - /* At least temporarily we will associate this winsys with - * the renderer in-case ->renderer_connect calls API that - * wants to query the current winsys... */ - renderer->winsys_vtable = winsys; - - if (!winsys->renderer_connect (renderer, &tmp_error)) - { - g_string_append_c (error_message, '\n'); - g_string_append (error_message, tmp_error->message); - g_error_free (tmp_error); - } - else - { - renderer->connected = TRUE; - g_string_free (error_message, TRUE); - return TRUE; - } - } - - if (!renderer->connected) - { - if (constraints_failed) - { - g_set_error (error, COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_BAD_CONSTRAINT, - "Failed to connected to any renderer due to constraints"); - return FALSE; - } - - renderer->winsys_vtable = NULL; - g_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, - "Failed to connected to any renderer: %s", - error_message->str); - g_string_free (error_message, TRUE); - return FALSE; - } - - return TRUE; -} - -CoglFilterReturn -_cogl_renderer_handle_native_event (CoglRenderer *renderer, - void *event) -{ - GSList *l, *next; - - /* Pass the event on to all of the registered filters in turn */ - for (l = renderer->event_filters; l; l = next) - { - CoglNativeFilterClosure *closure = l->data; - - /* The next pointer is taken now so that we can handle the - closure being removed during emission */ - next = l->next; - - if (closure->func (event, closure->data) == COGL_FILTER_REMOVE) - return COGL_FILTER_REMOVE; - } - - /* If the backend for the renderer also wants to see the events, it - should just register its own filter */ - - return COGL_FILTER_CONTINUE; -} - -void -_cogl_renderer_add_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - CoglNativeFilterClosure *closure; - - closure = g_new0 (CoglNativeFilterClosure, 1); - closure->func = func; - closure->data = data; - - renderer->event_filters = g_slist_prepend (renderer->event_filters, closure); -} - -void -_cogl_renderer_remove_native_filter (CoglRenderer *renderer, - CoglNativeFilterFunc func, - void *data) -{ - GSList *l, *prev = NULL; - - for (l = renderer->event_filters; l; prev = l, l = l->next) - { - CoglNativeFilterClosure *closure = l->data; - - if (closure->func == func && closure->data == data) - { - native_filter_closure_free (closure); - if (prev) - prev->next = g_slist_delete_link (prev->next, l); - else - renderer->event_filters = - g_slist_delete_link (renderer->event_filters, l); - break; - } - } -} - -void -cogl_renderer_set_winsys_id (CoglRenderer *renderer, - CoglWinsysID winsys_id) -{ - g_return_if_fail (!renderer->connected); - - renderer->winsys_id_override = winsys_id; -} - -CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer) -{ - g_return_val_if_fail (renderer->connected, 0); - - return renderer->winsys_vtable->id; -} - -void * -_cogl_renderer_get_proc_address (CoglRenderer *renderer, - const char *name, - gboolean in_core) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - return winsys->renderer_get_proc_address (renderer, name, in_core); -} - -void -cogl_renderer_add_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint) -{ - g_return_if_fail (!renderer->connected); - renderer->constraints = g_list_prepend (renderer->constraints, - GUINT_TO_POINTER (constraint)); -} - -void -cogl_renderer_remove_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint) -{ - g_return_if_fail (!renderer->connected); - renderer->constraints = g_list_remove (renderer->constraints, - GUINT_TO_POINTER (constraint)); -} - -void -cogl_renderer_set_driver (CoglRenderer *renderer, - CoglDriver driver) -{ - g_return_if_fail (!renderer->connected); - renderer->driver_override = driver; -} - -CoglDriver -cogl_renderer_get_driver (CoglRenderer *renderer) -{ - g_return_val_if_fail (renderer->connected, 0); - - return renderer->driver; -} - -void -cogl_renderer_foreach_output (CoglRenderer *renderer, - CoglOutputCallback callback, - void *user_data) -{ - GList *l; - - g_return_if_fail (renderer->connected); - g_return_if_fail (callback != NULL); - - for (l = renderer->outputs; l; l = l->next) - callback (l->data, user_data); -} - -CoglDmaBufHandle * -cogl_renderer_create_dma_buf (CoglRenderer *renderer, - int width, - int height, - GError **error) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - if (winsys->renderer_create_dma_buf) - return winsys->renderer_create_dma_buf (renderer, width, height, error); - - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "CoglRenderer doesn't support creating DMA buffers"); - - return NULL; -} - -void -cogl_renderer_bind_api (CoglRenderer *renderer) -{ - const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); - - winsys->renderer_bind_api (renderer); -} diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h deleted file mode 100644 index 70910c07b..000000000 --- a/cogl/cogl/cogl-renderer.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_RENDERER_H__ -#define __COGL_RENDERER_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-onscreen-template.h> -#include <cogl/cogl-output.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-renderer - * @short_description: Choosing a means to render - * - * A #CoglRenderer represents a means to render. It encapsulates the - * selection of an underlying driver, such as OpenGL or OpenGL-ES and - * a selection of a window system binding API such as GLX or EGL. - * - * A #CoglRenderer has two states, "unconnected" and "connected". When - * a renderer is first instantiated using cogl_renderer_new() it is - * unconnected so that it can be configured and constraints can be - * specified for how the backend driver and window system should be - * chosen. - * - * After configuration a #CoglRenderer can (optionally) be explicitly - * connected using cogl_renderer_connect() which allows for the - * handling of connection errors so that fallback configurations can - * be tried if necessary. Applications that don't support any - * fallbacks though can skip using cogl_renderer_connect() and leave - * Cogl to automatically connect the renderer. - * - * Once you have a configured #CoglRenderer it can be used to create a - * #CoglDisplay object using cogl_display_new(). - * - * <note>Many applications don't need to explicitly use - * cogl_renderer_new() or cogl_display_new() and can just jump - * straight to cogl_context_new() and pass a %NULL display argument so - * Cogl will automatically connect and setup a renderer and - * display.</note> - */ - - -/** - * COGL_RENDERER_ERROR: - * - * An error domain for exceptions reported by Cogl - */ -#define COGL_RENDERER_ERROR cogl_renderer_error_quark () - -COGL_EXPORT uint32_t -cogl_renderer_error_quark (void); - -typedef struct _CoglRenderer CoglRenderer; - -/** - * cogl_renderer_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_renderer_get_gtype (void); - -/** - * cogl_is_renderer: - * @object: A #CoglObject pointer - * - * Determines if the given @object is a #CoglRenderer - * - * Return value: %TRUE if @object is a #CoglRenderer, else %FALSE. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_renderer (void *object); - -/** - * cogl_renderer_new: - * - * Instantiates a new (unconnected) #CoglRenderer object. A - * #CoglRenderer represents a means to render. It encapsulates the - * selection of an underlying driver, such as OpenGL or OpenGL-ES and - * a selection of a window system binding API such as GLX or EGL. - * - * While the renderer is unconnected it can be configured so that - * applications may specify backend constraints, such as "must use - * x11" for example via cogl_renderer_add_constraint(). - * - * There are also some platform specific configuration apis such - * as cogl_xlib_renderer_set_foreign_display() that may also be - * used while the renderer is unconnected. - * - * Once the renderer has been configured, then it may (optionally) be - * explicitly connected using cogl_renderer_connect() which allows - * errors to be handled gracefully and potentially fallback - * configurations can be tried out if there are initial failures. - * - * If a renderer is not explicitly connected then cogl_display_new() - * will automatically connect the renderer for you. If you don't - * have any code to deal with error/fallback situations then its fine - * to just let Cogl do the connection for you. - * - * Once you have setup your renderer then the next step is to create a - * #CoglDisplay using cogl_display_new(). - * - * <note>Many applications don't need to explicitly use - * cogl_renderer_new() or cogl_display_new() and can just jump - * straight to cogl_context_new() and pass a %NULL display argument - * so Cogl will automatically connect and setup a renderer and - * display.</note> - * - * Return value: (transfer full): A newly created #CoglRenderer. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglRenderer * -cogl_renderer_new (void); - -/* optional configuration APIs */ - -/** - * CoglWinsysID: - * @COGL_WINSYS_ID_ANY: Implies no preference for which backend is used - * @COGL_WINSYS_ID_STUB: Use the no-op stub backend - * @COGL_WINSYS_ID_GLX: Use the GLX window system binding API - * @COGL_WINSYS_ID_EGL_XLIB: Use EGL with the X window system via XLib - * - * Identifies specific window system backends that Cogl supports. - * - * These can be used to query what backend Cogl is using or to try and - * explicitly select a backend to use. - */ -typedef enum -{ - COGL_WINSYS_ID_ANY, - COGL_WINSYS_ID_STUB, - COGL_WINSYS_ID_GLX, - COGL_WINSYS_ID_EGL_XLIB, - COGL_WINSYS_ID_CUSTOM, -} CoglWinsysID; - -/** - * cogl_renderer_set_winsys_id: - * @renderer: A #CoglRenderer - * @winsys_id: An ID of the winsys you explicitly want to use. - * - * This allows you to explicitly select a winsys backend to use instead - * of letting Cogl automatically select a backend. - * - * if you select an unsupported backend then cogl_renderer_connect() - * will fail and report an error. - * - * This may only be called on an un-connected #CoglRenderer. - */ -COGL_EXPORT void -cogl_renderer_set_winsys_id (CoglRenderer *renderer, - CoglWinsysID winsys_id); - -/** - * cogl_renderer_get_winsys_id: - * @renderer: A #CoglRenderer - * - * Queries which window system backend Cogl has chosen to use. - * - * This may only be called on a connected #CoglRenderer. - * - * Returns: The #CoglWinsysID corresponding to the chosen window - * system backend. - */ -COGL_EXPORT CoglWinsysID -cogl_renderer_get_winsys_id (CoglRenderer *renderer); - -/** - * cogl_renderer_check_onscreen_template: (skip) - * @renderer: A #CoglRenderer - * @onscreen_template: A #CoglOnscreenTemplate - * @error: A pointer to a #GError for reporting exceptions - * - * Tests if a given @onscreen_template can be supported with the given - * @renderer. - * - * Return value: %TRUE if the @onscreen_template can be supported, - * else %FALSE. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_renderer_check_onscreen_template (CoglRenderer *renderer, - CoglOnscreenTemplate *onscreen_template, - GError **error); - -/* Final connection API */ - -/** - * cogl_renderer_connect: - * @renderer: An unconnected #CoglRenderer - * @error: a pointer to a #GError for reporting exceptions - * - * Connects the configured @renderer. Renderer connection isn't a - * very active process, it basically just means validating that - * any given constraint criteria can be satisfied and that a - * usable driver and window system backend can be found. - * - * Return value: %TRUE if there was no error while connecting the - * given @renderer. %FALSE if there was an error. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_renderer_connect (CoglRenderer *renderer, GError **error); - -/** - * CoglRendererConstraint: - * @COGL_RENDERER_CONSTRAINT_USES_X11: Require the renderer to be X11 based - * @COGL_RENDERER_CONSTRAINT_USES_XLIB: Require the renderer to be X11 - * based and use Xlib - * @COGL_RENDERER_CONSTRAINT_USES_EGL: Require the renderer to be EGL based - * - * These constraint flags are hard-coded features of the different renderer - * backends. Sometimes a platform may support multiple rendering options which - * Cogl will usually choose from automatically. Some of these features are - * important to higher level applications and frameworks though, such as - * whether a renderer is X11 based because an application might only support - * X11 based input handling. An application might also need to ensure EGL is - * used internally too if they depend on access to an EGLDisplay for some - * purpose. - * - * Applications should ideally minimize how many of these constraints - * they depend on to ensure maximum portability. - * - * Since: 1.10 - * Stability: unstable - */ -typedef enum -{ - COGL_RENDERER_CONSTRAINT_USES_X11 = (1 << 0), - COGL_RENDERER_CONSTRAINT_USES_XLIB = (1 << 1), - COGL_RENDERER_CONSTRAINT_USES_EGL = (1 << 2), -} CoglRendererConstraint; - - -/** - * cogl_renderer_add_constraint: - * @renderer: An unconnected #CoglRenderer - * @constraint: A #CoglRendererConstraint to add - * - * This adds a renderer selection @constraint. - * - * Applications should ideally minimize how many of these constraints they - * depend on to ensure maximum portability. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_renderer_add_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint); - -/** - * cogl_renderer_remove_constraint: - * @renderer: An unconnected #CoglRenderer - * @constraint: A #CoglRendererConstraint to remove - * - * This removes a renderer selection @constraint. - * - * Applications should ideally minimize how many of these constraints they - * depend on to ensure maximum portability. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_renderer_remove_constraint (CoglRenderer *renderer, - CoglRendererConstraint constraint); - -/** - * CoglDriver: - * @COGL_DRIVER_ANY: Implies no preference for which driver is used - * @COGL_DRIVER_NOP: A No-Op driver. - * @COGL_DRIVER_GL: An OpenGL driver. - * @COGL_DRIVER_GL3: An OpenGL driver using the core GL 3.1 profile - * @COGL_DRIVER_GLES2: An OpenGL ES 2.0 driver. - * - * Identifiers for underlying hardware drivers that may be used by - * Cogl for rendering. - * - * Since: 1.10 - * Stability: unstable - */ -typedef enum -{ - COGL_DRIVER_ANY, - COGL_DRIVER_NOP, - COGL_DRIVER_GL, - COGL_DRIVER_GL3, - COGL_DRIVER_GLES2, -} CoglDriver; - -/** - * cogl_renderer_set_driver: - * @renderer: An unconnected #CoglRenderer - * - * Requests that Cogl should try to use a specific underlying driver - * for rendering. - * - * If you select an unsupported driver then cogl_renderer_connect() - * will fail and report an error. Most applications should not - * explicitly select a driver and should rely on Cogl automatically - * choosing the driver. - * - * This may only be called on an un-connected #CoglRenderer. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_renderer_set_driver (CoglRenderer *renderer, - CoglDriver driver); - -/** - * cogl_renderer_get_driver: - * @renderer: A connected #CoglRenderer - * - * Queries what underlying driver is being used by Cogl. - * - * This may only be called on a connected #CoglRenderer. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglDriver -cogl_renderer_get_driver (CoglRenderer *renderer); - -/** - * CoglOutputCallback: - * @output: The current display output being iterated - * @user_data: The user pointer passed to - * cogl_renderer_foreach_output() - * - * A callback type that can be passed to - * cogl_renderer_foreach_output() for iterating display outputs for a - * given renderer. - * - * Since: 1.14 - * Stability: Unstable - */ -typedef void (*CoglOutputCallback) (CoglOutput *output, void *user_data); - -/** - * cogl_renderer_foreach_output: - * @renderer: A connected #CoglRenderer - * @callback: (scope call): A #CoglOutputCallback to be called for - * each display output - * @user_data: A user pointer to be passed to @callback - * - * Iterates all known display outputs for the given @renderer and - * passes a corresponding #CoglOutput pointer to the given @callback - * for each one, along with the given @user_data. - * - * Since: 1.14 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_renderer_foreach_output (CoglRenderer *renderer, - CoglOutputCallback callback, - void *user_data); - -/** - * cogl_renderer_create_dma_buf: (skip) - * @renderer: A #CoglRenderer - * @width: width of the new - * @height: height of the new - * @error: (nullable): return location for a #GError - * - * Creates a new #CoglFramebuffer with @width x @height, and format - * hardcoded to XRGB, and exports the new framebuffer's DMA buffer - * handle. - * - * Returns: (nullable)(transfer full): a #CoglDmaBufHandle. The - * return result must be released with cogl_dma_buf_handle_free() - * after use. - */ -COGL_EXPORT CoglDmaBufHandle * -cogl_renderer_create_dma_buf (CoglRenderer *renderer, - int width, - int height, - GError **error); - -/** - * cogl_renderer_bind_api: (skip) - */ -COGL_EXPORT void -cogl_renderer_bind_api (CoglRenderer *renderer); - -G_END_DECLS - -#endif /* __COGL_RENDERER_H__ */ - diff --git a/cogl/cogl/cogl-sampler-cache-private.h b/cogl/cogl/cogl-sampler-cache-private.h deleted file mode 100644 index bfddc12a3..000000000 --- a/cogl/cogl/cogl-sampler-cache-private.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_SAMPLER_CACHE_PRIVATE_H -#define __COGL_SAMPLER_CACHE_PRIVATE_H - -#include "cogl-context.h" -#include "cogl-gl-header.h" - -/* These aren't defined in the GLES headers */ -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812d -#endif -#ifndef GL_MIRRORED_REPEAT -#define GL_MIRRORED_REPEAT 0x8370 -#endif - -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes. - * - * XXX: keep the values in sync with the CoglPipelineWrapMode enum - * so no conversion is actually needed. - */ -typedef enum _CoglSamplerCacheWrapMode -{ - COGL_SAMPLER_CACHE_WRAP_MODE_REPEAT = GL_REPEAT, - COGL_SAMPLER_CACHE_WRAP_MODE_MIRRORED_REPEAT = GL_MIRRORED_REPEAT, - COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, - COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER, - COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC = GL_ALWAYS -} CoglSamplerCacheWrapMode; - -typedef struct _CoglSamplerCache CoglSamplerCache; - -typedef struct _CoglSamplerCacheEntry -{ - GLuint sampler_object; - - GLenum min_filter; - GLenum mag_filter; - - CoglSamplerCacheWrapMode wrap_mode_s; - CoglSamplerCacheWrapMode wrap_mode_t; -} CoglSamplerCacheEntry; - -CoglSamplerCache * -_cogl_sampler_cache_new (CoglContext *context); - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_get_default_entry (CoglSamplerCache *cache); - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_wrap_modes (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - CoglSamplerCacheWrapMode wrap_mode_s, - CoglSamplerCacheWrapMode wrap_mode_t); - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_filters (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - GLenum min_filter, - GLenum mag_filter); - -void -_cogl_sampler_cache_free (CoglSamplerCache *cache); - -#endif /* __COGL_SAMPLER_CACHE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-sampler-cache.c b/cogl/cogl/cogl-sampler-cache.c deleted file mode 100644 index 9ec3160b6..000000000 --- a/cogl/cogl/cogl-sampler-cache.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-sampler-cache-private.h" -#include "cogl-context-private.h" - -struct _CoglSamplerCache -{ - CoglContext *context; - - /* The samplers are hashed in two tables. One is using the enum - values that Cogl exposes (so it can include the 'automatic' wrap - mode) and the other is using the converted values that will be - given to GL. The first is used to get a unique pointer for the - sampler state so that pipelines only need to store a single - pointer instead of the whole state and the second is used so that - only a single GL sampler object will be created for each unique - GL state. */ - GHashTable *hash_table_cogl; - GHashTable *hash_table_gl; -}; - -static CoglSamplerCacheWrapMode -get_real_wrap_mode (CoglSamplerCacheWrapMode wrap_mode) -{ - if (wrap_mode == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - return COGL_SAMPLER_CACHE_WRAP_MODE_CLAMP_TO_EDGE; - - return wrap_mode; -} - -static void -canonicalize_key (CoglSamplerCacheEntry *key) -{ - /* This converts the wrap modes to the enums that will actually be - given to GL so that it can be used as a key to get a unique GL - sampler object for the state */ - key->wrap_mode_s = get_real_wrap_mode (key->wrap_mode_s); - key->wrap_mode_t = get_real_wrap_mode (key->wrap_mode_t); -} - -static gboolean -wrap_mode_equal_gl (CoglSamplerCacheWrapMode wrap_mode0, - CoglSamplerCacheWrapMode wrap_mode1) -{ - /* We want to compare the actual GLenum that will be used so that if - two different wrap_modes actually use the same GL state we'll - still use the same sampler object */ - return get_real_wrap_mode (wrap_mode0) == get_real_wrap_mode (wrap_mode1); -} - -static gboolean -sampler_state_equal_gl (const void *value0, - const void *value1) -{ - const CoglSamplerCacheEntry *state0 = value0; - const CoglSamplerCacheEntry *state1 = value1; - - return (state0->mag_filter == state1->mag_filter && - state0->min_filter == state1->min_filter && - wrap_mode_equal_gl (state0->wrap_mode_s, state1->wrap_mode_s) && - wrap_mode_equal_gl (state0->wrap_mode_t, state1->wrap_mode_t)); -} - -static unsigned int -hash_wrap_mode_gl (unsigned int hash, - CoglSamplerCacheWrapMode wrap_mode) -{ - /* We want to hash the actual GLenum that will be used so that if - two different wrap_modes actually use the same GL state we'll - still use the same sampler object */ - GLenum real_wrap_mode = get_real_wrap_mode (wrap_mode); - - return _cogl_util_one_at_a_time_hash (hash, - &real_wrap_mode, - sizeof (real_wrap_mode)); -} - -static unsigned int -hash_sampler_state_gl (const void *key) -{ - const CoglSamplerCacheEntry *entry = key; - unsigned int hash = 0; - - hash = _cogl_util_one_at_a_time_hash (hash, &entry->mag_filter, - sizeof (entry->mag_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->min_filter, - sizeof (entry->min_filter)); - hash = hash_wrap_mode_gl (hash, entry->wrap_mode_s); - hash = hash_wrap_mode_gl (hash, entry->wrap_mode_t); - - return _cogl_util_one_at_a_time_mix (hash); -} - -static gboolean -sampler_state_equal_cogl (const void *value0, - const void *value1) -{ - const CoglSamplerCacheEntry *state0 = value0; - const CoglSamplerCacheEntry *state1 = value1; - - return (state0->mag_filter == state1->mag_filter && - state0->min_filter == state1->min_filter && - state0->wrap_mode_s == state1->wrap_mode_s && - state0->wrap_mode_t == state1->wrap_mode_t); -} - -static unsigned int -hash_sampler_state_cogl (const void *key) -{ - const CoglSamplerCacheEntry *entry = key; - unsigned int hash = 0; - - hash = _cogl_util_one_at_a_time_hash (hash, &entry->mag_filter, - sizeof (entry->mag_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->min_filter, - sizeof (entry->min_filter)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->wrap_mode_s, - sizeof (entry->wrap_mode_s)); - hash = _cogl_util_one_at_a_time_hash (hash, &entry->wrap_mode_t, - sizeof (entry->wrap_mode_t)); - - return _cogl_util_one_at_a_time_mix (hash); -} - -CoglSamplerCache * -_cogl_sampler_cache_new (CoglContext *context) -{ - CoglSamplerCache *cache = g_new (CoglSamplerCache, 1); - - /* No reference is taken on the context because it would create a - circular reference */ - cache->context = context; - - cache->hash_table_gl = g_hash_table_new (hash_sampler_state_gl, - sampler_state_equal_gl); - cache->hash_table_cogl = g_hash_table_new (hash_sampler_state_cogl, - sampler_state_equal_cogl); - - return cache; -} - -static CoglSamplerCacheEntry * -_cogl_sampler_cache_get_entry_gl (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *key) -{ - CoglSamplerCacheEntry *entry; - - entry = g_hash_table_lookup (cache->hash_table_gl, key); - - if (entry == NULL) - { - entry = g_memdup2 (key, sizeof (CoglSamplerCacheEntry)); - - cache->context->driver_vtable->sampler_init (cache->context, entry); - - g_hash_table_insert (cache->hash_table_gl, entry, entry); - } - - return entry; -} - -static CoglSamplerCacheEntry * -_cogl_sampler_cache_get_entry_cogl (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *key) -{ - CoglSamplerCacheEntry *entry; - - entry = g_hash_table_lookup (cache->hash_table_cogl, key); - - if (entry == NULL) - { - CoglSamplerCacheEntry canonical_key; - CoglSamplerCacheEntry *gl_entry; - - entry = g_memdup2 (key, sizeof (CoglSamplerCacheEntry)); - - /* Get the sampler object number from the canonical GL version - of the sampler state cache */ - canonical_key = *key; - canonicalize_key (&canonical_key); - gl_entry = _cogl_sampler_cache_get_entry_gl (cache, &canonical_key); - entry->sampler_object = gl_entry->sampler_object; - - g_hash_table_insert (cache->hash_table_cogl, entry, entry); - } - - return entry; -} - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_get_default_entry (CoglSamplerCache *cache) -{ - CoglSamplerCacheEntry key; - - key.wrap_mode_s = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; - key.wrap_mode_t = COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC; - - key.min_filter = GL_LINEAR; - key.mag_filter = GL_LINEAR; - - return _cogl_sampler_cache_get_entry_cogl (cache, &key); -} - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_wrap_modes (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - CoglSamplerCacheWrapMode wrap_mode_s, - CoglSamplerCacheWrapMode wrap_mode_t) -{ - CoglSamplerCacheEntry key = *old_entry; - - key.wrap_mode_s = wrap_mode_s; - key.wrap_mode_t = wrap_mode_t; - - return _cogl_sampler_cache_get_entry_cogl (cache, &key); -} - -const CoglSamplerCacheEntry * -_cogl_sampler_cache_update_filters (CoglSamplerCache *cache, - const CoglSamplerCacheEntry *old_entry, - GLenum min_filter, - GLenum mag_filter) -{ - CoglSamplerCacheEntry key = *old_entry; - - key.min_filter = min_filter; - key.mag_filter = mag_filter; - - return _cogl_sampler_cache_get_entry_cogl (cache, &key); -} - -static void -hash_table_free_gl_cb (void *key, - void *value, - void *user_data) -{ - CoglContext *context = user_data; - CoglSamplerCacheEntry *entry = value; - - context->driver_vtable->sampler_free (context, entry); - - g_free (entry); -} - -static void -hash_table_free_cogl_cb (void *key, - void *value, - void *user_data) -{ - CoglSamplerCacheEntry *entry = value; - - g_free (entry); -} - -void -_cogl_sampler_cache_free (CoglSamplerCache *cache) -{ - g_hash_table_foreach (cache->hash_table_gl, - hash_table_free_gl_cb, - cache->context); - - g_hash_table_destroy (cache->hash_table_gl); - - g_hash_table_foreach (cache->hash_table_cogl, - hash_table_free_cogl_cb, - cache->context); - - g_hash_table_destroy (cache->hash_table_cogl); - - g_free (cache); -} diff --git a/cogl/cogl/cogl-scanout.c b/cogl/cogl/cogl-scanout.c deleted file mode 100644 index cfd4bfd7e..000000000 --- a/cogl/cogl/cogl-scanout.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2019 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#include "cogl-config.h" - -#include "cogl-scanout.h" - -G_DEFINE_INTERFACE (CoglScanout, cogl_scanout, G_TYPE_OBJECT) - -static void -cogl_scanout_default_init (CoglScanoutInterface *iface) -{ -} - -gboolean -cogl_scanout_blit_to_framebuffer (CoglScanout *scanout, - CoglFramebuffer *framebuffer, - int x, - int y, - GError **error) -{ - CoglScanoutInterface *iface; - - g_return_val_if_fail (COGL_IS_SCANOUT (scanout), FALSE); - - iface = COGL_SCANOUT_GET_IFACE (scanout); - - if (iface->blit_to_framebuffer) - return iface->blit_to_framebuffer (scanout, framebuffer, x, y, error); - else - return FALSE; -} diff --git a/cogl/cogl/cogl-scanout.h b/cogl/cogl/cogl-scanout.h deleted file mode 100644 index d458a84fe..000000000 --- a/cogl/cogl/cogl-scanout.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2019 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#ifndef COGL_SCANOUT_H -#define COGL_SCANOUT_H - -#include "cogl/cogl-types.h" -#include "cogl/cogl-framebuffer.h" - -#include <glib-object.h> - -#define COGL_TYPE_SCANOUT (cogl_scanout_get_type ()) -COGL_EXPORT -G_DECLARE_INTERFACE (CoglScanout, cogl_scanout, - COGL, SCANOUT, GObject) - -struct _CoglScanoutInterface -{ - GTypeInterface parent_iface; - - gboolean (*blit_to_framebuffer) (CoglScanout *scanout, - CoglFramebuffer *framebuffer, - int x, - int y, - GError **error); -}; - -COGL_EXPORT -gboolean cogl_scanout_blit_to_framebuffer (CoglScanout *scanout, - CoglFramebuffer *framebuffer, - int x, - int y, - GError **error); - -#endif /* COGL_SCANOUT_H */ diff --git a/cogl/cogl/cogl-snippet-private.h b/cogl/cogl/cogl-snippet-private.h deleted file mode 100644 index 323117b77..000000000 --- a/cogl/cogl/cogl-snippet-private.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#ifndef __COGL_SNIPPET_PRIVATE_H -#define __COGL_SNIPPET_PRIVATE_H - -#include <glib.h> - -#include "cogl-snippet.h" -#include "cogl-object-private.h" - -/* These values are also used in the enum for CoglSnippetHook. They - are copied here because we don't really want these names to be part - of the public API */ -#define COGL_SNIPPET_HOOK_BAND_SIZE 2048 -#define COGL_SNIPPET_FIRST_PIPELINE_HOOK 0 -#define COGL_SNIPPET_FIRST_PIPELINE_VERTEX_HOOK \ - COGL_SNIPPET_FIRST_PIPELINE_HOOK -#define COGL_SNIPPET_FIRST_PIPELINE_FRAGMENT_HOOK \ - (COGL_SNIPPET_FIRST_PIPELINE_VERTEX_HOOK + COGL_SNIPPET_HOOK_BAND_SIZE) -#define COGL_SNIPPET_FIRST_LAYER_HOOK (COGL_SNIPPET_HOOK_BAND_SIZE * 2) -#define COGL_SNIPPET_FIRST_LAYER_VERTEX_HOOK COGL_SNIPPET_FIRST_LAYER_HOOK -#define COGL_SNIPPET_FIRST_LAYER_FRAGMENT_HOOK \ - (COGL_SNIPPET_FIRST_LAYER_VERTEX_HOOK + COGL_SNIPPET_HOOK_BAND_SIZE) - -struct _CoglSnippet -{ - CoglObject _parent; - - CoglSnippetHook hook; - - /* This is set to TRUE the first time the snippet is attached to the - pipeline. After that any attempts to modify the snippet will be - ignored. */ - gboolean immutable; - - char *declarations; - char *pre; - char *replace; - char *post; -}; - -void -_cogl_snippet_make_immutable (CoglSnippet *snippet); - -#endif /* __COGL_SNIPPET_PRIVATE_H */ - diff --git a/cogl/cogl/cogl-snippet.c b/cogl/cogl/cogl-snippet.c deleted file mode 100644 index d232a14f9..000000000 --- a/cogl/cogl/cogl-snippet.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-types.h" -#include "cogl-snippet-private.h" -#include "cogl-util.h" -#include "cogl-gtype-private.h" - -static void -_cogl_snippet_free (CoglSnippet *snippet); - -COGL_OBJECT_DEFINE (Snippet, snippet); -COGL_GTYPE_DEFINE_CLASS (Snippet, snippet); - -CoglSnippet * -cogl_snippet_new (CoglSnippetHook hook, - const char *declarations, - const char *post) -{ - CoglSnippet *snippet = g_new0 (CoglSnippet, 1); - - _cogl_snippet_object_new (snippet); - - snippet->hook = hook; - - cogl_snippet_set_declarations (snippet, declarations); - cogl_snippet_set_post (snippet, post); - - return snippet; -} - -CoglSnippetHook -cogl_snippet_get_hook (CoglSnippet *snippet) -{ - g_return_val_if_fail (cogl_is_snippet (snippet), 0); - - return snippet->hook; -} - -static gboolean -_cogl_snippet_modify (CoglSnippet *snippet) -{ - if (snippet->immutable) - { - g_warning ("A CoglSnippet should not be modified once it has been " - "attached to a pipeline. Any modifications after that point " - "will be ignored."); - - return FALSE; - } - - return TRUE; -} - -void -cogl_snippet_set_declarations (CoglSnippet *snippet, - const char *declarations) -{ - g_return_if_fail (cogl_is_snippet (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->declarations); - snippet->declarations = declarations ? g_strdup (declarations) : NULL; -} - -const char * -cogl_snippet_get_declarations (CoglSnippet *snippet) -{ - g_return_val_if_fail (cogl_is_snippet (snippet), NULL); - - return snippet->declarations; -} - -void -cogl_snippet_set_pre (CoglSnippet *snippet, - const char *pre) -{ - g_return_if_fail (cogl_is_snippet (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->pre); - snippet->pre = pre ? g_strdup (pre) : NULL; -} - -const char * -cogl_snippet_get_pre (CoglSnippet *snippet) -{ - g_return_val_if_fail (cogl_is_snippet (snippet), NULL); - - return snippet->pre; -} - -void -cogl_snippet_set_replace (CoglSnippet *snippet, - const char *replace) -{ - g_return_if_fail (cogl_is_snippet (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->replace); - snippet->replace = replace ? g_strdup (replace) : NULL; -} - -const char * -cogl_snippet_get_replace (CoglSnippet *snippet) -{ - g_return_val_if_fail (cogl_is_snippet (snippet), NULL); - - return snippet->replace; -} - -void -cogl_snippet_set_post (CoglSnippet *snippet, - const char *post) -{ - g_return_if_fail (cogl_is_snippet (snippet)); - - if (!_cogl_snippet_modify (snippet)) - return; - - g_free (snippet->post); - snippet->post = post ? g_strdup (post) : NULL; -} - -const char * -cogl_snippet_get_post (CoglSnippet *snippet) -{ - g_return_val_if_fail (cogl_is_snippet (snippet), NULL); - - return snippet->post; -} - -void -_cogl_snippet_make_immutable (CoglSnippet *snippet) -{ - snippet->immutable = TRUE; -} - -static void -_cogl_snippet_free (CoglSnippet *snippet) -{ - g_free (snippet->declarations); - g_free (snippet->pre); - g_free (snippet->replace); - g_free (snippet->post); - g_free (snippet); -} diff --git a/cogl/cogl/cogl-snippet.h b/cogl/cogl/cogl-snippet.h deleted file mode 100644 index 2d14b91fb..000000000 --- a/cogl/cogl/cogl-snippet.h +++ /dev/null @@ -1,865 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_SNIPPET_H__ -#define __COGL_SNIPPET_H__ - -G_BEGIN_DECLS - -/** - * SECTION:cogl-snippet - * @short_description: Functions for creating and manipulating shader snippets - * - * #CoglSnippet<!-- -->s are used to modify or replace parts of a - * #CoglPipeline using GLSL. GLSL is a programming language supported - * by OpenGL on programmable hardware to provide a more flexible - * description of what should be rendered. A description of GLSL - * itself is outside the scope of this documentation but any good - * OpenGL book should help to describe it. - * - * Unlike in OpenGL, when using GLSL with Cogl it is possible to write - * short snippets to replace small sections of the pipeline instead of - * having to replace the whole of either the vertex or fragment - * pipelines. Of course it is also possible to replace the whole of - * the pipeline if needed. - * - * Each snippet is a standalone chunk of code which would attach to - * the pipeline at a particular point. The code is split into four - * separate strings (all of which are optional): - * - * <glosslist> - * <glossentry> - * <glossterm>declarations</glossterm> - * <glossdef><para> - * The code in this string will be inserted outside of any function in - * the global scope of the shader. This can be used to declare - * uniforms, attributes, varyings and functions to be used by the - * snippet. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>pre</glossterm> - * <glossdef><para> - * The code in this string will be inserted before the hook point. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>post</glossterm> - * <glossdef><para> - * The code in this string will be inserted after the hook point. This - * can be used to modify the results of the builtin generated code for - * that hook point. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>replace</glossterm> - * <glossdef><para> - * If present the code in this string will replace the generated code - * for the hook point. - * </para></glossdef> - * </glossentry> - * </glosslist> - * - * All of the strings apart from the declarations string of a pipeline - * are generated in a single function so they can share variables - * declared from one string in another. The scope of the code is - * limited to each snippet so local variables declared in the snippet - * will not collide with variables declared in another - * snippet. However, code in the 'declarations' string is global to - * the shader so it is the application's responsibility to ensure that - * variables declared here will not collide with those from other - * snippets. - * - * The snippets can be added to a pipeline with - * cogl_pipeline_add_snippet() or - * cogl_pipeline_add_layer_snippet(). Which function to use depends on - * which hook the snippet is targeting. The snippets are all - * generated in the order they are added to the pipeline. That is, the - * post strings are executed in the order they are added to the - * pipeline and the pre strings are executed in reverse order. If any - * replace strings are given for a snippet then any other snippets - * with the same hook added before that snippet will be ignored. The - * different hooks are documented under #CoglSnippetHook. - * - * For portability with GLES2, it is recommended not to use the GLSL - * builtin names such as gl_FragColor. Instead there are replacement - * names under the cogl_* namespace which can be used instead. These - * are: - * - * <glosslist> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_modelview_matrix</emphasis></glossterm> - * <glossdef><para> - * The current modelview matrix. This is equivalent to - * #gl_ModelViewMatrix. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_projection_matrix</emphasis></glossterm> - * <glossdef><para> - * The current projection matrix. This is equivalent to - * #gl_ProjectionMatrix. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_modelview_projection_matrix</emphasis></glossterm> - * <glossdef><para> - * The combined modelview and projection matrix. A vertex shader - * would typically use this to transform the incoming vertex - * position. The separate modelview and projection matrices are - * usually only needed for lighting calculations. This is - * equivalent to #gl_ModelViewProjectionMatrix. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_texture_matrix</emphasis>[]</glossterm> - * <glossdef><para> - * An array of matrices for transforming the texture - * coordinates. This is equivalent to #gl_TextureMatrix. - * </para></glossdef> - * </glossentry> - * </glosslist> - * - * In a vertex shader, the following are also available: - * - * <glosslist> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_position_in</emphasis></glossterm> - * <glossdef><para> - * The incoming vertex position. This is equivalent to #gl_Vertex. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_color_in</emphasis></glossterm> - * <glossdef><para> - * The incoming vertex color. This is equivalent to #gl_Color. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_tex_coord_in</emphasis></glossterm> - * <glossdef><para> - * The texture coordinate for layer 0. This is an alternative name - * for #cogl_tex_coord0_in. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_tex_coord0_in</emphasis></glossterm> - * <glossdef><para> - * The texture coordinate for the layer 0. This is equivalent to - * #gl_MultiTexCoord0. There will also be #cogl_tex_coord1_in and - * so on if more layers are added to the pipeline. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec3 - * <emphasis>cogl_normal_in</emphasis></glossterm> - * <glossdef><para> - * The normal of the vertex. This is equivalent to #gl_Normal. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>vec4 - * <emphasis>cogl_position_out</emphasis></glossterm> - * <glossdef><para> - * The calculated position of the vertex. This must be written to - * in all vertex shaders. This is equivalent to #gl_Position. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>float - * <emphasis>cogl_point_size_in</emphasis></glossterm> - * <glossdef><para> - * The incoming point size from the cogl_point_size_in attribute. - * This is only available if - * cogl_pipeline_set_per_vertex_point_size() is set on the - * pipeline. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>float - * <emphasis>cogl_point_size_out</emphasis></glossterm> - * <glossdef><para> - * The calculated size of a point. This is equivalent to #gl_PointSize. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>varying vec4 - * <emphasis>cogl_color_out</emphasis></glossterm> - * <glossdef><para> - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>varying vec4 - * <emphasis>cogl_tex_coord0_out</emphasis></glossterm> - * <glossdef><para> - * The calculated texture coordinate for layer 0 of the pipeline. - * This is equivalent to #gl_TexCoord[0]. There will also be - * #cogl_tex_coord1_out and so on if more layers are added to the - * pipeline. In the fragment shader, this varying is called - * #cogl_tex_coord0_in. - * </para></glossdef> - * </glossentry> - * </glosslist> - * - * In a fragment shader, the following are also available: - * - * <glosslist> - * <glossentry> - * <glossterm>varying vec4 <emphasis>cogl_color_in</emphasis></glossterm> - * <glossdef><para> - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>varying vec4 - * <emphasis>cogl_tex_coord0_in</emphasis></glossterm> - * <glossdef><para> - * The texture coordinate for layer 0. This is equivalent to - * #gl_TexCoord[0]. There will also be #cogl_tex_coord1_in and so - * on if more layers are added to the pipeline. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>vec4 <emphasis>cogl_color_out</emphasis></glossterm> - * <glossdef><para> - * The final calculated color of the fragment. All fragment shaders - * must write to this variable. This is equivalent to - * #gl_FrontColor. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>float <emphasis>cogl_depth_out</emphasis></glossterm> - * <glossdef><para> - * An optional output variable specifying the depth value to use - * for this fragment. This is equivalent to #gl_FragDepth. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>bool <emphasis>cogl_front_facing</emphasis></glossterm> - * <glossdef><para> - * A readonly variable that will be true if the current primitive - * is front facing. This can be used to implement two-sided - * coloring algorithms. This is equivalent to #gl_FrontFacing. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>vec2 <emphasis>cogl_point_coord</emphasis></glossterm> - * <glossdef><para> - * When rendering points, this will contain a vec2 which represents - * the position within the point of the current fragment. - * vec2(0.0,0.0) will be the topleft of the point and vec2(1.0,1.0) - * will be the bottom right. Note that there is currently a bug in - * Cogl where when rendering to an offscreen buffer these - * coordinates will be upside-down. The value is undefined when not - * rendering points. - * </para></glossdef> - * </glossentry> - * </glosslist> - * - * Here is an example of using a snippet to add a desaturate effect to the - * generated color on a pipeline. - * - * <programlisting> - * CoglPipeline *pipeline = cogl_pipeline_new (); - * - * /<!-- -->* Set up the pipeline here, ie by adding a texture or other - * layers *<!-- -->/ - * - * /<!-- -->* Create the snippet. The first string is the declarations which - * we will use to add a uniform. The second is the 'post' string which - * will contain the code to perform the desaturation. *<!-- -->/ - * CoglSnippet *snippet = - * cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, - * "uniform float factor;", - * "float gray = dot (vec3 (0.299, 0.587, 0.114), " - * " cogl_color_out.rgb);" - * "cogl_color_out.rgb = mix (vec3 (gray)," - * " cogl_color_out.rgb," - * " factor);"); - * - * /<!-- -->* Add it to the pipeline *<!-- -->/ - * cogl_pipeline_add_snippet (pipeline, snippet); - * /<!-- -->* The pipeline keeps a reference to the snippet - * so we don't need to *<!-- -->/ - * cogl_object_unref (snippet); - * - * /<!-- -->* Update the custom uniform on the pipeline *<!-- -->/ - * int location = cogl_pipeline_get_uniform_location (pipeline, "factor"); - * cogl_pipeline_set_uniform_1f (pipeline, location, 0.5f); - * - * /<!-- -->* Now we can render with the snippet as usual *<!-- -->/ - * cogl_push_source (pipeline); - * cogl_rectangle (0, 0, 10, 10); - * cogl_pop_source (); - * </programlisting> - */ -typedef struct _CoglSnippet CoglSnippet; - -#define COGL_SNIPPET(OBJECT) ((CoglSnippet *)OBJECT) - -/** - * cogl_snippet_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_snippet_get_gtype (void); - -/* Enumeration of all the hook points that a snippet can be attached - to within a pipeline. */ -/** - * CoglSnippetHook: - * @COGL_SNIPPET_HOOK_VERTEX_GLOBALS: A hook for declaring global data - * that can be shared with all other snippets that are on a vertex - * hook. - * @COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS: A hook for declaring global - * data wthat can be shared with all other snippets that are on a - * fragment hook. - * @COGL_SNIPPET_HOOK_VERTEX: A hook for the entire vertex processing - * stage of the pipeline. - * @COGL_SNIPPET_HOOK_VERTEX_TRANSFORM: A hook for the vertex transformation. - * @COGL_SNIPPET_HOOK_POINT_SIZE: A hook for manipulating the point - * size of a vertex. This is only used if - * cogl_pipeline_set_per_vertex_point_size() is enabled on the - * pipeline. - * @COGL_SNIPPET_HOOK_FRAGMENT: A hook for the entire fragment - * processing stage of the pipeline. - * @COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM: A hook for applying the - * layer matrix to a texture coordinate for a layer. - * @COGL_SNIPPET_HOOK_LAYER_FRAGMENT: A hook for the fragment - * processing of a particular layer. - * @COGL_SNIPPET_HOOK_TEXTURE_LOOKUP: A hook for the texture lookup - * stage of a given layer in a pipeline. - * - * #CoglSnippetHook is used to specify a location within a - * #CoglPipeline where the code of the snippet should be used when it - * is attached to a pipeline. - * - * <glosslist> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_VERTEX_GLOBALS</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet at the beginning of the global section of the - * shader for the vertex processing. Any declarations here can be - * shared with all other snippets that are attached to a vertex hook. - * Only the ‘declarations’ string is used and the other strings are - * ignored. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet at the beginning of the global section of the - * shader for the fragment processing. Any declarations here can be - * shared with all other snippets that are attached to a fragment - * hook. Only the ‘declarations’ string is used and the other strings - * are ignored. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_VERTEX</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the vertex processing - * stage of the pipeline. This gives a chance for the application to - * modify the vertex attributes generated by the shader. Typically the - * snippet will modify cogl_color_out or cogl_position_out builtins. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before any vertex processing is done. - * </para> - * <para> - * The ‘replace’ string in @snippet will be used instead of the - * generated vertex processing if it is present. This can be used if - * the application wants to provide a complete vertex shader and - * doesn't need the generated output from Cogl. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted after all of the - * standard vertex processing is done. This can be used to modify the - * outputs. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_VERTEX_TRANSFORM</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the vertex transform stage. - * Typically the snippet will use the cogl_modelview_matrix, - * cogl_projection_matrix and cogl_modelview_projection_matrix matrices and the - * cogl_position_in attribute. The hook must write to cogl_position_out. - * The default processing for this hook will multiply cogl_position_in by - * the combined modelview-projection matrix and store it on cogl_position_out. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before the vertex transform is done. - * </para> - * <para> - * The ‘replace’ string in @snippet will be used instead of the - * generated vertex transform if it is present. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted after all of the - * standard vertex transformation is done. This can be used to modify the - * cogl_position_out in addition to the default processing. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_POINT_SIZE</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the point size - * calculation step within the vertex shader stage. The snippet should - * write to the builtin cogl_point_size_out with the new point size. - * The snippet can either read cogl_point_size_in directly and write a - * new value or first read an existing value in cogl_point_size_out - * that would be set by a previous snippet. Note that this hook is - * only used if cogl_pipeline_set_per_vertex_point_size() is enabled - * on the pipeline. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted just before - * calculating the point size. - * </para> - * <para> - * The ‘replace’ string in @snippet will be used instead of the - * generated point size calculation if it is present. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted after the - * standard point size calculation is done. This can be used to modify - * cogl_point_size_out in addition to the default processing. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_FRAGMENT</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the fragment processing - * stage of the pipeline. This gives a chance for the application to - * modify the fragment color generated by the shader. Typically the - * snippet will modify cogl_color_out. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before any fragment processing is done. - * </para> - * <para> - * The ‘replace’ string in @snippet will be used instead of the - * generated fragment processing if it is present. This can be used if - * the application wants to provide a complete fragment shader and - * doesn't need the generated output from Cogl. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted after all of the - * standard fragment processing is done. At this point the generated - * value for the rest of the pipeline state will already be in - * cogl_color_out so the application can modify the result by altering - * this variable. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the texture coordinate - * transformation of a particular layer. This can be used to replace - * the processing for a layer or to modify the results. - * </para> - * <para> - * Within the snippet code for this hook there are two extra - * variables. The first is a mat4 called cogl_matrix which represents - * the user matrix for this layer. The second is called cogl_tex_coord - * and represents the incoming and outgoing texture coordinate. On - * entry to the hook, cogl_tex_coord contains the value of the - * corresponding texture coordinate attribute for this layer. The hook - * is expected to modify this variable. The output will be passed as a - * varying to the fragment processing stage. The default code will - * just multiply cogl_matrix by cogl_tex_coord and store the result in - * cogl_tex_coord. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted just before the - * fragment processing for this layer. At this point cogl_tex_coord - * still contains the value of the texture coordinate attribute. - * </para> - * <para> - * If a ‘replace’ string is given then this will be used instead of - * the default fragment processing for this layer. The snippet can - * modify cogl_tex_coord or leave it as is to apply no transformation. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted just after the - * transformation. At this point cogl_tex_coord will contain the - * results of the transformation but it can be further modified by the - * snippet. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_LAYER_FRAGMENT</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the fragment processing - * of a particular layer. This can be used to replace the processing - * for a layer or to modify the results. - * </para> - * <para> - * Within the snippet code for this hook there is an extra vec4 - * variable called ‘cogl_layer’. This contains the resulting color - * that will be used for the layer. This can be modified in the ‘post’ - * section or it the default processing can be replaced entirely using - * the ‘replace’ section. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted just before the - * fragment processing for this layer. - * </para> - * <para> - * If a ‘replace’ string is given then this will be used instead of - * the default fragment processing for this layer. The snippet must write to - * the ‘cogl_layer’ variable in that case. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted just after the - * fragment processing for the layer. The results can be modified by changing - * the value of the ‘cogl_layer’ variable. - * </para> - * </glossdef> - * </glossentry> - * <glossentry> - * <glossterm>%COGL_SNIPPET_HOOK_TEXTURE_LOOKUP</glossterm> - * <glossdef> - * <para> - * Adds a shader snippet that will hook on to the texture lookup part - * of a given layer. This gives a chance for the application to modify - * the coordinates that will be used for the texture lookup or to - * alter the returned texel. - * </para> - * <para> - * Within the snippet code for this hook there are three extra - * variables available. ‘cogl_sampler’ is a sampler object - * representing the sampler for the layer where the snippet is - * attached. ‘cogl_tex_coord’ is a vec4 which contains the texture - * coordinates that will be used for the texture lookup. This can be - * modified. ‘cogl_texel’ will contain the result of the texture - * lookup. This can also be modified. - * </para> - * <para> - * The ‘declarations’ string in @snippet will be inserted in the - * global scope of the shader. Use this to declare any uniforms, - * attributes or functions that the snippet requires. - * </para> - * <para> - * The ‘pre’ string in @snippet will be inserted at the top of the - * main() function before any fragment processing is done. This is a - * good place to modify the cogl_tex_coord variable. - * </para> - * <para> - * If a ‘replace’ string is given then this will be used instead of a - * the default texture lookup. The snippet would typically use its own - * sampler in this case. - * </para> - * <para> - * The ‘post’ string in @snippet will be inserted after texture lookup - * has been performed. Here the snippet can modify the cogl_texel - * variable to alter the returned texel. - * </para> - * </glossdef> - * </glossentry> - * </glosslist> - * - * Since: 1.10 - * Stability: Unstable - */ -typedef enum -{ - /* Per pipeline vertex hooks */ - COGL_SNIPPET_HOOK_VERTEX = 0, - COGL_SNIPPET_HOOK_VERTEX_TRANSFORM, - COGL_SNIPPET_HOOK_VERTEX_GLOBALS, - COGL_SNIPPET_HOOK_POINT_SIZE, - - /* Per pipeline fragment hooks */ - COGL_SNIPPET_HOOK_FRAGMENT = 2048, - COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS, - - /* Per layer vertex hooks */ - COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM = 4096, - - /* Per layer fragment hooks */ - COGL_SNIPPET_HOOK_LAYER_FRAGMENT = 6144, - COGL_SNIPPET_HOOK_TEXTURE_LOOKUP -} CoglSnippetHook; - -/** - * cogl_snippet_new: - * @hook: The point in the pipeline that this snippet will wrap around - * or replace. - * @declarations: The source code for the declarations for this - * snippet or %NULL. See cogl_snippet_set_declarations(). - * @post: The source code to run after the hook point where this - * shader snippet is attached or %NULL. See cogl_snippet_set_post(). - * - * Allocates and initializes a new snippet with the given source strings. - * - * Return value: a pointer to a new #CoglSnippet - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT CoglSnippet * -cogl_snippet_new (CoglSnippetHook hook, - const char *declarations, - const char *post); - -/** - * cogl_snippet_get_hook: - * @snippet: A #CoglSnippet - * - * Return value: the hook that was set when cogl_snippet_new() was - * called. - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT CoglSnippetHook -cogl_snippet_get_hook (CoglSnippet *snippet); - -/** - * cogl_is_snippet: - * @object: A #CoglObject pointer - * - * Gets whether the given @object references an existing snippet object. - * - * Return value: %TRUE if the @object references a #CoglSnippet, - * %FALSE otherwise - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_snippet (void *object); - -/** - * cogl_snippet_set_declarations: - * @snippet: A #CoglSnippet - * @declarations: The new source string for the declarations section - * of this snippet. - * - * Sets a source string that will be inserted in the global scope of - * the generated shader when this snippet is used on a pipeline. This - * string is typically used to declare uniforms, attributes or - * functions that will be used by the other parts of the snippets. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_snippet_set_declarations (CoglSnippet *snippet, - const char *declarations); - -/** - * cogl_snippet_get_declarations: - * @snippet: A #CoglSnippet - * - * Return value: the source string that was set with - * cogl_snippet_set_declarations() or %NULL if none was set. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT const char * -cogl_snippet_get_declarations (CoglSnippet *snippet); - -/** - * cogl_snippet_set_pre: - * @snippet: A #CoglSnippet - * @pre: The new source string for the pre section of this snippet. - * - * Sets a source string that will be inserted before the hook point in - * the generated shader for the pipeline that this snippet is attached - * to. Please see the documentation of each hook point in - * #CoglPipeline for a description of how this string should be used. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_snippet_set_pre (CoglSnippet *snippet, - const char *pre); - -/** - * cogl_snippet_get_pre: - * @snippet: A #CoglSnippet - * - * Return value: the source string that was set with - * cogl_snippet_set_pre() or %NULL if none was set. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT const char * -cogl_snippet_get_pre (CoglSnippet *snippet); - -/** - * cogl_snippet_set_replace: - * @snippet: A #CoglSnippet - * @replace: The new source string for the replace section of this snippet. - * - * Sets a source string that will be used instead of any generated - * source code or any previous snippets for this hook point. Please - * see the documentation of each hook point in #CoglPipeline for a - * description of how this string should be used. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_snippet_set_replace (CoglSnippet *snippet, - const char *replace); - -/** - * cogl_snippet_get_replace: - * @snippet: A #CoglSnippet - * - * Return value: the source string that was set with - * cogl_snippet_set_replace() or %NULL if none was set. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT const char * -cogl_snippet_get_replace (CoglSnippet *snippet); - -/** - * cogl_snippet_set_post: - * @snippet: A #CoglSnippet - * @post: The new source string for the post section of this snippet. - * - * Sets a source string that will be inserted after the hook point in - * the generated shader for the pipeline that this snippet is attached - * to. Please see the documentation of each hook point in - * #CoglPipeline for a description of how this string should be used. - * - * This function should only be called before the snippet is attached - * to its first pipeline. After that the snippet should be considered - * immutable. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_snippet_set_post (CoglSnippet *snippet, - const char *post); - -/** - * cogl_snippet_get_post: - * @snippet: A #CoglSnippet - * - * Return value: the source string that was set with - * cogl_snippet_set_post() or %NULL if none was set. - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT const char * -cogl_snippet_get_post (CoglSnippet *snippet); - -G_END_DECLS - -#endif /* __COGL_SNIPPET_H__ */ diff --git a/cogl/cogl/cogl-spans.c b/cogl/cogl/cogl-spans.c deleted file mode 100644 index 8f7eaf4e3..000000000 --- a/cogl/cogl/cogl-spans.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "math.h" - -#include "cogl-util.h" -#include "cogl-spans.h" - -void -_cogl_span_iter_update (CoglSpanIter *iter) -{ - /* Pick current span */ - iter->span = &iter->spans[iter->index]; - - /* Offset next position by span size */ - iter->next_pos = iter->pos + iter->span->size - iter->span->waste; - - /* Check if span intersects the area to cover */ - if (iter->next_pos <= iter->cover_start || - iter->pos >= iter->cover_end) - { - /* Intersection undefined */ - iter->intersects = FALSE; - return; - } - - iter->intersects = TRUE; - - /* Clip start position to coverage area */ - if (iter->pos < iter->cover_start) - iter->intersect_start = iter->cover_start; - else - iter->intersect_start = iter->pos; - - /* Clip end position to coverage area */ - if (iter->next_pos > iter->cover_end) - iter->intersect_end = iter->cover_end; - else - iter->intersect_end = iter->next_pos; -} - -void -_cogl_span_iter_begin (CoglSpanIter *iter, - const CoglSpan *spans, - int n_spans, - float normalize_factor, - float cover_start, - float cover_end, - CoglPipelineWrapMode wrap_mode) -{ - /* XXX: If CLAMP_TO_EDGE needs to be emulated then it needs to be - * done at a higher level than here... */ - g_return_if_fail (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT || - wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT); - - iter->span = NULL; - - iter->spans = spans; - iter->n_spans = n_spans; - - /* We always iterate in a positive direction from the origin. If - * iter->flipped == TRUE that means whoever is using this API should - * interpreted the current span as extending in the opposite direction. I.e. - * it extends to the left if iterating the X axis, or up if the Y axis. */ - if (cover_start > cover_end) - { - float tmp = cover_start; - cover_start = cover_end; - cover_end = tmp; - iter->flipped = TRUE; - } - else - iter->flipped = FALSE; - - /* The texture spans cover the normalized texture coordinate space ranging - * from [0,1] but to help support repeating of sliced textures we allow - * iteration of any range so we need to relate the start of the range to the - * nearest point equivalent to 0. - */ - if (normalize_factor != 1.0) - { - float cover_start_normalized = cover_start / normalize_factor; - iter->origin = floorf (cover_start_normalized) * normalize_factor; - } - else - iter->origin = floorf (cover_start); - - iter->wrap_mode = wrap_mode; - - if (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT) - iter->index = 0; - else if (wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT) - { - if ((int)iter->origin % 2) - { - iter->index = iter->n_spans - 1; - iter->mirror_direction = -1; - iter->flipped = !iter->flipped; - } - else - { - iter->index = 0; - iter->mirror_direction = 1; - } - } - else - g_warn_if_reached (); - - iter->cover_start = cover_start; - iter->cover_end = cover_end; - iter->pos = iter->origin; - - /* Update intersection */ - _cogl_span_iter_update (iter); - - while (iter->next_pos <= iter->cover_start) - _cogl_span_iter_next (iter); -} - -void -_cogl_span_iter_next (CoglSpanIter *iter) -{ - /* Move current position */ - iter->pos = iter->next_pos; - - if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT) - iter->index = (iter->index + 1) % iter->n_spans; - else if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT) - { - iter->index += iter->mirror_direction; - if (iter->index == iter->n_spans || iter->index == -1) - { - iter->mirror_direction = -iter->mirror_direction; - iter->index += iter->mirror_direction; - iter->flipped = !iter->flipped; - } - } - else - g_warn_if_reached (); - - /* Update intersection */ - _cogl_span_iter_update (iter); -} - -gboolean -_cogl_span_iter_end (CoglSpanIter *iter) -{ - /* End reached when whole area covered */ - return iter->pos >= iter->cover_end; -} - - diff --git a/cogl/cogl/cogl-spans.h b/cogl/cogl/cogl-spans.h deleted file mode 100644 index d93c39688..000000000 --- a/cogl/cogl/cogl-spans.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_SPANS_PRIVATE_H -#define __COGL_SPANS_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-pipeline-layer-state.h" - -typedef struct _CoglSpan -{ - float start; - float size; - float waste; -} CoglSpan; - -typedef struct _CoglSpanIter -{ - int index; - const CoglSpan *spans; - int n_spans; - const CoglSpan *span; - float pos; - float next_pos; - float origin; - float cover_start; - float cover_end; - float intersect_start; - float intersect_end; - gboolean intersects; - gboolean flipped; - CoglPipelineWrapMode wrap_mode; - int mirror_direction; -} CoglSpanIter; - -void -_cogl_span_iter_update (CoglSpanIter *iter); - -void -_cogl_span_iter_begin (CoglSpanIter *iter, - const CoglSpan *spans, - int n_spans, - float normalize_factor, - float cover_start, - float cover_end, - CoglPipelineWrapMode wrap_mode); - -void -_cogl_span_iter_next (CoglSpanIter *iter); - -gboolean -_cogl_span_iter_end (CoglSpanIter *iter); - -#endif /* __COGL_SPANS_PRIVATE_H */ diff --git a/cogl/cogl/cogl-sub-texture-private.h b/cogl/cogl/cogl-sub-texture-private.h deleted file mode 100644 index 75c476d6e..000000000 --- a/cogl/cogl/cogl-sub-texture-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_SUB_TEXTURE_PRIVATE_H -#define __COGL_SUB_TEXTURE_PRIVATE_H - -#include "cogl-texture-private.h" - -#include <glib.h> - -struct _CoglSubTexture -{ - CoglTexture _parent; - - /* This is the texture that was passed in to - _cogl_sub_texture_new. If this is also a sub texture then we will - use the full texture from that to render instead of making a - chain. However we want to preserve the next texture in case the - user is expecting us to keep a reference and also so that we can - later add a cogl_sub_texture_get_parent_texture() function. */ - CoglTexture *next_texture; - /* This is the texture that will actually be used to draw. It will - point to the end of the chain if a sub texture of a sub texture - is created */ - CoglTexture *full_texture; - - /* The offset of the region represented by this sub-texture. This is - * the offset in full_texture which won't necessarily be the same as - * the offset passed to _cogl_sub_texture_new if next_texture is - * actually already a sub texture */ - int sub_x; - int sub_y; -}; - -#endif /* __COGL_SUB_TEXTURE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-sub-texture.c b/cogl/cogl/cogl-sub-texture.c deleted file mode 100644 index 8e5d372f2..000000000 --- a/cogl/cogl/cogl-sub-texture.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-sub-texture-private.h" -#include "cogl-sub-texture.h" -#include "cogl-context-private.h" -#include "cogl-object.h" -#include "cogl-texture-driver.h" -#include "cogl-texture-2d.h" -#include "cogl-gtype-private.h" -#include "driver/gl/cogl-texture-gl-private.h" - -#include <string.h> -#include <math.h> - -static void _cogl_sub_texture_free (CoglSubTexture *sub_tex); - -COGL_TEXTURE_DEFINE (SubTexture, sub_texture); -COGL_GTYPE_DEFINE_CLASS (SubTexture, sub_texture); - -static const CoglTextureVtable cogl_sub_texture_vtable; - -static void -_cogl_sub_texture_unmap_quad (CoglSubTexture *sub_tex, - float *coords) -{ - CoglTexture *tex = COGL_TEXTURE (sub_tex); - float width = cogl_texture_get_width (sub_tex->full_texture); - float height = cogl_texture_get_height (sub_tex->full_texture); - - coords[0] = (coords[0] * width - sub_tex->sub_x) / tex->width; - coords[1] = (coords[1] * height - sub_tex->sub_y) / tex->height; - coords[2] = (coords[2] * width - sub_tex->sub_x) / tex->width; - coords[3] = (coords[3] * height - sub_tex->sub_y) / tex->height; -} - -static void -_cogl_sub_texture_map_quad (CoglSubTexture *sub_tex, - float *coords) -{ - CoglTexture *tex = COGL_TEXTURE (sub_tex); - float width = cogl_texture_get_width (sub_tex->full_texture); - float height = cogl_texture_get_height (sub_tex->full_texture); - - coords[0] = (coords[0] * tex->width + sub_tex->sub_x) / width; - coords[1] = (coords[1] * tex->height + sub_tex->sub_y) / height; - coords[2] = (coords[2] * tex->width + sub_tex->sub_x) / width; - coords[3] = (coords[3] * tex->height + sub_tex->sub_y) / height; -} - -typedef struct _CoglSubTextureForeachData -{ - CoglSubTexture *sub_tex; - CoglMetaTextureCallback callback; - void *user_data; -} CoglSubTextureForeachData; - -static void -unmap_coords_cb (CoglTexture *slice_texture, - const float *slice_texture_coords, - const float *meta_coords, - void *user_data) -{ - CoglSubTextureForeachData *data = user_data; - float unmapped_coords[4]; - - memcpy (unmapped_coords, meta_coords, sizeof (unmapped_coords)); - - _cogl_sub_texture_unmap_quad (data->sub_tex, unmapped_coords); - - data->callback (slice_texture, - slice_texture_coords, - unmapped_coords, - data->user_data); -} - -static void -_cogl_sub_texture_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - CoglTexture *full_texture = sub_tex->full_texture; - float mapped_coords[4] = - { virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2}; - float virtual_coords[4] = - { virtual_tx_1, virtual_ty_1, virtual_tx_2, virtual_ty_2}; - - /* map the virtual coordinates to ->full_texture coordinates */ - _cogl_sub_texture_map_quad (sub_tex, mapped_coords); - - /* TODO: Add something like cogl_is_low_level_texture() */ - if (cogl_is_texture_2d (full_texture)) - { - callback (sub_tex->full_texture, - mapped_coords, - virtual_coords, - user_data); - } - else - { - CoglSubTextureForeachData data; - - data.sub_tex = sub_tex; - data.callback = callback; - data.user_data = user_data; - - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (full_texture), - mapped_coords[0], - mapped_coords[1], - mapped_coords[2], - mapped_coords[3], - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - unmap_coords_cb, - &data); - } -} - -static void -_cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (sub_tex->full_texture, - wrap_mode_s, - wrap_mode_t); -} - -static void -_cogl_sub_texture_free (CoglSubTexture *sub_tex) -{ - cogl_object_unref (sub_tex->next_texture); - cogl_object_unref (sub_tex->full_texture); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (sub_tex)); -} - -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 */ - g_return_val_if_fail (sub_x >= 0 && sub_y >= 0, NULL); - g_return_val_if_fail (sub_width > 0 && sub_height > 0, NULL); - g_return_val_if_fail (sub_x + sub_width <= next_width, NULL); - g_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); -} - -static gboolean -_cogl_sub_texture_allocate (CoglTexture *tex, - GError **error) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - gboolean status = cogl_texture_allocate (sub_tex->full_texture, error); - - _cogl_texture_set_allocated (tex, - _cogl_texture_get_format (sub_tex->full_texture), - tex->width, tex->height); - - return status; -} - -CoglTexture * -cogl_sub_texture_get_parent (CoglSubTexture *sub_texture) -{ - return sub_texture->next_texture; -} - -static int -_cogl_sub_texture_get_max_waste (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_max_waste (sub_tex->full_texture); -} - -static gboolean -_cogl_sub_texture_is_sliced (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_is_sliced (sub_tex->full_texture); -} - -static gboolean -_cogl_sub_texture_can_hardware_repeat (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - /* We can hardware repeat if the subtexture actually represents all of the - of the full texture */ - return (tex->width == - cogl_texture_get_width (sub_tex->full_texture) && - tex->height == - cogl_texture_get_height (sub_tex->full_texture) && - _cogl_texture_can_hardware_repeat (sub_tex->full_texture)); -} - -static void -_cogl_sub_texture_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - /* This won't work if the sub texture is not the size of the full - texture and the coordinates are outside the range [0,1] */ - *s = ((*s * tex->width + sub_tex->sub_x) / - cogl_texture_get_width (sub_tex->full_texture)); - *t = ((*t * tex->height + sub_tex->sub_y) / - cogl_texture_get_height (sub_tex->full_texture)); - - _cogl_texture_transform_coords_to_gl (sub_tex->full_texture, s, t); -} - -static CoglTransformResult -_cogl_sub_texture_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - int i; - - /* We can't support repeating with this method. In this case - cogl-primitives will resort to manual repeating */ - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - _cogl_sub_texture_map_quad (sub_tex, coords); - - return _cogl_texture_transform_quad_coords_to_gl (sub_tex->full_texture, - coords); -} - -static gboolean -_cogl_sub_texture_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_get_gl_texture (sub_tex->full_texture, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_sub_texture_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_gl_flush_legacy_texobj_filters (sub_tex->full_texture, - min_filter, mag_filter); -} - -static void -_cogl_sub_texture_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - _cogl_texture_pre_paint (sub_tex->full_texture, flags); -} - -static void -_cogl_sub_texture_ensure_non_quad_rendering (CoglTexture *tex) -{ -} - -static gboolean -_cogl_sub_texture_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - if (level != 0) - { - int full_width = cogl_texture_get_width (sub_tex->full_texture); - int full_height = cogl_texture_get_width (sub_tex->full_texture); - - g_return_val_if_fail (sub_tex->sub_x == 0 && - cogl_texture_get_width (tex) == full_width, - FALSE); - g_return_val_if_fail (sub_tex->sub_y == 0 && - cogl_texture_get_height (tex) == full_height, - FALSE); - } - - return _cogl_texture_set_region_from_bitmap (sub_tex->full_texture, - src_x, src_y, - dst_width, dst_height, - bmp, - dst_x + sub_tex->sub_x, - dst_y + sub_tex->sub_y, - level, - error); -} - -static gboolean -_cogl_sub_texture_is_get_data_supported (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return cogl_texture_is_get_data_supported (sub_tex->full_texture); -} - -static CoglPixelFormat -_cogl_sub_texture_get_format (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_get_format (sub_tex->full_texture); -} - -static GLenum -_cogl_sub_texture_get_gl_format (CoglTexture *tex) -{ - CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); - - return _cogl_texture_gl_get_format (sub_tex->full_texture); -} - -static const CoglTextureVtable -cogl_sub_texture_vtable = - { - FALSE, /* not primitive */ - _cogl_sub_texture_allocate, - _cogl_sub_texture_set_region, - _cogl_sub_texture_is_get_data_supported, - NULL, /* get_data */ - _cogl_sub_texture_foreach_sub_texture_in_region, - _cogl_sub_texture_get_max_waste, - _cogl_sub_texture_is_sliced, - _cogl_sub_texture_can_hardware_repeat, - _cogl_sub_texture_transform_coords_to_gl, - _cogl_sub_texture_transform_quad_coords_to_gl, - _cogl_sub_texture_get_gl_texture, - _cogl_sub_texture_gl_flush_legacy_texobj_filters, - _cogl_sub_texture_pre_paint, - _cogl_sub_texture_ensure_non_quad_rendering, - _cogl_sub_texture_gl_flush_legacy_texobj_wrap_modes, - _cogl_sub_texture_get_format, - _cogl_sub_texture_get_gl_format, - NULL /* set_auto_mipmap */ - }; diff --git a/cogl/cogl/cogl-sub-texture.h b/cogl/cogl/cogl-sub-texture.h deleted file mode 100644 index 97874e763..000000000 --- a/cogl/cogl/cogl-sub-texture.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_SUB_TEXTURE_H -#define __COGL_SUB_TEXTURE_H - -G_BEGIN_DECLS - -/** - * SECTION:cogl-sub-texture - * @short_description: Functions for creating and manipulating - * sub-textures. - * - * These functions allow high-level textures to be created that - * represent a sub-region of another texture. For example these - * can be used to implement custom texture atlasing schemes. - */ - - -#define COGL_SUB_TEXTURE(tex) ((CoglSubTexture *) tex) -typedef struct _CoglSubTexture CoglSubTexture; - -/** - * cogl_sub_texture_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -GType cogl_sub_texture_get_gtype (void); - -/** - * cogl_sub_texture_new: - * @ctx: A #CoglContext pointer - * @parent_texture: The full texture containing a sub-region you want - * to make a #CoglSubTexture from. - * @sub_x: The top-left x coordinate of the parent region to make - * a texture from. - * @sub_y: The top-left y coordinate of the parent region to make - * a texture from. - * @sub_width: The width of the parent region to make a texture from. - * @sub_height: The height of the parent region to make a texture - * from. - * - * Creates a high-level #CoglSubTexture representing a sub-region of - * any other #CoglTexture. The sub-region must strictly lye within the - * bounds of the @parent_texture. The returned texture implements the - * #CoglMetaTexture interface because it's not a low level texture - * that hardware can understand natively. - * - * <note>Remember: Unless you are using high level drawing APIs such - * as cogl_rectangle() or other APIs documented to understand the - * #CoglMetaTexture interface then you need to use the - * #CoglMetaTexture interface to resolve a #CoglSubTexture into a - * low-level texture before drawing.</note> - * - * Return value: (transfer full): A newly allocated #CoglSubTexture - * representing a sub-region of @parent_texture. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglSubTexture * -cogl_sub_texture_new (CoglContext *ctx, - CoglTexture *parent_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height); - -/** - * cogl_sub_texture_get_parent: - * @sub_texture: A pointer to a #CoglSubTexture - * - * Retrieves the parent texture that @sub_texture derives its content - * from. This is the texture that was passed to - * cogl_sub_texture_new() as the parent_texture argument. - * - * Return value: (transfer none): The parent texture that @sub_texture - * derives its content from. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglTexture * -cogl_sub_texture_get_parent (CoglSubTexture *sub_texture); - -/** - * cogl_is_sub_texture: - * @object: a #CoglObject - * - * Checks whether @object is a #CoglSubTexture. - * - * Return value: %TRUE if the passed @object represents a - * #CoglSubTexture and %FALSE otherwise. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_sub_texture (void *object); - -G_END_DECLS - -#endif /* __COGL_SUB_TEXTURE_H */ diff --git a/cogl/cogl/cogl-swap-chain-private.h b/cogl/cogl/cogl-swap-chain-private.h deleted file mode 100644 index 3e14c2932..000000000 --- a/cogl/cogl/cogl-swap-chain-private.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_SWAP_CHAIN_PRIVATE_H -#define __COGL_SWAP_CHAIN_PRIVATE_H - -#include "cogl-object-private.h" - -struct _CoglSwapChain -{ - CoglObject _parent; - - int length; -}; - -#endif /* __COGL_SWAP_CHAIN_PRIVATE_H */ diff --git a/cogl/cogl/cogl-swap-chain.c b/cogl/cogl/cogl-swap-chain.c deleted file mode 100644 index fdb3c4d6c..000000000 --- a/cogl/cogl/cogl-swap-chain.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-object.h" - -#include "cogl-swap-chain-private.h" -#include "cogl-swap-chain.h" -#include "cogl-gtype-private.h" - -static void _cogl_swap_chain_free (CoglSwapChain *swap_chain); - -COGL_OBJECT_DEFINE (SwapChain, swap_chain); -COGL_GTYPE_DEFINE_CLASS (SwapChain, swap_chain); - - -static void -_cogl_swap_chain_free (CoglSwapChain *swap_chain) -{ - g_free (swap_chain); -} - -CoglSwapChain * -cogl_swap_chain_new (void) -{ - CoglSwapChain *swap_chain = g_new0 (CoglSwapChain, 1); - - swap_chain->length = -1; /* no preference */ - - return _cogl_swap_chain_object_new (swap_chain); -} - -void -cogl_swap_chain_set_length (CoglSwapChain *swap_chain, - int length) -{ - swap_chain->length = length; -} diff --git a/cogl/cogl/cogl-swap-chain.h b/cogl/cogl/cogl-swap-chain.h deleted file mode 100644 index 6e965ee9a..000000000 --- a/cogl/cogl/cogl-swap-chain.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_SWAP_CHAIN_H__ -#define __COGL_SWAP_CHAIN_H__ - -#include <cogl/cogl-types.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -typedef struct _CoglSwapChain CoglSwapChain; - -/** - * cogl_swap_chain_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_swap_chain_get_gtype (void); - -COGL_EXPORT CoglSwapChain * -cogl_swap_chain_new (void); - -COGL_EXPORT void -cogl_swap_chain_set_has_alpha (CoglSwapChain *swap_chain, - gboolean has_alpha); - -COGL_EXPORT void -cogl_swap_chain_set_length (CoglSwapChain *swap_chain, - int length); - -COGL_EXPORT gboolean -cogl_is_swap_chain (void *object); - -G_END_DECLS - -#endif /* __COGL_SWAP_CHAIN_H__ */ diff --git a/cogl/cogl/cogl-texture-2d-private.h b/cogl/cogl/cogl-texture-2d-private.h deleted file mode 100644 index 4f41dadf5..000000000 --- a/cogl/cogl/cogl-texture-2d-private.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_2D_PRIVATE_H -#define __COGL_TEXTURE_2D_PRIVATE_H - -#include "cogl-object-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d.h" - -struct _CoglTexture2D -{ - CoglTexture _parent; - - /* The internal format of the GL texture represented as a - CoglPixelFormat */ - CoglPixelFormat internal_format; - - gboolean auto_mipmap; - gboolean mipmaps_dirty; - gboolean is_get_data_supported; - - /* TODO: factor out these OpenGL specific members into some form - * of driver private state. */ - - /* The internal format of the GL texture represented as a GL enum */ - GLenum gl_internal_format; - /* The texture object number */ - GLuint gl_texture; - GLenum gl_target; - GLenum gl_legacy_texobj_min_filter; - GLenum gl_legacy_texobj_mag_filter; - GLint gl_legacy_texobj_wrap_mode_s; - GLint gl_legacy_texobj_wrap_mode_t; - CoglTexturePixel first_pixel; - - struct { - void *user_data; - GDestroyNotify destroy; - } egl_image_external; -}; - -CoglTexture2D * -_cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, - gboolean can_convert_in_place); - -CoglTexture2D * -_cogl_texture_2d_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader); - -void -_cogl_texture_2d_set_auto_mipmap (CoglTexture *tex, - gboolean value); - -/* - * _cogl_texture_2d_externally_modified: - * @texture: A #CoglTexture2D object - * - * This should be called whenever the texture is modified other than - * by using cogl_texture_set_region. It will cause the mipmaps to be - * invalidated - */ -void -_cogl_texture_2d_externally_modified (CoglTexture *texture); - -/* - * _cogl_texture_2d_copy_from_framebuffer: - * @texture: A #CoglTexture2D pointer - * @src_x: X-position to within the framebuffer to read from - * @src_y: Y-position to within the framebuffer to read from - * @width: width of the rectangle to copy - * @height: height of the rectangle to copy - * @src_fb: A source #CoglFramebuffer to copy from - * @dst_x: X-position to store the image within the texture - * @dst_y: Y-position to store the image within the texture - * @level: The mipmap level of @texture to copy too - * - * This copies a portion of the given @src_fb into the - * texture. - */ -void -_cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *texture, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - -#endif /* __COGL_TEXTURE_2D_PRIVATE_H */ diff --git a/cogl/cogl/cogl-texture-2d-sliced-private.h b/cogl/cogl/cogl-texture-2d-sliced-private.h deleted file mode 100644 index 5ca4cbf32..000000000 --- a/cogl/cogl/cogl-texture-2d-sliced-private.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_2D_SLICED_PRIVATE_H -#define __COGL_TEXTURE_2D_SLICED_PRIVATE_H - -#include "cogl-bitmap-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-sliced.h" - -#include <glib.h> - -struct _CoglTexture2DSliced -{ - CoglTexture _parent; - - GArray *slice_x_spans; - GArray *slice_y_spans; - GArray *slice_textures; - int max_waste; - CoglPixelFormat internal_format; -}; - -CoglTexture2DSliced * -_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - int max_waste, - gboolean can_convert_in_place); - -#endif /* __COGL_TEXTURE_2D_SLICED_PRIVATE_H */ diff --git a/cogl/cogl/cogl-texture-2d-sliced.c b/cogl/cogl/cogl-texture-2d-sliced.c deleted file mode 100644 index 8e7f91f70..000000000 --- a/cogl/cogl/cogl-texture-2d-sliced.c +++ /dev/null @@ -1,1342 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum <mallum@openedhand.com> - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-2d-sliced-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-spans.h" -#include "cogl-journal-private.h" -#include "cogl-primitive-texture.h" -#include "cogl-gtype-private.h" -#include "driver/gl/cogl-texture-gl-private.h" - -#include <string.h> -#include <stdlib.h> -#include <math.h> - -static void _cogl_texture_2d_sliced_free (CoglTexture2DSliced *tex_2ds); - -COGL_TEXTURE_DEFINE (Texture2DSliced, texture_2d_sliced); -COGL_GTYPE_DEFINE_CLASS (Texture2DSliced, texture_2d_sliced, - COGL_GTYPE_IMPLEMENT_INTERFACE (texture)); - -static const CoglTextureVtable cogl_texture_2d_sliced_vtable; - -typedef struct _ForeachData -{ - CoglMetaTextureCallback callback; - void *user_data; - float x_normalize_factor; - float y_normalize_factor; -} ForeachData; - -static void -re_normalize_sub_texture_coords_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - ForeachData *data = user_data; - /* The coordinates passed to the span iterating code were - * un-normalized so we need to renormalize them before passing them - * on */ - float re_normalized_coords[4] = - { - meta_coords[0] * data->x_normalize_factor, - meta_coords[1] * data->y_normalize_factor, - meta_coords[2] * data->x_normalize_factor, - meta_coords[3] * data->y_normalize_factor - }; - - data->callback (sub_texture, sub_texture_coords, re_normalized_coords, - data->user_data); -} - -static void -_cogl_texture_2d_sliced_foreach_sub_texture_in_region ( - CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglSpan *x_spans = (CoglSpan *)tex_2ds->slice_x_spans->data; - CoglSpan *y_spans = (CoglSpan *)tex_2ds->slice_y_spans->data; - CoglTexture **textures = (CoglTexture **)tex_2ds->slice_textures->data; - float un_normalized_coords[4]; - ForeachData data; - - /* NB: its convenient for us to store non-normalized coordinates in - * our CoglSpans but that means we need to un-normalize the incoming - * virtual coordinates and make sure we re-normalize the coordinates - * before calling the given callback. - */ - - data.callback = callback; - data.user_data = user_data; - data.x_normalize_factor = 1.0f / tex->width; - data.y_normalize_factor = 1.0f / tex->height; - - un_normalized_coords[0] = virtual_tx_1 * tex->width; - un_normalized_coords[1] = virtual_ty_1 * tex->height; - un_normalized_coords[2] = virtual_tx_2 * tex->width; - un_normalized_coords[3] = virtual_ty_2 * tex->height; - - /* Note that the normalize factors passed here are the reciprocal of - * the factors calculated above because the span iterating code - * normalizes by dividing by the factor instead of multiplying */ - _cogl_texture_spans_foreach_in_region (x_spans, - tex_2ds->slice_x_spans->len, - y_spans, - tex_2ds->slice_y_spans->len, - textures, - un_normalized_coords, - tex->width, - tex->height, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - re_normalize_sub_texture_coords_cb, - &data); -} - -static uint8_t * -_cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, - CoglPixelFormat format) -{ - CoglSpan *last_x_span; - CoglSpan *last_y_span; - uint8_t *waste_buf = NULL; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - - /* If the texture has any waste then allocate a buffer big enough to - fill the gaps */ - last_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, - tex_2ds->slice_x_spans->len - 1); - last_y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, - tex_2ds->slice_y_spans->len - 1); - if (last_x_span->waste > 0 || last_y_span->waste > 0) - { - int bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - CoglSpan *first_x_span - = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - CoglSpan *first_y_span - = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - unsigned int right_size = first_y_span->size * last_x_span->waste; - unsigned int bottom_size = first_x_span->size * last_y_span->waste; - - waste_buf = g_malloc (MAX (right_size, bottom_size) * bpp); - } - - return waste_buf; -} - -static gboolean -_cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, - CoglBitmap *source_bmp, - CoglTexture2D *slice_tex, - uint8_t *waste_buf, - CoglSpan *x_span, - CoglSpan *y_span, - CoglSpanIter *x_iter, - CoglSpanIter *y_iter, - int src_x, - int src_y, - int dst_x, - int dst_y, - GError **error) -{ - gboolean need_x, need_y; - CoglContext *ctx = COGL_TEXTURE (tex_2ds)->context; - - /* If the x_span is sliced and the upload touches the - rightmost pixels then fill the waste with copies of the - pixels */ - need_x = x_span->waste > 0 && - x_iter->intersect_end - x_iter->pos >= x_span->size - x_span->waste; - - /* same for the bottom-most pixels */ - need_y = y_span->waste > 0 && - y_iter->intersect_end - y_iter->pos >= y_span->size - y_span->waste; - - if (need_x || need_y) - { - int bmp_rowstride = cogl_bitmap_get_rowstride (source_bmp); - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - uint8_t *bmp_data; - const uint8_t *src; - uint8_t *dst; - unsigned int wy, wx; - CoglBitmap *waste_bmp; - - /* We only support single plane formats here */ - if (cogl_pixel_format_get_n_planes (source_format) == 1) - return FALSE; - - bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error); - if (bmp_data == NULL) - return FALSE; - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - if (need_x) - { - src = (bmp_data + ((src_y + (int) y_iter->intersect_start - dst_y) * - bmp_rowstride) + - (src_x + (int)x_span->start + (int)x_span->size - - (int)x_span->waste - dst_x - 1) * bpp); - - dst = waste_buf; - - for (wy = 0; - wy < y_iter->intersect_end - y_iter->intersect_start; - wy++) - { - for (wx = 0; wx < x_span->waste; wx++) - { - memcpy (dst, src, bpp); - dst += bpp; - } - src += bmp_rowstride; - } - - waste_bmp = cogl_bitmap_new_for_data (ctx, - x_span->waste, - y_iter->intersect_end - - y_iter->intersect_start, - source_format, - x_span->waste * bpp, - waste_buf); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - 0, /* src_x */ - 0, /* src_y */ - x_span->waste, /* width */ - /* height */ - y_iter->intersect_end - - y_iter->intersect_start, - waste_bmp, - /* dst_x */ - x_span->size - x_span->waste, - y_iter->intersect_start - - y_span->start, /* dst_y */ - 0, /* level */ - error)) - { - cogl_object_unref (waste_bmp); - _cogl_bitmap_unmap (source_bmp); - return FALSE; - } - - cogl_object_unref (waste_bmp); - } - - if (need_y) - { - unsigned int copy_width, intersect_width; - - src = (bmp_data + ((src_x + (int) x_iter->intersect_start - dst_x) * - bpp) + - (src_y + (int)y_span->start + (int)y_span->size - - (int)y_span->waste - dst_y - 1) * bmp_rowstride); - - dst = waste_buf; - - if (x_iter->intersect_end - x_iter->pos - >= x_span->size - x_span->waste) - copy_width = x_span->size + x_iter->pos - x_iter->intersect_start; - else - copy_width = x_iter->intersect_end - x_iter->intersect_start; - - intersect_width = x_iter->intersect_end - x_iter->intersect_start; - - for (wy = 0; wy < y_span->waste; wy++) - { - memcpy (dst, src, intersect_width * bpp); - dst += intersect_width * bpp; - - for (wx = intersect_width; wx < copy_width; wx++) - { - memcpy (dst, dst - bpp, bpp); - dst += bpp; - } - } - - waste_bmp = cogl_bitmap_new_for_data (ctx, - copy_width, - y_span->waste, - source_format, - copy_width * bpp, - waste_buf); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - 0, /* src_x */ - 0, /* src_y */ - copy_width, /* width */ - y_span->waste, /* height */ - waste_bmp, - /* dst_x */ - x_iter->intersect_start - - x_iter->pos, - /* dst_y */ - y_span->size - y_span->waste, - 0, /* level */ - error)) - { - cogl_object_unref (waste_bmp); - _cogl_bitmap_unmap (source_bmp); - return FALSE; - } - - cogl_object_unref (waste_bmp); - } - - _cogl_bitmap_unmap (source_bmp); - } - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_upload_bitmap (CoglTexture2DSliced *tex_2ds, - CoglBitmap *bmp, - GError **error) -{ - CoglSpan *x_span; - CoglSpan *y_span; - CoglTexture2D *slice_tex; - int x, y; - uint8_t *waste_buf; - CoglPixelFormat bmp_format; - - bmp_format = cogl_bitmap_get_format (bmp); - - waste_buf = _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds, - bmp_format); - - /* Iterate vertical slices */ - for (y = 0; y < tex_2ds->slice_y_spans->len; ++y) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y); - - /* Iterate horizontal slices */ - for (x = 0; x < tex_2ds->slice_x_spans->len; ++x) - { - int slice_num = y * tex_2ds->slice_x_spans->len + x; - CoglSpanIter x_iter, y_iter; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x); - - /* Pick the gl texture object handle */ - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, slice_num); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - x_span->start, /* src x */ - y_span->start, /* src y */ - x_span->size - - x_span->waste, /* width */ - y_span->size - - y_span->waste, /* height */ - bmp, - 0, /* dst x */ - 0, /* dst y */ - 0, /* level */ - error)) - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - - /* Set up a fake iterator that covers the whole slice */ - x_iter.intersect_start = x_span->start; - x_iter.intersect_end = (x_span->start + - x_span->size - - x_span->waste); - x_iter.pos = x_span->start; - - y_iter.intersect_start = y_span->start; - y_iter.intersect_end = (y_span->start + - y_span->size - - y_span->waste); - y_iter.pos = y_span->start; - - if (!_cogl_texture_2d_sliced_set_waste (tex_2ds, - bmp, - slice_tex, - waste_buf, - x_span, y_span, - &x_iter, &y_iter, - 0, /* src_x */ - 0, /* src_y */ - 0, /* dst_x */ - 0, - error)) /* dst_y */ - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - } - } - - if (waste_buf) - g_free (waste_buf); - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_upload_subregion (CoglTexture2DSliced *tex_2ds, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - CoglBitmap *source_bmp, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglSpan *x_span; - CoglSpan *y_span; - CoglSpanIter x_iter; - CoglSpanIter y_iter; - CoglTexture2D *slice_tex; - int source_x = 0, source_y = 0; - int inter_w = 0, inter_h = 0; - int local_x = 0, local_y = 0; - uint8_t *waste_buf; - CoglPixelFormat source_format; - - source_format = cogl_bitmap_get_format (source_bmp); - - waste_buf = - _cogl_texture_2d_sliced_allocate_waste_buffer (tex_2ds, source_format); - - /* Iterate vertical spans */ - for (source_y = src_y, - _cogl_span_iter_begin (&y_iter, - (CoglSpan *)tex_2ds->slice_y_spans->data, - tex_2ds->slice_y_spans->len, - tex->height, - dst_y, - dst_y + height, - COGL_PIPELINE_WRAP_MODE_REPEAT); - - !_cogl_span_iter_end (&y_iter); - - _cogl_span_iter_next (&y_iter), - source_y += inter_h ) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, - y_iter.index); - - /* Iterate horizontal spans */ - for (source_x = src_x, - _cogl_span_iter_begin (&x_iter, - (CoglSpan *)tex_2ds->slice_x_spans->data, - tex_2ds->slice_x_spans->len, - tex->width, - dst_x, - dst_x + width, - COGL_PIPELINE_WRAP_MODE_REPEAT); - - !_cogl_span_iter_end (&x_iter); - - _cogl_span_iter_next (&x_iter), - source_x += inter_w ) - { - int slice_num; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, - x_iter.index); - - /* Pick intersection width and height */ - inter_w = (x_iter.intersect_end - x_iter.intersect_start); - inter_h = (y_iter.intersect_end - y_iter.intersect_start); - - /* Localize intersection top-left corner to slice*/ - local_x = (x_iter.intersect_start - x_iter.pos); - local_y = (y_iter.intersect_start - y_iter.pos); - - slice_num = y_iter.index * tex_2ds->slice_x_spans->len + x_iter.index; - - /* Pick slice texture */ - slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, slice_num); - - if (!_cogl_texture_set_region_from_bitmap (COGL_TEXTURE (slice_tex), - source_x, - source_y, - inter_w, /* width */ - inter_h, /* height */ - source_bmp, - local_x, /* dst x */ - local_y, /* dst y */ - 0, /* level */ - error)) - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - - if (!_cogl_texture_2d_sliced_set_waste (tex_2ds, - source_bmp, - slice_tex, - waste_buf, - x_span, y_span, - &x_iter, &y_iter, - src_x, src_y, - dst_x, dst_y, - error)) - { - if (waste_buf) - g_free (waste_buf); - return FALSE; - } - } - } - - if (waste_buf) - g_free (waste_buf); - - return TRUE; -} - -static int -_cogl_rect_slices_for_size (int size_to_fill, - int max_span_size, - int max_waste, - GArray *out_spans) -{ - int n_spans = 0; - CoglSpan span; - - /* Init first slice span */ - span.start = 0; - span.size = max_span_size; - span.waste = 0; - - /* Repeat until whole area covered */ - while (size_to_fill >= span.size) - { - /* Add another slice span of same size */ - if (out_spans) - g_array_append_val (out_spans, span); - span.start += span.size; - size_to_fill -= span.size; - n_spans++; - } - - /* Add one last smaller slice span */ - if (size_to_fill > 0) - { - span.size = size_to_fill; - if (out_spans) - g_array_append_val (out_spans, span); - n_spans++; - } - - return n_spans; -} - -static void -_cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - /* Pass the set wrap mode on to all of the child textures */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, - i); - - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (COGL_TEXTURE (slice_tex), - wrap_mode_s, - wrap_mode_t); - } -} - -static void -free_spans (CoglTexture2DSliced *tex_2ds) -{ - if (tex_2ds->slice_x_spans != NULL) - { - g_array_free (tex_2ds->slice_x_spans, TRUE); - tex_2ds->slice_x_spans = NULL; - } - - if (tex_2ds->slice_y_spans != NULL) - { - g_array_free (tex_2ds->slice_y_spans, TRUE); - tex_2ds->slice_y_spans = NULL; - } -} - -static gboolean -setup_spans (CoglContext *ctx, - CoglTexture2DSliced *tex_2ds, - int width, - int height, - int max_waste, - CoglPixelFormat internal_format, - GError **error) -{ - int max_width; - int max_height; - int n_x_slices; - int n_y_slices; - - int (*slices_for_size) (int, int, int, GArray*); - - /* Initialize size of largest slice according to supported features */ - max_width = width; - max_height = height; - slices_for_size = _cogl_rect_slices_for_size; - - /* Negative number means no slicing forced by the user */ - if (max_waste <= -1) - { - CoglSpan span; - - /* Check if size supported else bail out */ - if (!ctx->driver_vtable->texture_2d_can_create (ctx, - max_width, - max_height, - internal_format)) - { - g_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, - "Sliced texture size of %d x %d not possible " - "with max waste set to -1", - width, - height); - return FALSE; - } - - n_x_slices = 1; - n_y_slices = 1; - - /* Init span arrays */ - tex_2ds->slice_x_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - 1); - - tex_2ds->slice_y_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - 1); - - /* Add a single span for width and height */ - span.start = 0; - span.size = max_width; - span.waste = max_width - width; - g_array_append_val (tex_2ds->slice_x_spans, span); - - span.size = max_height; - span.waste = max_height - height; - g_array_append_val (tex_2ds->slice_y_spans, span); - } - else - { - /* Decrease the size of largest slice until supported by GL */ - while (!ctx->driver_vtable->texture_2d_can_create (ctx, - max_width, - max_height, - internal_format)) - { - /* Alternate between width and height */ - if (max_width > max_height) - max_width /= 2; - else - max_height /= 2; - - if (max_width == 0 || max_height == 0) - { - /* Maybe it would be ok to just g_warn_if_reached() for this - * codepath */ - g_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, - "No suitable slice geometry found"); - free_spans (tex_2ds); - return FALSE; - } - } - - /* Determine the slices required to cover the bitmap area */ - n_x_slices = slices_for_size (width, - max_width, max_waste, - NULL); - - n_y_slices = slices_for_size (height, - max_height, max_waste, - NULL); - - /* Init span arrays with reserved size */ - tex_2ds->slice_x_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - n_x_slices); - - tex_2ds->slice_y_spans = g_array_sized_new (FALSE, FALSE, - sizeof (CoglSpan), - n_y_slices); - - /* Fill span arrays with info */ - slices_for_size (width, - max_width, max_waste, - tex_2ds->slice_x_spans); - - slices_for_size (height, - max_height, max_waste, - tex_2ds->slice_y_spans); - } - - return TRUE; -} - -static void -free_slices (CoglTexture2DSliced *tex_2ds) -{ - if (tex_2ds->slice_textures != NULL) - { - int i; - - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = - g_array_index (tex_2ds->slice_textures, CoglTexture2D *, i); - cogl_object_unref (slice_tex); - } - - g_array_free (tex_2ds->slice_textures, TRUE); - tex_2ds->slice_textures = NULL; - } - - free_spans (tex_2ds); -} - -static gboolean -allocate_slices (CoglTexture2DSliced *tex_2ds, - int width, - int height, - int max_waste, - CoglPixelFormat internal_format, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglContext *ctx = tex->context; - int n_x_slices; - int n_y_slices; - int n_slices; - int x, y; - CoglSpan *x_span; - CoglSpan *y_span; - - tex_2ds->internal_format = internal_format; - - if (!setup_spans (ctx, tex_2ds, - width, - height, - max_waste, - internal_format, - error)) - { - return FALSE; - } - - n_x_slices = tex_2ds->slice_x_spans->len; - n_y_slices = tex_2ds->slice_y_spans->len; - n_slices = n_x_slices * n_y_slices; - - tex_2ds->slice_textures = g_array_sized_new (FALSE, FALSE, - sizeof (CoglTexture2D *), - n_slices); - - /* Allocate each slice */ - for (y = 0; y < n_y_slices; ++y) - { - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, y); - - for (x = 0; x < n_x_slices; ++x) - { - CoglTexture *slice; - - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, x); - - COGL_NOTE (SLICING, "CREATE SLICE (%d,%d)\tsize (%d,%d)", - x, y, - (int)(x_span->size - x_span->waste), - (int)(y_span->size - y_span->waste)); - - slice = COGL_TEXTURE ( - cogl_texture_2d_new_with_size (ctx, - x_span->size, y_span->size)); - - _cogl_texture_copy_internal_format (tex, slice); - - g_array_append_val (tex_2ds->slice_textures, slice); - if (!cogl_texture_allocate (slice, error)) - { - free_slices (tex_2ds); - return FALSE; - } - } - } - - return TRUE; -} - -static void -_cogl_texture_2d_sliced_free (CoglTexture2DSliced *tex_2ds) -{ - free_slices (tex_2ds); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_2ds)); -} - -static CoglTexture2DSliced * -_cogl_texture_2d_sliced_create_base (CoglContext *ctx, - int width, - int height, - int max_waste, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglTexture2DSliced *tex_2ds = g_new0 (CoglTexture2DSliced, 1); - - _cogl_texture_init (COGL_TEXTURE (tex_2ds), ctx, width, height, - internal_format, loader, - &cogl_texture_2d_sliced_vtable); - - tex_2ds->max_waste = max_waste; - - return _cogl_texture_2d_sliced_object_new (tex_2ds); -} - -CoglTexture2DSliced * -cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, - int width, - int height, - int max_waste) -{ - CoglTextureLoader *loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; - loader->src.sized.width = width; - loader->src.sized.height = height; - - return _cogl_texture_2d_sliced_create_base (ctx, - width, - height, - max_waste, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, - loader); -} - -CoglTexture2DSliced * -_cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - int max_waste, - gboolean can_convert_in_place) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (cogl_is_bitmap (bmp), NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = cogl_object_ref (bmp); - loader->src.bitmap.can_convert_in_place = can_convert_in_place; - - return _cogl_texture_2d_sliced_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - max_waste, - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTexture2DSliced * -cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - int max_waste) -{ - return _cogl_texture_2d_sliced_new_from_bitmap (bmp, - max_waste, - FALSE); -} - -CoglTexture2DSliced * -cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, - int width, - int height, - int max_waste, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture2DSliced *tex_2ds; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_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, 0); - - /* Wrap the data into a bitmap */ - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - tex_2ds = cogl_texture_2d_sliced_new_from_bitmap (bmp, max_waste); - - cogl_object_unref (bmp); - - if (tex_2ds && - !cogl_texture_allocate (COGL_TEXTURE (tex_2ds), error)) - { - cogl_object_unref (tex_2ds); - return NULL; - } - - return tex_2ds; -} - -CoglTexture2DSliced * -cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, - const char *filename, - int max_waste, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture2DSliced *tex_2ds = NULL; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - bmp = _cogl_bitmap_from_file (ctx, filename, error); - if (bmp == NULL) - return NULL; - - tex_2ds = _cogl_texture_2d_sliced_new_from_bitmap (bmp, - max_waste, - TRUE); /* can convert in-place */ - - cogl_object_unref (bmp); - - return tex_2ds; -} - -static gboolean -allocate_with_size (CoglTexture2DSliced *tex_2ds, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglPixelFormat internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (allocate_slices (tex_2ds, - loader->src.sized.width, - loader->src.sized.height, - tex_2ds->max_waste, - internal_format, - error)) - { - _cogl_texture_set_allocated (COGL_TEXTURE (tex_2ds), - internal_format, - loader->src.sized.width, - loader->src.sized.height); - return TRUE; - } - else - return FALSE; -} - -static gboolean -allocate_from_bitmap (CoglTexture2DSliced *tex_2ds, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2ds); - CoglBitmap *bmp = loader->src.bitmap.bitmap; - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; - CoglPixelFormat internal_format; - CoglBitmap *upload_bmp; - - g_return_val_if_fail (tex_2ds->slice_textures == NULL, FALSE); - - internal_format = - _cogl_texture_determine_internal_format (tex, - cogl_bitmap_get_format (bmp)); - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - can_convert_in_place, - error); - if (upload_bmp == NULL) - return FALSE; - - if (!allocate_slices (tex_2ds, - width, - height, - tex_2ds->max_waste, - internal_format, - error)) - { - cogl_object_unref (upload_bmp); - return FALSE; - } - - if (!_cogl_texture_2d_sliced_upload_bitmap (tex_2ds, - upload_bmp, - error)) - { - free_slices (tex_2ds); - cogl_object_unref (upload_bmp); - return FALSE; - } - - cogl_object_unref (upload_bmp); - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static gboolean -_cogl_texture_2d_sliced_allocate (CoglTexture *tex, - GError **error) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTextureLoader *loader = tex->loader; - - g_return_val_if_fail (loader, FALSE); - - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZED: - return allocate_with_size (tex_2ds, loader, error); - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - return allocate_from_bitmap (tex_2ds, loader, error); - default: - break; - } - - g_return_val_if_reached (FALSE); -} - -static int -_cogl_texture_2d_sliced_get_max_waste (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - return tex_2ds->max_waste; -} - -static gboolean -_cogl_texture_2d_sliced_is_sliced (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - /* It's only after allocating a sliced texture that we will know - * whether it really needed to be sliced... */ - if (!tex->allocated) - cogl_texture_allocate (tex, NULL); - - if (tex_2ds->slice_x_spans->len != 1 || - tex_2ds->slice_y_spans->len != 1) - return TRUE; - else - return FALSE; -} - -static gboolean -_cogl_texture_2d_sliced_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - CoglSpan *x_span; - CoglSpan *y_span; - - /* If there's more than one texture then we can't hardware repeat */ - if (tex_2ds->slice_textures->len != 1) - return FALSE; - - /* If there's any waste then we can't hardware repeat */ - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - if (x_span->waste > 0 || y_span->waste > 0) - return FALSE; - - /* Otherwise pass the query on to the single slice texture */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - return _cogl_texture_can_hardware_repeat (COGL_TEXTURE (slice_tex)); -} - -static void -_cogl_texture_2d_sliced_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglSpan *x_span; - CoglSpan *y_span; - CoglTexture2D *slice_tex; - - g_assert (!_cogl_texture_2d_sliced_is_sliced (tex)); - - /* Don't include the waste in the texture coordinates */ - x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); - y_span = &g_array_index (tex_2ds->slice_y_spans, CoglSpan, 0); - - *s *= tex->width / (float)x_span->size; - *t *= tex->height / (float)y_span->size; - - /* Let the child texture further transform the coords */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - _cogl_texture_transform_coords_to_gl (COGL_TEXTURE (slice_tex), s, t); -} - -static CoglTransformResult -_cogl_texture_2d_sliced_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - gboolean need_repeat = FALSE; - int i; - - /* This is a bit lazy - in the case where the quad lies entirely - * within a single slice we could avoid the fallback. But that - * could likely lead to visual inconsistency if the fallback involves - * dropping layers, so this might be the right thing to do anyways. - */ - if (_cogl_texture_2d_sliced_is_sliced (tex)) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - need_repeat = TRUE; - - if (need_repeat && !_cogl_texture_2d_sliced_can_hardware_repeat (tex)) - return COGL_TRANSFORM_SOFTWARE_REPEAT; - - _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 0, coords + 1); - _cogl_texture_2d_sliced_transform_coords_to_gl (tex, coords + 2, coords + 3); - - return (need_repeat - ? COGL_TRANSFORM_HARDWARE_REPEAT : COGL_TRANSFORM_NO_REPEAT); -} - -static gboolean -_cogl_texture_2d_sliced_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - - if (tex_2ds->slice_textures == NULL) - return FALSE; - - if (tex_2ds->slice_textures->len < 1) - return FALSE; - - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - - return cogl_texture_get_gl_texture (COGL_TEXTURE (slice_tex), - out_gl_handle, out_gl_target); -} - -static void -_cogl_texture_2d_sliced_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - int i; - - g_return_if_fail (tex_2ds->slice_textures != NULL); - - /* Apply new filters to every slice. The slice texture itself should - cache the value and avoid resubmitting the same filter value to - GL */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, i); - _cogl_texture_gl_flush_legacy_texobj_filters (COGL_TEXTURE (slice_tex), - min_filter, mag_filter); - } -} - -static void -_cogl_texture_2d_sliced_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - g_return_if_fail (tex_2ds->slice_textures != NULL); - - /* Pass the pre-paint on to every slice */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, i); - _cogl_texture_pre_paint (COGL_TEXTURE (slice_tex), flags); - } -} - -static void -_cogl_texture_2d_sliced_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - int i; - - g_return_if_fail (tex_2ds->slice_textures != NULL); - - /* Pass the call on to every slice */ - for (i = 0; i < tex_2ds->slice_textures->len; i++) - { - CoglTexture2D *slice_tex = g_array_index (tex_2ds->slice_textures, - CoglTexture2D *, i); - _cogl_texture_ensure_non_quad_rendering (COGL_TEXTURE (slice_tex)); - } -} - -static gboolean -_cogl_texture_2d_sliced_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglBitmap *upload_bmp; - gboolean status; - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - _cogl_texture_get_format (tex), - FALSE, /* can't convert in - place */ - error); - if (!upload_bmp) - return FALSE; - - status = _cogl_texture_2d_sliced_upload_subregion (tex_2ds, - src_x, src_y, - dst_x, dst_y, - dst_width, dst_height, - upload_bmp, - error); - cogl_object_unref (upload_bmp); - - return status; -} - -static CoglPixelFormat -_cogl_texture_2d_sliced_get_format (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - - return tex_2ds->internal_format; -} - -static GLenum -_cogl_texture_2d_sliced_get_gl_format (CoglTexture *tex) -{ - CoglTexture2DSliced *tex_2ds = COGL_TEXTURE_2D_SLICED (tex); - CoglTexture2D *slice_tex; - - /* Assert that we've allocated our slices at this point */ - cogl_texture_allocate (tex, NULL); /* (abort on error) */ - - /* Pass the call on to the first slice */ - slice_tex = g_array_index (tex_2ds->slice_textures, CoglTexture2D *, 0); - return _cogl_texture_gl_get_format (COGL_TEXTURE (slice_tex)); -} - -static const CoglTextureVtable -cogl_texture_2d_sliced_vtable = - { - FALSE, /* not primitive */ - _cogl_texture_2d_sliced_allocate, - _cogl_texture_2d_sliced_set_region, - NULL, /* is_get_data_supported */ - NULL, /* get_data */ - _cogl_texture_2d_sliced_foreach_sub_texture_in_region, - _cogl_texture_2d_sliced_get_max_waste, - _cogl_texture_2d_sliced_is_sliced, - _cogl_texture_2d_sliced_can_hardware_repeat, - _cogl_texture_2d_sliced_transform_coords_to_gl, - _cogl_texture_2d_sliced_transform_quad_coords_to_gl, - _cogl_texture_2d_sliced_get_gl_texture, - _cogl_texture_2d_sliced_gl_flush_legacy_texobj_filters, - _cogl_texture_2d_sliced_pre_paint, - _cogl_texture_2d_sliced_ensure_non_quad_rendering, - _cogl_texture_2d_sliced_gl_flush_legacy_texobj_wrap_modes, - _cogl_texture_2d_sliced_get_format, - _cogl_texture_2d_sliced_get_gl_format, - NULL /* set_auto_mipmap */ - }; diff --git a/cogl/cogl/cogl-texture-2d-sliced.h b/cogl/cogl/cogl-texture-2d-sliced.h deleted file mode 100644 index 98b8479d3..000000000 --- a/cogl/cogl/cogl-texture-2d-sliced.h +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_TEXURE_2D_SLICED_H -#define __COGL_TEXURE_2D_SLICED_H - -#include "cogl-context.h" -#include "cogl-types.h" - -/** - * SECTION:cogl-texture-2d-sliced - * @short_description: Functions for creating and manipulating 2D meta - * textures that may internally be comprised of - * multiple 2D textures with power-of-two sizes. - * - * These functions allow high-level meta textures (See the - * #CoglMetaTexture interface) to be allocated that may internally be - * comprised of multiple 2D texture "slices" with power-of-two sizes. - * - * This API can be useful when working with GPUs that don't have - * native support for non-power-of-two textures or if you want to load - * a texture that is larger than the GPUs maximum texture size limits. - * - * The algorithm for slicing works by first trying to map a virtual - * size to the next larger power-of-two size and then seeing how many - * wasted pixels that would result in. For example if you have a - * virtual texture that's 259 texels wide, the next pot size = 512 and - * the amount of waste would be 253 texels. If the amount of waste is - * above a max-waste threshold then we would next slice that texture - * into one that's 256 texels and then looking at how many more texels - * remain unallocated after that we choose the next power-of-two size. - * For the example of a 259 texel image that would mean having a 256 - * texel wide texture, leaving 3 texels unallocated so we'd then - * create a 4 texel wide texture - now there is only one texel of - * waste. The algorithm continues to slice the right most textures - * until the amount of waste is less than or equal to a specified - * max-waste threshold. The same logic for slicing from left to right - * is also applied from top to bottom. - */ - -typedef struct _CoglTexture2DSliced CoglTexture2DSliced; -#define COGL_TEXTURE_2D_SLICED(X) ((CoglTexture2DSliced *)X) - -/** - * cogl_texture_2d_sliced_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_texture_2d_sliced_get_gtype (void); - -/** - * cogl_texture_2d_sliced_new_with_size: (skip) - * @ctx: A #CoglContext - * @width: The virtual width of your sliced texture. - * @height: The virtual height of your sliced texture. - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * - * Creates a #CoglTexture2DSliced that may internally be comprised of - * 1 or more #CoglTexture2D textures depending on GPU limitations. - * For example if the GPU only supports power-of-two sized textures - * then a sliced texture will turn a non-power-of-two size into a - * combination of smaller power-of-two sized textures. If the - * requested texture size is larger than is supported by the hardware - * then the texture will be sliced into smaller textures that can be - * accessed by the hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * <note>It's possible for the allocation of a sliced texture to fail - * later due to impossible slicing constraints if a negative - * @max_waste value is given. If the given virtual texture size size - * is larger than is supported by the hardware but slicing is disabled - * the texture size would be too large to handle.</note> - * - * Returns: (transfer full): A new #CoglTexture2DSliced object with no storage - * allocated yet. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT CoglTexture2DSliced * -cogl_texture_2d_sliced_new_with_size (CoglContext *ctx, - int width, - int height, - int max_waste); - -/** - * cogl_texture_2d_sliced_new_from_file: (skip) - * @ctx: A #CoglContext - * @filename: the file to load - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a #CoglTexture2DSliced from an image file. - * - * A #CoglTexture2DSliced may internally be comprised of 1 or more - * #CoglTexture2D textures depending on GPU limitations. For example - * if the GPU only supports power-of-two sized textures then a sliced - * texture will turn a non-power-of-two size into a combination of - * smaller power-of-two sized textures. If the requested texture size - * is larger than is supported by the hardware then the texture will - * be sliced into smaller textures that can be accessed by the - * hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * <note>It's possible for the allocation of a sliced texture to fail - * later due to impossible slicing constraints if a negative - * @max_waste value is given. If the given virtual texture size is - * larger than is supported by the hardware but slicing is disabled - * the texture size would be too large to handle.</note> - * - * Return value: (transfer full): A newly created #CoglTexture2DSliced - * or %NULL on failure and @error will be updated. - * - * Since: 1.16 - */ -COGL_EXPORT CoglTexture2DSliced * -cogl_texture_2d_sliced_new_from_file (CoglContext *ctx, - const char *filename, - int max_waste, - GError **error); - -/** - * cogl_texture_2d_sliced_new_from_data: (skip) - * @ctx: A #CoglContext - * @width: width of texture in pixels - * @height: height of texture in pixels - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * @rowstride: the memory offset in bytes between the start of each - * row in @data. A value of 0 will make Cogl automatically - * calculate @rowstride from @width and @format. - * @data: pointer the memory region where the source buffer resides - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a new #CoglTexture2DSliced texture based on data residing - * in memory. - * - * A #CoglTexture2DSliced may internally be comprised of 1 or more - * #CoglTexture2D textures depending on GPU limitations. For example - * if the GPU only supports power-of-two sized textures then a sliced - * texture will turn a non-power-of-two size into a combination of - * smaller power-of-two sized textures. If the requested texture size - * is larger than is supported by the hardware then the texture will - * be sliced into smaller textures that can be accessed by the - * hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * <note>This api will always immediately allocate GPU memory for all - * the required texture slices and upload the given data so that the - * @data pointer does not need to remain valid once this function - * returns. This means it is not possible to configure the texture - * before it is allocated. If you do need to configure the texture - * before allocation (to specify constraints on the internal format - * for example) then you can instead create a #CoglBitmap for your - * data and use cogl_texture_2d_sliced_new_from_bitmap() or use - * cogl_texture_2d_sliced_new_with_size() and then upload data using - * cogl_texture_set_data()</note> - * - * <note>It's possible for the allocation of a sliced texture to fail - * due to impossible slicing constraints if a negative @max_waste - * value is given. If the given virtual texture size is larger than is - * supported by the hardware but slicing is disabled the texture size - * would be too large to handle.</note> - * - * Return value: (transfer full): A newly created #CoglTexture2DSliced - * or %NULL on failure and @error will be updated. - * - * Since: 1.16 - */ -COGL_EXPORT CoglTexture2DSliced * -cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, - int width, - int height, - int max_waste, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error); - -/** - * cogl_texture_2d_sliced_new_from_bitmap: - * @bmp: A #CoglBitmap - * @max_waste: The threshold of how wide a strip of wasted texels - * are allowed along the right and bottom textures before - * they must be sliced to reduce the amount of waste. A - * negative can be passed to disable slicing. - * - * Creates a new #CoglTexture2DSliced texture based on data residing - * in a bitmap. - * - * A #CoglTexture2DSliced may internally be comprised of 1 or more - * #CoglTexture2D textures depending on GPU limitations. For example - * if the GPU only supports power-of-two sized textures then a sliced - * texture will turn a non-power-of-two size into a combination of - * smaller power-of-two sized textures. If the requested texture size - * is larger than is supported by the hardware then the texture will - * be sliced into smaller textures that can be accessed by the - * hardware. - * - * @max_waste is used as a threshold for recursively slicing the - * right-most or bottom-most slices into smaller sizes until the - * wasted padding at the bottom and right of the textures is less than - * specified. A negative @max_waste will disable slicing. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or let Cogl automatically allocate - * storage lazily. - * - * <note>It's possible for the allocation of a sliced texture to fail - * later due to impossible slicing constraints if a negative - * @max_waste value is given. If the given virtual texture size is - * larger than is supported by the hardware but slicing is disabled - * the texture size would be too large to handle.</note> - * - * Return value: (transfer full): A newly created #CoglTexture2DSliced - * or %NULL on failure and @error will be updated. - * - * Since: 1.16 - */ -COGL_EXPORT CoglTexture2DSliced * -cogl_texture_2d_sliced_new_from_bitmap (CoglBitmap *bmp, - int max_waste); - -/** - * cogl_is_texture_2d_sliced: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a #CoglTexture2DSliced. - * - * Return value: %TRUE if the object references a #CoglTexture2DSliced - * and %FALSE otherwise. - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_is_texture_2d_sliced (void *object); - -#endif /* __COGL_TEXURE_2D_SLICED_H */ diff --git a/cogl/cogl/cogl-texture-2d.c b/cogl/cogl/cogl-texture-2d.c deleted file mode 100644 index bababf749..000000000 --- a/cogl/cogl/cogl-texture-2d.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-driver.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-journal-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-gtype-private.h" -#include "driver/gl/cogl-texture-2d-gl-private.h" -#ifdef COGL_HAS_EGL_SUPPORT -#include "winsys/cogl-winsys-egl-private.h" -#endif - -#include <string.h> -#include <math.h> - -#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT -#include "cogl-wayland-server.h" -#endif - -static void _cogl_texture_2d_free (CoglTexture2D *tex_2d); - -COGL_TEXTURE_DEFINE (Texture2D, texture_2d); -COGL_GTYPE_DEFINE_CLASS (Texture2D, texture_2d, - COGL_GTYPE_IMPLEMENT_INTERFACE (texture)); - -static const CoglTextureVtable cogl_texture_2d_vtable; - -typedef struct _CoglTexture2DManualRepeatData -{ - CoglTexture2D *tex_2d; - CoglMetaTextureCallback callback; - void *user_data; -} CoglTexture2DManualRepeatData; - -static void -_cogl_texture_2d_free (CoglTexture2D *tex_2d) -{ - CoglContext *ctx = COGL_TEXTURE (tex_2d)->context; - - ctx->driver_vtable->texture_2d_free (tex_2d); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_2d)); -} - -void -_cogl_texture_2d_set_auto_mipmap (CoglTexture *tex, - gboolean value) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - tex_2d->auto_mipmap = value; -} - -CoglTexture2D * -_cogl_texture_2d_create_base (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format, - CoglTextureLoader *loader) -{ - CoglTexture2D *tex_2d = g_new (CoglTexture2D, 1); - CoglTexture *tex = COGL_TEXTURE (tex_2d); - - _cogl_texture_init (tex, ctx, width, height, internal_format, loader, - &cogl_texture_2d_vtable); - - tex_2d->mipmaps_dirty = TRUE; - tex_2d->auto_mipmap = TRUE; - tex_2d->is_get_data_supported = TRUE; - - tex_2d->gl_target = GL_TEXTURE_2D; - - ctx->driver_vtable->texture_2d_init (tex_2d); - - return _cogl_texture_2d_object_new (tex_2d); -} - -CoglTexture2D * -cogl_texture_2d_new_with_size (CoglContext *ctx, - int width, - int height) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (width >= 1, NULL); - g_return_val_if_fail (height >= 1, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_SIZED; - loader->src.sized.width = width; - loader->src.sized.height = height; - - return _cogl_texture_2d_create_base (ctx, width, height, - COGL_PIXEL_FORMAT_RGBA_8888_PRE, loader); -} - -static gboolean -_cogl_texture_2d_allocate (CoglTexture *tex, - GError **error) -{ - CoglContext *ctx = tex->context; - - return ctx->driver_vtable->texture_2d_allocate (tex, error); -} - -CoglTexture2D * -_cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, - gboolean can_convert_in_place) -{ - CoglTextureLoader *loader; - - g_return_val_if_fail (bmp != NULL, NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_BITMAP; - loader->src.bitmap.bitmap = cogl_object_ref (bmp); - loader->src.bitmap.can_convert_in_place = can_convert_in_place; - - return _cogl_texture_2d_create_base (_cogl_bitmap_get_context (bmp), - cogl_bitmap_get_width (bmp), - cogl_bitmap_get_height (bmp), - cogl_bitmap_get_format (bmp), - loader); -} - -CoglTexture2D * -cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp) -{ - return _cogl_texture_2d_new_from_bitmap (bmp, - FALSE); /* can't convert in place */ -} - -CoglTexture2D * -cogl_texture_2d_new_from_file (CoglContext *ctx, - const char *filename, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture2D *tex_2d = NULL; - - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - bmp = _cogl_bitmap_from_file (ctx, filename, error); - if (bmp == NULL) - return NULL; - - tex_2d = _cogl_texture_2d_new_from_bitmap (bmp, - TRUE); /* can convert in-place */ - - cogl_object_unref (bmp); - - return tex_2d; -} - -CoglTexture2D * -cogl_texture_2d_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture2D *tex_2d; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_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, 0); - - /* Wrap the data into a bitmap */ - bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - tex_2d = cogl_texture_2d_new_from_bitmap (bmp); - - cogl_object_unref (bmp); - - if (tex_2d && - !cogl_texture_allocate (COGL_TEXTURE (tex_2d), error)) - { - cogl_object_unref (tex_2d); - return NULL; - } - - return tex_2d; -} - -#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) -/* 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, - CoglEglImageFlags flags, - GError **error) -{ - CoglTextureLoader *loader; - CoglTexture2D *tex; - - g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - - g_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; - loader->src.egl_image.flags = flags; - - tex = _cogl_texture_2d_create_base (ctx, width, height, format, loader); - - if (!cogl_texture_allocate (COGL_TEXTURE (tex), error)) - { - cogl_object_unref (tex); - return NULL; - } - - return tex; -} -#endif /* defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) */ - -void -_cogl_texture_2d_externally_modified (CoglTexture *texture) -{ - if (!cogl_is_texture_2d (texture)) - return; - - COGL_TEXTURE_2D (texture)->mipmaps_dirty = TRUE; -} - -void -_cogl_texture_2d_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = tex->context; - - /* Assert that the storage for this texture has been allocated */ - cogl_texture_allocate (tex, NULL); /* (abort on error) */ - - ctx->driver_vtable->texture_2d_copy_from_framebuffer (tex_2d, - src_x, - src_y, - width, - height, - src_fb, - dst_x, - dst_y, - level); - - tex_2d->mipmaps_dirty = TRUE; -} - -static int -_cogl_texture_2d_get_max_waste (CoglTexture *tex) -{ - return -1; -} - -static gboolean -_cogl_texture_2d_is_sliced (CoglTexture *tex) -{ - return FALSE; -} - -static gboolean -_cogl_texture_2d_can_hardware_repeat (CoglTexture *tex) -{ - return TRUE; -} - -static void -_cogl_texture_2d_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - /* The texture coordinates map directly so we don't need to do - anything */ -} - -static CoglTransformResult -_cogl_texture_2d_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - /* The texture coordinates map directly so we don't need to do - anything other than check for repeats */ - - int i; - - for (i = 0; i < 4; i++) - if (coords[i] < 0.0f || coords[i] > 1.0f) - { - /* Repeat is needed */ - return (_cogl_texture_2d_can_hardware_repeat (tex) ? - COGL_TRANSFORM_HARDWARE_REPEAT : - COGL_TRANSFORM_SOFTWARE_REPEAT); - } - - /* No repeat is needed */ - return COGL_TRANSFORM_NO_REPEAT; -} - -static gboolean -_cogl_texture_2d_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglContext *ctx = tex->context; - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - if (ctx->driver_vtable->texture_2d_get_gl_handle) - { - GLuint handle; - - if (out_gl_target) - *out_gl_target = tex_2d->gl_target; - - handle = ctx->driver_vtable->texture_2d_get_gl_handle (tex_2d); - - if (out_gl_handle) - *out_gl_handle = handle; - - return handle ? TRUE : FALSE; - } - else - return FALSE; -} - -static void -_cogl_texture_2d_pre_paint (CoglTexture *tex, CoglTexturePrePaintFlags flags) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - /* Only update if the mipmaps are dirty */ - if ((flags & COGL_TEXTURE_NEEDS_MIPMAP) && - tex_2d->auto_mipmap && tex_2d->mipmaps_dirty) - { - CoglContext *ctx = tex->context; - - /* Since we are about to ask the GPU to generate mipmaps of tex, we - * better make sure tex is up-to-date. - */ - _cogl_texture_flush_journal_rendering (tex); - - ctx->driver_vtable->texture_2d_generate_mipmap (tex_2d); - - tex_2d->mipmaps_dirty = FALSE; - } -} - -static void -_cogl_texture_2d_ensure_non_quad_rendering (CoglTexture *tex) -{ - /* Nothing needs to be done */ -} - -static gboolean -_cogl_texture_2d_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *bmp, - GError **error) -{ - CoglContext *ctx = tex->context; - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - - if (!ctx->driver_vtable->texture_2d_copy_from_bitmap (tex_2d, - src_x, - src_y, - width, - height, - bmp, - dst_x, - dst_y, - level, - error)) - { - return FALSE; - } - - tex_2d->mipmaps_dirty = TRUE; - - return TRUE; -} - -static gboolean -_cogl_texture_2d_is_get_data_supported (CoglTexture *tex) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglContext *ctx = tex->context; - - return ctx->driver_vtable->texture_2d_is_get_data_supported (tex_2d); -} - -static gboolean -_cogl_texture_2d_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglContext *ctx = tex->context; - - if (ctx->driver_vtable->texture_2d_get_data) - { - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - ctx->driver_vtable->texture_2d_get_data (tex_2d, format, rowstride, data); - return TRUE; - } - else - return FALSE; -} - -static CoglPixelFormat -_cogl_texture_2d_get_format (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->internal_format; -} - -static GLenum -_cogl_texture_2d_get_gl_format (CoglTexture *tex) -{ - return COGL_TEXTURE_2D (tex)->gl_internal_format; -} - -static const CoglTextureVtable -cogl_texture_2d_vtable = - { - TRUE, /* primitive */ - _cogl_texture_2d_allocate, - _cogl_texture_2d_set_region, - _cogl_texture_2d_is_get_data_supported, - _cogl_texture_2d_get_data, - NULL, /* foreach_sub_texture_in_region */ - _cogl_texture_2d_get_max_waste, - _cogl_texture_2d_is_sliced, - _cogl_texture_2d_can_hardware_repeat, - _cogl_texture_2d_transform_coords_to_gl, - _cogl_texture_2d_transform_quad_coords_to_gl, - _cogl_texture_2d_get_gl_texture, - _cogl_texture_2d_gl_flush_legacy_texobj_filters, - _cogl_texture_2d_pre_paint, - _cogl_texture_2d_ensure_non_quad_rendering, - _cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes, - _cogl_texture_2d_get_format, - _cogl_texture_2d_get_gl_format, - _cogl_texture_2d_set_auto_mipmap - }; diff --git a/cogl/cogl/cogl-texture-2d.h b/cogl/cogl/cogl-texture-2d.h deleted file mode 100644 index 9bee64692..000000000 --- a/cogl/cogl/cogl-texture-2d.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_TEXTURE_2D_H -#define __COGL_TEXTURE_2D_H - -#include "cogl-context.h" -#include "cogl-bitmap.h" - -#ifdef COGL_HAS_EGL_SUPPORT -#include "cogl-egl-defines.h" -#endif - -G_BEGIN_DECLS - -/** - * SECTION:cogl-texture-2d - * @short_description: Functions for creating and manipulating 2D textures - * - * These functions allow low-level 2D textures to be allocated. These - * differ from sliced textures for example which may internally be - * made up of multiple 2D textures, or atlas textures where Cogl must - * internally modify user texture coordinates before they can be used - * by the GPU. - */ - -typedef struct _CoglTexture2D CoglTexture2D; -#define COGL_TEXTURE_2D(X) ((CoglTexture2D *)X) - -typedef enum _CoglEglImageFlags -{ - COGL_EGL_IMAGE_FLAG_NONE = 0, - COGL_EGL_IMAGE_FLAG_NO_GET_DATA = 1 << 0, -} CoglEglImageFlags; - -/** - * cogl_texture_2d_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_texture_2d_get_gtype (void); - -/** - * cogl_is_texture_2d: - * @object: A #CoglObject - * - * Gets whether the given object references an existing #CoglTexture2D - * object. - * - * Return value: %TRUE if the object references a #CoglTexture2D, - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_is_texture_2d (void *object); - -/** - * cogl_texture_2d_new_with_size: (skip) - * @ctx: A #CoglContext - * @width: Width of the texture to allocate - * @height: Height of the texture to allocate - * - * Creates a low-level #CoglTexture2D texture with a given @width and - * @height that your GPU can texture from directly. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Returns: (transfer full): A new #CoglTexture2D object with no storage yet allocated. - * - * Since: 2.0 - */ -COGL_EXPORT CoglTexture2D * -cogl_texture_2d_new_with_size (CoglContext *ctx, - int width, - int height); - -/** - * cogl_texture_2d_new_from_file: (skip) - * @ctx: A #CoglContext - * @filename: the file to load - * @error: A #GError to catch exceptional errors or %NULL - * - * Creates a low-level #CoglTexture2D texture from an image file. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Return value: (transfer full): A newly created #CoglTexture2D or %NULL on failure - * and @error will be updated. - * - * Since: 1.16 - */ -COGL_EXPORT CoglTexture2D * -cogl_texture_2d_new_from_file (CoglContext *ctx, - const char *filename, - GError **error); - -/** - * cogl_texture_2d_new_from_data: (skip) - * @ctx: A #CoglContext - * @width: width of texture in pixels - * @height: height of texture in pixels - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data. A value of 0 will make Cogl automatically - * calculate @rowstride from @width and @format. - * @data: pointer the memory region where the source buffer resides - * @error: A #GError for exceptions - * - * Creates a low-level #CoglTexture2D texture based on data residing - * in memory. - * - * <note>This api will always immediately allocate GPU memory for the - * texture and upload the given data so that the @data pointer does - * not need to remain valid once this function returns. This means it - * is not possible to configure the texture before it is allocated. If - * you do need to configure the texture before allocation (to specify - * constraints on the internal format for example) then you can - * instead create a #CoglBitmap for your data and use - * cogl_texture_2d_new_from_bitmap() or use - * cogl_texture_2d_new_with_size() and then upload data using - * cogl_texture_set_data()</note> - * - * Returns: (transfer full): A newly allocated #CoglTexture2D, or if - * the size is not supported (because it is too large or a - * non-power-of-two size that the hardware doesn't support) - * it will return %NULL and set @error. - * - * Since: 2.0 - */ -COGL_EXPORT CoglTexture2D * -cogl_texture_2d_new_from_data (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - GError **error); - -/** - * cogl_texture_2d_new_from_bitmap: - * @bitmap: A #CoglBitmap - * - * Creates a low-level #CoglTexture2D texture based on data residing - * in a #CoglBitmap. - * - * The storage for the texture is not allocated before this function - * returns. You can call cogl_texture_allocate() to explicitly - * allocate the underlying storage or preferably let Cogl - * automatically allocate storage lazily when it may know more about - * how the texture is being used and can optimize how it is allocated. - * - * The texture is still configurable until it has been allocated so - * for example you can influence the internal format of the texture - * using cogl_texture_set_components() and - * cogl_texture_set_premultiplied(). - * - * Returns: (transfer full): A newly allocated #CoglTexture2D - * - * Since: 2.0 - * Stability: unstable - */ -COGL_EXPORT CoglTexture2D * -cogl_texture_2d_new_from_bitmap (CoglBitmap *bitmap); - -/** - * cogl_egl_texture_2d_new_from_image: (skip) - */ -#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) -/* 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. */ -COGL_EXPORT CoglTexture2D * -cogl_egl_texture_2d_new_from_image (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - EGLImageKHR image, - CoglEglImageFlags flags, - GError **error); - -typedef gboolean (*CoglTexture2DEGLImageExternalAlloc) (CoglTexture2D *tex_2d, - gpointer user_data, - GError **error); - -/** - * cogl_texture_2d_new_from_egl_image_external: (skip) - */ -COGL_EXPORT CoglTexture2D * -cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, - int width, - int height, - CoglTexture2DEGLImageExternalAlloc alloc, - gpointer user_data, - GDestroyNotify destroy, - GError **error); - -COGL_EXPORT void -cogl_texture_2d_egl_image_external_bind (CoglTexture2D *tex_2d); - -COGL_EXPORT void -cogl_texture_2d_egl_image_external_alloc_finish (CoglTexture2D *tex_2d, - void *user_data, - GDestroyNotify destroy); -#endif - -G_END_DECLS - -#endif /* __COGL_TEXTURE_2D_H */ diff --git a/cogl/cogl/cogl-texture-driver.h b/cogl/cogl/cogl-texture-driver.h deleted file mode 100644 index 8fa0d86a1..000000000 --- a/cogl/cogl/cogl-texture-driver.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_DRIVER_H -#define __COGL_TEXTURE_DRIVER_H - -typedef struct _CoglTextureDriver CoglTextureDriver; - -struct _CoglTextureDriver -{ - /* - * A very small wrapper around glGenTextures() that ensures we default to - * non-mipmap filters when creating textures. This is to save some memory as - * the driver will not allocate room for the mipmap tree. - */ - GLuint - (* gen) (CoglContext *ctx, - GLenum gl_target, - CoglPixelFormat internal_format); - - /* - * This uploads a sub-region from source_bmp to a single GL texture - * handle (i.e a single CoglTexture slice) - * - * It also updates the array of tex->first_pixels[slice_index] if - * dst_{x,y} == 0 - * - * The driver abstraction is in place because GLES doesn't support the pixel - * store options required to source from a subregion, so for GLES we have - * to manually create a transient source bitmap. - * - * XXX: sorry for the ridiculous number of arguments :-( - */ - gboolean - (* upload_subregion_to_gl) (CoglContext *ctx, - CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error); - - /* - * Replaces the contents of the GL texture with the entire bitmap. On - * GL this just directly calls glTexImage2D, but under GLES it needs - * to copy the bitmap if the rowstride is not a multiple of a possible - * alignment value because there is no GL_UNPACK_ROW_LENGTH - */ - gboolean - (* upload_to_gl) (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error); - - /* - * This sets up the glPixelStore state for an download to a destination with - * the same size, and with no offset. - */ - /* NB: GLES can't download pixel data into a sub region of a larger - * destination buffer, the GL driver has a more flexible version of - * this function that it uses internally. */ - void - (* prep_gl_for_pixels_download) (CoglContext *ctx, - int image_width, - int pixels_rowstride, - int pixels_bpp); - - /* - * This driver abstraction is needed because GLES doesn't support - * glGetTexImage (). On GLES this currently just returns FALSE which - * will lead to a generic fallback path being used that simply - * renders the texture and reads it back from the framebuffer. (See - * _cogl_texture_draw_and_read () ) - */ - gboolean - (* gl_get_tex_image) (CoglContext *ctx, - GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - uint8_t *dest); - - /* - * It may depend on the driver as to what texture sizes are supported... - */ - gboolean - (* size_supported) (CoglContext *ctx, - GLenum gl_target, - GLenum gl_intformat, - GLenum gl_format, - GLenum gl_type, - int width, - int height); - - - gboolean - (* format_supports_upload) (CoglContext *ctx, - CoglPixelFormat format); - - /* - * The driver may impose constraints on what formats can be used to store - * texture data read from textures. For example GLES currently only supports - * RGBA_8888, and so we need to manually convert the data if the final - * destination has another format. - */ - CoglPixelFormat - (* find_best_gl_get_data_format) (CoglContext *context, - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type); -}; - -#endif /* __COGL_TEXTURE_DRIVER_H */ - diff --git a/cogl/cogl/cogl-texture-private.h b/cogl/cogl/cogl-texture-private.h deleted file mode 100644 index d20de6bce..000000000 --- a/cogl/cogl/cogl-texture-private.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_PRIVATE_H -#define __COGL_TEXTURE_PRIVATE_H - -#include "cogl-bitmap-private.h" -#include "cogl-object-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-spans.h" -#include "cogl-meta-texture.h" -#include "cogl-framebuffer.h" -#include "cogl-texture-2d.h" - -#ifdef COGL_HAS_EGL_SUPPORT -#include "cogl-egl-defines.h" -#endif - -typedef struct _CoglTextureVtable CoglTextureVtable; - -/* Encodes three possibiloities result of transforming a quad */ -typedef enum -{ - /* quad doesn't cross the boundaries of a texture */ - COGL_TRANSFORM_NO_REPEAT, - /* quad crosses boundaries, hardware wrap mode can handle */ - COGL_TRANSFORM_HARDWARE_REPEAT, - /* quad crosses boundaries, needs software fallback; - * for a sliced texture, this might not actually involve - * repeating, just a quad crossing multiple slices */ - COGL_TRANSFORM_SOFTWARE_REPEAT, -} CoglTransformResult; - -/* Flags given to the pre_paint method */ -typedef enum -{ - /* The texture is going to be used with filters that require - mipmapping. This gives the texture the opportunity to - automatically update the mipmap tree */ - COGL_TEXTURE_NEEDS_MIPMAP = 1 -} CoglTexturePrePaintFlags; - -struct _CoglTextureVtable -{ - /* Virtual functions that must be implemented for a texture - backend */ - - gboolean is_primitive; - - gboolean (* allocate) (CoglTexture *tex, - GError **error); - - /* This should update the specified sub region of the texture with a - sub region of the given bitmap. The bitmap is not converted - before being set so the caller is expected to have called - _cogl_bitmap_convert_for_upload with a suitable internal_format - before passing here */ - gboolean (* set_region) (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bitmap, - GError **error); - - gboolean (* is_get_data_supported) (CoglTexture *texture); - - /* This should copy the image data of the texture into @data. The - requested format will have been first passed through - ctx->texture_driver->find_best_gl_get_data_format so it should - always be a format that is valid for GL (ie, no conversion should - be necessary). */ - gboolean (* get_data) (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - - void (* foreach_sub_texture_in_region) (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data); - - int (* get_max_waste) (CoglTexture *tex); - - gboolean (* is_sliced) (CoglTexture *tex); - - gboolean (* can_hardware_repeat) (CoglTexture *tex); - - void (* transform_coords_to_gl) (CoglTexture *tex, - float *s, - float *t); - CoglTransformResult (* transform_quad_coords_to_gl) (CoglTexture *tex, - float *coords); - - gboolean (* get_gl_texture) (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target); - - /* OpenGL driver specific virtual function */ - void (* gl_flush_legacy_texobj_filters) (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter); - - void (* pre_paint) (CoglTexture *tex, CoglTexturePrePaintFlags flags); - void (* ensure_non_quad_rendering) (CoglTexture *tex); - - /* OpenGL driver specific virtual function */ - void (* gl_flush_legacy_texobj_wrap_modes) (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t); - - CoglPixelFormat (* get_format) (CoglTexture *tex); - GLenum (* get_gl_format) (CoglTexture *tex); - - /* Only needs to be implemented if is_primitive == TRUE */ - void (* set_auto_mipmap) (CoglTexture *texture, - gboolean value); -}; - -typedef enum _CoglTextureSoureType { - COGL_TEXTURE_SOURCE_TYPE_SIZED = 1, - COGL_TEXTURE_SOURCE_TYPE_BITMAP, - COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE, - COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL -} CoglTextureSourceType; - -typedef struct _CoglTextureLoader -{ - CoglTextureSourceType src_type; - union { - struct { - int width; - int height; - int depth; /* for 3d textures */ - } sized; - struct { - CoglBitmap *bitmap; - int height; /* for 3d textures */ - int depth; /* for 3d textures */ - gboolean can_convert_in_place; - } bitmap; -#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) - struct { - EGLImageKHR image; - int width; - int height; - CoglPixelFormat format; - CoglEglImageFlags flags; - } egl_image; -#endif -#if defined (COGL_HAS_EGL_SUPPORT) - struct { - int width; - int height; - CoglTexture2DEGLImageExternalAlloc alloc; - CoglPixelFormat format; - } egl_image_external; -#endif - struct { - int width; - int height; - unsigned int gl_handle; - CoglPixelFormat format; - } gl_foreign; - } src; -} CoglTextureLoader; - -struct _CoglTexture -{ - CoglObject _parent; - CoglContext *context; - CoglTextureLoader *loader; - GList *framebuffers; - int max_level_set; - int max_level_requested; - int width; - int height; - gboolean allocated; - - /* - * Internal format - */ - CoglTextureComponents components; - unsigned int premultiplied:1; - - const CoglTextureVtable *vtable; -}; - -typedef enum _CoglTextureChangeFlags -{ - /* Whenever the internals of a texture are changed such that the - * underlying GL textures that represent the CoglTexture change then - * we notify cogl-material.c via - * _cogl_pipeline_texture_pre_change_notify - */ - COGL_TEXTURE_CHANGE_GL_TEXTURES - -} CoglTextureChangeFlags; - -typedef struct _CoglTexturePixel CoglTexturePixel; - -/* This is used by the texture backends to store the first pixel of - each GL texture. This is only used when glGenerateMipmap is not - available so that we can temporarily set GL_GENERATE_MIPMAP and - reupload a pixel */ -struct _CoglTexturePixel -{ - /* We need to store the format of the pixel because we store the - data in the source format which might end up being different for - each slice if a subregion is updated with a different format */ - GLenum gl_format; - GLenum gl_type; - uint8_t data[4]; -}; - -void -_cogl_texture_init (CoglTexture *texture, - CoglContext *ctx, - int width, - int height, - CoglPixelFormat src_format, - CoglTextureLoader *loader, - const CoglTextureVtable *vtable); - -void -_cogl_texture_free (CoglTexture *texture); - -/* This is used to register a type to the list of handle types that - will be considered a texture in cogl_is_texture() */ -void -_cogl_texture_register_texture_type (const CoglObjectClass *klass); - -#define COGL_TEXTURE_DEFINE(TypeName, type_name) \ - COGL_OBJECT_DEFINE_WITH_CODE_GTYPE \ - (TypeName, type_name, \ - _cogl_texture_register_texture_type (&_cogl_##type_name##_class)) - -#define COGL_TEXTURE_INTERNAL_DEFINE(TypeName, type_name) \ - COGL_OBJECT_INTERNAL_DEFINE_WITH_CODE \ - (TypeName, type_name, \ - _cogl_texture_register_texture_type (&_cogl_##type_name##_class)) - -COGL_EXPORT gboolean -_cogl_texture_can_hardware_repeat (CoglTexture *texture); - -void -_cogl_texture_transform_coords_to_gl (CoglTexture *texture, - float *s, - float *t); -CoglTransformResult -_cogl_texture_transform_quad_coords_to_gl (CoglTexture *texture, - float *coords); - -void -_cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags); - -void -_cogl_texture_ensure_non_quad_rendering (CoglTexture *texture); - -/* - * This determines a CoglPixelFormat according to texture::components - * and texture::premultiplied (i.e. the user required components and - * whether the texture should be considered premultiplied) - * - * A reference/source format can be given (or COGL_PIXEL_FORMAT_ANY) - * and wherever possible this function tries to simply return the - * given source format if its compatible with the required components. - * - * Texture backends can call this when allocating a texture to know - * how to convert a source image in preparation for uploading. - */ -CoglPixelFormat -_cogl_texture_determine_internal_format (CoglTexture *texture, - CoglPixelFormat src_format); - -/* This is called by texture backends when they have successfully - * allocated a texture. - * - * Most texture backends currently track the internal layout of - * textures using a CoglPixelFormat which will be finalized when a - * texture is allocated. At this point we need to update - * texture::components and texture::premultiplied according to the - * determined layout. - * - * XXX: Going forward we should probably aim to stop using - * CoglPixelFormat at all for tracking the internal layout of - * textures. - */ -void -_cogl_texture_set_internal_format (CoglTexture *texture, - CoglPixelFormat internal_format); - -void -_cogl_texture_associate_framebuffer (CoglTexture *texture, - CoglFramebuffer *framebuffer); - -const GList * -_cogl_texture_get_associated_framebuffers (CoglTexture *texture); - -void -_cogl_texture_flush_journal_rendering (CoglTexture *texture); - -void -_cogl_texture_spans_foreach_in_region (CoglSpan *x_spans, - int n_x_spans, - CoglSpan *y_spans, - int n_y_spans, - CoglTexture **textures, - float *virtual_coords, - float x_normalize_factor, - float y_normalize_factor, - CoglPipelineWrapMode wrap_x, - CoglPipelineWrapMode wrap_y, - CoglMetaTextureCallback callback, - void *user_data); - -COGL_EXPORT gboolean -_cogl_texture_set_region (CoglTexture *texture, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int dst_x, - int dst_y, - int level, - GError **error); - -gboolean -_cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bmp, - int dst_x, - int dst_y, - int level, - GError **error); - -gboolean -_cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, - CoglPixelFormat dst_format); - -int -_cogl_texture_get_n_levels (CoglTexture *texture); - -void -cogl_texture_set_max_level (CoglTexture *texture, - int max_level); - -void -_cogl_texture_get_level_size (CoglTexture *texture, - int level, - int *width, - int *height, - int *depth); - -void -_cogl_texture_set_allocated (CoglTexture *texture, - CoglPixelFormat internal_format, - int width, - int height); - -COGL_EXPORT CoglPixelFormat -_cogl_texture_get_format (CoglTexture *texture); - -CoglTextureLoader * -_cogl_texture_create_loader (void); - -void -_cogl_texture_copy_internal_format (CoglTexture *src, - CoglTexture *dest); - -#endif /* __COGL_TEXTURE_PRIVATE_H */ diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c deleted file mode 100644 index 0206caac3..000000000 --- a/cogl/cogl/cogl-texture.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * Copyright (C) 2010 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum <mallum@openedhand.com> - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-buffer-private.h" -#include "cogl-pixel-buffer-private.h" -#include "cogl-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-driver.h" -#include "cogl-texture-2d-sliced-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-sub-texture-private.h" -#include "cogl-atlas-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-object-private.h" -#include "cogl-offscreen-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl1-context.h" -#include "cogl-sub-texture.h" -#include "cogl-primitive-texture.h" -#include "cogl-gtype-private.h" - -#include <string.h> -#include <stdlib.h> -#include <math.h> - -COGL_GTYPE_DEFINE_INTERFACE (Texture, texture); - -uint32_t -cogl_texture_error_quark (void) -{ - return g_quark_from_static_string ("cogl-texture-error-quark"); -} - -/* XXX: - * The CoglObject macros don't support any form of inheritance, so for - * now we implement the CoglObject support for the CoglTexture - * abstract class manually. - */ - -static GSList *_cogl_texture_types; - -void -_cogl_texture_register_texture_type (const CoglObjectClass *klass) -{ - _cogl_texture_types = g_slist_prepend (_cogl_texture_types, (void *) klass); -} - -gboolean -cogl_is_texture (void *object) -{ - CoglObject *obj = (CoglObject *)object; - GSList *l; - - if (object == NULL) - return FALSE; - - for (l = _cogl_texture_types; l; l = l->next) - if (l->data == obj->klass) - return TRUE; - - return FALSE; -} - -void -_cogl_texture_init (CoglTexture *texture, - CoglContext *context, - int width, - int height, - CoglPixelFormat src_format, - CoglTextureLoader *loader, - const CoglTextureVtable *vtable) -{ - texture->context = context; - texture->max_level_set = 0; - texture->max_level_requested = 1000; /* OpenGL default GL_TEXTURE_MAX_LEVEL */ - texture->width = width; - texture->height = height; - texture->allocated = FALSE; - texture->vtable = vtable; - texture->framebuffers = NULL; - - texture->loader = loader; - - _cogl_texture_set_internal_format (texture, src_format); - - /* Although we want to initialize texture::components according - * to the source format, we always want the internal layout to - * be considered premultiplied by default. - * - * NB: this ->premultiplied state is user configurable so to avoid - * awkward documentation, setting this to 'true' does not depend on - * ->components having an alpha component (we will simply ignore the - * premultiplied status later if there is no alpha component). - * This way we don't have to worry about updating the - * ->premultiplied state in _set_components(). Similarly we don't - * have to worry about updating the ->components state in - * _set_premultiplied(). - */ - texture->premultiplied = TRUE; -} - -static void -_cogl_texture_free_loader (CoglTexture *texture) -{ - if (texture->loader) - { - CoglTextureLoader *loader = texture->loader; - switch (loader->src_type) - { - case COGL_TEXTURE_SOURCE_TYPE_SIZED: - case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE: - case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL: - break; - case COGL_TEXTURE_SOURCE_TYPE_BITMAP: - cogl_object_unref (loader->src.bitmap.bitmap); - break; - } - g_free (loader); - texture->loader = NULL; - } -} - -CoglTextureLoader * -_cogl_texture_create_loader (void) -{ - return g_new0 (CoglTextureLoader, 1); -} - -void -_cogl_texture_free (CoglTexture *texture) -{ - _cogl_texture_free_loader (texture); - - g_free (texture); -} - -gboolean -_cogl_texture_needs_premult_conversion (CoglPixelFormat src_format, - CoglPixelFormat dst_format) -{ - return ((src_format & dst_format & COGL_A_BIT) && - src_format != COGL_PIXEL_FORMAT_A_8 && - dst_format != COGL_PIXEL_FORMAT_A_8 && - (src_format & COGL_PREMULT_BIT) != - (dst_format & COGL_PREMULT_BIT)); -} - -gboolean -cogl_texture_is_get_data_supported (CoglTexture *texture) -{ - if (texture->vtable->is_get_data_supported) - return texture->vtable->is_get_data_supported (texture); - else - return TRUE; -} - -unsigned int -cogl_texture_get_width (CoglTexture *texture) -{ - return texture->width; -} - -unsigned int -cogl_texture_get_height (CoglTexture *texture) -{ - return texture->height; -} - -CoglPixelFormat -_cogl_texture_get_format (CoglTexture *texture) -{ - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - return texture->vtable->get_format (texture); -} - -int -cogl_texture_get_max_waste (CoglTexture *texture) -{ - return texture->vtable->get_max_waste (texture); -} - -int -_cogl_texture_get_n_levels (CoglTexture *texture) -{ - int width = cogl_texture_get_width (texture); - int height = cogl_texture_get_height (texture); - int max_dimension = MAX (width, height); - int n_levels = _cogl_util_fls (max_dimension); - - return MIN (n_levels, texture->max_level_requested + 1); -} - -void -cogl_texture_set_max_level (CoglTexture *texture, - int max_level) -{ - texture->max_level_requested = max_level; -} - -void -_cogl_texture_get_level_size (CoglTexture *texture, - int level, - int *width, - int *height, - int *depth) -{ - int current_width = cogl_texture_get_width (texture); - int current_height = cogl_texture_get_height (texture); - int current_depth = 0; - int i; - - /* NB: The OpenGL spec (like D3D) uses a floor() convention to - * round down the size of a mipmap level when dividing the size - * of the previous level results in a fraction... - */ - for (i = 0; i < level; i++) - { - current_width = MAX (1, current_width >> 1); - current_height = MAX (1, current_height >> 1); - current_depth = MAX (1, current_depth >> 1); - } - - if (width) - *width = current_width; - if (height) - *height = current_height; - if (depth) - *depth = current_depth; -} - -gboolean -cogl_texture_is_sliced (CoglTexture *texture) -{ - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - return texture->vtable->is_sliced (texture); -} - -/* If this returns FALSE, that implies _foreach_sub_texture_in_region - * will be needed to iterate over multiple sub textures for regions whose - * texture coordinates extend out of the range [0,1] - */ -gboolean -_cogl_texture_can_hardware_repeat (CoglTexture *texture) -{ - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - return texture->vtable->can_hardware_repeat (texture); -} - -/* NB: You can't use this with textures comprised of multiple sub textures (use - * cogl_texture_is_sliced() to check) since coordinate transformation for such - * textures will be different for each slice. */ -void -_cogl_texture_transform_coords_to_gl (CoglTexture *texture, - float *s, - float *t) -{ - texture->vtable->transform_coords_to_gl (texture, s, t); -} - -CoglTransformResult -_cogl_texture_transform_quad_coords_to_gl (CoglTexture *texture, - float *coords) -{ - return texture->vtable->transform_quad_coords_to_gl (texture, coords); -} - -gboolean -cogl_texture_get_gl_texture (CoglTexture *texture, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - if (!texture->allocated) - cogl_texture_allocate (texture, NULL); - - return texture->vtable->get_gl_texture (texture, - out_gl_handle, out_gl_target); -} - -void -_cogl_texture_pre_paint (CoglTexture *texture, CoglTexturePrePaintFlags flags) -{ - /* Assert that the storage for the texture exists already if we're - * about to reference it for painting. - * - * Note: we abort on error here since it's a bit late to do anything - * about it if we fail to allocate the texture and the app could - * have explicitly allocated the texture earlier to handle problems - * gracefully. - * - * XXX: Maybe it could even be considered a programmer error if the - * texture hasn't been allocated by this point since it implies we - * are about to paint with undefined texture contents? - */ - cogl_texture_allocate (texture, NULL); - - texture->vtable->pre_paint (texture, flags); -} - -void -_cogl_texture_ensure_non_quad_rendering (CoglTexture *texture) -{ - texture->vtable->ensure_non_quad_rendering (texture); -} - -gboolean -_cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bmp, - int dst_x, - int dst_y, - int level, - GError **error) -{ - g_return_val_if_fail (cogl_bitmap_get_width (bmp) - src_x >= width, FALSE); - g_return_val_if_fail (cogl_bitmap_get_height (bmp) - src_y >= height, FALSE); - g_return_val_if_fail (width > 0, FALSE); - g_return_val_if_fail (height > 0, FALSE); - - /* Assert that the storage for this texture has been allocated */ - if (!cogl_texture_allocate (texture, error)) - return FALSE; - - /* Note that we don't prepare the bitmap for upload here because - some backends may be internally using a different format for the - actual GL texture than that reported by - _cogl_texture_get_format. For example the atlas textures are - always stored in an RGBA texture even if the texture format is - advertised as RGB. */ - - return texture->vtable->set_region (texture, - src_x, src_y, - dst_x, dst_y, - width, height, - level, - bmp, - error); -} - -gboolean -cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bitmap) -{ - GError *ignore_error = NULL; - gboolean status = - _cogl_texture_set_region_from_bitmap (texture, - src_x, src_y, - dst_width, dst_height, - bitmap, - dst_x, dst_y, - 0, /* level */ - &ignore_error); - - g_clear_error (&ignore_error); - return status; -} - -gboolean -_cogl_texture_set_region (CoglTexture *texture, - int width, - int height, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int dst_x, - int dst_y, - int level, - GError **error) -{ - CoglContext *ctx = texture->context; - CoglBitmap *source_bmp; - gboolean ret; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - /* Rowstride from width if none specified */ - if (rowstride == 0) - rowstride = cogl_pixel_format_get_bytes_per_pixel (format, 0) * width; - - /* Init source bitmap */ - source_bmp = cogl_bitmap_new_for_data (ctx, - width, height, - format, - rowstride, - (uint8_t *) data); - - ret = _cogl_texture_set_region_from_bitmap (texture, - 0, 0, - width, height, - source_bmp, - dst_x, dst_y, - level, - error); - - cogl_object_unref (source_bmp); - - return ret; -} - -gboolean -cogl_texture_set_region (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - int width, - int height, - CoglPixelFormat format, - unsigned int rowstride, - const uint8_t *data) -{ - GError *ignore_error = NULL; - const uint8_t *first_pixel; - int bytes_per_pixel; - gboolean status; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - /* Rowstride from width if none specified */ - bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0); - if (rowstride == 0) - rowstride = bytes_per_pixel * width; - - first_pixel = data + rowstride * src_y + bytes_per_pixel * src_x; - - status = _cogl_texture_set_region (texture, - dst_width, - dst_height, - format, - rowstride, - first_pixel, - dst_x, - dst_y, - 0, - &ignore_error); - g_clear_error (&ignore_error); - return status; -} - -gboolean -cogl_texture_set_data (CoglTexture *texture, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int level, - GError **error) -{ - int level_width; - int level_height; - - _cogl_texture_get_level_size (texture, - level, - &level_width, - &level_height, - NULL); - - return _cogl_texture_set_region (texture, - level_width, - level_height, - format, - rowstride, - data, - 0, 0, /* dest x, y */ - level, - error); -} - -static gboolean -get_texture_bits_via_offscreen (CoglTexture *meta_texture, - CoglTexture *sub_texture, - int x, - int y, - int width, - int height, - uint8_t *dst_bits, - unsigned int dst_rowstride, - CoglPixelFormat closest_format) -{ - CoglContext *ctx = sub_texture->context; - CoglOffscreen *offscreen; - CoglFramebuffer *framebuffer; - CoglBitmap *bitmap; - gboolean ret; - GError *ignore_error = NULL; - CoglPixelFormat real_format; - - offscreen = _cogl_offscreen_new_with_texture_full - (sub_texture, - COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL, - 0); - - framebuffer = COGL_FRAMEBUFFER (offscreen); - if (!cogl_framebuffer_allocate (framebuffer, &ignore_error)) - { - g_error_free (ignore_error); - return FALSE; - } - - /* Currently the framebuffer's internal format corresponds to the - * internal format of @sub_texture but in the case of atlas textures - * it's possible that this format doesn't reflect the correct - * premultiplied alpha status or what components are valid since - * atlas textures are always stored in a shared texture with a - * format of _RGBA_8888. - * - * Here we override the internal format to make sure the - * framebuffer's internal format matches the internal format of the - * parent meta_texture instead. - */ - real_format = _cogl_texture_get_format (meta_texture); - _cogl_framebuffer_set_internal_format (framebuffer, real_format); - - bitmap = cogl_bitmap_new_for_data (ctx, - width, height, - closest_format, - dst_rowstride, - dst_bits); - ret = _cogl_framebuffer_read_pixels_into_bitmap (framebuffer, - x, y, - COGL_READ_PIXELS_COLOR_BUFFER, - bitmap, - &ignore_error); - - g_clear_error (&ignore_error); - - cogl_object_unref (bitmap); - - g_object_unref (framebuffer); - - return ret; -} - -static gboolean -get_texture_bits_via_copy (CoglTexture *texture, - int x, - int y, - int width, - int height, - uint8_t *dst_bits, - unsigned int dst_rowstride, - CoglPixelFormat dst_format) -{ - unsigned int full_rowstride; - uint8_t *full_bits; - gboolean ret = TRUE; - int bpp; - int full_tex_width, full_tex_height; - - g_return_val_if_fail (dst_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (dst_format) == 1, FALSE); - - full_tex_width = cogl_texture_get_width (texture); - full_tex_height = cogl_texture_get_height (texture); - - bpp = cogl_pixel_format_get_bytes_per_pixel (dst_format, 0); - - full_rowstride = bpp * full_tex_width; - full_bits = g_malloc (full_rowstride * full_tex_height); - - if (texture->vtable->get_data (texture, - dst_format, - full_rowstride, - full_bits)) - { - uint8_t *dst = dst_bits; - uint8_t *src = full_bits + x * bpp + y * full_rowstride; - int i; - - for (i = 0; i < height; i++) - { - memcpy (dst, src, bpp * width); - dst += dst_rowstride; - src += full_rowstride; - } - } - else - ret = FALSE; - - g_free (full_bits); - - return ret; -} - -typedef struct -{ - CoglTexture *meta_texture; - int orig_width; - int orig_height; - CoglBitmap *target_bmp; - uint8_t *target_bits; - gboolean success; - GError *error; -} CoglTextureGetData; - -static void -texture_get_cb (CoglTexture *subtexture, - const float *subtexture_coords, - const float *virtual_coords, - void *user_data) -{ - CoglTextureGetData *tg_data = user_data; - CoglTexture *meta_texture = tg_data->meta_texture; - CoglPixelFormat closest_format = cogl_bitmap_get_format (tg_data->target_bmp); - /* We already asserted that we have a single plane format */ - int bpp = cogl_pixel_format_get_bytes_per_pixel (closest_format, 0); - unsigned int rowstride = cogl_bitmap_get_rowstride (tg_data->target_bmp); - int subtexture_width = cogl_texture_get_width (subtexture); - int subtexture_height = cogl_texture_get_height (subtexture); - - int x_in_subtexture = (int) (0.5 + subtexture_width * subtexture_coords[0]); - int y_in_subtexture = (int) (0.5 + subtexture_height * subtexture_coords[1]); - int width = ((int) (0.5 + subtexture_width * subtexture_coords[2]) - - x_in_subtexture); - int height = ((int) (0.5 + subtexture_height * subtexture_coords[3]) - - y_in_subtexture); - int x_in_bitmap = (int) (0.5 + tg_data->orig_width * virtual_coords[0]); - int y_in_bitmap = (int) (0.5 + tg_data->orig_height * virtual_coords[1]); - - uint8_t *dst_bits; - - if (!tg_data->success) - return; - - dst_bits = tg_data->target_bits + x_in_bitmap * bpp + y_in_bitmap * rowstride; - - /* If we can read everything as a single slice, then go ahead and do that - * to avoid allocating an FBO. We'll leave it up to the GL implementation to - * do glGetTexImage as efficiently as possible. (GLES doesn't have that, - * so we'll fall through) - */ - if (x_in_subtexture == 0 && y_in_subtexture == 0 && - width == subtexture_width && height == subtexture_height) - { - if (subtexture->vtable->get_data (subtexture, - closest_format, - rowstride, - dst_bits)) - return; - } - - /* Next best option is a FBO and glReadPixels */ - if (get_texture_bits_via_offscreen (meta_texture, - subtexture, - x_in_subtexture, y_in_subtexture, - width, height, - dst_bits, - rowstride, - closest_format)) - return; - - /* Getting ugly: read the entire texture, copy out the part we want */ - if (get_texture_bits_via_copy (subtexture, - x_in_subtexture, y_in_subtexture, - width, height, - dst_bits, - rowstride, - closest_format)) - return; - - /* No luck, the caller will fall back to the draw-to-backbuffer and - * read implementation */ - tg_data->success = FALSE; -} - -int -cogl_texture_get_data (CoglTexture *texture, - CoglPixelFormat format, - unsigned int rowstride, - uint8_t *data) -{ - CoglContext *ctx = texture->context; - int bpp; - int byte_size; - CoglPixelFormat closest_format; - GLenum closest_gl_format; - GLenum closest_gl_type; - CoglBitmap *target_bmp; - int tex_width; - int tex_height; - CoglPixelFormat texture_format; - GError *ignore_error = NULL; - - CoglTextureGetData tg_data; - - texture_format = _cogl_texture_get_format (texture); - - /* Default to internal format if none specified */ - if (format == COGL_PIXEL_FORMAT_ANY) - format = texture_format; - - /* We only support single plane formats */ - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, 0); - - tex_width = cogl_texture_get_width (texture); - tex_height = cogl_texture_get_height (texture); - - /* Rowstride from texture width if none specified */ - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - if (rowstride == 0) - rowstride = tex_width * bpp; - - /* Return byte size if only that requested */ - byte_size = tex_height * rowstride; - if (data == NULL) - return byte_size; - - closest_format = - ctx->texture_driver->find_best_gl_get_data_format (ctx, - format, - &closest_gl_format, - &closest_gl_type); - - /* We can assume that whatever data GL gives us will have the - premult status of the original texture */ - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (closest_format)) - closest_format = ((closest_format & ~COGL_PREMULT_BIT) | - (texture_format & COGL_PREMULT_BIT)); - - /* If the application is requesting a conversion from a - * component-alpha texture and the driver doesn't support them - * natively then we can only read into an alpha-format buffer. In - * this case the driver will be faking the alpha textures with a - * red-component texture and it won't swizzle to the correct format - * while reading */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES)) - { - if (texture_format == COGL_PIXEL_FORMAT_A_8) - { - closest_format = COGL_PIXEL_FORMAT_A_8; - } - else if (format == COGL_PIXEL_FORMAT_A_8) - { - /* If we are converting to a component-alpha texture then we - * need to read all of the components to a temporary buffer - * because there is no way to get just the 4th component. - * Note: it doesn't matter whether the texture is - * pre-multiplied here because we're only going to look at - * the alpha component */ - closest_format = COGL_PIXEL_FORMAT_RGBA_8888; - } - } - - /* Is the requested format supported? */ - if (closest_format == format) - /* Target user data directly */ - target_bmp = cogl_bitmap_new_for_data (ctx, - tex_width, - tex_height, - format, - rowstride, - data); - else - { - target_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - tex_width, tex_height, - closest_format, - &ignore_error); - if (!target_bmp) - { - g_error_free (ignore_error); - return 0; - } - } - - tg_data.target_bits = _cogl_bitmap_map (target_bmp, COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - &ignore_error); - if (tg_data.target_bits) - { - tg_data.meta_texture = texture; - tg_data.orig_width = tex_width; - tg_data.orig_height = tex_height; - tg_data.target_bmp = target_bmp; - tg_data.error = NULL; - tg_data.success = TRUE; - - /* If there are any dependent framebuffers on the texture then we - need to flush their journals so the texture contents will be - up-to-date */ - _cogl_texture_flush_journal_rendering (texture); - - /* Iterating through the subtextures allows piecing together - * the data for a sliced texture, and allows us to do the - * read-from-framebuffer logic here in a simple fashion rather than - * passing offsets down through the code. */ - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture), - 0, 0, 1, 1, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - texture_get_cb, - &tg_data); - - _cogl_bitmap_unmap (target_bmp); - } - else - { - g_error_free (ignore_error); - tg_data.success = FALSE; - } - - /* XXX: In some cases this api may fail to read back the texture - * data; such as for GLES which doesn't support glGetTexImage - */ - if (!tg_data.success) - { - cogl_object_unref (target_bmp); - return 0; - } - - /* Was intermediate used? */ - if (closest_format != format) - { - CoglBitmap *new_bmp; - gboolean result; - GError *error = NULL; - - /* Convert to requested format directly into the user's buffer */ - new_bmp = cogl_bitmap_new_for_data (ctx, - tex_width, tex_height, - format, - rowstride, - data); - result = _cogl_bitmap_convert_into_bitmap (target_bmp, new_bmp, &error); - - if (!result) - { - g_error_free (error); - /* Return failure after cleaning up */ - byte_size = 0; - } - - cogl_object_unref (new_bmp); - } - - cogl_object_unref (target_bmp); - - return byte_size; -} - -static void -on_framebuffer_destroy (CoglFramebuffer *framebuffer, - CoglTexture *texture) -{ - texture->framebuffers = g_list_remove (texture->framebuffers, framebuffer); -} - -void -_cogl_texture_associate_framebuffer (CoglTexture *texture, - CoglFramebuffer *framebuffer) -{ - /* Note: we don't take a reference on the framebuffer here because - * that would introduce a circular reference. */ - texture->framebuffers = g_list_prepend (texture->framebuffers, framebuffer); - - g_signal_connect (framebuffer, "destroy", - G_CALLBACK (on_framebuffer_destroy), - texture); -} - -const GList * -_cogl_texture_get_associated_framebuffers (CoglTexture *texture) -{ - return texture->framebuffers; -} - -void -_cogl_texture_flush_journal_rendering (CoglTexture *texture) -{ - GList *l; - - /* It could be that a referenced texture is part of a framebuffer - * which has an associated journal that must be flushed before it - * can be sampled from by the current primitive... */ - for (l = texture->framebuffers; l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); -} - -/* This function lets you define a meta texture as a grid of textures - * whereby the x and y grid-lines are defined by an array of - * CoglSpans. With that grid based description this function can then - * iterate all the cells of the grid that lye within a region - * specified as virtual, meta-texture, coordinates. This function can - * also cope with regions that extend beyond the original meta-texture - * grid by iterating cells repeatedly according to the wrap_x/y - * arguments. - * - * To differentiate between texture coordinates of a specific, real, - * slice texture and the texture coordinates of a composite, meta - * texture, the coordinates of the meta texture are called "virtual" - * coordinates and the coordinates of spans are called "slice" - * coordinates. - * - * Note: no guarantee is given about the order in which the slices - * will be visited. - * - * Note: The slice coordinates passed to @callback are always - * normalized coordinates even if the span coordinates aren't - * normalized. - */ -void -_cogl_texture_spans_foreach_in_region (CoglSpan *x_spans, - int n_x_spans, - CoglSpan *y_spans, - int n_y_spans, - CoglTexture **textures, - float *virtual_coords, - float x_normalize_factor, - float y_normalize_factor, - CoglPipelineWrapMode wrap_x, - CoglPipelineWrapMode wrap_y, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglSpanIter iter_x; - CoglSpanIter iter_y; - float slice_coords[4]; - float span_virtual_coords[4]; - - /* Iterate the y axis of the virtual rectangle */ - for (_cogl_span_iter_begin (&iter_y, - y_spans, - n_y_spans, - y_normalize_factor, - virtual_coords[1], - virtual_coords[3], - wrap_y); - !_cogl_span_iter_end (&iter_y); - _cogl_span_iter_next (&iter_y)) - { - if (iter_y.flipped) - { - slice_coords[1] = iter_y.intersect_end; - slice_coords[3] = iter_y.intersect_start; - span_virtual_coords[1] = iter_y.intersect_end; - span_virtual_coords[3] = iter_y.intersect_start; - } - else - { - slice_coords[1] = iter_y.intersect_start; - slice_coords[3] = iter_y.intersect_end; - span_virtual_coords[1] = iter_y.intersect_start; - span_virtual_coords[3] = iter_y.intersect_end; - } - - /* Map the current intersection to normalized slice coordinates */ - slice_coords[1] = (slice_coords[1] - iter_y.pos) / iter_y.span->size; - slice_coords[3] = (slice_coords[3] - iter_y.pos) / iter_y.span->size; - - /* Iterate the x axis of the virtual rectangle */ - for (_cogl_span_iter_begin (&iter_x, - x_spans, - n_x_spans, - x_normalize_factor, - virtual_coords[0], - virtual_coords[2], - wrap_x); - !_cogl_span_iter_end (&iter_x); - _cogl_span_iter_next (&iter_x)) - { - CoglTexture *span_tex; - - if (iter_x.flipped) - { - slice_coords[0] = iter_x.intersect_end; - slice_coords[2] = iter_x.intersect_start; - span_virtual_coords[0] = iter_x.intersect_end; - span_virtual_coords[2] = iter_x.intersect_start; - } - else - { - slice_coords[0] = iter_x.intersect_start; - slice_coords[2] = iter_x.intersect_end; - span_virtual_coords[0] = iter_x.intersect_start; - span_virtual_coords[2] = iter_x.intersect_end; - } - - /* Map the current intersection to normalized slice coordinates */ - slice_coords[0] = (slice_coords[0] - iter_x.pos) / iter_x.span->size; - slice_coords[2] = (slice_coords[2] - iter_x.pos) / iter_x.span->size; - - /* Pluck out the cogl texture for this span */ - span_tex = textures[iter_y.index * n_x_spans + iter_x.index]; - - callback (COGL_TEXTURE (span_tex), - slice_coords, - span_virtual_coords, - user_data); - } - } -} - -void -_cogl_texture_set_allocated (CoglTexture *texture, - CoglPixelFormat internal_format, - int width, - int height) -{ - _cogl_texture_set_internal_format (texture, internal_format); - - texture->width = width; - texture->height = height; - texture->allocated = TRUE; - - _cogl_texture_free_loader (texture); -} - -gboolean -cogl_texture_allocate (CoglTexture *texture, - GError **error) -{ - if (texture->allocated) - return TRUE; - - if (texture->components == COGL_TEXTURE_COMPONENTS_RG && - !cogl_has_feature (texture->context, COGL_FEATURE_ID_TEXTURE_RG)) - g_set_error (error, - COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_FORMAT, - "A red-green texture was requested but the driver " - "does not support them"); - - texture->allocated = texture->vtable->allocate (texture, error); - - return texture->allocated; -} - -void -_cogl_texture_set_internal_format (CoglTexture *texture, - CoglPixelFormat internal_format) -{ - texture->premultiplied = FALSE; - - if (internal_format == COGL_PIXEL_FORMAT_ANY) - internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; - - if (internal_format == COGL_PIXEL_FORMAT_A_8) - { - texture->components = COGL_TEXTURE_COMPONENTS_A; - return; - } - else if (internal_format == COGL_PIXEL_FORMAT_RG_88) - { - texture->components = COGL_TEXTURE_COMPONENTS_RG; - return; - } - else if (internal_format & COGL_DEPTH_BIT) - { - texture->components = COGL_TEXTURE_COMPONENTS_DEPTH; - return; - } - else if (internal_format & COGL_A_BIT) - { - texture->components = COGL_TEXTURE_COMPONENTS_RGBA; - if (internal_format & COGL_PREMULT_BIT) - texture->premultiplied = TRUE; - return; - } - else - texture->components = COGL_TEXTURE_COMPONENTS_RGB; -} - -CoglPixelFormat -_cogl_texture_determine_internal_format (CoglTexture *texture, - CoglPixelFormat src_format) -{ - switch (texture->components) - { - case COGL_TEXTURE_COMPONENTS_DEPTH: - if (src_format & COGL_DEPTH_BIT) - return src_format; - else - { - CoglContext *ctx = texture->context; - - if (_cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || - _cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) - { - return COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8; - } - else - return COGL_PIXEL_FORMAT_DEPTH_16; - } - case COGL_TEXTURE_COMPONENTS_A: - return COGL_PIXEL_FORMAT_A_8; - case COGL_TEXTURE_COMPONENTS_RG: - return COGL_PIXEL_FORMAT_RG_88; - case COGL_TEXTURE_COMPONENTS_RGB: - if (src_format != COGL_PIXEL_FORMAT_ANY && - !(src_format & COGL_A_BIT) && !(src_format & COGL_DEPTH_BIT)) - return src_format; - else - return COGL_PIXEL_FORMAT_RGB_888; - case COGL_TEXTURE_COMPONENTS_RGBA: - { - CoglPixelFormat format; - - if (src_format != COGL_PIXEL_FORMAT_ANY && - (src_format & COGL_A_BIT) && src_format != COGL_PIXEL_FORMAT_A_8) - format = src_format; - else - format = COGL_PIXEL_FORMAT_RGBA_8888; - - if (texture->premultiplied) - { - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (format)) - return format |= COGL_PREMULT_BIT; - else - return COGL_PIXEL_FORMAT_RGBA_8888_PRE; - } - else - return format & ~COGL_PREMULT_BIT; - } - } - - g_return_val_if_reached (COGL_PIXEL_FORMAT_RGBA_8888_PRE); -} - -void -cogl_texture_set_components (CoglTexture *texture, - CoglTextureComponents components) -{ - g_return_if_fail (!texture->allocated); - - if (texture->components == components) - return; - - texture->components = components; -} - -CoglTextureComponents -cogl_texture_get_components (CoglTexture *texture) -{ - return texture->components; -} - -void -cogl_texture_set_premultiplied (CoglTexture *texture, - gboolean premultiplied) -{ - g_return_if_fail (!texture->allocated); - - premultiplied = !!premultiplied; - - if (texture->premultiplied == premultiplied) - return; - - texture->premultiplied = premultiplied; -} - -gboolean -cogl_texture_get_premultiplied (CoglTexture *texture) -{ - return texture->premultiplied; -} - -void -_cogl_texture_copy_internal_format (CoglTexture *src, - CoglTexture *dest) -{ - cogl_texture_set_components (dest, src->components); - cogl_texture_set_premultiplied (dest, src->premultiplied); -} diff --git a/cogl/cogl/cogl-texture.h b/cogl/cogl/cogl-texture.h deleted file mode 100644 index c86b4e3a5..000000000 --- a/cogl/cogl/cogl-texture.h +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_TEXTURE_H__ -#define __COGL_TEXTURE_H__ - -/* We forward declare the CoglTexture type here to avoid some circular - * dependency issues with the following headers. - */ -#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \ - !defined(COGL_GIR_SCANNING) -/* For the public C api we typedef interface types as void to avoid needing - * lots of casting in code and instead we will rely on runtime type checking - * for these objects. */ -typedef void CoglTexture; -#else -typedef struct _CoglTexture CoglTexture; -#define COGL_TEXTURE(X) ((CoglTexture *)X) -#endif - -#include <cogl/cogl-types.h> -#include <cogl/cogl-macros.h> -#include <cogl/cogl-defines.h> -#include <cogl/cogl-pixel-buffer.h> -#include <cogl/cogl-pixel-format.h> -#include <cogl/cogl-bitmap.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-texture - * @short_description: Functions for creating and manipulating textures - * - * Cogl allows creating and manipulating textures using a uniform - * API that tries to hide all the various complexities of creating, - * loading and manipulating textures. - */ - -#define COGL_TEXTURE_MAX_WASTE 127 - -/** - * cogl_texture_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_texture_get_gtype (void); - -/** - * COGL_TEXTURE_ERROR: - * - * #GError domain for texture errors. - * - * Since: 1.8 - * Stability: Unstable - */ -#define COGL_TEXTURE_ERROR (cogl_texture_error_quark ()) - -/** - * CoglTextureError: - * @COGL_TEXTURE_ERROR_SIZE: Unsupported size - * @COGL_TEXTURE_ERROR_FORMAT: Unsupported format - * @COGL_TEXTURE_ERROR_TYPE: A primitive texture type that is - * unsupported by the driver was used - * - * Error codes that can be thrown when allocating textures. - * - * Since: 1.8 - * Stability: Unstable - */ -typedef enum -{ - COGL_TEXTURE_ERROR_SIZE, - COGL_TEXTURE_ERROR_FORMAT, - COGL_TEXTURE_ERROR_BAD_PARAMETER, - COGL_TEXTURE_ERROR_TYPE -} CoglTextureError; - -COGL_EXPORT -uint32_t cogl_texture_error_quark (void); - -/** - * cogl_is_texture: - * @object: A #CoglObject pointer - * - * Gets whether the given object references a texture object. - * - * Return value: %TRUE if the @object references a texture, and - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_is_texture (void *object); - -/** - * CoglTextureComponents: - * @COGL_TEXTURE_COMPONENTS_A: Only the alpha component - * @COGL_TEXTURE_COMPONENTS_RG: Red and green components. Note that - * this can only be used if the %COGL_FEATURE_ID_TEXTURE_RG feature - * is advertised. - * @COGL_TEXTURE_COMPONENTS_RGB: Red, green and blue components - * @COGL_TEXTURE_COMPONENTS_RGBA: Red, green, blue and alpha components - * @COGL_TEXTURE_COMPONENTS_DEPTH: Only a depth component - * - * See cogl_texture_set_components(). - * - * Since: 1.18 - */ -typedef enum _CoglTextureComponents -{ - COGL_TEXTURE_COMPONENTS_A = 1, - COGL_TEXTURE_COMPONENTS_RG, - COGL_TEXTURE_COMPONENTS_RGB, - COGL_TEXTURE_COMPONENTS_RGBA, - COGL_TEXTURE_COMPONENTS_DEPTH -} CoglTextureComponents; - -/** - * cogl_texture_set_components: - * @texture: a #CoglTexture pointer. - * - * Affects the internal storage format for this texture by specifying - * what components will be required for sampling later. - * - * This api affects how data is uploaded to the GPU since unused - * components can potentially be discarded from source data. - * - * For textures created by the ‘_with_size’ constructors the default - * is %COGL_TEXTURE_COMPONENTS_RGBA. The other constructors which take - * a %CoglBitmap or a data pointer default to the same components as - * the pixel format of the data. - * - * Note that the %COGL_TEXTURE_COMPONENTS_RG format is not available - * on all drivers. The availability can be determined by checking for - * the %COGL_FEATURE_ID_TEXTURE_RG feature. If this format is used on - * a driver where it is not available then %COGL_TEXTURE_ERROR_FORMAT - * will be raised when the texture is allocated. Even if the feature - * is not available then %COGL_PIXEL_FORMAT_RG_88 can still be used as - * an image format as long as %COGL_TEXTURE_COMPONENTS_RG isn't used - * as the texture's components. - * - * Since: 1.18 - */ -COGL_EXPORT void -cogl_texture_set_components (CoglTexture *texture, - CoglTextureComponents components); - -/** - * cogl_texture_get_components: - * @texture: a #CoglTexture pointer. - * - * Queries what components the given @texture stores internally as set - * via cogl_texture_set_components(). - * - * For textures created by the ‘_with_size’ constructors the default - * is %COGL_TEXTURE_COMPONENTS_RGBA. The other constructors which take - * a %CoglBitmap or a data pointer default to the same components as - * the pixel format of the data. - * - * Since: 1.18 - */ -COGL_EXPORT CoglTextureComponents -cogl_texture_get_components (CoglTexture *texture); - -/** - * cogl_texture_set_premultiplied: - * @texture: a #CoglTexture pointer. - * @premultiplied: Whether any internally stored red, green or blue - * components are pre-multiplied by an alpha - * component. - * - * Affects the internal storage format for this texture by specifying - * whether red, green and blue color components should be stored as - * pre-multiplied alpha values. - * - * This api affects how data is uploaded to the GPU since Cogl will - * convert source data to have premultiplied or unpremultiplied - * components according to this state. - * - * For example if you create a texture via - * cogl_texture_2d_new_with_size() and then upload data via - * cogl_texture_set_data() passing a source format of - * %COGL_PIXEL_FORMAT_RGBA_8888 then Cogl will internally multiply the - * red, green and blue components of the source data by the alpha - * component, for each pixel so that the internally stored data has - * pre-multiplied alpha components. If you instead upload data that - * already has pre-multiplied components by passing - * %COGL_PIXEL_FORMAT_RGBA_8888_PRE as the source format to - * cogl_texture_set_data() then the data can be uploaded without being - * converted. - * - * By default the @premultipled state is @TRUE. - * - * Since: 1.18 - */ -COGL_EXPORT void -cogl_texture_set_premultiplied (CoglTexture *texture, - gboolean premultiplied); - -/** - * cogl_texture_get_premultiplied: - * @texture: a #CoglTexture pointer. - * - * Queries the pre-multiplied alpha status for internally stored red, - * green and blue components for the given @texture as set by - * cogl_texture_set_premultiplied(). - * - * By default the pre-multipled state is @TRUE. - * - * Return value: %TRUE if red, green and blue components are - * internally stored pre-multiplied by the alpha - * value or %FALSE if not. - * Since: 1.18 - */ -COGL_EXPORT gboolean -cogl_texture_get_premultiplied (CoglTexture *texture); - -/** - * cogl_texture_get_width: - * @texture: a #CoglTexture pointer. - * - * Queries the width of a cogl texture. - * - * Return value: the width of the GPU side texture in pixels - */ -COGL_EXPORT unsigned int -cogl_texture_get_width (CoglTexture *texture); - -/** - * cogl_texture_get_height: - * @texture: a #CoglTexture pointer. - * - * Queries the height of a cogl texture. - * - * Return value: the height of the GPU side texture in pixels - */ -COGL_EXPORT unsigned int -cogl_texture_get_height (CoglTexture *texture); - -/** - * cogl_texture_get_max_waste: - * @texture: a #CoglTexture pointer. - * - * Queries the maximum wasted (unused) pixels in one dimension of a GPU side - * texture. - * - * Return value: the maximum waste - */ -COGL_EXPORT int -cogl_texture_get_max_waste (CoglTexture *texture); - -/** - * cogl_texture_is_sliced: - * @texture: a #CoglTexture pointer. - * - * Queries if a texture is sliced (stored as multiple GPU side tecture - * objects). - * - * Return value: %TRUE if the texture is sliced, %FALSE if the texture - * is stored as a single GPU texture - */ -COGL_EXPORT gboolean -cogl_texture_is_sliced (CoglTexture *texture); - -/** - * cogl_texture_get_gl_texture: - * @texture: a #CoglTexture pointer. - * @out_gl_handle: (out) (allow-none): pointer to return location for the - * textures GL handle, or %NULL. - * @out_gl_target: (out) (allow-none): pointer to return location for the - * GL target type, or %NULL. - * - * Queries the GL handles for a GPU side texture through its #CoglTexture. - * - * If the texture is spliced the data for the first sub texture will be - * queried. - * - * Return value: %TRUE if the handle was successfully retrieved, %FALSE - * if the handle was invalid - */ -COGL_EXPORT gboolean -cogl_texture_get_gl_texture (CoglTexture *texture, - unsigned int *out_gl_handle, - unsigned int *out_gl_target); - -/** - * cogl_texture_get_data: - * @texture: a #CoglTexture pointer. - * @format: the #CoglPixelFormat to store the texture as. - * @rowstride: the rowstride of @data in bytes or pass 0 to calculate - * from the bytes-per-pixel of @format multiplied by the - * @texture width. - * @data: (array) (nullable): memory location to write the @texture's contents, - * or %NULL to only query the data size through the return value. - * - * Copies the pixel data from a cogl texture to system memory. - * - * <note>Don't pass the value of cogl_texture_get_rowstride() as the - * @rowstride argument, the rowstride should be the rowstride you - * want for the destination @data buffer not the rowstride of the - * source texture</note> - * - * Return value: the size of the texture data in bytes - */ -COGL_EXPORT int -cogl_texture_get_data (CoglTexture *texture, - CoglPixelFormat format, - unsigned int rowstride, - uint8_t *data); - -/** - * cogl_texture_set_region: - * @texture: a #CoglTexture. - * @src_x: upper left coordinate to use from source data. - * @src_y: upper left coordinate to use from source data. - * @dst_x: upper left destination horizontal coordinate. - * @dst_y: upper left destination vertical coordinate. - * @dst_width: width of destination region to write. (Must be less - * than or equal to @width) - * @dst_height: height of destination region to write. (Must be less - * than or equal to @height) - * @width: width of source data buffer. - * @height: height of source data buffer. - * @format: the #CoglPixelFormat used in the source buffer. - * @rowstride: rowstride of source buffer (computed from width if none - * specified) - * @data: (array): the actual pixel data. - * - * Sets the pixels in a rectangular subregion of @texture from an in-memory - * buffer containing pixel data. - * - * <note>The region set can't be larger than the source @data</note> - * - * Return value: %TRUE if the subregion upload was successful, and - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_set_region (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - int width, - int height, - CoglPixelFormat format, - unsigned int rowstride, - const uint8_t *data); - -/** - * cogl_texture_set_data: - * @texture a #CoglTexture. - * @format: the #CoglPixelFormat used in the source @data buffer. - * @rowstride: rowstride of the source @data buffer (computed from - * the texture width and @format if it equals 0) - * @data: (array): the source data, pointing to the first top-left pixel to set - * @level: The mipmap level to update (Normally 0 for the largest, - * base texture) - * @error: A #GError to return exceptional errors - * - * Sets all the pixels for a given mipmap @level by copying the pixel - * data pointed to by the @data argument into the given @texture. - * - * @data should point to the first pixel to copy corresponding - * to the top left of the mipmap @level being set. - * - * If @rowstride equals 0 then it will be automatically calculated - * from the width of the mipmap level and the bytes-per-pixel for the - * given @format. - * - * A mipmap @level of 0 corresponds to the largest, base image of a - * texture and @level 1 is half the width and height of level 0. If - * dividing any dimension of the previous level by two results in a - * fraction then round the number down (floor()), but clamp to 1 - * something like this: - * - * |[ - * next_width = MAX (1, floor (prev_width)); - * ]| - * - * You can determine the number of mipmap levels for a given texture - * like this: - * - * |[ - * n_levels = 1 + floor (log2 (max_dimension)); - * ]| - * - * Where %max_dimension is the larger of cogl_texture_get_width() and - * cogl_texture_get_height(). - * - * It is an error to pass a @level number >= the number of levels that - * @texture can have according to the above calculation. - * - * <note>Since the storage for a #CoglTexture is allocated lazily then - * if the given @texture has not previously been allocated then this - * api can return %FALSE and throw an exceptional @error if there is - * not enough memory to allocate storage for @texture.</note> - * - * Return value: %TRUE if the data upload was successful, and - * %FALSE otherwise - */ -COGL_EXPORT gboolean -cogl_texture_set_data (CoglTexture *texture, - CoglPixelFormat format, - int rowstride, - const uint8_t *data, - int level, - GError **error); - -/** - * cogl_texture_set_region_from_bitmap: - * @texture: a #CoglTexture pointer - * @src_x: upper left coordinate to use from the source bitmap. - * @src_y: upper left coordinate to use from the source bitmap - * @dst_x: upper left destination horizontal coordinate. - * @dst_y: upper left destination vertical coordinate. - * @dst_width: width of destination region to write. (Must be less - * than or equal to the bitmap width) - * @dst_height: height of destination region to write. (Must be less - * than or equal to the bitmap height) - * @bitmap: The source bitmap to read from - * - * Copies a specified source region from @bitmap to the position - * (@src_x, @src_y) of the given destination texture @handle. - * - * <note>The region updated can't be larger than the source - * bitmap</note> - * - * Return value: %TRUE if the subregion upload was successful, and - * %FALSE otherwise - * - * Since: 1.8 - * Stability: unstable - */ -COGL_EXPORT gboolean -cogl_texture_set_region_from_bitmap (CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - unsigned int dst_width, - unsigned int dst_height, - CoglBitmap *bitmap); - -/** - * cogl_texture_allocate: - * @texture: A #CoglTexture - * @error: A #GError to return exceptional errors or %NULL - * - * Explicitly allocates the storage for the given @texture which - * allows you to be sure that there is enough memory for the - * texture and if not then the error can be handled gracefully. - * - * <note>Normally applications don't need to use this api directly - * since the texture will be implicitly allocated when data is set on - * the texture, or if the texture is attached to a #CoglOffscreen - * framebuffer and rendered too.</note> - * - * Return value: %TRUE if the texture was successfully allocated, - * otherwise %FALSE and @error will be updated if it - * wasn't %NULL. - */ -COGL_EXPORT gboolean -cogl_texture_allocate (CoglTexture *texture, - GError **error); - -/** - * cogl_texture_is_get_data_supported: (skip) - */ -COGL_EXPORT gboolean -cogl_texture_is_get_data_supported (CoglTexture *texture); - -G_END_DECLS - -#endif /* __COGL_TEXTURE_H__ */ diff --git a/cogl/cogl/cogl-trace.c b/cogl/cogl/cogl-trace.c deleted file mode 100644 index 80c3da77f..000000000 --- a/cogl/cogl/cogl-trace.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2018 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#include "cogl-config.h" - -#include "cogl/cogl-trace.h" - -#ifdef HAVE_TRACING - -#include <sysprof-capture.h> -#include <sysprof-capture-writer.h> -#include <sysprof-clock.h> -#include <syscall.h> -#include <sys/types.h> -#include <unistd.h> - -#define COGL_TRACE_OUTPUT_FILE "cogl-trace-sp-capture.syscap" -#define BUFFER_LENGTH (4096 * 4) - -struct _CoglTraceContext -{ - SysprofCaptureWriter *writer; -}; - -typedef struct _CoglTraceThreadContext -{ - int cpu_id; - GPid pid; - char *group; -} CoglTraceThreadContext; - -typedef struct -{ - int fd; - char *filename; - char *group; -} TraceData; - -static void -trace_data_free (gpointer user_data) -{ - TraceData *data = user_data; - - data->fd = -1; - g_clear_pointer (&data->group, g_free); - g_clear_pointer (&data->filename, g_free); - g_free (data); -} - -static void cogl_trace_thread_context_free (gpointer data); - -GPrivate cogl_trace_thread_data = G_PRIVATE_INIT (cogl_trace_thread_context_free); -CoglTraceContext *cogl_trace_context; -GMutex cogl_trace_mutex; - -static CoglTraceContext * -cogl_trace_context_new (int fd, - const char *filename) -{ - CoglTraceContext *context; - SysprofCaptureWriter *writer; - - if (fd != -1) - { - g_debug ("Initializing trace context with fd=%d", fd); - writer = sysprof_capture_writer_new_from_fd (fd, BUFFER_LENGTH); - } - else if (filename != NULL) - { - g_debug ("Initializing trace context with filename='%s'", filename); - writer = sysprof_capture_writer_new (filename, BUFFER_LENGTH); - } - else - { - g_debug ("Initializing trace context with default filename"); - writer = sysprof_capture_writer_new (COGL_TRACE_OUTPUT_FILE, BUFFER_LENGTH); - } - - context = g_new0 (CoglTraceContext, 1); - context->writer = writer; - return context; -} - -static void -cogl_trace_context_free (CoglTraceContext *trace_context) -{ - g_clear_pointer (&trace_context->writer, sysprof_capture_writer_unref); - g_free (trace_context); -} - -static void -ensure_trace_context (TraceData *data) -{ - g_mutex_lock (&cogl_trace_mutex); - if (!cogl_trace_context) - cogl_trace_context = cogl_trace_context_new (data->fd, data->filename); - g_mutex_unlock (&cogl_trace_mutex); -} - -static CoglTraceThreadContext * -cogl_trace_thread_context_new (const char *group) -{ - CoglTraceThreadContext *thread_context; - pid_t tid; - - tid = (pid_t) syscall (SYS_gettid); - - thread_context = g_new0 (CoglTraceThreadContext, 1); - thread_context->cpu_id = -1; - thread_context->pid = getpid (); - thread_context->group = - group ? g_strdup (group) : g_strdup_printf ("t:%d", tid); - - return thread_context; -} - -static gboolean -enable_tracing_idle_callback (gpointer user_data) -{ - CoglTraceThreadContext *thread_context = - g_private_get (&cogl_trace_thread_data); - TraceData *data = user_data; - - ensure_trace_context (data); - - if (thread_context) - { - g_warning ("Tracing already enabled"); - return G_SOURCE_REMOVE; - } - - thread_context = cogl_trace_thread_context_new (data->group); - g_private_set (&cogl_trace_thread_data, thread_context); - - return G_SOURCE_REMOVE; -} - -static void -cogl_trace_thread_context_free (gpointer data) -{ - CoglTraceThreadContext *thread_context = data; - - if (!thread_context) - return; - - g_free (thread_context->group); - g_free (thread_context); -} - -static gboolean -disable_tracing_idle_callback (gpointer user_data) -{ - CoglTraceThreadContext *thread_context = - g_private_get (&cogl_trace_thread_data); - CoglTraceContext *trace_context; - - if (!thread_context) - { - g_warning ("Tracing not enabled"); - return G_SOURCE_REMOVE; - } - - g_private_replace (&cogl_trace_thread_data, NULL); - - g_mutex_lock (&cogl_trace_mutex); - trace_context = cogl_trace_context; - sysprof_capture_writer_flush (trace_context->writer); - - g_clear_pointer (&cogl_trace_context, cogl_trace_context_free); - - g_mutex_unlock (&cogl_trace_mutex); - - return G_SOURCE_REMOVE; -} - -static void -set_tracing_enabled_on_thread (GMainContext *main_context, - const char *group, - int fd, - const char *filename) -{ - TraceData *data; - GSource *source; - - data = g_new0 (TraceData, 1); - data->fd = fd; - data->group = group ? strdup (group) : NULL; - data->filename = filename ? strdup (filename) : NULL; - - source = g_idle_source_new (); - - g_source_set_callback (source, - enable_tracing_idle_callback, - data, - trace_data_free); - - g_source_attach (source, main_context); - g_source_unref (source); -} - -void -cogl_set_tracing_enabled_on_thread_with_fd (GMainContext *main_context, - const char *group, - int fd) -{ - set_tracing_enabled_on_thread (main_context, group, fd, NULL); -} - -void -cogl_set_tracing_enabled_on_thread (GMainContext *main_context, - const char *group, - const char *filename) -{ - set_tracing_enabled_on_thread (main_context, group, -1, filename); -} - -void -cogl_set_tracing_disabled_on_thread (GMainContext *main_context) -{ - GSource *source; - - source = g_idle_source_new (); - - g_source_set_callback (source, disable_tracing_idle_callback, NULL, NULL); - - g_source_attach (source, main_context); - g_source_unref (source); -} - -void -cogl_trace_end (CoglTraceHead *head) -{ - SysprofTimeStamp end_time; - CoglTraceContext *trace_context; - CoglTraceThreadContext *trace_thread_context; - - end_time = g_get_monotonic_time () * 1000; - trace_context = cogl_trace_context; - trace_thread_context = g_private_get (&cogl_trace_thread_data); - - g_mutex_lock (&cogl_trace_mutex); - if (!sysprof_capture_writer_add_mark (trace_context->writer, - head->begin_time, - trace_thread_context->cpu_id, - trace_thread_context->pid, - (uint64_t) end_time - head->begin_time, - trace_thread_context->group, - head->name, - NULL)) - { - /* XXX: g_main_context_get_thread_default() might be wrong, it probably - * needs to store the GMainContext in CoglTraceThreadContext when creating - * and use it here. - */ - if (errno == EPIPE) - cogl_set_tracing_disabled_on_thread (g_main_context_get_thread_default ()); - } - g_mutex_unlock (&cogl_trace_mutex); -} - -#else - -#include <string.h> -#include <stdio.h> - -void -cogl_set_tracing_enabled_on_thread_with_fd (void *data, - const char *group, - int fd) -{ - fprintf (stderr, "Tracing not enabled"); -} - -void -cogl_set_tracing_enabled_on_thread (void *data, - const char *group, - const char *filename) -{ - fprintf (stderr, "Tracing not enabled"); -} - -void -cogl_set_tracing_disabled_on_thread (void *data) -{ - fprintf (stderr, "Tracing not enabled"); -} - -#endif /* HAVE_TRACING */ diff --git a/cogl/cogl/cogl-trace.h b/cogl/cogl/cogl-trace.h deleted file mode 100644 index 2900da095..000000000 --- a/cogl/cogl/cogl-trace.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2018 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * SPDX-License-Identifier: MIT - * - */ - -#ifndef COGL_TRACE_H -#define COGL_TRACE_H - -#include <glib.h> -#include <stdint.h> -#include <errno.h> - -#include "cogl/cogl-defines.h" -#include "cogl/cogl-macros.h" - -#ifdef COGL_HAS_TRACING - -typedef struct _CoglTraceContext CoglTraceContext; - -typedef struct _CoglTraceHead -{ - uint64_t begin_time; - const char *name; -} CoglTraceHead; - -COGL_EXPORT -GPrivate cogl_trace_thread_data; -COGL_EXPORT -CoglTraceContext *cogl_trace_context; -COGL_EXPORT -GMutex cogl_trace_mutex; - -COGL_EXPORT void -cogl_set_tracing_enabled_on_thread_with_fd (GMainContext *main_context, - const char *group, - int fd); - -COGL_EXPORT void -cogl_set_tracing_enabled_on_thread (GMainContext *main_context, - const char *group, - const char *filename); - -COGL_EXPORT void -cogl_set_tracing_disabled_on_thread (GMainContext *main_context); - -static inline void -cogl_trace_begin (CoglTraceHead *head, - const char *name) -{ - head->begin_time = g_get_monotonic_time () * 1000; - head->name = name; -} - -COGL_EXPORT void -cogl_trace_end (CoglTraceHead *head); - -static inline void -cogl_auto_trace_end_helper (CoglTraceHead **head) -{ - if (*head) - cogl_trace_end (*head); -} - -#define COGL_TRACE_BEGIN(Name, description) \ - CoglTraceHead CoglTrace##Name = { 0 }; \ - if (g_private_get (&cogl_trace_thread_data)) \ - cogl_trace_begin (&CoglTrace##Name, description); \ - -#define COGL_TRACE_END(Name)\ - if (g_private_get (&cogl_trace_thread_data)) \ - cogl_trace_end (&CoglTrace##Name); - -#define COGL_TRACE_BEGIN_SCOPED(Name, description) \ - CoglTraceHead CoglTrace##Name = { 0 }; \ - __attribute__((cleanup (cogl_auto_trace_end_helper))) \ - CoglTraceHead *ScopedCoglTrace##Name = NULL; \ - if (g_private_get (&cogl_trace_thread_data)) \ - { \ - cogl_trace_begin (&CoglTrace##Name, description); \ - ScopedCoglTrace##Name = &CoglTrace##Name; \ - } - -#else /* COGL_HAS_TRACING */ - -#include <stdio.h> - -#define COGL_TRACE_BEGIN(Name, description) (void) 0 -#define COGL_TRACE_END(Name) (void) 0 -#define COGL_TRACE_BEGIN_SCOPED(Name, description) (void) 0 - -COGL_EXPORT void -cogl_set_tracing_enabled_on_thread_with_fd (void *data, - const char *group, - int fd); -COGL_EXPORT void -cogl_set_tracing_enabled_on_thread (void *data, - const char *group, - const char *filename); -COGL_EXPORT void -cogl_set_tracing_disabled_on_thread (void *data); - -#endif /* COGL_HAS_TRACING */ - -#endif /* COGL_TRACE_H */ diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h deleted file mode 100644 index cd92b2ecd..000000000 --- a/cogl/cogl/cogl-types.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_TYPES_H__ -#define __COGL_TYPES_H__ - -#include <stdint.h> -#include <stddef.h> - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-macros.h> -#include <graphene.h> - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-types - * @short_description: Types used throughout the library - * - * General types used by various Cogl functions. -*/ - -/* Some structures are meant to be opaque but they have public - definitions because we want the size to be public so they can be - allocated on the stack. This macro is used to ensure that users - don't accidentally access private members */ -#ifdef COGL_COMPILATION -#define COGL_PRIVATE(x) x -#else -#define COGL_PRIVATE(x) private_member_ ## x -#endif - -/* To help catch accidental changes to public structs that should - * be stack allocated we use this macro to compile time assert that - * a struct size is as expected. - */ -#define COGL_STRUCT_SIZE_ASSERT(TYPE, SIZE) \ -typedef struct { \ - char compile_time_assert_ ## TYPE ## _size[ \ - (sizeof (TYPE) == (SIZE)) ? 1 : -1]; \ - } _ ## TYPE ## SizeCheck - -/** - * CoglHandle: - * - * Type used for storing references to cogl objects, the CoglHandle is - * a fully opaque type without any public data members. - */ -typedef void * CoglHandle; - -#define COGL_TYPE_HANDLE (cogl_handle_get_type ()) -COGL_EXPORT GType -cogl_handle_get_type (void) G_GNUC_CONST; - -typedef struct _CoglFramebuffer CoglFramebuffer; - -/** - * CoglAngle: - * - * Integer representation of an angle such that 1024 corresponds to - * full circle (i.e., 2 * pi). - * - * Since: 1.0 - */ -typedef int32_t CoglAngle; - -typedef struct _CoglColor CoglColor; -typedef struct _CoglTextureVertex CoglTextureVertex; - -/** - * CoglDmaBufHandle: (skip) - * - * An opaque type that tracks the lifetime of a DMA buffer fd. Release - * with cogl_dma_buf_handle_free(). - */ -typedef struct _CoglDmaBufHandle CoglDmaBufHandle; - -/* Enum declarations */ - -#define COGL_A_BIT (1 << 4) -#define COGL_BGR_BIT (1 << 5) -#define COGL_AFIRST_BIT (1 << 6) -#define COGL_PREMULT_BIT (1 << 7) -#define COGL_DEPTH_BIT (1 << 8) -#define COGL_STENCIL_BIT (1 << 9) - -/** - * CoglBufferTarget: - * @COGL_WINDOW_BUFFER: FIXME - * @COGL_OFFSCREEN_BUFFER: FIXME - * - * Target flags for FBOs. - * - * Since: 0.8 - */ -typedef enum -{ - COGL_WINDOW_BUFFER = (1 << 1), - COGL_OFFSCREEN_BUFFER = (1 << 2) -} CoglBufferTarget; - -/** - * CoglColor: - * @red: amount of red - * @green: amount of green - * @blue: amount of green - * @alpha: alpha - * - * A structure for holding a color definition. The contents of - * the CoglColor structure are private and should never by accessed - * directly. - * - * Since: 1.0 - */ -struct _CoglColor -{ - /*< private >*/ - uint8_t COGL_PRIVATE (red); - uint8_t COGL_PRIVATE (green); - uint8_t COGL_PRIVATE (blue); - - uint8_t COGL_PRIVATE (alpha); - - /* padding in case we want to change to floats at - * some point */ - uint32_t COGL_PRIVATE (padding0); - uint32_t COGL_PRIVATE (padding1); - uint32_t COGL_PRIVATE (padding2); -}; -COGL_STRUCT_SIZE_ASSERT (CoglColor, 16); - -/** - * CoglTextureVertex: - * @x: Model x-coordinate - * @y: Model y-coordinate - * @z: Model z-coordinate - * @tx: Texture x-coordinate - * @ty: Texture y-coordinate - * @color: The color to use at this vertex. This is ignored if - * use_color is %FALSE when calling cogl_polygon() - * - * Used to specify vertex information when calling cogl_polygon() - */ -struct _CoglTextureVertex -{ - float x, y, z; - float tx, ty; - - CoglColor color; -}; -COGL_STRUCT_SIZE_ASSERT (CoglTextureVertex, 36); - -/** - * CoglTextureFlags: - * @COGL_TEXTURE_NONE: No flags specified - * @COGL_TEXTURE_NO_AUTO_MIPMAP: Disables the automatic generation of - * the mipmap pyramid from the base level image whenever it is - * updated. The mipmaps are only generated when the texture is - * rendered with a mipmap filter so it should be free to leave out - * this flag when using other filtering modes - * @COGL_TEXTURE_NO_SLICING: Disables the slicing of the texture - * @COGL_TEXTURE_NO_ATLAS: Disables the insertion of the texture inside - * the texture atlas used by Cogl - * - * Flags to pass to the cogl_texture_new_* family of functions. - * - * Since: 1.0 - */ -typedef enum -{ - COGL_TEXTURE_NONE = 0, - COGL_TEXTURE_NO_AUTO_MIPMAP = 1 << 0, - COGL_TEXTURE_NO_SLICING = 1 << 1, - COGL_TEXTURE_NO_ATLAS = 1 << 2 -} CoglTextureFlags; - -/** - * COGL_BLEND_STRING_ERROR: - * - * #GError domain for blend string parser errors - * - * Since: 1.0 - */ -#define COGL_BLEND_STRING_ERROR (cogl_blend_string_error_quark ()) - -/** - * CoglBlendStringError: - * @COGL_BLEND_STRING_ERROR_PARSE_ERROR: Generic parse error - * @COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR: Argument parse error - * @COGL_BLEND_STRING_ERROR_INVALID_ERROR: Internal parser error - * @COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR: Blend string not - * supported by the GPU - * - * Error enumeration for the blend strings parser - * - * Since: 1.0 - */ -typedef enum /*< prefix=COGL_BLEND_STRING_ERROR >*/ -{ - COGL_BLEND_STRING_ERROR_PARSE_ERROR, - COGL_BLEND_STRING_ERROR_ARGUMENT_PARSE_ERROR, - COGL_BLEND_STRING_ERROR_INVALID_ERROR, - COGL_BLEND_STRING_ERROR_GPU_UNSUPPORTED_ERROR -} CoglBlendStringError; - -COGL_EXPORT uint32_t -cogl_blend_string_error_quark (void); - -#define COGL_SYSTEM_ERROR (_cogl_system_error_quark ()) - -/** - * CoglSystemError: - * @COGL_SYSTEM_ERROR_UNSUPPORTED: You tried to use a feature or - * configuration not currently available. - * @COGL_SYSTEM_ERROR_NO_MEMORY: You tried to allocate a resource - * such as a texture and there wasn't enough memory. - * - * Error enumeration for Cogl - * - * The @COGL_SYSTEM_ERROR_UNSUPPORTED error can be thrown for a - * variety of reasons. For example: - * - * <itemizedlist> - * <listitem><para>You've tried to use a feature that is not - * advertised by cogl_has_feature().</para></listitem> - * <listitem><para>The GPU can not handle the configuration you have - * requested. An example might be if you try to use too many texture - * layers in a single #CoglPipeline</para></listitem> - * <listitem><para>The driver does not support some - * configuration.</para></listiem> - * </itemizedlist> - * - * Currently this is only used by Cogl API marked as experimental so - * this enum should also be considered experimental. - * - * Since: 1.4 - * Stability: unstable - */ -typedef enum /*< prefix=COGL_ERROR >*/ -{ - COGL_SYSTEM_ERROR_UNSUPPORTED, - COGL_SYSTEM_ERROR_NO_MEMORY -} CoglSystemError; - -COGL_EXPORT uint32_t -_cogl_system_error_quark (void); - -/** - * CoglAttributeType: - * @COGL_ATTRIBUTE_TYPE_BYTE: Data is the same size of a byte - * @COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE: Data is the same size of an - * unsigned byte - * @COGL_ATTRIBUTE_TYPE_SHORT: Data is the same size of a short integer - * @COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT: Data is the same size of - * an unsigned short integer - * @COGL_ATTRIBUTE_TYPE_FLOAT: Data is the same size of a float - * - * Data types for the components of a vertex attribute. - * - * Since: 1.0 - */ -typedef enum -{ - COGL_ATTRIBUTE_TYPE_BYTE = 0x1400, - COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE = 0x1401, - COGL_ATTRIBUTE_TYPE_SHORT = 0x1402, - COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT = 0x1403, - COGL_ATTRIBUTE_TYPE_FLOAT = 0x1406 -} CoglAttributeType; - -/** - * CoglIndicesType: - * @COGL_INDICES_TYPE_UNSIGNED_BYTE: Your indices are unsigned bytes - * @COGL_INDICES_TYPE_UNSIGNED_SHORT: Your indices are unsigned shorts - * @COGL_INDICES_TYPE_UNSIGNED_INT: Your indices are unsigned ints - * - * You should aim to use the smallest data type that gives you enough - * range, since it reduces the size of your index array and can help - * reduce the demand on memory bandwidth. - * - * Note that %COGL_INDICES_TYPE_UNSIGNED_INT is only supported if the - * %COGL_FEATURE_ID_UNSIGNED_INT_INDICES feature is available. This - * should always be available on OpenGL but on OpenGL ES it will only - * be available if the GL_OES_element_index_uint extension is - * advertized. - */ -typedef enum -{ - COGL_INDICES_TYPE_UNSIGNED_BYTE, - COGL_INDICES_TYPE_UNSIGNED_SHORT, - COGL_INDICES_TYPE_UNSIGNED_INT -} CoglIndicesType; - -/** - * CoglVerticesMode: - * @COGL_VERTICES_MODE_POINTS: FIXME, equivalent to - * <constant>GL_POINTS</constant> - * @COGL_VERTICES_MODE_LINES: FIXME, equivalent to <constant>GL_LINES</constant> - * @COGL_VERTICES_MODE_LINE_LOOP: FIXME, equivalent to - * <constant>GL_LINE_LOOP</constant> - * @COGL_VERTICES_MODE_LINE_STRIP: FIXME, equivalent to - * <constant>GL_LINE_STRIP</constant> - * @COGL_VERTICES_MODE_TRIANGLES: FIXME, equivalent to - * <constant>GL_TRIANGLES</constant> - * @COGL_VERTICES_MODE_TRIANGLE_STRIP: FIXME, equivalent to - * <constant>GL_TRIANGLE_STRIP</constant> - * @COGL_VERTICES_MODE_TRIANGLE_FAN: FIXME, equivalent to <constant>GL_TRIANGLE_FAN</constant> - * - * Different ways of interpreting vertices when drawing. - * - * Since: 1.0 - */ -typedef enum -{ - COGL_VERTICES_MODE_POINTS = 0x0000, - COGL_VERTICES_MODE_LINES = 0x0001, - COGL_VERTICES_MODE_LINE_LOOP = 0x0002, - COGL_VERTICES_MODE_LINE_STRIP = 0x0003, - COGL_VERTICES_MODE_TRIANGLES = 0x0004, - COGL_VERTICES_MODE_TRIANGLE_STRIP = 0x0005, - COGL_VERTICES_MODE_TRIANGLE_FAN = 0x0006 -} CoglVerticesMode; - -/* NB: The above definitions are taken from gl.h equivalents */ - - -/* XXX: should this be CoglMaterialDepthTestFunction? - * It makes it very verbose but would be consistent with - * CoglMaterialWrapMode */ - -/** - * CoglDepthTestFunction: - * @COGL_DEPTH_TEST_FUNCTION_NEVER: Never passes. - * @COGL_DEPTH_TEST_FUNCTION_LESS: Passes if the fragment's depth - * value is less than the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_EQUAL: Passes if the fragment's depth - * value is equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_LEQUAL: Passes if the fragment's depth - * value is less or equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_GREATER: Passes if the fragment's depth - * value is greater than the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_NOTEQUAL: Passes if the fragment's depth - * value is not equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_GEQUAL: Passes if the fragment's depth - * value greater than or equal to the value currently in the depth buffer. - * @COGL_DEPTH_TEST_FUNCTION_ALWAYS: Always passes. - * - * When using depth testing one of these functions is used to compare - * the depth of an incoming fragment against the depth value currently - * stored in the depth buffer. The function is changed using - * cogl_depth_state_set_test_function(). - * - * The test is only done when depth testing is explicitly enabled. (See - * cogl_depth_state_set_test_enabled()) - */ -typedef enum -{ - COGL_DEPTH_TEST_FUNCTION_NEVER = 0x0200, - COGL_DEPTH_TEST_FUNCTION_LESS = 0x0201, - COGL_DEPTH_TEST_FUNCTION_EQUAL = 0x0202, - COGL_DEPTH_TEST_FUNCTION_LEQUAL = 0x0203, - COGL_DEPTH_TEST_FUNCTION_GREATER = 0x0204, - COGL_DEPTH_TEST_FUNCTION_NOTEQUAL = 0x0205, - COGL_DEPTH_TEST_FUNCTION_GEQUAL = 0x0206, - COGL_DEPTH_TEST_FUNCTION_ALWAYS = 0x0207 -} CoglDepthTestFunction; -/* NB: The above definitions are taken from gl.h equivalents */ - -typedef enum /*< prefix=COGL_RENDERER_ERROR >*/ -{ - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, - COGL_RENDERER_ERROR_BAD_CONSTRAINT -} CoglRendererError; - -/** - * CoglFilterReturn: - * @COGL_FILTER_CONTINUE: The event was not handled, continues the - * processing - * @COGL_FILTER_REMOVE: Remove the event, stops the processing - * - * Return values for the #CoglXlibFilterFunc and #CoglWin32FilterFunc functions. - * - * Stability: Unstable - */ -typedef enum _CoglFilterReturn { /*< prefix=COGL_FILTER >*/ - COGL_FILTER_CONTINUE, - COGL_FILTER_REMOVE -} CoglFilterReturn; - -typedef enum _CoglWinsysFeature -{ - /* Available if the window system can support multiple onscreen - * framebuffers at the same time. */ - COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, - - /* Available if its possible to query a counter that - * increments at each vblank. */ - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - - /* Available if its possible to wait until the next vertical - * blank period */ - COGL_WINSYS_FEATURE_VBLANK_WAIT, - - /* Available if the window system supports mapping native - * pixmaps to textures. */ - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP, - - /* Available if the window system supports reporting an event - * for swap buffer completions. */ - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, - - /* Available if it's possible to swap a list of sub rectangles - * from the back buffer to the front buffer */ - COGL_WINSYS_FEATURE_SWAP_REGION, - - /* Available if swap_region requests can be automatically throttled - * to the vblank frequency. */ - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, - - /* Available if the swap region implementation won't tear and thus - * only needs to be throttled to the framerate */ - COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED, - - /* Available if the age of the back buffer can be queried */ - COGL_WINSYS_FEATURE_BUFFER_AGE, - - /* Available if the winsys directly handles _SYNC and _COMPLETE events */ - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, - - COGL_WINSYS_FEATURE_N_FEATURES -} CoglWinsysFeature; - -/** - * CoglWinding: - * @COGL_WINDING_CLOCKWISE: Vertices are in a clockwise order - * @COGL_WINDING_COUNTER_CLOCKWISE: Vertices are in a counter-clockwise order - * - * Enum used to represent the two directions of rotation. This can be - * used to set the front face for culling by calling - * cogl_pipeline_set_front_face_winding(). - */ -typedef enum -{ - COGL_WINDING_CLOCKWISE, - COGL_WINDING_COUNTER_CLOCKWISE -} CoglWinding; - -/** - * CoglBufferBit: - * @COGL_BUFFER_BIT_COLOR: Selects the primary color buffer - * @COGL_BUFFER_BIT_DEPTH: Selects the depth buffer - * @COGL_BUFFER_BIT_STENCIL: Selects the stencil buffer - * - * Types of auxiliary buffers - * - * Since: 1.0 - */ -typedef enum -{ - COGL_BUFFER_BIT_COLOR = 1L<<0, - COGL_BUFFER_BIT_DEPTH = 1L<<1, - COGL_BUFFER_BIT_STENCIL = 1L<<2 -} CoglBufferBit; - -/** - * CoglReadPixelsFlags: - * @COGL_READ_PIXELS_COLOR_BUFFER: Read from the color buffer - * - * Flags for cogl_framebuffer_read_pixels_into_bitmap() - * - * Since: 1.0 - */ -typedef enum /*< prefix=COGL_READ_PIXELS >*/ -{ - COGL_READ_PIXELS_COLOR_BUFFER = 1L << 0 -} CoglReadPixelsFlags; - -/** - * CoglStereoMode: - * @COGL_STEREO_BOTH: draw to both stereo buffers - * @COGL_STEREO_LEFT: draw only to the left stereo buffer - * @COGL_STEREO_RIGHT: draw only to the left stereo buffer - * - * Represents how draw should affect the two buffers - * of a stereo framebuffer. See cogl_framebuffer_set_stereo_mode(). - */ -typedef enum -{ - COGL_STEREO_BOTH, - COGL_STEREO_LEFT, - COGL_STEREO_RIGHT -} CoglStereoMode; - -G_END_DECLS - -#endif /* __COGL_TYPES_H__ */ diff --git a/cogl/cogl/cogl-util.c b/cogl/cogl/cogl-util.c deleted file mode 100644 index 84a8c5c30..000000000 --- a/cogl/cogl/cogl-util.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-util.h" -#include "cogl-private.h" - -/* - * cogl_util_next_p2: - * @a: Value to get the next power of two - * - * Calculates the next power of two greater than or equal to @a. - * - * Return value: @a if @a is already a power of two, otherwise returns - * the next nearest power of two. - */ -COGL_EXPORT int -_cogl_util_next_p2 (int a) -{ - int rval = 1; - - while (rval < a) - rval <<= 1; - - return rval; -} - -unsigned int -_cogl_util_one_at_a_time_mix (unsigned int hash) -{ - hash += ( hash << 3 ); - hash ^= ( hash >> 11 ); - hash += ( hash << 15 ); - - return hash; -} - -/* tests/conform/test-bitmask.c tests some cogl internals and includes this - * file directly but since these functions depend on other internal Cogl - * symbols we hide them from test-bitmask.c - * - * XXX: maybe there's a better way for us to handle internal testing - * to avoid needing hacks like this. - */ -#ifndef _COGL_IN_TEST_BITMASK - -/* Given a set of red, green and blue component masks, a depth and - * bits per pixel this function tries to determine a corresponding - * CoglPixelFormat. - * - * The depth is measured in bits not including padding for un-used - * alpha. The bits per pixel (bpp) does include padding for un-used - * alpha. - * - * This function firstly aims to match formats with RGB ordered - * components and only considers alpha coming first, in the most - * significant bits. If the function fails to match then it recurses - * by either switching the r and b masks around to check for BGR - * ordered formats or it recurses with the masks shifted to check for - * formats where the alpha component is the least significant bits. - */ -static CoglPixelFormat -_cogl_util_pixel_format_from_masks_real (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - gboolean check_bgr, - gboolean check_afirst, - int recursion_depth) -{ - CoglPixelFormat image_format; - - if (depth == 24 && bpp == 24 && - r_mask == 0xff0000 && g_mask == 0xff00 && b_mask == 0xff) - { - return COGL_PIXEL_FORMAT_RGB_888; - } - else if ((depth == 24 || depth == 32) && bpp == 32 && - r_mask == 0xff0000 && g_mask == 0xff00 && b_mask == 0xff) - { - return COGL_PIXEL_FORMAT_ARGB_8888_PRE; - } - else if ((depth == 30 || depth == 32) && - r_mask == 0x3ff00000 && g_mask == 0xffc00 && b_mask == 0x3ff) - { - return COGL_PIXEL_FORMAT_ARGB_2101010_PRE; - } - else if (depth == 16 && bpp == 16 && - r_mask == 0xf800 && g_mask == 0x7e0 && b_mask == 0x1f) - { - return COGL_PIXEL_FORMAT_RGB_565; - } - - if (recursion_depth == 2) - return 0; - - /* Check for BGR ordering if we didn't find a match */ - if (check_bgr) - { - image_format = - _cogl_util_pixel_format_from_masks_real (b_mask, g_mask, r_mask, - depth, bpp, - FALSE, - TRUE, - recursion_depth + 1); - if (image_format) - return image_format ^ COGL_BGR_BIT; - } - - /* Check for alpha in the least significant bits if we still - * haven't found a match... */ - if (check_afirst && depth != bpp) - { - int shift = bpp - depth; - - image_format = - _cogl_util_pixel_format_from_masks_real (r_mask >> shift, - g_mask >> shift, - b_mask >> shift, - depth, bpp, - TRUE, - FALSE, - recursion_depth + 1); - if (image_format) - return image_format ^ COGL_AFIRST_BIT; - } - - return 0; -} - -CoglPixelFormat -_cogl_util_pixel_format_from_masks (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - gboolean byte_order_is_lsb_first) -{ - CoglPixelFormat image_format = - _cogl_util_pixel_format_from_masks_real (r_mask, g_mask, b_mask, - depth, bpp, - TRUE, - TRUE, - 0); - - if (!image_format) - { - const char *byte_order[] = { "MSB first", "LSB first" }; - g_warning ("Could not find a matching pixel format for red mask=0x%lx," - "green mask=0x%lx, blue mask=0x%lx at depth=%d, bpp=%d " - "and byte order=%s\n", r_mask, g_mask, b_mask, depth, bpp, - byte_order[!!byte_order_is_lsb_first]); - return 0; - } - - /* If the image is in little-endian then the order in memory is - reversed */ - if (byte_order_is_lsb_first && - _cogl_pixel_format_is_endian_dependant (image_format)) - { - image_format ^= COGL_BGR_BIT; - if (image_format & COGL_A_BIT) - image_format ^= COGL_AFIRST_BIT; - } - - return image_format; -} - -#endif /* _COGL_IN_TEST_BITMASK */ diff --git a/cogl/cogl/cogl-util.h b/cogl/cogl/cogl-util.h deleted file mode 100644 index 8ebf01bb9..000000000 --- a/cogl/cogl/cogl-util.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_UTIL_H -#define __COGL_UTIL_H - -#include <glib.h> -#include <math.h> - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-pixel-format.h> -#include "cogl-types.h" - -#include <stdio.h> - -/* Double check that config.h has been included */ -#ifndef COGL_CONFIG_H_INCLUDED -#error "cogl-config.h must be included before including cogl-util.h" -#endif - -int -_cogl_util_next_p2 (int a); - -/* The signbit macro is defined by ISO C99 so it should be available, - however if it's not we can fallback to an evil hack */ -#ifdef signbit -#define cogl_util_float_signbit(x) signbit(x) -#else -/* This trick was stolen from here: - http://lists.boost.org/Archives/boost/2006/08/108731.php - - It xors the integer reinterpretations of -1.0f and 1.0f. In theory - they should only differ by the signbit so that gives a mask for the - sign which we can just test against the value */ -static inline gboolean -cogl_util_float_signbit (float x) -{ - static const union { float f; uint32_t i; } negative_one = { -1.0f }; - static const union { float f; uint32_t i; } positive_one = { +1.0f }; - union { float f; uint32_t i; } value = { x }; - - return !!((negative_one.i ^ positive_one.i) & value.i); -} -#endif - -/* This is a replacement for the nearbyint function which always - rounds to the nearest integer. nearbyint is apparently a C99 - function so it might not always be available but also it seems in - glibc it is defined as a function call so this macro could end up - faster anyway. We can't just add 0.5f because it will break for - negative numbers. */ -#define COGL_UTIL_NEARBYINT(x) ((int) ((x) < 0.0f ? (x) - 0.5f : (x) + 0.5f)) - -/* Returns whether the given integer is a power of two */ -static inline gboolean -_cogl_util_is_pot (unsigned int num) -{ - /* Make sure there is only one bit set */ - return (num & (num - 1)) == 0; -} - -/* Split Bob Jenkins' One-at-a-Time hash - * - * This uses the One-at-a-Time hash algorithm designed by Bob Jenkins - * but the mixing step is split out so the function can be used in a - * more incremental fashion. - */ -static inline unsigned int -_cogl_util_one_at_a_time_hash (unsigned int hash, - const void *key, - size_t bytes) -{ - const unsigned char *p = key; - size_t i; - - for (i = 0; i < bytes; i++) - { - hash += p[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - return hash; -} - -unsigned int -_cogl_util_one_at_a_time_mix (unsigned int hash); - - -#define _cogl_util_ffsl __builtin_ffsl - -static inline unsigned int -_cogl_util_fls (unsigned int n) -{ - return n == 0 ? 0 : sizeof (unsigned int) * 8 - __builtin_clz (n); -} - -#define _cogl_util_popcountl __builtin_popcountl - -/* Match a CoglPixelFormat according to channel masks, color depth, - * bits per pixel and byte order. These information are provided by - * the Visual and XImage structures. - * - * If no specific pixel format could be found, COGL_PIXEL_FORMAT_ANY - * is returned. - */ -CoglPixelFormat -_cogl_util_pixel_format_from_masks (unsigned long r_mask, - unsigned long g_mask, - unsigned long b_mask, - int depth, int bpp, - int byte_order); - -/* _COGL_STATIC_ASSERT: - * @expression: An expression to assert evaluates to true at compile - * time. - * @message: A message to print to the console if the assertion fails - * at compile time. - * - * Allows you to assert that an expression evaluates to true at - * compile time and aborts compilation if not. If possible message - * will also be printed if the assertion fails. - */ -#define _COGL_STATIC_ASSERT(EXPRESSION, MESSAGE) \ - _Static_assert (EXPRESSION, MESSAGE); - -static inline void -_cogl_util_scissor_intersect (int rect_x0, - int rect_y0, - int rect_x1, - int rect_y1, - int *scissor_x0, - int *scissor_y0, - int *scissor_x1, - int *scissor_y1) -{ - *scissor_x0 = MAX (*scissor_x0, rect_x0); - *scissor_y0 = MAX (*scissor_y0, rect_y0); - *scissor_x1 = MIN (*scissor_x1, rect_x1); - *scissor_y1 = MIN (*scissor_y1, rect_y1); -} - -#endif /* __COGL_UTIL_H */ diff --git a/cogl/cogl/cogl-version.h b/cogl/cogl/cogl-version.h deleted file mode 100644 index 089c4998a..000000000 --- a/cogl/cogl/cogl-version.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_VERSION_H__ -#define __COGL_VERSION_H__ - -#include <cogl/cogl-defines.h> - - -/* Macros to handle compacting a 3-component version number into an - * int for quick comparison. This assumes all of the components are <= - * 1023 and that an int is >= 31 bits */ -#define COGL_VERSION_COMPONENT_BITS 10 -#define COGL_VERSION_MAX_COMPONENT_VALUE \ - ((1 << COGL_VERSION_COMPONENT_BITS) - 1) - -/** - * COGL_VERSION_ENCODE: - * @major: The major part of a version number - * @minor: The minor part of a version number - * @micro: The micro part of a version number - * - * Encodes a 3 part version number into a single integer. This can be - * used to compare the Cogl version. For example if there is a known - * bug in Cogl versions between 1.3.2 and 1.3.4 you could use the - * following code to provide a workaround: - * - * |[ - * #if COGL_VERSION >= COGL_VERSION_ENCODE (1, 3, 2) && \ - * COGL_VERSION <= COGL_VERSION_ENCODE (1, 3, 4) - * /<!-- -->* Do the workaround *<!-- -->/ - * #endif - * ]| - * - * Since: 1.12.0 - */ -#define COGL_VERSION_ENCODE(major, minor, micro) \ - (((major) << (COGL_VERSION_COMPONENT_BITS * 2)) | \ - ((minor) << COGL_VERSION_COMPONENT_BITS) \ - | (micro)) - -/** - * COGL_VERSION_GET_MAJOR: - * @version: An encoded version number - * - * Extracts the major part of an encoded version number. - * - * Since: 1.12.0 - */ -#define COGL_VERSION_GET_MAJOR(version) \ - (((version) >> (COGL_VERSION_COMPONENT_BITS * 2)) \ - & COGL_VERSION_MAX_COMPONENT_VALUE) - -/** - * COGL_VERSION_GET_MINOR: - * @version: An encoded version number - * - * Extracts the minor part of an encoded version number. - * - * Since: 1.12.0 - */ -#define COGL_VERSION_GET_MINOR(version) \ - (((version) >> COGL_VERSION_COMPONENT_BITS) & \ - COGL_VERSION_MAX_COMPONENT_VALUE) - -/** - * COGL_VERSION_GET_MICRO: - * @version: An encoded version number - * - * Extracts the micro part of an encoded version number. - * - * Since: 1.12.0 - */ -#define COGL_VERSION_GET_MICRO(version) \ - ((version) & COGL_VERSION_MAX_COMPONENT_VALUE) - -/** - * COGL_VERSION_CHECK: - * @major: The major part of a version number - * @minor: The minor part of a version number - * @micro: The micro part of a version number - * - * A convenient macro to check whether the Cogl version being compiled - * against is at least the given version number. For example if the - * function cogl_pipeline_frobnicate was added in version 2.0.1 and - * you want to conditionally use that function when it is available, - * you could write the following: - * - * |[ - * #if COGL_VERSION_CHECK (2, 0, 1) - * cogl_pipeline_frobnicate (pipeline); - * #else - * /<!-- -->* Frobnication is not supported. Use a red color instead *<!-- -->/ - * cogl_pipeline_set_color_4f (pipeline, 1.0f, 0.0f, 0.0f, 1.0f); - * #endif - * ]| - * - * Return value: %TRUE if the Cogl version being compiled against is - * greater than or equal to the given three part version number. - * Since: 1.12.0 - */ -#define COGL_VERSION_CHECK(major, minor, micro) \ - (COGL_VERSION >= COGL_VERSION_ENCODE (major, minor, micro)) - -#endif /* __COGL_VERSION_H__ */ diff --git a/cogl/cogl/cogl-wayland-server.h b/cogl/cogl/cogl-wayland-server.h deleted file mode 100644 index f4d83bc24..000000000 --- a/cogl/cogl/cogl-wayland-server.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef __COGL_WAYLAND_SERVER_H -#define __COGL_WAYLAND_SERVER_H - -#include <wayland-server.h> - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_WAYLAND_SERVER_ -#endif - -#endif /* COGL_COMPILATION */ - -#include <cogl/cogl-context.h> -#include <cogl/cogl-texture-2d.h> - -G_BEGIN_DECLS - -/** - * cogl_wayland_display_set_compositor_display: - * @display: a #CoglDisplay - * @wayland_display: A compositor's Wayland display pointer - * - * Informs Cogl of a compositor's Wayland display pointer. This - * enables Cogl to register private wayland extensions required to - * pass buffers between the clients and compositor. - * - * Since: 1.10 - * Stability: unstable - */ -COGL_EXPORT void -cogl_wayland_display_set_compositor_display (CoglDisplay *display, - struct wl_display *wayland_display); - -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_WAYLAND_SERVER_ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_WAYLAND_SERVER_ -#endif - -#endif /* __COGL_WAYLAND_SERVER_H */ diff --git a/cogl/cogl/cogl-x11-onscreen.c b/cogl/cogl/cogl-x11-onscreen.c deleted file mode 100644 index 2a4bf9e3b..000000000 --- a/cogl/cogl/cogl-x11-onscreen.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - */ - -#include "cogl-config.h" - -#include "cogl-x11-onscreen.h" - -G_DEFINE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, - G_TYPE_OBJECT) - -Window -cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglX11OnscreenInterface *iface = - COGL_X11_ONSCREEN_GET_IFACE (x11_onscreen); - - return iface->get_x11_window (x11_onscreen); -} - -static void -cogl_x11_onscreen_default_init (CoglX11OnscreenInterface *iface) -{ -} diff --git a/cogl/cogl/cogl-x11-onscreen.h b/cogl/cogl/cogl-x11-onscreen.h deleted file mode 100644 index 80bec7893..000000000 --- a/cogl/cogl/cogl-x11-onscreen.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef COGL_X11_ONSCREEN_H -#define COGL_X11_ONSCREEN_H - -#include <glib-object.h> -#include <X11/Xlib.h> - -#include "cogl-macros.h" - -#define COGL_TYPE_X11_ONSCREEN (cogl_x11_onscreen_get_type ()) -COGL_EXPORT -G_DECLARE_INTERFACE (CoglX11Onscreen, cogl_x11_onscreen, - COGL, X11_ONSCREEN, - GObject) - -struct _CoglX11OnscreenInterface -{ - GTypeInterface parent_iface; - - Window (* get_x11_window) (CoglX11Onscreen *x11_onscreen); -}; - -COGL_EXPORT -Window cogl_x11_onscreen_get_x11_window (CoglX11Onscreen *x11_onscreen); - -#endif /* COGL_X11_ONSCREEN_H */ diff --git a/cogl/cogl/cogl-x11-renderer-private.h b/cogl/cogl/cogl-x11-renderer-private.h deleted file mode 100644 index 17655da2b..000000000 --- a/cogl/cogl/cogl-x11-renderer-private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_RENDERER_X11_PRIVATE_H -#define __COGL_RENDERER_X11_PRIVATE_H - -typedef struct _CoglX11Renderer -{ - int damage_base; - int randr_base; -} CoglX11Renderer; - -#endif /* __COGL_RENDERER_X11_PRIVATE_H */ diff --git a/cogl/cogl/cogl-xlib-private.h b/cogl/cogl/cogl-xlib-private.h deleted file mode 100644 index 317163fb2..000000000 --- a/cogl/cogl/cogl-xlib-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_XLIB_PRIVATE_H -#define __COGL_XLIB_PRIVATE_H - -#include <X11/Xlib.h> - -typedef struct _CoglXlibTrapState CoglXlibTrapState; - -struct _CoglXlibTrapState -{ - /* These values are intended to be internal to - * _cogl_xlib_{un,}trap_errors but they need to be in the header so - * that the struct can be allocated on the stack */ - int (* old_error_handler) (Display *, XErrorEvent *); - int trapped_error_code; - CoglXlibTrapState *old_state; -}; - -#endif /* __COGL_XLIB_PRIVATE_H */ diff --git a/cogl/cogl/cogl-xlib-renderer-private.h b/cogl/cogl/cogl-xlib-renderer-private.h deleted file mode 100644 index edfa189b7..000000000 --- a/cogl/cogl/cogl-xlib-renderer-private.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_RENDERER_XLIB_PRIVATE_H -#define __COGL_RENDERER_XLIB_PRIVATE_H - -#include <X11/Xutil.h> - -#include "cogl-object-private.h" -#include "cogl-xlib-private.h" -#include "cogl-x11-renderer-private.h" -#include "cogl-context.h" -#include "cogl-output.h" - -typedef struct _CoglXlibRenderer -{ - CoglX11Renderer _parent; - - Display *xdpy; - - /* Current top of the XError trap state stack. The actual memory for - these is expected to be allocated on the stack by the caller */ - CoglXlibTrapState *trap_state; - - unsigned long outputs_update_serial; - - XVisualInfo *xvisinfo; -} CoglXlibRenderer; - -gboolean -_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error); - -void -_cogl_xlib_renderer_disconnect (CoglRenderer *renderer); - -/* - * cogl_xlib_renderer_trap_errors: - * @state: A temporary place to store data for the trap. - * - * Traps every X error until _cogl_xlib_renderer_untrap_errors() - * called. You should allocate an uninitialised CoglXlibTrapState - * struct on the stack to pass to this function. The same pointer - * should later be passed to _cogl_xlib_renderer_untrap_errors(). - * - * Calls to _cogl_xlib_renderer_trap_errors() can be nested as long as - * _cogl_xlib_renderer_untrap_errors() is called with the - * corresponding state pointers in reverse order. - */ -void -_cogl_xlib_renderer_trap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state); - -/* - * cogl_xlib_renderer_untrap_errors: - * @state: The state that was passed to _cogl_xlib_renderer_trap_errors(). - * - * Removes the X error trap and returns the current status. - * - * Return value: the trapped error code, or 0 for success - */ -int -_cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state); - -CoglXlibRenderer * -_cogl_xlib_renderer_get_data (CoglRenderer *renderer); - -CoglOutput * -_cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, - int x, - int y, - int width, - int height); - -#endif /* __COGL_RENDERER_XLIB_PRIVATE_H */ diff --git a/cogl/cogl/cogl-xlib-renderer.c b/cogl/cogl/cogl-xlib-renderer.c deleted file mode 100644 index 163fb32b5..000000000 --- a/cogl/cogl/cogl-xlib-renderer.c +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-xlib-renderer.h" -#include "cogl-util.h" -#include "cogl-object.h" - -#include "cogl-output-private.h" -#include "cogl-renderer-private.h" -#include "cogl-xlib-renderer-private.h" -#include "cogl-x11-renderer-private.h" -#include "cogl-poll-private.h" -#include "winsys/cogl-winsys-private.h" - -#include <X11/Xlib.h> -#include <X11/extensions/Xdamage.h> -#include <X11/extensions/Xrandr.h> - -#include <stdlib.h> -#include <string.h> - -static char *_cogl_x11_display_name = NULL; -static GList *_cogl_xlib_renderers = NULL; - -static void -_xlib_renderer_data_free (CoglXlibRenderer *data) -{ - if (data->xvisinfo) - XFree (data->xvisinfo); - - g_free (data); -} - -CoglXlibRenderer * -_cogl_xlib_renderer_get_data (CoglRenderer *renderer) -{ - /* Constructs a CoglXlibRenderer struct on demand and attaches it to - the object using user data. It's done this way instead of using a - subclassing hierarchy in the winsys data because all EGL winsys's - need the EGL winsys data but only one of them wants the Xlib - data. */ - - if (!renderer->custom_winsys_user_data) - renderer->custom_winsys_user_data = g_new0 (CoglXlibRenderer, 1); - - return renderer->custom_winsys_user_data; -} - -static void -register_xlib_renderer (CoglRenderer *renderer) -{ - GList *l; - - for (l = _cogl_xlib_renderers; l; l = l->next) - if (l->data == renderer) - return; - - _cogl_xlib_renderers = g_list_prepend (_cogl_xlib_renderers, renderer); -} - -static void -unregister_xlib_renderer (CoglRenderer *renderer) -{ - _cogl_xlib_renderers = g_list_remove (_cogl_xlib_renderers, renderer); -} - -static CoglRenderer * -get_renderer_for_xdisplay (Display *xdpy) -{ - GList *l; - - for (l = _cogl_xlib_renderers; l; l = l->next) - { - CoglRenderer *renderer = l->data; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - if (xlib_renderer->xdpy == xdpy) - return renderer; - } - - return NULL; -} - -static int -error_handler (Display *xdpy, - XErrorEvent *error) -{ - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - - renderer = get_renderer_for_xdisplay (xdpy); - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - g_assert (xlib_renderer->trap_state); - - xlib_renderer->trap_state->trapped_error_code = error->error_code; - - return 0; -} - -void -_cogl_xlib_renderer_trap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state) -{ - CoglXlibRenderer *xlib_renderer; - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - state->trapped_error_code = 0; - state->old_error_handler = XSetErrorHandler (error_handler); - - state->old_state = xlib_renderer->trap_state; - xlib_renderer->trap_state = state; -} - -int -_cogl_xlib_renderer_untrap_errors (CoglRenderer *renderer, - CoglXlibTrapState *state) -{ - CoglXlibRenderer *xlib_renderer; - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - g_assert (state == xlib_renderer->trap_state); - - XSetErrorHandler (state->old_error_handler); - - xlib_renderer->trap_state = state->old_state; - - return state->trapped_error_code; -} - -static Display * -assert_xlib_display (CoglRenderer *renderer, GError **error) -{ - Display *xdpy = cogl_xlib_renderer_get_foreign_display (renderer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - /* A foreign display may have already been set... */ - if (xdpy) - { - xlib_renderer->xdpy = xdpy; - return xdpy; - } - - xdpy = XOpenDisplay (_cogl_x11_display_name); - if (xdpy == NULL) - { - g_set_error (error, - COGL_RENDERER_ERROR, - COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, - "Failed to open X Display %s", _cogl_x11_display_name); - return NULL; - } - - xlib_renderer->xdpy = xdpy; - return xdpy; -} - -static int -compare_outputs (CoglOutput *a, - CoglOutput *b) -{ - return strcmp (a->name, b->name); -} - -#define CSO(X) COGL_SUBPIXEL_ORDER_ ## X -static CoglSubpixelOrder subpixel_map[6][6] = { - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR), - CSO(VERTICAL_RGB), CSO(VERTICAL_BGR) }, /* 0 */ - { CSO(UNKNOWN), CSO(NONE), CSO(VERTICAL_RGB), CSO(VERTICAL_BGR), - CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB) }, /* 90 */ - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB), - CSO(VERTICAL_BGR), CSO(VERTICAL_RGB) }, /* 180 */ - { CSO(UNKNOWN), CSO(NONE), CSO(VERTICAL_BGR), CSO(VERTICAL_RGB), - CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR) }, /* 270 */ - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_BGR), CSO(HORIZONTAL_RGB), - CSO(VERTICAL_RGB), CSO(VERTICAL_BGR) }, /* Reflect_X */ - { CSO(UNKNOWN), CSO(NONE), CSO(HORIZONTAL_RGB), CSO(HORIZONTAL_BGR), - CSO(VERTICAL_BGR), CSO(VERTICAL_RGB) }, /* Reflect_Y */ -}; -#undef CSO - -static void -update_outputs (CoglRenderer *renderer, - gboolean notify) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - XRRScreenResources *resources; - CoglXlibTrapState state; - gboolean error = FALSE; - GList *new_outputs = NULL; - GList *l, *m; - gboolean changed = FALSE; - int i; - - xlib_renderer->outputs_update_serial = XNextRequest (xlib_renderer->xdpy); - - resources = XRRGetScreenResources (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy)); - - _cogl_xlib_renderer_trap_errors (renderer, &state); - - for (i = 0; resources && i < resources->ncrtc && !error; i++) - { - XRRCrtcInfo *crtc_info = NULL; - XRROutputInfo *output_info = NULL; - CoglOutput *output; - float refresh_rate = 0; - int j; - - crtc_info = XRRGetCrtcInfo (xlib_renderer->xdpy, - resources, resources->crtcs[i]); - if (crtc_info == NULL) - { - error = TRUE; - goto next; - } - - if (crtc_info->mode == None) - goto next; - - for (j = 0; j < resources->nmode; j++) - { - if (resources->modes[j].id == crtc_info->mode) - refresh_rate = (resources->modes[j].dotClock / - ((float)resources->modes[j].hTotal * - resources->modes[j].vTotal)); - } - - output_info = XRRGetOutputInfo (xlib_renderer->xdpy, - resources, - crtc_info->outputs[0]); - if (output_info == NULL) - { - error = TRUE; - goto next; - } - - output = _cogl_output_new (output_info->name); - output->x = crtc_info->x; - output->y = crtc_info->y; - output->width = crtc_info->width; - output->height = crtc_info->height; - if ((crtc_info->rotation & (RR_Rotate_90 | RR_Rotate_270)) != 0) - { - output->mm_width = output_info->mm_height; - output->mm_height = output_info->mm_width; - } - else - { - output->mm_width = output_info->mm_width; - output->mm_height = output_info->mm_height; - } - - output->refresh_rate = refresh_rate; - - switch (output_info->subpixel_order) - { - case SubPixelUnknown: - default: - output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN; - break; - case SubPixelNone: - output->subpixel_order = COGL_SUBPIXEL_ORDER_NONE; - break; - case SubPixelHorizontalRGB: - output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB; - break; - case SubPixelHorizontalBGR: - output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR; - break; - case SubPixelVerticalRGB: - output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_RGB; - break; - case SubPixelVerticalBGR: - output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_BGR; - break; - } - - output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB; - - /* Handle the effect of rotation and reflection on subpixel order (ugh) */ - for (j = 0; j < 6; j++) - { - if ((crtc_info->rotation & (1 << j)) != 0) - output->subpixel_order = subpixel_map[j][output->subpixel_order]; - } - - new_outputs = g_list_prepend (new_outputs, output); - - next: - if (crtc_info != NULL) - XFree (crtc_info); - - if (output_info != NULL) - XFree (output_info); - } - - XFree (resources); - - if (!error) - { - new_outputs = g_list_sort (new_outputs, (GCompareFunc)compare_outputs); - - l = new_outputs; - m = renderer->outputs; - - while (l || m) - { - int cmp; - CoglOutput *output_l = l ? (CoglOutput *)l->data : NULL; - CoglOutput *output_m = m ? (CoglOutput *)m->data : NULL; - - if (l && m) - cmp = compare_outputs (output_l, output_m); - else if (l) - cmp = -1; - else - cmp = 1; - - if (cmp == 0) - { - GList *m_next = m->next; - - if (!_cogl_output_values_equal (output_l, output_m)) - { - renderer->outputs = g_list_remove_link (renderer->outputs, m); - renderer->outputs = g_list_insert_before (renderer->outputs, - m_next, output_l); - cogl_object_ref (output_l); - - changed = TRUE; - } - - l = l->next; - m = m_next; - } - else if (cmp < 0) - { - renderer->outputs = - g_list_insert_before (renderer->outputs, m, output_l); - cogl_object_ref (output_l); - changed = TRUE; - l = l->next; - } - else - { - GList *m_next = m->next; - renderer->outputs = g_list_remove_link (renderer->outputs, m); - changed = TRUE; - m = m_next; - } - } - } - - g_list_free_full (new_outputs, (GDestroyNotify)cogl_object_unref); - _cogl_xlib_renderer_untrap_errors (renderer, &state); - - if (changed) - { - const CoglWinsysVtable *winsys = renderer->winsys_vtable; - - if (notify) - COGL_NOTE (WINSYS, "Outputs changed:"); - else - COGL_NOTE (WINSYS, "Outputs:"); - - for (l = renderer->outputs; l; l = l->next) - { - CoglOutput *output = l->data; - const char *subpixel_string; - - switch (output->subpixel_order) - { - case COGL_SUBPIXEL_ORDER_UNKNOWN: - default: - subpixel_string = "unknown"; - break; - case COGL_SUBPIXEL_ORDER_NONE: - subpixel_string = "none"; - break; - case COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB: - subpixel_string = "horizontal_rgb"; - break; - case COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR: - subpixel_string = "horizontal_bgr"; - break; - case COGL_SUBPIXEL_ORDER_VERTICAL_RGB: - subpixel_string = "vertical_rgb"; - break; - case COGL_SUBPIXEL_ORDER_VERTICAL_BGR: - subpixel_string = "vertical_bgr"; - break; - } - - COGL_NOTE (WINSYS, - " %10s: +%d+%dx%dx%d mm=%dx%d dpi=%.1fx%.1f " - "subpixel_order=%s refresh_rate=%.3f", - output->name, - output->x, output->y, output->width, output->height, - output->mm_width, output->mm_height, - output->width / (output->mm_width / 25.4), - output->height / (output->mm_height / 25.4), - subpixel_string, - output->refresh_rate); - } - - if (notify && winsys->renderer_outputs_changed != NULL) - winsys->renderer_outputs_changed (renderer); - } -} - -static CoglFilterReturn -randr_filter (XEvent *event, - void *data) -{ - CoglRenderer *renderer = data; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglX11Renderer *x11_renderer = - (CoglX11Renderer *) xlib_renderer; - - if (x11_renderer->randr_base != -1 && - (event->xany.type == x11_renderer->randr_base + RRScreenChangeNotify || - event->xany.type == x11_renderer->randr_base + RRNotify) && - event->xany.serial >= xlib_renderer->outputs_update_serial) - update_outputs (renderer, TRUE); - - return COGL_FILTER_CONTINUE; -} - -static int64_t -prepare_xlib_events_timeout (void *user_data) -{ - CoglRenderer *renderer = user_data; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - return XPending (xlib_renderer->xdpy) ? 0 : -1; -} - -static void -dispatch_xlib_events (void *user_data, int revents) -{ - CoglRenderer *renderer = user_data; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (renderer->xlib_enable_event_retrieval) - while (XPending (xlib_renderer->xdpy)) - { - XEvent xevent; - - XNextEvent (xlib_renderer->xdpy, &xevent); - - cogl_xlib_renderer_handle_event (renderer, &xevent); - } -} - -gboolean -_cogl_xlib_renderer_connect (CoglRenderer *renderer, GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglX11Renderer *x11_renderer = - (CoglX11Renderer *) xlib_renderer; - int damage_error; - int randr_error; - - if (!assert_xlib_display (renderer, error)) - return FALSE; - - if (getenv ("COGL_X11_SYNC")) - XSynchronize (xlib_renderer->xdpy, TRUE); - - /* Check whether damage events are supported on this display */ - if (!XDamageQueryExtension (xlib_renderer->xdpy, - &x11_renderer->damage_base, - &damage_error)) - x11_renderer->damage_base = -1; - - /* Check whether randr is supported on this display */ - if (!XRRQueryExtension (xlib_renderer->xdpy, - &x11_renderer->randr_base, - &randr_error)) - x11_renderer->randr_base = -1; - - xlib_renderer->trap_state = NULL; - - if (renderer->xlib_enable_event_retrieval) - { - _cogl_poll_renderer_add_fd (renderer, - ConnectionNumber (xlib_renderer->xdpy), - COGL_POLL_FD_EVENT_IN, - prepare_xlib_events_timeout, - dispatch_xlib_events, - renderer); - } - - XRRSelectInput(xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - RRScreenChangeNotifyMask - | RRCrtcChangeNotifyMask - | RROutputPropertyNotifyMask); - update_outputs (renderer, FALSE); - - register_xlib_renderer (renderer); - - cogl_xlib_renderer_add_filter (renderer, - randr_filter, - renderer); - - return TRUE; -} - -void -_cogl_xlib_renderer_disconnect (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - - g_list_free_full (renderer->outputs, (GDestroyNotify)cogl_object_unref); - renderer->outputs = NULL; - - if (!renderer->foreign_xdpy && xlib_renderer->xdpy) - XCloseDisplay (xlib_renderer->xdpy); - - g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free); - - unregister_xlib_renderer (renderer); -} - -Display * -cogl_xlib_renderer_get_display (CoglRenderer *renderer) -{ - CoglXlibRenderer *xlib_renderer; - - g_return_val_if_fail (cogl_is_renderer (renderer), NULL); - - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - return xlib_renderer->xdpy; -} - -CoglFilterReturn -cogl_xlib_renderer_handle_event (CoglRenderer *renderer, - XEvent *event) -{ - return _cogl_renderer_handle_native_event (renderer, event); -} - -void -cogl_xlib_renderer_add_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data) -{ - _cogl_renderer_add_native_filter (renderer, - (CoglNativeFilterFunc)func, data); -} - -void -cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data) -{ - _cogl_renderer_remove_native_filter (renderer, - (CoglNativeFilterFunc)func, data); -} - -CoglOutput * -_cogl_xlib_renderer_output_for_rectangle (CoglRenderer *renderer, - int x, - int y, - int width, - int height) -{ - int max_overlap = 0; - CoglOutput *max_overlapped = NULL; - GList *l; - int xa1 = x, xa2 = x + width; - int ya1 = y, ya2 = y + height; - - for (l = renderer->outputs; l; l = l->next) - { - CoglOutput *output = l->data; - int xb1 = output->x, xb2 = output->x + output->width; - int yb1 = output->y, yb2 = output->y + output->height; - - int overlap_x = MIN(xa2, xb2) - MAX(xa1, xb1); - int overlap_y = MIN(ya2, yb2) - MAX(ya1, yb1); - - if (overlap_x > 0 && overlap_y > 0) - { - int overlap = overlap_x * overlap_y; - if (overlap > max_overlap) - { - max_overlap = overlap; - max_overlapped = output; - } - } - } - - return max_overlapped; -} diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h deleted file mode 100644 index 3afdabb27..000000000 --- a/cogl/cogl/cogl-xlib-renderer.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_XLIB_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl-xlib.h> can be included directly." -#endif - -#ifndef __COGL_XLIB_RENDERER_H__ -#define __COGL_XLIB_RENDERER_H__ - -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_XLIB_RENDERER_H_MUST_UNDEF_COGL_H_INSIDE_COGL_XLIB_RENDERER_ -#endif - -#endif /* COGL_COMPILATION */ - -#include <cogl/cogl-renderer.h> - -G_BEGIN_DECLS - -/** - * cogl_xlib_renderer_handle_event: (skip) - * @renderer: a #CoglRenderer - * @event: pointer to an XEvent structure - * - * This function processes a single event; it can be used to hook into - * external event retrieval (for example that done by Clutter or - * GDK). - * - * Return value: #CoglFilterReturn. %COGL_FILTER_REMOVE indicates that - * Cogl has internally handled the event and the caller should do no - * further processing. %COGL_FILTER_CONTINUE indicates that Cogl is - * either not interested in the event, or has used the event to update - * internal state without taking any exclusive action. - */ -COGL_EXPORT CoglFilterReturn -cogl_xlib_renderer_handle_event (CoglRenderer *renderer, - XEvent *event); - -/* - * CoglXlibFilterFunc: - * @event: pointer to an XEvent structure - * @data: the data that was given when the filter was added - * - * A callback function that can be registered with - * cogl_xlib_renderer_add_filter(). The function should return - * %COGL_FILTER_REMOVE if it wants to prevent further processing or - * %COGL_FILTER_CONTINUE otherwise. - */ -typedef CoglFilterReturn (* CoglXlibFilterFunc) (XEvent *event, - void *data); - -/** - * cogl_xlib_renderer_add_filter: (skip) - * @renderer: a #CoglRenderer - * @func: the callback function - * @data: user data passed to @func when called - * - * Adds a callback function that will receive all native events. The - * function can stop further processing of the event by return - * %COGL_FILTER_REMOVE. - */ -COGL_EXPORT void -cogl_xlib_renderer_add_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data); - -/** - * cogl_xlib_renderer_remove_filter: (skip) - * @renderer: a #CoglRenderer - * @func: the callback function - * @data: user data given when the callback was installed - * - * Removes a callback that was previously added with - * cogl_xlib_renderer_add_filter(). - */ -COGL_EXPORT void -cogl_xlib_renderer_remove_filter (CoglRenderer *renderer, - CoglXlibFilterFunc func, - void *data); - -/** - * cogl_xlib_renderer_get_foreign_display: (skip) - * @renderer: a #CoglRenderer - * - * Return value: the foreign Xlib display that will be used by any Xlib based - * winsys backend. The display needs to be set with - * cogl_xlib_renderer_set_foreign_display() before this function is called. - */ -COGL_EXPORT Display * -cogl_xlib_renderer_get_foreign_display (CoglRenderer *renderer); - -/** - * cogl_xlib_renderer_set_foreign_display: (skip) - * @renderer: a #CoglRenderer - * - * Sets a foreign Xlib display that Cogl will use for and Xlib based winsys - * backend. - * - * Note that calling this function will automatically disable Cogl's - * event retrieval. Cogl still needs to see all of the X events so the - * application should also use cogl_xlib_renderer_handle_event() if it - * uses this function. - */ -COGL_EXPORT void -cogl_xlib_renderer_set_foreign_display (CoglRenderer *renderer, - Display *display); - -/** - * cogl_xlib_renderer_get_display: (skip) - */ -COGL_EXPORT Display * -cogl_xlib_renderer_get_display (CoglRenderer *renderer); - -/** - * cogl_xlib_renderer_request_reset_on_video_memory_purge: (skip) - * @renderer: a #CoglRenderer - * @enable: The new value - * - * Sets whether Cogl should make use of the - * NV_robustness_video_memory_purge extension, if exposed by the - * driver, by initializing the GLX context appropriately. - * - * The extension is only useful when running on certain versions of - * the NVIDIA driver. Quoting from the spec: - * - * "The NVIDIA OpenGL driver architecture on Linux has a limitation: - * resources located in video memory are not persistent across certain - * events. VT switches, suspend/resume events, and mode switching - * events may erase the contents of video memory. Any resource that - * is located exclusively in video memory, such as framebuffer objects - * (FBOs), will be lost." - * - * "This extension provides a way for applications to discover when video - * memory content has been lost, so that the application can re-populate - * the video memory content as necessary." - * - * "Any driver that exposes this extension is a driver that considers - * video memory to be volatile. Once the driver stack has been - * improved, the extension will no longer be exposed." - * - * cogl_get_graphics_reset_status() needs to be called at least once - * every frame to find out if video memory was purged. - * - * Note that this doesn't cause Cogl to enable robust buffer access - * but other context reset errors may still happen and be reported via - * cogl_get_graphics_reset_status() if external factors cause the - * driver to trigger them. - * - * This defaults to %FALSE and is effective only if called before - * cogl_display_setup() . - */ -COGL_EXPORT void -cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, - gboolean enable); -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_XLIB_RENDERER_H_MUST_UNDEF_COGL_H_INSIDE_COGL_XLIB_RENDERER_ -#undef __COGL_H_INSIDE__ -#undef __COGL_XLIB_RENDERER_H_MUST_UNDEF_COGL_H_INSIDE_COGL_XLIB_RENDERER_ -#endif - -#endif /* __COGL_XLIB_RENDERER_H__ */ diff --git a/cogl/cogl/cogl-xlib.h b/cogl/cogl/cogl-xlib.h deleted file mode 100644 index 4fd803b88..000000000 --- a/cogl/cogl/cogl-xlib.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __COGL_XLIB_H__ -#define __COGL_XLIB_H__ - -#include <X11/Xlib.h> - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_XLIB_H_INSIDE__ */ -#ifndef __COGL_XLIB_H_INSIDE__ -#define __COGL_XLIB_H_INSIDE__ -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_XLIB_H_MUST_UNDEF_COGL_H_INSIDE__ -#endif - -#endif /* COGL_COMPILATION */ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-xlib-renderer.h> -#include <cogl/cogl-macros.h> - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_XLIB_H_MUST_UNDEF_COGL_H_INSIDE__ -#undef __COGL_H_INSIDE__ -#undef __COGL_XLIB_H_INSIDE__ -#undef __COGL_XLIB_H_MUST_UNDEF_COGL_H_INSIDE__ -#endif - -#endif /* __COGL_XLIB_H__ */ diff --git a/cogl/cogl/cogl.c b/cogl/cogl/cogl.c deleted file mode 100644 index a9cd5ca21..000000000 --- a/cogl/cogl/cogl.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> -#include <math.h> -#include <stdlib.h> - -#include "cogl-i18n-private.h" -#include "cogl-debug.h" -#include "cogl-graphene.h" -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-journal-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-driver.h" -#include "cogl-attribute-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-renderer-private.h" -#include "cogl-private.h" -#include "cogl1-context.h" -#include "cogl-offscreen.h" -#include "winsys/cogl-winsys-private.h" - -GCallback -cogl_get_proc_address (const char* name) -{ - _COGL_GET_CONTEXT (ctx, NULL); - - return _cogl_renderer_get_proc_address (ctx->display->renderer, name, FALSE); -} - -gboolean -_cogl_check_extension (const char *name, char * const *ext) -{ - while (*ext) - if (!strcmp (name, *ext)) - return TRUE; - else - ext++; - - return FALSE; -} - -/* XXX: This API has been deprecated */ -void -cogl_set_depth_test_enabled (gboolean setting) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_depth_test_enabled == setting) - return; - - ctx->legacy_depth_test_enabled = setting; -} - -/* XXX: This API has been deprecated */ -gboolean -cogl_get_depth_test_enabled (void) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - return ctx->legacy_depth_test_enabled; -} - -void -cogl_set_backface_culling_enabled (gboolean setting) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (ctx->legacy_backface_culling_enabled == setting) - return; - - ctx->legacy_backface_culling_enabled = setting; -} - -gboolean -cogl_get_backface_culling_enabled (void) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - return ctx->legacy_backface_culling_enabled; -} - -gboolean -cogl_has_feature (CoglContext *ctx, CoglFeatureID feature) -{ - return COGL_FLAGS_GET (ctx->features, feature); -} - -gboolean -cogl_has_features (CoglContext *ctx, ...) -{ - va_list args; - CoglFeatureID feature; - - va_start (args, ctx); - while ((feature = va_arg (args, CoglFeatureID))) - if (!cogl_has_feature (ctx, feature)) - return FALSE; - va_end (args); - - return TRUE; -} - -void -cogl_foreach_feature (CoglContext *ctx, - CoglFeatureCallback callback, - void *user_data) -{ - int i; - for (i = 0; i < _COGL_N_FEATURE_IDS; i++) - if (COGL_FLAGS_GET (ctx->features, i)) - callback (i, user_data); -} - -void -cogl_flush (void) -{ - GList *l; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (l = ctx->framebuffers; l; l = l->next) - _cogl_framebuffer_flush_journal (l->data); -} - -uint32_t -_cogl_driver_error_quark (void) -{ - return g_quark_from_static_string ("cogl-driver-error-quark"); -} - -/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1) - * to Cogl window/framebuffer coordinates (ranging from 0 to buffer-size) with - * (0,0) being top left. */ -#define VIEWPORT_TRANSFORM_X(x, vp_origin_x, vp_width) \ - ( ( ((x) + 1.0) * ((vp_width) / 2.0) ) + (vp_origin_x) ) -/* Note: for Y we first flip all coordinates around the X axis while in - * normalized device coordinates */ -#define VIEWPORT_TRANSFORM_Y(y, vp_origin_y, vp_height) \ - ( ( ((-(y)) + 1.0) * ((vp_height) / 2.0) ) + (vp_origin_y) ) - -/* Transform a homogeneous vertex position from model space to Cogl - * window coordinates (with 0,0 being top left) */ -void -_cogl_transform_point (const graphene_matrix_t *matrix_mv, - const graphene_matrix_t *matrix_p, - const float *viewport, - float *x, - float *y) -{ - float z = 0; - float w = 1; - - /* Apply the modelview matrix transform */ - cogl_graphene_matrix_project_point (matrix_mv, x, y, &z, &w); - - /* Apply the projection matrix transform */ - cogl_graphene_matrix_project_point (matrix_p, x, y, &z, &w); - - /* Perform perspective division */ - *x /= w; - *y /= w; - - /* Apply viewport transform */ - *x = VIEWPORT_TRANSFORM_X (*x, viewport[0], viewport[2]); - *y = VIEWPORT_TRANSFORM_Y (*y, viewport[1], viewport[3]); -} - -#undef VIEWPORT_TRANSFORM_X -#undef VIEWPORT_TRANSFORM_Y - -uint32_t -_cogl_system_error_quark (void) -{ - return g_quark_from_static_string ("cogl-system-error-quark"); -} - -void -_cogl_init (void) -{ - static gboolean initialized = FALSE; - - if (initialized == FALSE) - { -#if !GLIB_CHECK_VERSION (2, 36, 0) - g_type_init (); -#endif - - _cogl_debug_check_environment (); - initialized = TRUE; - } -} diff --git a/cogl/cogl/cogl.h b/cogl/cogl/cogl.h deleted file mode 100644 index 4a63a368f..000000000 --- a/cogl/cogl/cogl.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_H__ -#define __COGL_H__ - -#ifdef COGL_COMPILATION -#error "<cogl/cogl.h> shouldn't be included internally" -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE__ -#endif - -#include <graphene.h> - -/* We currently keep gtype integration delimited in case we eventually - * want to split it out into a separate utility library when Cogl - * becomes a standalone project. (like cairo-gobject.so) - */ -#define _COGL_SUPPORTS_GTYPE_INTEGRATION - -/* - * API common to the 1.x and 2.0 api... - */ - -#include <cogl/cogl-defines.h> -#include <cogl/cogl-macros.h> - -#include <cogl/cogl-object.h> -#include <cogl/cogl1-context.h> -#include <cogl/cogl-bitmap.h> -#include <cogl/cogl-color.h> -#include <cogl/cogl-dma-buf-handle.h> -#include <cogl/cogl-matrix-stack.h> -#include <cogl/cogl-offscreen.h> -#include <cogl/cogl-pixel-format.h> -#include <cogl/cogl-texture.h> -#include <cogl/cogl-types.h> -#include <cogl/cogl-version.h> - -/* - * 1.x only api... - */ -#if 0 -#ifndef COGL_ENABLE_EXPERIMENTAL_2_0_API -#warning -#endif -#endif - -/* It would be good to move these casts up into 1.x only api if we can - * update Clutter, Mutter and GnomeShell to avoid redundant casts when - * they enable the experimental api... */ -#include <cogl/deprecated/cogl-type-casts.h> - -#include <cogl/deprecated/cogl-auto-texture.h> -#include <cogl/deprecated/cogl-shader.h> -#include <cogl/deprecated/cogl-material-compat.h> - -#ifdef COGL_ENABLE_MUTTER_API -#include <cogl/cogl-mutter.h> -#endif - -#include <cogl/cogl-swap-chain.h> -#include <cogl/cogl-renderer.h> -#include <cogl/cogl-output.h> -#include <cogl/cogl-display.h> -#include <cogl/cogl-context.h> -#include <cogl/cogl-buffer.h> -#include <cogl/cogl-pixel-buffer.h> -#include <cogl/cogl-texture-2d.h> -#include <cogl/cogl-texture-2d-sliced.h> -#include <cogl/cogl-sub-texture.h> -#include <cogl/cogl-atlas-texture.h> -#include <cogl/cogl-meta-texture.h> -#include <cogl/cogl-primitive-texture.h> -#include <cogl/cogl-index-buffer.h> -#include <cogl/cogl-attribute-buffer.h> -#include <cogl/cogl-indices.h> -#include <cogl/cogl-attribute.h> -#include <cogl/cogl-primitive.h> -#include <cogl/cogl-depth-state.h> -#include <cogl/cogl-pipeline.h> -#include <cogl/cogl-pipeline-state.h> -#include <cogl/cogl-pipeline-layer-state.h> -#include <cogl/cogl-snippet.h> -#include <cogl/cogl-framebuffer.h> -#include <cogl/cogl-onscreen.h> -#include <cogl/cogl-frame-info.h> -#include <cogl/cogl-poll.h> -#include <cogl/cogl-fence.h> -#include <cogl/cogl-glib-source.h> -#include <cogl/cogl-trace.h> -#include <cogl/cogl-scanout.h> -#include <cogl/cogl-graphene.h> -/* XXX: This will definitely go away once all the Clutter winsys - * code has been migrated down into Cogl! */ -#include <cogl/deprecated/cogl-clutter.h> - -/** - * SECTION:cogl - * @short_description: General purpose API - * - * General utility functions for COGL. - */ - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE__ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE__ -#endif - -#endif /* __COGL_H__ */ diff --git a/cogl/cogl/cogl1-context.h b/cogl/cogl/cogl1-context.h deleted file mode 100644 index 755a48452..000000000 --- a/cogl/cogl/cogl1-context.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_1_CONTEXT_H__ -#define __COGL_1_CONTEXT_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-texture.h> -#include <cogl/cogl-framebuffer.h> -#include <cogl/cogl-macros.h> - -G_BEGIN_DECLS - -/** - * cogl_get_option_group: - * - * Retrieves the #GOptionGroup used by Cogl to parse the command - * line options. Clutter uses this to handle the Cogl command line - * options during its initialization process. - * - * Return value: a #GOptionGroup - * - * Since: 1.0 - * Deprecated: 1.16: Not replaced - */ -COGL_DEPRECATED -COGL_EXPORT GOptionGroup * -cogl_get_option_group (void); - -/* Misc */ -/** - * cogl_get_proc_address: (skip) - * @name: the name of the function. - * - * Gets a pointer to a given GL or GL ES extension function. This acts - * as a wrapper around glXGetProcAddress() or whatever is the - * appropriate function for the current backend. - * - * <note>This function should not be used to query core opengl API - * symbols since eglGetProcAddress for example doesn't allow this and - * and may return a junk pointer if you do.</note> - * - * Return value: a pointer to the requested function or %NULL if the - * function is not available. - */ -COGL_EXPORT GCallback -cogl_get_proc_address (const char *name); - -/** - * cogl_set_depth_test_enabled: - * @setting: %TRUE to enable depth testing or %FALSE to disable. - * - * Sets whether depth testing is enabled. If it is disabled then the - * order that actors are layered on the screen depends solely on the - * order specified using clutter_actor_raise() and - * clutter_actor_lower(), otherwise it will also take into account the - * actor's depth. Depth testing is disabled by default. - * - * Deprecated: 1.16: Use cogl_pipeline_set_depth_state() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_depth_state) -COGL_EXPORT void -cogl_set_depth_test_enabled (gboolean setting); - -/** - * cogl_get_depth_test_enabled: - * - * Queries if depth testing has been enabled via cogl_set_depth_test_enable() - * - * Return value: %TRUE if depth testing is enabled, and %FALSE otherwise - * - * Deprecated: 1.16: Use cogl_pipeline_set_depth_state() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_depth_state) -COGL_EXPORT gboolean -cogl_get_depth_test_enabled (void); - -/** - * cogl_set_backface_culling_enabled: - * @setting: %TRUE to enable backface culling or %FALSE to disable. - * - * Sets whether textures positioned so that their backface is showing - * should be hidden. This can be used to efficiently draw two-sided - * textures or fully closed cubes without enabling depth testing. This - * only affects calls to the cogl_rectangle* family of functions and - * cogl_vertex_buffer_draw*. Backface culling is disabled by default. - * - * Deprecated: 1.16: Use cogl_pipeline_set_cull_face_mode() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_cull_face_mode) -COGL_EXPORT void -cogl_set_backface_culling_enabled (gboolean setting); - -/** - * cogl_get_backface_culling_enabled: - * - * Queries if backface culling has been enabled via - * cogl_set_backface_culling_enabled() - * - * Return value: %TRUE if backface culling is enabled, and %FALSE otherwise - * - * Deprecated: 1.16: Use cogl_pipeline_get_cull_face_mode() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_get_cull_face_mode) -COGL_EXPORT gboolean -cogl_get_backface_culling_enabled (void); - -/** - * cogl_flush: - * - * This function should only need to be called in exceptional circumstances. - * - * As an optimization Cogl drawing functions may batch up primitives - * internally, so if you are trying to use raw GL outside of Cogl you stand a - * better chance of being successful if you ask Cogl to flush any batched - * geometry before making your state changes. - * - * It only ensure that the underlying driver is issued all the commands - * necessary to draw the batched primitives. It provides no guarantees about - * when the driver will complete the rendering. - * - * This provides no guarantees about the GL state upon returning and to avoid - * confusing Cogl you should aim to restore any changes you make before - * resuming use of Cogl. - * - * If you are making state changes with the intention of affecting Cogl drawing - * primitives you are 100% on your own since you stand a good chance of - * conflicting with Cogl internals. For example clutter-gst which currently - * uses direct GL calls to bind ARBfp programs will very likely break when Cogl - * starts to use ARBfb programs itself for the material API. - * - * Since: 1.0 - */ -COGL_EXPORT void -cogl_flush (void); - -G_END_DECLS - -#endif /* __COGL_1_CONTEXT_H__ */ diff --git a/cogl/cogl/deprecated/cogl-auto-texture.c b/cogl/cogl/deprecated/cogl-auto-texture.c deleted file mode 100644 index 99431a5c2..000000000 --- a/cogl/cogl/deprecated/cogl-auto-texture.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2011,2012 Intel Corporation. - * Copyright (C) 2010 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum <mallum@openedhand.com> - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-texture.h" -#include "cogl-util.h" -#include "cogl-texture-2d.h" -#include "cogl-texture-2d-private.h" -#include "cogl-primitive-texture.h" -#include "cogl-texture-2d-sliced-private.h" -#include "cogl-private.h" -#include "cogl-object.h" -#include "cogl-bitmap-private.h" -#include "cogl-atlas-texture-private.h" -#include "cogl-sub-texture.h" - -#include "deprecated/cogl-auto-texture.h" - -static CoglTexture * -_cogl_texture_new_from_bitmap (CoglBitmap *bitmap, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - gboolean can_convert_in_place, - GError **error); - -static void -set_auto_mipmap_cb (CoglTexture *sub_texture, - const float *sub_texture_coords, - const float *meta_coords, - void *user_data) -{ - cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (sub_texture), - FALSE); -} - -CoglTexture * -cogl_texture_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - GError *skip_error = NULL; - - _COGL_GET_CONTEXT (ctx, NULL); - - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - - _cogl_texture_set_internal_format (tex, internal_format); - - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - skip_error = NULL; - cogl_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - /* If it fails resort to sliced textures */ - int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE; - tex = COGL_TEXTURE (cogl_texture_2d_sliced_new_with_size (ctx, - width, - height, - max_waste)); - - _cogl_texture_set_internal_format (tex, internal_format); - } - - /* NB: This api existed before Cogl introduced lazy allocation of - * textures and so we maintain its original synchronous allocation - * semantics and return NULL if allocation fails... */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - cogl_object_unref (tex); - return NULL; - } - - if (tex && - flags & COGL_TEXTURE_NO_AUTO_MIPMAP) - { - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex), - 0, 0, 1, 1, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, - set_auto_mipmap_cb, - NULL); - } - - return tex; -} - -static 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, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture *tex; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); - g_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, 0); - - /* 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, - FALSE, /* can't convert in place */ - error); - - cogl_object_unref (bmp); - - return tex; -} - -CoglTexture * -cogl_texture_new_from_data (int width, - int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - int rowstride, - const uint8_t *data) -{ - g_autoptr (GError) error = NULL; - CoglTexture *tex; - - _COGL_GET_CONTEXT (ctx, NULL); - - tex = _cogl_texture_new_from_data (ctx, - width, height, - flags, - format, internal_format, - rowstride, - data, - &error); - if (!tex) - { - COGL_NOTE (TEXTURES, "Failed to create texture with size %dx%d and " - "format %s (internal: %s) from data: %s", - width, height, - cogl_pixel_format_to_string (format), - cogl_pixel_format_to_string (internal_format), - error->message); - return NULL; - } - return tex; -} - -static CoglTexture * -_cogl_texture_new_from_bitmap (CoglBitmap *bitmap, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - gboolean can_convert_in_place, - GError **error) -{ - CoglTexture *tex; - GError *internal_error = NULL; - - if (!flags && - !COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_ATLAS)) - { - /* First try putting the texture in the atlas */ - CoglAtlasTexture *atlas_tex = - _cogl_atlas_texture_new_from_bitmap (bitmap, - can_convert_in_place); - - _cogl_texture_set_internal_format (COGL_TEXTURE (atlas_tex), - internal_format); - - if (cogl_texture_allocate (COGL_TEXTURE (atlas_tex), &internal_error)) - return COGL_TEXTURE (atlas_tex); - - g_error_free (internal_error); - internal_error = NULL; - cogl_object_unref (atlas_tex); - } - - /* If that doesn't work try a fast path 2D texture */ - tex = COGL_TEXTURE (_cogl_texture_2d_new_from_bitmap (bitmap, - can_convert_in_place)); - - _cogl_texture_set_internal_format (tex, internal_format); - - if (!cogl_texture_allocate (tex, &internal_error)) - { - COGL_NOTE (TEXTURES, - "Failed to allocate texture from bitmap with size " - "%dx%d and format %s (internal: %s), " - "falling back on slicing: %s", - cogl_bitmap_get_width (bitmap), - cogl_bitmap_get_height (bitmap), - cogl_pixel_format_to_string (cogl_bitmap_get_format (bitmap)), - cogl_pixel_format_to_string (internal_format), - internal_error->message); - g_error_free (internal_error); - internal_error = NULL; - cogl_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - /* Otherwise create a sliced texture */ - int max_waste = flags & COGL_TEXTURE_NO_SLICING ? -1 : COGL_TEXTURE_MAX_WASTE; - tex = COGL_TEXTURE (_cogl_texture_2d_sliced_new_from_bitmap (bitmap, - max_waste, - can_convert_in_place)); - - _cogl_texture_set_internal_format (tex, internal_format); - - if (!cogl_texture_allocate (tex, error)) - { - cogl_object_unref (tex); - tex = NULL; - } - } - - if (tex && - flags & COGL_TEXTURE_NO_AUTO_MIPMAP) - { - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (tex), - 0, 0, 1, 1, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE, - set_auto_mipmap_cb, - NULL); - } - - return tex; -} - -CoglTexture * -cogl_texture_new_from_bitmap (CoglBitmap *bitmap, - CoglTextureFlags flags, - CoglPixelFormat internal_format) -{ - g_autoptr (GError) error = NULL; - - CoglTexture *tex = - _cogl_texture_new_from_bitmap (bitmap, - flags, - internal_format, - FALSE, /* can't convert in-place */ - &error); - if (!tex) - { - COGL_NOTE (TEXTURES, "Failed to create texture from bitmap: %s", - error->message); - return NULL; - } - return tex; -} - -CoglTexture * -cogl_texture_new_from_file (const char *filename, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error) -{ - CoglBitmap *bmp; - CoglTexture *texture = NULL; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_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; -} - -CoglTexture * -cogl_texture_new_from_sub_texture (CoglTexture *full_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height) -{ - _COGL_GET_CONTEXT (ctx, NULL); - return COGL_TEXTURE (cogl_sub_texture_new (ctx, - full_texture, sub_x, sub_y, - sub_width, sub_height)); -} diff --git a/cogl/cogl/deprecated/cogl-auto-texture.h b/cogl/cogl/deprecated/cogl-auto-texture.h deleted file mode 100644 index 61ac84ed2..000000000 --- a/cogl/cogl/deprecated/cogl-auto-texture.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2014 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_AUTO_TEXTURE_H__ -#define __COGL_AUTO_TEXTURE_H__ - -G_BEGIN_DECLS - -#include <cogl/cogl-texture.h> - -/** - * cogl_texture_new_with_size: - * @width: width of texture in pixels. - * @height: height of texture in pixels. - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture. - * - * Creates a new #CoglTexture with the specified dimensions and pixel format. - * - * Return value: (transfer full): A newly created #CoglTexture or %NULL on failure - * - * Since: 0.8 - * Deprecated: 1.18: Use specific constructors such as - * cogl_texture_2d_new_with_size() - */ -COGL_DEPRECATED_FOR (cogl_texture_2d_new_with_size__OR__cogl_texture_2d_sliced_new_with_size) -COGL_EXPORT CoglTexture * -cogl_texture_new_with_size (unsigned int width, - unsigned int height, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -/** - * cogl_texture_new_from_file: - * @filename: the file to load - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture. If %COGL_PIXEL_FORMAT_ANY is given then a premultiplied - * format similar to the format of the source data will be used. The - * default blending equations of Cogl expect premultiplied color data; - * the main use of passing a non-premultiplied format here is if you - * have non-premultiplied source data and are going to adjust the blend - * mode (see cogl_material_set_blend()) or use the data for something - * other than straight blending. - * @error: return location for a #GError or %NULL - * - * Creates a #CoglTexture from an image file. - * - * Return value: (transfer full): A newly created #CoglTexture or - * %NULL on failure - * - * Since: 0.8 - * Deprecated: 1.18: Use specific constructors such as - * cogl_texture_2d_new_from_file() - */ -COGL_DEPRECATED_FOR (cogl_texture_2d_new_from_file__OR__cogl_texture_2d_sliced_new_from_file) -COGL_EXPORT CoglTexture * -cogl_texture_new_from_file (const char *filename, - CoglTextureFlags flags, - CoglPixelFormat internal_format, - GError **error); - -/** - * cogl_texture_new_from_data: - * @width: width of texture in pixels - * @height: height of texture in pixels - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @format: the #CoglPixelFormat the buffer is stored in in RAM - * @internal_format: the #CoglPixelFormat that will be used for storing - * the buffer on the GPU. If COGL_PIXEL_FORMAT_ANY is given then a - * premultiplied format similar to the format of the source data will - * be used. The default blending equations of Cogl expect premultiplied - * color data; the main use of passing a non-premultiplied format here - * is if you have non-premultiplied source data and are going to adjust - * the blend mode (see cogl_material_set_blend()) or use the data for - * something other than straight blending. - * @rowstride: the memory offset in bytes between the starts of - * scanlines in @data - * @data: (array): pointer the memory region where the source buffer resides - * - * Creates a new #CoglTexture based on data residing in memory. - * - * Return value: (transfer full): A newly created #CoglTexture or - * %NULL on failure - * - * Since: 0.8 - * Deprecated: 1.18: Use specific constructors such as - * cogl_texture_2d_new_from_data() - */ -COGL_DEPRECATED_FOR (cogl_texture_2d_new_from_data__OR__cogl_texture_2d_sliced_new_from_data) -COGL_EXPORT CoglTexture * -cogl_texture_new_from_data (int width, - int height, - CoglTextureFlags flags, - CoglPixelFormat format, - CoglPixelFormat internal_format, - int rowstride, - const uint8_t *data); - -/** - * cogl_texture_new_from_bitmap: - * @bitmap: A #CoglBitmap pointer - * @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE - * @internal_format: the #CoglPixelFormat to use for the GPU storage of the - * texture - * - * Creates a #CoglTexture from a #CoglBitmap. - * - * Return value: (transfer full): A newly created #CoglTexture or - * %NULL on failure - * - * Since: 1.0 - * Deprecated: 1.18: Use specific constructors such as - * cogl_texture_2d_new_from_bitmap() - */ -COGL_DEPRECATED_FOR (cogl_texture_2d_new_from_bitmap__OR__cogl_texture_2d_sliced_new_from_bitmap) -COGL_EXPORT CoglTexture * -cogl_texture_new_from_bitmap (CoglBitmap *bitmap, - CoglTextureFlags flags, - CoglPixelFormat internal_format); - -/** - * cogl_texture_new_from_sub_texture: - * @full_texture: a #CoglTexture pointer - * @sub_x: X coordinate of the top-left of the subregion - * @sub_y: Y coordinate of the top-left of the subregion - * @sub_width: Width in pixels of the subregion - * @sub_height: Height in pixels of the subregion - * - * Creates a new texture which represents a subregion of another - * texture. The GL resources will be shared so that no new texture - * data is actually allocated. - * - * Sub textures have undefined behaviour texture coordinates outside - * of the range [0,1] are used. - * - * The sub texture will keep a reference to the full texture so you do - * not need to keep one separately if you only want to use the sub - * texture. - * - * Return value: (transfer full): A newly created #CoglTexture or - * %NULL on failure - * Since: 1.2 - * Deprecated: 1.18: Use cogl_sub_texture_new() - */ -COGL_DEPRECATED_FOR (cogl_sub_texture_new) -COGL_EXPORT CoglTexture * -cogl_texture_new_from_sub_texture (CoglTexture *full_texture, - int sub_x, - int sub_y, - int sub_width, - int sub_height); - -G_END_DECLS - -#endif /* __COGL_AUTO_TEXTURE_H__ */ diff --git a/cogl/cogl/deprecated/cogl-clutter.c b/cogl/cogl/deprecated/cogl-clutter.c deleted file mode 100644 index a2528c8be..000000000 --- a/cogl/cogl/deprecated/cogl-clutter.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <glib.h> -#include <string.h> - -#include "cogl-util.h" -#include "cogl-types.h" -#include "cogl-private.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-private.h" -#ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-xlib-renderer.h" -#endif -#include "winsys/cogl-winsys-private.h" -#include "deprecated/cogl-clutter.h" - -gboolean -cogl_clutter_winsys_has_feature (CoglWinsysFeature feature) -{ - return _cogl_winsys_has_feature (feature); -} diff --git a/cogl/cogl/deprecated/cogl-clutter.h b/cogl/cogl/deprecated/cogl-clutter.h deleted file mode 100644 index 3cf624d20..000000000 --- a/cogl/cogl/deprecated/cogl-clutter.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_CLUTTER_H__ -#define __COGL_CLUTTER_H__ - -G_BEGIN_DECLS - -#define cogl_clutter_winsys_has_feature cogl_clutter_winsys_has_feature_CLUTTER -COGL_DEPRECATED_FOR (cogl_has_feature) -COGL_EXPORT gboolean -cogl_clutter_winsys_has_feature (CoglWinsysFeature feature); - -G_END_DECLS - -#endif /* __COGL_CLUTTER_H__ */ diff --git a/cogl/cogl/deprecated/cogl-material-compat.c b/cogl/cogl/deprecated/cogl-material-compat.c deleted file mode 100644 index ac7923325..000000000 --- a/cogl/cogl/deprecated/cogl-material-compat.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <cogl-pipeline.h> -#include <cogl-pipeline-private.h> -#include <cogl-types.h> -#include <cogl-context-private.h> -#include <deprecated/cogl-material-compat.h> - -G_DEFINE_BOXED_TYPE (CoglMaterial, cogl_material, - cogl_object_ref, cogl_object_unref) - -CoglMaterial * -cogl_material_new (void) -{ - _COGL_GET_CONTEXT(ctx, NULL); - return COGL_MATERIAL (cogl_pipeline_new (ctx)); -} - -void -cogl_material_set_color (CoglMaterial *material, - const CoglColor *color) -{ - cogl_pipeline_set_color (COGL_PIPELINE (material), color); -} - -void -cogl_material_set_color4ub (CoglMaterial *material, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha) -{ - cogl_pipeline_set_color4ub (COGL_PIPELINE (material), - red, green, blue, alpha); -} - -gboolean -cogl_material_set_blend (CoglMaterial *material, - const char *blend_string, - GError **error) -{ - return cogl_pipeline_set_blend (COGL_PIPELINE (material), - blend_string, - error); -} - -void -cogl_material_set_blend_constant (CoglMaterial *material, - const CoglColor *constant_color) -{ - cogl_pipeline_set_blend_constant (COGL_PIPELINE (material), constant_color); -} - -void -cogl_material_set_point_size (CoglMaterial *material, - float point_size) -{ - cogl_pipeline_set_point_size (COGL_PIPELINE (material), point_size); -} - -void -cogl_material_set_user_program (CoglMaterial *material, - CoglHandle program) -{ - cogl_pipeline_set_user_program (COGL_PIPELINE (material), program); -} - -void -cogl_material_set_layer (CoglMaterial *material, - int layer_index, - CoglHandle texture) -{ - cogl_pipeline_set_layer_texture (COGL_PIPELINE (material), - layer_index, texture); -} - -gboolean -cogl_material_set_layer_combine (CoglMaterial *material, - int layer_index, - const char *blend_string, - GError **error) -{ - return cogl_pipeline_set_layer_combine (COGL_PIPELINE (material), - layer_index, - blend_string, - error); -} - -void -cogl_material_set_layer_combine_constant (CoglMaterial *material, - int layer_index, - const CoglColor *constant) -{ - cogl_pipeline_set_layer_combine_constant (COGL_PIPELINE (material), - layer_index, - constant); -} - -void -cogl_material_set_layer_matrix (CoglMaterial *material, - int layer_index, - const graphene_matrix_t *matrix) -{ - cogl_pipeline_set_layer_matrix (COGL_PIPELINE (material), - layer_index, matrix); -} - -void -cogl_material_set_layer_filters (CoglMaterial *material, - int layer_index, - CoglMaterialFilter min_filter, - CoglMaterialFilter mag_filter) -{ - cogl_pipeline_set_layer_filters (COGL_PIPELINE (material), - layer_index, - min_filter, - mag_filter); -} - -gboolean -cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index, - gboolean enable, - GError **error) -{ - CoglPipeline *pipeline = COGL_PIPELINE (material); - return cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline, - layer_index, - enable, - error); -} diff --git a/cogl/cogl/deprecated/cogl-material-compat.h b/cogl/cogl/deprecated/cogl-material-compat.h deleted file mode 100644 index 04842f546..000000000 --- a/cogl/cogl/deprecated/cogl-material-compat.h +++ /dev/null @@ -1,642 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_MATERIAL_H__ -#define __COGL_MATERIAL_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-depth-state.h> -#include <cogl/cogl-macros.h> -#include <cogl/cogl-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-material - * @short_description: Functions for creating and manipulating materials - * - * COGL allows creating and manipulating materials used to fill in - * geometry. Materials may simply be lighting attributes (such as an - * ambient and diffuse colour) or might represent one or more textures - * blended together. - */ - -typedef struct _CoglMaterial CoglMaterial; -typedef struct _CoglMaterialLayer CoglMaterialLayer; - -#define COGL_TYPE_MATERIAL (cogl_material_get_type ()) -COGL_EXPORT -GType cogl_material_get_type (void); - -#define COGL_MATERIAL(OBJECT) ((CoglMaterial *)OBJECT) - -/** - * CoglMaterialFilter: - * @COGL_MATERIAL_FILTER_NEAREST: Measuring in manhatten distance from the, - * current pixel center, use the nearest texture texel - * @COGL_MATERIAL_FILTER_LINEAR: Use the weighted average of the 4 texels - * nearest the current pixel center - * @COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_MATERIAL_FILTER_NEAREST criterion - * @COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST: Select the mimap level whose - * texel size most closely matches the current pixel, and use the - * %COGL_MATERIAL_FILTER_LINEAR criterion - * @COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_MATERIAL_FILTER_NEAREST criterion on each one and take - * their weighted average - * @COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR: Select the two mimap levels - * whose texel size most closely matches the current pixel, use - * the %COGL_MATERIAL_FILTER_LINEAR criterion on each one and take - * their weighted average - * - * Texture filtering is used whenever the current pixel maps either to more - * than one texture element (texel) or less than one. These filter enums - * correspond to different strategies used to come up with a pixel color, by - * possibly referring to multiple neighbouring texels and taking a weighted - * average or simply using the nearest texel. - */ -typedef enum -{ - COGL_MATERIAL_FILTER_NEAREST = 0x2600, - COGL_MATERIAL_FILTER_LINEAR = 0x2601, - COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST = 0x2700, - COGL_MATERIAL_FILTER_LINEAR_MIPMAP_NEAREST = 0x2701, - COGL_MATERIAL_FILTER_NEAREST_MIPMAP_LINEAR = 0x2702, - COGL_MATERIAL_FILTER_LINEAR_MIPMAP_LINEAR = 0x2703 -} CoglMaterialFilter; -/* NB: these values come from the equivalents in gl.h */ - -/** - * CoglMaterialWrapMode: - * @COGL_MATERIAL_WRAP_MODE_REPEAT: The texture will be repeated. This - * is useful for example to draw a tiled background. - * @COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE: The coordinates outside the - * range 0→1 will sample copies of the edge pixels of the - * texture. This is useful to avoid artifacts if only one copy of - * the texture is being rendered. - * @COGL_MATERIAL_WRAP_MODE_AUTOMATIC: Cogl will try to automatically - * decide which of the above two to use. For cogl_rectangle(), it - * will use repeat mode if any of the texture coordinates are - * outside the range 0→1, otherwise it will use clamp to edge. For - * cogl_polygon() it will always use repeat mode. For - * cogl_vertex_buffer_draw() it will use repeat mode except for - * layers that have point sprite coordinate generation enabled. This - * is the default value. - * - * The wrap mode specifies what happens when texture coordinates - * outside the range 0→1 are used. Note that if the filter mode is - * anything but %COGL_MATERIAL_FILTER_NEAREST then texels outside the - * range 0→1 might be used even when the coordinate is exactly 0 or 1 - * because OpenGL will try to sample neighbouring pixels. For example - * if you are trying to render the full texture then you may get - * artifacts around the edges when the pixels from the other side are - * merged in if the wrap mode is set to repeat. - * - * Since: 1.4 - */ -/* GL_ALWAYS is just used here as a value that is known not to clash - * with any valid GL wrap modes - * - * XXX: keep the values in sync with the CoglMaterialWrapModeInternal - * enum so no conversion is actually needed. - */ -typedef enum -{ - COGL_MATERIAL_WRAP_MODE_REPEAT = 0x2901, - COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, - COGL_MATERIAL_WRAP_MODE_AUTOMATIC = 0x0207 -} CoglMaterialWrapMode; -/* NB: these values come from the equivalents in gl.h */ - -/** - * cogl_material_new: - * - * Allocates and initializes a blank white material - * - * Return value: a pointer to a new #CoglMaterial - * Deprecated: 1.16: Use cogl_pipeline_new() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_new) -COGL_EXPORT CoglMaterial * -cogl_material_new (void); - -/** - * cogl_material_set_color: - * @material: A #CoglMaterial object - * @color: The components of the color - * - * Sets the basic color of the material, used when no lighting is enabled. - * - * Note that if you don't add any layers to the material then the color - * will be blended unmodified with the destination; the default blend - * expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for - * semi-transparent red. See cogl_color_premultiply(). - * - * The default value is (1.0, 1.0, 1.0, 1.0) - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_color() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_color) -COGL_EXPORT void -cogl_material_set_color (CoglMaterial *material, - const CoglColor *color); - -/** - * cogl_material_set_color4ub: - * @material: A #CoglMaterial object - * @red: The red component - * @green: The green component - * @blue: The blue component - * @alpha: The alpha component - * - * Sets the basic color of the material, used when no lighting is enabled. - * - * The default value is (0xff, 0xff, 0xff, 0xff) - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_color4ub() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_color4ub) -COGL_EXPORT void -cogl_material_set_color4ub (CoglMaterial *material, - uint8_t red, - uint8_t green, - uint8_t blue, - uint8_t alpha); - -/** - * CoglMaterialAlphaFunc: - * @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through. - * @COGL_MATERIAL_ALPHA_FUNC_LESS: Let the fragment through if the incoming - * alpha value is less than the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_EQUAL: Let the fragment through if the incoming - * alpha value equals the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_LEQUAL: Let the fragment through if the incoming - * alpha value is less than or equal to the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_GREATER: Let the fragment through if the incoming - * alpha value is greater than the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL: Let the fragment through if the incoming - * alpha value does not equal the reference alpha value - * @COGL_MATERIAL_ALPHA_FUNC_GEQUAL: Let the fragment through if the incoming - * alpha value is greater than or equal to the reference alpha value. - * @COGL_MATERIAL_ALPHA_FUNC_ALWAYS: Always let the fragment through. - * - * Alpha testing happens before blending primitives with the framebuffer and - * gives an opportunity to discard fragments based on a comparison with the - * incoming alpha value and a reference alpha value. The #CoglMaterialAlphaFunc - * determines how the comparison is done. - */ -typedef enum -{ - COGL_MATERIAL_ALPHA_FUNC_NEVER = 0x0200, - COGL_MATERIAL_ALPHA_FUNC_LESS = 0x0201, - COGL_MATERIAL_ALPHA_FUNC_EQUAL = 0x0202, - COGL_MATERIAL_ALPHA_FUNC_LEQUAL = 0x0203, - COGL_MATERIAL_ALPHA_FUNC_GREATER = 0x0204, - COGL_MATERIAL_ALPHA_FUNC_NOTEQUAL = 0x0205, - COGL_MATERIAL_ALPHA_FUNC_GEQUAL = 0x0206, - COGL_MATERIAL_ALPHA_FUNC_ALWAYS = 0x0207 -} CoglMaterialAlphaFunc; - -/** - * cogl_material_set_alpha_test_function: - * @material: A #CoglMaterial object - * @alpha_func: A @CoglMaterialAlphaFunc constant - * @alpha_reference: A reference point that the chosen alpha function uses - * to compare incoming fragments to. - * - * Before a primitive is blended with the framebuffer, it goes through an - * alpha test stage which lets you discard fragments based on the current - * alpha value. This function lets you change the function used to evaluate - * the alpha channel, and thus determine which fragments are discarded - * and which continue on to the blending stage. - * - * The default is %COGL_MATERIAL_ALPHA_FUNC_ALWAYS - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_alpha_test_function() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_alpha_test_function) -COGL_EXPORT void -cogl_material_set_alpha_test_function (CoglMaterial *material, - CoglMaterialAlphaFunc alpha_func, - float alpha_reference); - -/** - * cogl_material_set_blend: - * @material: A #CoglMaterial object - * @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link> - * describing the desired blend function. - * @error: return location for a #GError that may report lack of driver - * support if you give separate blend string statements for the alpha - * channel and RGB channels since some drivers, or backends such as - * GLES 1.1, don't support this feature. May be %NULL, in which case a - * warning will be printed out using GLib's logging facilities if an - * error is encountered. - * - * If not already familiar; please refer <link linkend="cogl-Blend-Strings">here</link> - * for an overview of what blend strings are, and their syntax. - * - * Blending occurs after the alpha test function, and combines fragments with - * the framebuffer. - - * Currently the only blend function Cogl exposes is ADD(). So any valid - * blend statements will be of the form: - * - * |[ - * <channel-mask>=ADD(SRC_COLOR*(<factor>), DST_COLOR*(<factor>)) - * ]| - * - * <warning>The brackets around blend factors are currently not - * optional!</warning> - * - * This is the list of source-names usable as blend factors: - * <itemizedlist> - * <listitem><para>SRC_COLOR: The color of the incoming fragment</para></listitem> - * <listitem><para>DST_COLOR: The color of the framebuffer</para></listitem> - * <listitem><para>CONSTANT: The constant set via cogl_material_set_blend_constant()</para></listitem> - * </itemizedlist> - * - * The source names can be used according to the - * <link linkend="cogl-Blend-String-syntax">color-source and factor syntax</link>, - * so for example "(1-SRC_COLOR[A])" would be a valid factor, as would - * "(CONSTANT[RGB])" - * - * These can also be used as factors: - * <itemizedlist> - * <listitem>0: (0, 0, 0, 0)</listitem> - * <listitem>1: (1, 1, 1, 1)</listitem> - * <listitem>SRC_ALPHA_SATURATE_FACTOR: (f,f,f,1) where f = MIN(SRC_COLOR[A],1-DST_COLOR[A])</listitem> - * </itemizedlist> - * - * <note>Remember; all color components are normalized to the range [0, 1] - * before computing the result of blending.</note> - * - * <example id="cogl-Blend-Strings-blend-unpremul"> - * <title>Blend Strings/1</title> - * <para>Blend a non-premultiplied source over a destination with - * premultiplied alpha:</para> - * <programlisting> - * "RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))" - * "A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * </programlisting> - * </example> - * - * <example id="cogl-Blend-Strings-blend-premul"> - * <title>Blend Strings/2</title> - * <para>Blend a premultiplied source over a destination with - * premultiplied alpha</para> - * <programlisting> - * "RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))" - * </programlisting> - * </example> - * - * The default blend string is: - * |[ - * RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A])) - * ]| - * - * That gives normal alpha-blending when the calculated color for the material - * is in premultiplied form. - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described blending is supported by the underlying driver/hardware. If - * there was an error, %FALSE is returned and @error is set accordingly (if - * present). - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_blend() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_blend) -COGL_EXPORT gboolean -cogl_material_set_blend (CoglMaterial *material, - const char *blend_string, - GError **error); - -/** - * cogl_material_set_blend_constant: - * @material: A #CoglMaterial object - * @constant_color: The constant color you want - * - * When blending is setup to reference a CONSTANT blend factor then - * blending will depend on the constant set with this function. - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_blend_constant() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_blend_constant) -COGL_EXPORT void -cogl_material_set_blend_constant (CoglMaterial *material, - const CoglColor *constant_color); - -/** - * cogl_material_set_point_size: - * @material: a material. - * @point_size: the new point size. - * - * Changes the size of points drawn when %COGL_VERTICES_MODE_POINTS is - * used with the vertex buffer API. Note that typically the GPU will - * only support a limited minimum and maximum range of point sizes. If - * the chosen point size is outside that range then the nearest value - * within that range will be used instead. The size of a point is in - * screen space so it will be the same regardless of any - * transformations. The default point size is 1.0. - * - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_set_point_size() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_point_size) -COGL_EXPORT void -cogl_material_set_point_size (CoglMaterial *material, - float point_size); - -/** - * cogl_material_set_user_program: - * @material: a #CoglMaterial object. - * @program: A #CoglHandle to a linked CoglProgram - * - * Associates a linked CoglProgram with the given material so that the - * program can take full control of vertex and/or fragment processing. - * - * This is an example of how it can be used to associate an ARBfp - * program with a #CoglMaterial: - * |[ - * CoglHandle shader; - * CoglHandle program; - * CoglMaterial *material; - * - * shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - * cogl_shader_source (shader, - * "!!ARBfp1.0\n" - * "MOV result.color,fragment.color;\n" - * "END\n"); - * - * program = cogl_create_program (); - * cogl_program_attach_shader (program, shader); - * cogl_program_link (program); - * - * material = cogl_material_new (); - * cogl_material_set_user_program (material, program); - * - * cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); - * cogl_rectangle (0, 0, 100, 100); - * ]| - * - * It is possibly worth keeping in mind that this API is not part of - * the long term design for how we want to expose shaders to Cogl - * developers (We are planning on deprecating the cogl_program and - * cogl_shader APIs in favour of a "snippet" framework) but in the - * meantime we hope this will handle most practical GLSL and ARBfp - * requirements. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_material_set_user_program (CoglMaterial *material, - CoglHandle program); - -/** - * cogl_material_set_layer: - * @material: A #CoglMaterial object - * @layer_index: the index of the layer - * @texture: a #CoglHandle for the layer object - * - * In addition to the standard OpenGL lighting model a Cogl material may have - * one or more layers comprised of textures that can be blended together in - * order, with a number of different texture combine modes. This function - * defines a new texture layer. - * - * The index values of multiple layers do not have to be consecutive; it is - * only their relative order that is important. - * - * <note>In the future, we may define other types of material layers, such - * as purely GLSL based layers.</note> - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_layer() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_layer) -COGL_EXPORT void -cogl_material_set_layer (CoglMaterial *material, - int layer_index, - CoglHandle texture); - -/** - * cogl_material_set_layer_combine: - * @material: A #CoglMaterial object - * @layer_index: Specifies the layer you want define a combine function for - * @blend_string: A <link linkend="cogl-Blend-Strings">Cogl blend string</link> - * describing the desired texture combine function. - * @error: A #GError that may report parse errors or lack of GPU/driver - * support. May be %NULL, in which case a warning will be printed out if an - * error is encountered. - * - * If not already familiar; you can refer - * <link linkend="cogl-Blend-Strings">here</link> for an overview of what blend - * strings are and there syntax. - * - * These are all the functions available for texture combining: - * <itemizedlist> - * <listitem>REPLACE(arg0) = arg0</listitem> - * <listitem>MODULATE(arg0, arg1) = arg0 x arg1</listitem> - * <listitem>ADD(arg0, arg1) = arg0 + arg1</listitem> - * <listitem>ADD_SIGNED(arg0, arg1) = arg0 + arg1 - 0.5</listitem> - * <listitem>INTERPOLATE(arg0, arg1, arg2) = arg0 x arg2 + arg1 x (1 - arg2)</listitem> - * <listitem>SUBTRACT(arg0, arg1) = arg0 - arg1</listitem> - * <listitem> - * <programlisting> - * DOT3_RGB(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * </programlisting> - * </listitem> - * <listitem> - * <programlisting> - * DOT3_RGBA(arg0, arg1) = 4 x ((arg0[R] - 0.5)) * (arg1[R] - 0.5) + - * (arg0[G] - 0.5)) * (arg1[G] - 0.5) + - * (arg0[B] - 0.5)) * (arg1[B] - 0.5)) - * </programlisting> - * </listitem> - * </itemizedlist> - * - * Refer to the - * <link linkend="cogl-Blend-String-syntax">color-source syntax</link> for - * describing the arguments. The valid source names for texture combining - * are: - * <variablelist> - * <varlistentry> - * <term>TEXTURE</term> - * <listitem>Use the color from the current texture layer</listitem> - * </varlistentry> - * <varlistentry> - * <term>TEXTURE_0, TEXTURE_1, etc</term> - * <listitem>Use the color from the specified texture layer</listitem> - * </varlistentry> - * <varlistentry> - * <term>CONSTANT</term> - * <listitem>Use the color from the constant given with - * cogl_material_set_layer_constant()</listitem> - * </varlistentry> - * <varlistentry> - * <term>PRIMARY</term> - * <listitem>Use the color of the material as set with - * cogl_material_set_color()</listitem> - * </varlistentry> - * <varlistentry> - * <term>PREVIOUS</term> - * <listitem>Either use the texture color from the previous layer, or - * if this is layer 0, use the color of the material as set with - * cogl_material_set_color()</listitem> - * </varlistentry> - * </variablelist> - * - * <refsect2 id="cogl-Layer-Combine-Examples"> - * <title>Layer Combine Examples</title> - * <para>This is effectively what the default blending is:</para> - * <informalexample><programlisting> - * RGBA = MODULATE (PREVIOUS, TEXTURE) - * </programlisting></informalexample> - * <para>This could be used to cross-fade between two images, using - * the alpha component of a constant as the interpolator. The constant - * color is given by calling cogl_material_set_layer_constant.</para> - * <informalexample><programlisting> - * RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A]) - * </programlisting></informalexample> - * </refsect2> - * - * <note>You can't give a multiplication factor for arguments as you can - * with blending.</note> - * - * Return value: %TRUE if the blend string was successfully parsed, and the - * described texture combining is supported by the underlying driver and - * or hardware. On failure, %FALSE is returned and @error is set - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_combine() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_combine) -COGL_EXPORT gboolean -cogl_material_set_layer_combine (CoglMaterial *material, - int layer_index, - const char *blend_string, - GError **error); - -/** - * cogl_material_set_layer_combine_constant: - * @material: A #CoglMaterial object - * @layer_index: Specifies the layer you want to specify a constant used - * for texture combining - * @constant: The constant color you want - * - * When you are using the 'CONSTANT' color source in a layer combine - * description then you can use this function to define its value. - * - * Since: 1.0 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_combine_constant() - * instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_combine_constant) -COGL_EXPORT void -cogl_material_set_layer_combine_constant (CoglMaterial *material, - int layer_index, - const CoglColor *constant); - -/** - * cogl_material_set_layer_matrix: - * @material: A #CoglMaterial object - * @layer_index: the index for the layer inside @material - * @matrix: the transformation matrix for the layer - * - * This function lets you set a matrix that can be used to e.g. translate - * and rotate a single layer of a material used to fill your geometry. - * Deprecated: 1.16: Use cogl_pipeline_set_layer_matrix() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_matrix) -COGL_EXPORT void -cogl_material_set_layer_matrix (CoglMaterial *material, - int layer_index, - const graphene_matrix_t *matrix); - -/** - * cogl_material_set_layer_filters: - * @material: A #CoglMaterial object - * @layer_index: the layer number to change. - * @min_filter: the filter used when scaling a texture down. - * @mag_filter: the filter used when magnifying a texture. - * - * Changes the decimation and interpolation filters used when a texture is - * drawn at other scales than 100%. - * Deprecated: 1.16: Use cogl_pipeline_set_layer_filters() instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_filters) -COGL_EXPORT void -cogl_material_set_layer_filters (CoglMaterial *material, - int layer_index, - CoglMaterialFilter min_filter, - CoglMaterialFilter mag_filter); - -/** - * cogl_material_set_layer_point_sprite_coords_enabled: - * @material: a #CoglHandle to a material. - * @layer_index: the layer number to change. - * @enable: whether to enable point sprite coord generation. - * @error: A return location for a GError, or NULL to ignore errors. - * - * When rendering points, if @enable is %TRUE then the texture - * coordinates for this layer will be replaced with coordinates that - * vary from 0.0 to 1.0 across the primitive. The top left of the - * point will have the coordinates 0.0,0.0 and the bottom right will - * have 1.0,1.0. If @enable is %FALSE then the coordinates will be - * fixed for the entire point. - * - * Return value: %TRUE if the function succeeds, %FALSE otherwise. - * Since: 1.4 - * Deprecated: 1.16: Use cogl_pipeline_set_layer_point_sprite_coords_enabled() - * instead - */ -COGL_DEPRECATED_FOR (cogl_pipeline_set_layer_point_sprite_coords_enabled) -COGL_EXPORT gboolean -cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material, - int layer_index, - gboolean enable, - GError **error); - -G_END_DECLS - -#endif /* __COGL_MATERIAL_H__ */ diff --git a/cogl/cogl/deprecated/cogl-program-private.h b/cogl/cogl/deprecated/cogl-program-private.h deleted file mode 100644 index 38b5f59d8..000000000 --- a/cogl/cogl/deprecated/cogl-program-private.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_PROGRAM_H -#define __COGL_PROGRAM_H - -#include "cogl-object-private.h" -#include "cogl-shader-private.h" - -typedef struct _CoglProgram CoglProgram; - -struct _CoglProgram -{ - CoglHandleObject _parent; - - GSList *attached_shaders; - - GArray *custom_uniforms; - - /* An age counter that changes whenever the list of shaders is modified */ - unsigned int age; -}; - -typedef struct _CoglProgramUniform CoglProgramUniform; - -struct _CoglProgramUniform -{ - char *name; - CoglBoxedValue value; - /* The cached GL location for this uniform. This is only valid - between calls to _cogl_program_dirty_all_uniforms */ - GLint location; - /* Whether we have a location yet */ - unsigned int location_valid : 1; - /* Whether the uniform value has changed since the last time the - uniforms were flushed */ - unsigned int dirty : 1; -}; - -/* Internal function to flush the custom uniforms for the given use - program. This assumes the target GL program is already bound. The - gl_program still needs to be passed so that CoglProgram can query - the uniform locations. gl_program_changed should be set to TRUE if - we are flushing the uniforms against a different GL program from - the last time it was flushed. This will cause it to requery all of - the locations and assume that all uniforms are dirty */ -void -_cogl_program_flush_uniforms (CoglProgram *program, - GLuint gl_program, - gboolean gl_program_changed); - -gboolean -_cogl_program_has_fragment_shader (CoglHandle handle); - -gboolean -_cogl_program_has_vertex_shader (CoglHandle handle); - -#endif /* __COGL_PROGRAM_H */ diff --git a/cogl/cogl/deprecated/cogl-program.c b/cogl/cogl/deprecated/cogl-program.c deleted file mode 100644 index fe75e8e68..000000000 --- a/cogl/cogl/deprecated/cogl-program.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" - -#include "deprecated/cogl-shader-private.h" -#include "deprecated/cogl-program-private.h" - -#include <string.h> - -static void _cogl_program_free (CoglProgram *program); - -COGL_HANDLE_DEFINE (Program, program); - -/* A CoglProgram is effectively just a list of shaders that will be - used together and a set of values for the custom uniforms. No - actual GL program is created - instead this is the responsibility - of the GLSL material backend. The uniform values are collected in - an array and then flushed whenever the material backend requests - it. */ - -static void -_cogl_program_free (CoglProgram *program) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Unref all of the attached shaders and destroy the list */ - g_slist_free_full (program->attached_shaders, cogl_object_unref); - - for (i = 0; i < program->custom_uniforms->len; i++) - { - CoglProgramUniform *uniform = - &g_array_index (program->custom_uniforms, CoglProgramUniform, i); - - g_free (uniform->name); - - if (uniform->value.count > 1) - g_free (uniform->value.v.array); - } - - g_array_free (program->custom_uniforms, TRUE); - - g_free (program); -} - -CoglHandle -cogl_create_program (void) -{ - CoglProgram *program; - - program = g_new0 (CoglProgram, 1); - - program->custom_uniforms = - g_array_new (FALSE, FALSE, sizeof (CoglProgramUniform)); - program->age = 0; - - return _cogl_program_handle_new (program); -} - -void -cogl_program_attach_shader (CoglHandle program_handle, - CoglHandle shader_handle) -{ - CoglProgram *program; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_program (program_handle) || !cogl_is_shader (shader_handle)) - return; - - program = program_handle; - - program->attached_shaders - = g_slist_prepend (program->attached_shaders, - cogl_object_ref (shader_handle)); - - program->age++; -} - -void -cogl_program_link (CoglHandle handle) -{ - /* There's no point in linking the program here because it will have - to be relinked with a different fixed functionality shader - whenever the settings change */ -} - -int -cogl_program_get_uniform_location (CoglHandle handle, - const char *uniform_name) -{ - int i; - CoglProgram *program; - CoglProgramUniform *uniform; - - if (!cogl_is_program (handle)) - return -1; - - program = handle; - - /* We can't just ask the GL program object for the uniform location - directly because it will change every time the program is linked - with a different shader. Instead we make our own mapping of - uniform numbers and cache the names */ - for (i = 0; i < program->custom_uniforms->len; i++) - { - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, i); - - if (!strcmp (uniform->name, uniform_name)) - return i; - } - - /* Create a new uniform with the given name */ - g_array_set_size (program->custom_uniforms, - program->custom_uniforms->len + 1); - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, - program->custom_uniforms->len - 1); - - uniform->name = g_strdup (uniform_name); - memset (&uniform->value, 0, sizeof (CoglBoxedValue)); - uniform->dirty = TRUE; - uniform->location_valid = FALSE; - - return program->custom_uniforms->len - 1; -} - -static CoglProgramUniform * -cogl_program_modify_uniform (CoglProgram *program, - int uniform_no) -{ - CoglProgramUniform *uniform; - - g_return_val_if_fail (cogl_is_program (program), NULL); - g_return_val_if_fail (uniform_no >= 0 && - uniform_no < program->custom_uniforms->len, - NULL); - - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, uniform_no); - uniform->dirty = TRUE; - - return uniform; -} - -void -cogl_program_set_uniform_1f (CoglHandle handle, - int uniform_location, - float value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (handle, uniform_location); - _cogl_boxed_value_set_1f (&uniform->value, value); -} - -void -cogl_program_set_uniform_1i (CoglHandle handle, - int uniform_location, - int value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (handle, uniform_location); - _cogl_boxed_value_set_1i (&uniform->value, value); -} - -void -cogl_program_set_uniform_float (CoglHandle handle, - int uniform_location, - int n_components, - int count, - const float *value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (handle, uniform_location); - _cogl_boxed_value_set_float (&uniform->value, n_components, count, value); -} - -void -cogl_program_set_uniform_int (CoglHandle handle, - int uniform_location, - int n_components, - int count, - const int *value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (handle, uniform_location); - _cogl_boxed_value_set_int (&uniform->value, n_components, count, value); -} - -void -cogl_program_set_uniform_matrix (CoglHandle handle, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value) -{ - CoglProgramUniform *uniform; - - uniform = cogl_program_modify_uniform (handle, uniform_location); - _cogl_boxed_value_set_matrix (&uniform->value, - dimensions, - count, - transpose, - value); -} - -void -_cogl_program_flush_uniforms (CoglProgram *program, - GLuint gl_program, - gboolean gl_program_changed) -{ - CoglProgramUniform *uniform; - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - for (i = 0; i < program->custom_uniforms->len; i++) - { - uniform = &g_array_index (program->custom_uniforms, - CoglProgramUniform, i); - - if (gl_program_changed || uniform->dirty) - { - if (gl_program_changed || !uniform->location_valid) - { - uniform->location = - ctx->glGetUniformLocation (gl_program, uniform->name); - - uniform->location_valid = TRUE; - } - - /* If the uniform isn't really in the program then there's - no need to actually set it */ - if (uniform->location != -1) - { - _cogl_boxed_value_set_uniform (ctx, - uniform->location, - &uniform->value); - } - - uniform->dirty = FALSE; - } - } -} - -static gboolean -_cogl_program_has_shader_type (CoglProgram *program, - CoglShaderType type) -{ - GSList *l; - - for (l = program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - - if (shader->type == type) - return TRUE; - } - - return FALSE; -} - -gboolean -_cogl_program_has_fragment_shader (CoglHandle handle) -{ - return _cogl_program_has_shader_type (handle, COGL_SHADER_TYPE_FRAGMENT); -} - -gboolean -_cogl_program_has_vertex_shader (CoglHandle handle) -{ - return _cogl_program_has_shader_type (handle, COGL_SHADER_TYPE_VERTEX); -} diff --git a/cogl/cogl/deprecated/cogl-shader-private.h b/cogl/cogl/deprecated/cogl-shader-private.h deleted file mode 100644 index ae47f1879..000000000 --- a/cogl/cogl/deprecated/cogl-shader-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_SHADER_H -#define __COGL_SHADER_H - -#include "cogl-object-private.h" -#include "cogl-shader.h" -#include "cogl-gl-header.h" -#include "cogl-pipeline.h" - -typedef struct _CoglShader CoglShader; - -struct _CoglShader -{ - CoglHandleObject _parent; - GLuint gl_handle; - CoglPipeline *compilation_pipeline; - CoglShaderType type; - char *source; -}; - -#endif /* __COGL_SHADER_H */ diff --git a/cogl/cogl/deprecated/cogl-shader.c b/cogl/cogl/deprecated/cogl-shader.c deleted file mode 100644 index fb1b7ae28..000000000 --- a/cogl/cogl/deprecated/cogl-shader.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-glsl-shader-boilerplate.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "deprecated/cogl-shader-private.h" - -#include <glib.h> - -#include <string.h> - -static void _cogl_shader_free (CoglShader *shader); - -COGL_HANDLE_DEFINE (Shader, shader); - -static void -_cogl_shader_free (CoglShader *shader) -{ - /* Frees shader resources but its handle is not - released! Do that separately before this! */ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader->gl_handle) - GE (ctx, glDeleteShader (shader->gl_handle)); - - g_free (shader); -} - -CoglHandle -cogl_create_shader (CoglShaderType type) -{ - CoglShader *shader; - - _COGL_GET_CONTEXT (ctx, NULL); - - switch (type) - { - case COGL_SHADER_TYPE_VERTEX: - case COGL_SHADER_TYPE_FRAGMENT: - break; - default: - g_warning ("Unexpected shader type (0x%08lX) given to " - "cogl_create_shader", (unsigned long) type); - return NULL; - } - - shader = g_new0 (CoglShader, 1); - shader->gl_handle = 0; - shader->compilation_pipeline = NULL; - shader->type = type; - - return _cogl_shader_handle_new (shader); -} - -void -cogl_shader_source (CoglHandle handle, - const char *source) -{ - CoglShader *shader; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!cogl_is_shader (handle)) - return; - - shader = handle; - - shader->source = g_strdup (source); -} - -CoglShaderType -cogl_shader_get_type (CoglHandle handle) -{ - CoglShader *shader; - - _COGL_GET_CONTEXT (ctx, COGL_SHADER_TYPE_VERTEX); - - if (!cogl_is_shader (handle)) - { - g_warning ("Non shader handle type passed to cogl_shader_get_type"); - return COGL_SHADER_TYPE_VERTEX; - } - - shader = handle; - return shader->type; -} diff --git a/cogl/cogl/deprecated/cogl-shader.h b/cogl/cogl/deprecated/cogl-shader.h deleted file mode 100644 index 79c023664..000000000 --- a/cogl/cogl/deprecated/cogl-shader.h +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_SHADER_H__ -#define __COGL_SHADER_H__ - -#include <cogl/cogl-types.h> -#include <cogl/cogl-defines.h> -#include <cogl/cogl-macros.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-shaders - * @short_description: Functions for accessing the programmable GL pipeline - * - * Cogl allows accessing the GL programmable pipeline in order to create - * vertex and fragment shaders. - * - * When using GLSL Cogl provides replacement names for most of the - * builtin varyings and uniforms. It is recommended to use these names - * wherever possible to increase portability between OpenGL 2.0 and - * GLES 2.0. GLES 2.0 does not have most of the builtins under their - * original names so they will only work with the Cogl names. - * - * For use in all GLSL shaders, the Cogl builtins are as follows: - * - * <tip> - * <glosslist> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_modelview_matrix</emphasis></glossterm> - * <glossdef><para> - * The current modelview matrix. This is equivalent to - * #gl_ModelViewMatrix. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_projection_matrix</emphasis></glossterm> - * <glossdef><para> - * The current projection matrix. This is equivalent to - * #gl_ProjectionMatrix. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_modelview_projection_matrix</emphasis></glossterm> - * <glossdef><para> - * The combined modelview and projection matrix. A vertex shader - * would typically use this to transform the incoming vertex - * position. The separate modelview and projection matrices are - * usually only needed for lighting calculations. This is - * equivalent to #gl_ModelViewProjectionMatrix. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>uniform mat4 - * <emphasis>cogl_texture_matrix</emphasis>[]</glossterm> - * <glossdef><para> - * An array of matrices for transforming the texture - * coordinates. This is equivalent to #gl_TextureMatrix. - * </para></glossdef> - * </glossentry> - * </glosslist> - * </tip> - * - * In a vertex shader, the following are also available: - * - * <tip> - * <glosslist> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_position_in</emphasis></glossterm> - * <glossdef><para> - * The incoming vertex position. This is equivalent to #gl_Vertex. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_color_in</emphasis></glossterm> - * <glossdef><para> - * The incoming vertex color. This is equivalent to #gl_Color. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_tex_coord_in</emphasis></glossterm> - * <glossdef><para> - * The texture coordinate for the first texture unit. This is - * equivalent to #gl_MultiTexCoord0. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec4 - * <emphasis>cogl_tex_coord0_in</emphasis></glossterm> - * <glossdef><para> - * The texture coordinate for the first texture unit. This is - * equivalent to #gl_MultiTexCoord0. There is also - * #cogl_tex_coord1_in and so on. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>attribute vec3 - * <emphasis>cogl_normal_in</emphasis></glossterm> - * <glossdef><para> - * The normal of the vertex. This is equivalent to #gl_Normal. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>vec4 - * <emphasis>cogl_position_out</emphasis></glossterm> - * <glossdef><para> - * The calculated position of the vertex. This must be written to - * in all vertex shaders. This is equivalent to #gl_Position. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>float - * <emphasis>cogl_point_size_out</emphasis></glossterm> - * <glossdef><para> - * The calculated size of a point. This is equivalent to #gl_PointSize. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>varying vec4 - * <emphasis>cogl_color_out</emphasis></glossterm> - * <glossdef><para> - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>varying vec4 - * <emphasis>cogl_tex_coord_out</emphasis>[]</glossterm> - * <glossdef><para> - * An array of calculated texture coordinates for a vertex. This is - * equivalent to #gl_TexCoord. - * </para></glossdef> - * </glossentry> - * </glosslist> - * </tip> - * - * In a fragment shader, the following are also available: - * - * <tip> - * <glosslist> - * <glossentry> - * <glossterm>varying vec4 <emphasis>cogl_color_in</emphasis></glossterm> - * <glossdef><para> - * The calculated color of a vertex. This is equivalent to #gl_FrontColor. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>varying vec4 - * <emphasis>cogl_tex_coord_in</emphasis>[]</glossterm> - * <glossdef><para> - * An array of calculated texture coordinates for a vertex. This is - * equivalent to #gl_TexCoord. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>vec4 <emphasis>cogl_color_out</emphasis></glossterm> - * <glossdef><para> - * The final calculated color of the fragment. All fragment shaders - * must write to this variable. This is equivalent to - * #gl_FrontColor. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>float <emphasis>cogl_depth_out</emphasis></glossterm> - * <glossdef><para> - * An optional output variable specifying the depth value to use - * for this fragment. This is equivalent to #gl_FragDepth. - * </para></glossdef> - * </glossentry> - * <glossentry> - * <glossterm>bool <emphasis>cogl_front_facing</emphasis></glossterm> - * <glossdef><para> - * A readonly variable that will be true if the current primitive - * is front facing. This can be used to implement two-sided - * coloring algorithms. This is equivalent to #gl_FrontFacing. - * </para></glossdef> - * </glossentry> - * </glosslist> - * </tip> - * - * It's worth nothing that this API isn't what Cogl would like to have - * in the long term and it may be removed in Cogl 2.0. The - * experimental #CoglShader API is the proposed replacement. - */ - -/** - * CoglShaderType: - * @COGL_SHADER_TYPE_VERTEX: A program for processing vertices - * @COGL_SHADER_TYPE_FRAGMENT: A program for processing fragments - * - * Types of shaders - * - * Since: 1.0 - */ -typedef enum -{ - COGL_SHADER_TYPE_VERTEX, - COGL_SHADER_TYPE_FRAGMENT -} CoglShaderType; - -/** - * cogl_create_shader: - * @shader_type: COGL_SHADER_TYPE_VERTEX or COGL_SHADER_TYPE_FRAGMENT. - * - * Create a new shader handle, use cogl_shader_source() to set the - * source code to be used on it. - * - * Returns: a new shader handle. - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT CoglHandle -cogl_create_shader (CoglShaderType shader_type); - -/** - * cogl_is_shader: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing shader object. - * - * Returns: %TRUE if the handle references a shader, - * %FALSE otherwise - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT gboolean -cogl_is_shader (CoglHandle handle); - -/** - * cogl_shader_source: - * @shader: #CoglHandle for a shader. - * @source: Shader source. - * - * Replaces the current source associated with a shader with a new - * one. - * - * Please see <link - * linkend="cogl-Shaders-and-Programmable-Pipeline.description">above</link> - * for a description of the recommended format for the shader code. - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_shader_source (CoglHandle shader, - const char *source); - -/** - * cogl_shader_get_type: - * @handle: #CoglHandle for a shader. - * - * Retrieves the type of a shader #CoglHandle - * - * Return value: %COGL_SHADER_TYPE_VERTEX if the shader is a vertex processor - * or %COGL_SHADER_TYPE_FRAGMENT if the shader is a frament processor - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT CoglShaderType -cogl_shader_get_type (CoglHandle handle); - -/** - * cogl_create_program: - * - * Create a new cogl program object that can be used to replace parts of the GL - * rendering pipeline with custom code. - * - * Returns: a new cogl program. - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT CoglHandle -cogl_create_program (void); - -/** - * cogl_is_program: - * @handle: A CoglHandle - * - * Gets whether the given handle references an existing program object. - * - * Returns: %TRUE if the handle references a program, - * %FALSE otherwise - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT gboolean -cogl_is_program (CoglHandle handle); - -/** - * cogl_program_attach_shader: - * @program_handle: a #CoglHandle for a shdaer program. - * @shader_handle: a #CoglHandle for a vertex of fragment shader. - * - * Attaches a shader to a program object. A program can have multiple - * vertex or fragment shaders but only one of them may provide a - * main() function. It is allowed to use a program with only a vertex - * shader or only a fragment shader. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_attach_shader (CoglHandle program_handle, - CoglHandle shader_handle); - -/** - * cogl_program_link: - * @handle: a #CoglHandle for a shader program. - * - * Links a program making it ready for use. Note that calling this - * function is optional. If it is not called the program will - * automatically be linked the first time it is used. - * - * Deprecated: 1.16: Use #CoglSnippet api - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_link (CoglHandle handle); - -/** - * cogl_program_get_uniform_location: - * @handle: a #CoglHandle for a shader program. - * @uniform_name: the name of a uniform. - * - * Retrieve the location (offset) of a uniform variable in a shader program, - * a uniform is a variable that is constant for all vertices/fragments for a - * shader object and is possible to modify as an external parameter. - * - * Return value: the offset of a uniform in a specified program. - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT int -cogl_program_get_uniform_location (CoglHandle handle, - const char *uniform_name); - -/** - * cogl_program_set_uniform_1f: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @value: the new value of the uniform. - * - * Changes the value of a floating point uniform for the given linked - * @program. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_1f (CoglHandle program, - int uniform_location, - float value); - -/** - * cogl_program_set_uniform_1i: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @value: the new value of the uniform. - * - * Changes the value of an integer uniform for the given linked - * @program. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_1i (CoglHandle program, - int uniform_location, - int value); - -/** - * cogl_program_set_uniform_float: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @n_components: The number of components for the uniform. For - * example with glsl you'd use 3 for a vec3 or 4 for a vec4. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @value: (array length=count): the new value of the uniform[s]. - * - * Changes the value of a float vector uniform, or uniform array for - * the given linked @program. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_float (CoglHandle program, - int uniform_location, - int n_components, - int count, - const float *value); - -/** - * cogl_program_set_uniform_int: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @n_components: The number of components for the uniform. For - * example with glsl you'd use 3 for a vec3 or 4 for a vec4. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @value: (array length=count): the new value of the uniform[s]. - * - * Changes the value of a int vector uniform, or uniform array for - * the given linked @program. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_int (CoglHandle program, - int uniform_location, - int n_components, - int count, - const int *value); - -/** - * cogl_program_set_uniform_matrix: - * @program: A #CoglHandle for a linked program - * @uniform_location: the uniform location retrieved from - * cogl_program_get_uniform_location(). - * @dimensions: The dimensions of the matrix. So for for example pass - * 2 for a 2x2 matrix or 3 for 3x3. - * @count: For uniform arrays this is the array length otherwise just - * pass 1 - * @transpose: Whether to transpose the matrix when setting the uniform. - * @value: (array length=count): the new value of the uniform. - * - * Changes the value of a matrix uniform, or uniform array in the - * given linked @program. - * - * Since: 1.4 - * Deprecated: 1.16: Use #CoglSnippet api instead - */ -COGL_DEPRECATED_FOR (cogl_snippet_) -COGL_EXPORT void -cogl_program_set_uniform_matrix (CoglHandle program, - int uniform_location, - int dimensions, - int count, - gboolean transpose, - const float *value); - -G_END_DECLS - -#endif /* __COGL_SHADER_H__ */ diff --git a/cogl/cogl/deprecated/cogl-type-casts.h b/cogl/cogl/deprecated/cogl-type-casts.h deleted file mode 100644 index 4ea811011..000000000 --- a/cogl/cogl/deprecated/cogl-type-casts.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) -#error "Only <cogl/cogl.h> can be included directly." -#endif - -#ifndef __COGL_TYPE_CASTS_H__ -#define __COGL_TYPE_CASTS_H__ - -/* The various interface types in Cogl used to be more strongly typed - * which required lots type casting by developers. We provided - * macros for performing these casts following a widely used Gnome - * coding style. Since we now consistently typedef these interfaces - * as void for the public C api and use runtime type checking to - * catch programming errors the casts have become redundant and - * so these macros are only kept for compatibility... - */ - -#if !defined(COGL_ENABLE_MUTTER_API) && !defined(COGL_GIR_SCANNING) -#define COGL_BUFFER(X) (X) -#define COGL_TEXTURE(X) (X) -#define COGL_META_TEXTURE(X) (X) -#define COGL_PRIMITIVE_TEXTURE(X) (X) -#endif - -#endif /* __COGL_TYPE_CASTS_H__ */ diff --git a/cogl/cogl/driver/gl/cogl-attribute-gl-private.h b/cogl/cogl/driver/gl/cogl-attribute-gl-private.h deleted file mode 100644 index 8370621e3..000000000 --- a/cogl/cogl/driver/gl/cogl-attribute-gl-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_ATTRIBUTE_GL_PRIVATE_H_ -#define _COGL_ATTRIBUTE_GL_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-framebuffer.h" -#include "cogl-attribute.h" -#include "cogl-attribute-private.h" - -void -_cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); - -#endif /* _COGL_ATTRIBUTE_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-attribute-gl.c b/cogl/cogl/driver/gl/cogl-attribute-gl.c deleted file mode 100644 index d619e286f..000000000 --- a/cogl/cogl/driver/gl/cogl-attribute-gl.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-private.h" -#include "cogl-context-private.h" -#include "cogl-attribute.h" -#include "cogl-attribute-private.h" -#include "driver/gl/cogl-attribute-gl-private.h" -#include "driver/gl/cogl-buffer-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-pipeline-progend-glsl-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -typedef struct _ForeachChangedBitState -{ - CoglContext *context; - const CoglBitmask *new_bits; - CoglPipeline *pipeline; -} ForeachChangedBitState; - -static gboolean -toggle_custom_attribute_enabled_cb (int bit_num, void *user_data) -{ - ForeachChangedBitState *state = user_data; - gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num); - CoglContext *context = state->context; - - if (enabled) - GE( context, glEnableVertexAttribArray (bit_num) ); - else - GE( context, glDisableVertexAttribArray (bit_num) ); - - return TRUE; -} - -static void -foreach_changed_bit_and_save (CoglContext *context, - CoglBitmask *current_bits, - const CoglBitmask *new_bits, - CoglBitmaskForeachFunc callback, - ForeachChangedBitState *state) -{ - /* Get the list of bits that are different */ - _cogl_bitmask_clear_all (&context->changed_bits_tmp); - _cogl_bitmask_set_bits (&context->changed_bits_tmp, current_bits); - _cogl_bitmask_xor_bits (&context->changed_bits_tmp, new_bits); - - /* Iterate over each bit to change */ - state->new_bits = new_bits; - _cogl_bitmask_foreach (&context->changed_bits_tmp, - callback, - state); - - /* Store the new values */ - _cogl_bitmask_clear_all (current_bits); - _cogl_bitmask_set_bits (current_bits, new_bits); -} - -static void -setup_generic_buffered_attribute (CoglContext *context, - CoglPipeline *pipeline, - CoglAttribute *attribute, - uint8_t *base) -{ - int name_index = attribute->name_state->name_index; - int attrib_location = - _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index); - - if (attrib_location == -1) - return; - - GE( context, glVertexAttribPointer (attrib_location, - attribute->d.buffered.n_components, - attribute->d.buffered.type, - attribute->normalized, - attribute->d.buffered.stride, - base + attribute->d.buffered.offset) ); - _cogl_bitmask_set (&context->enable_custom_attributes_tmp, - attrib_location, TRUE); -} - -static void -setup_generic_const_attribute (CoglContext *context, - CoglPipeline *pipeline, - CoglAttribute *attribute) -{ - int name_index = attribute->name_state->name_index; - int attrib_location = - _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index); - int columns; - int i; - - if (attrib_location == -1) - return; - - if (attribute->d.constant.boxed.type == COGL_BOXED_MATRIX) - columns = attribute->d.constant.boxed.size; - else - columns = 1; - - /* Note: it's ok to access a COGL_BOXED_FLOAT as a matrix with only - * one column... */ - - switch (attribute->d.constant.boxed.size) - { - case 1: - GE( context, glVertexAttrib1fv (attrib_location, - attribute->d.constant.boxed.v.matrix)); - break; - case 2: - for (i = 0; i < columns; i++) - GE( context, glVertexAttrib2fv (attrib_location + i, - attribute->d.constant.boxed.v.matrix)); - break; - case 3: - for (i = 0; i < columns; i++) - GE( context, glVertexAttrib3fv (attrib_location + i, - attribute->d.constant.boxed.v.matrix)); - break; - case 4: - for (i = 0; i < columns; i++) - GE( context, glVertexAttrib4fv (attrib_location + i, - attribute->d.constant.boxed.v.matrix)); - break; - default: - g_warn_if_reached (); - } -} - -static void -apply_attribute_enable_updates (CoglContext *context, - CoglPipeline *pipeline) -{ - ForeachChangedBitState changed_bits_state; - - changed_bits_state.context = context; - changed_bits_state.pipeline = pipeline; - changed_bits_state.new_bits = &context->enable_custom_attributes_tmp; - foreach_changed_bit_and_save (context, - &context->enabled_custom_attributes, - &context->enable_custom_attributes_tmp, - toggle_custom_attribute_enabled_cb, - &changed_bits_state); -} - -void -_cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - int i; - gboolean with_color_attrib = FALSE; - gboolean unknown_color_alpha = FALSE; - CoglPipeline *copy = NULL; - - /* Iterate the attributes to see if we have a color attribute which - * may affect our decision to enable blending or not. - * - * We need to do this before flushing the pipeline. */ - for (i = 0; i < n_attributes; i++) - switch (attributes[i]->name_state->name_id) - { - case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY: - if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 && - _cogl_attribute_get_n_components (attributes[i]) == 4) - unknown_color_alpha = TRUE; - with_color_attrib = TRUE; - break; - - default: - break; - } - - if (G_UNLIKELY (layers_state->options.flags)) - { - /* If we haven't already created a derived pipeline... */ - if (!copy) - { - copy = cogl_pipeline_copy (pipeline); - pipeline = copy; - } - _cogl_pipeline_apply_overrides (pipeline, &layers_state->options); - - /* TODO: - * overrides = cogl_pipeline_get_data (pipeline, - * last_overrides_key); - * if (overrides) - * { - * age = cogl_pipeline_get_age (pipeline); - * XXX: actually we also need to check for legacy_state - * if (overrides->ags != age || - * memcmp (&overrides->options, &options, - * sizeof (options) != 0) - * { - * cogl_object_unref (overrides->weak_pipeline); - * g_free (overrides); - * overrides = NULL; - * } - * } - * if (!overrides) - * { - * overrides = g_new0 (Overrides, 1); - * overrides->weak_pipeline = - * cogl_pipeline_weak_copy (pipeline); - * _cogl_pipeline_apply_overrides (overrides->weak_pipeline, - * &options); - * - * cogl_pipeline_set_data (pipeline, last_overrides_key, - * weak_overrides, - * free_overrides_cb, - * NULL); - * } - * pipeline = overrides->weak_pipeline; - */ - } - - _cogl_pipeline_flush_gl_state (ctx, - pipeline, - framebuffer, - with_color_attrib, - unknown_color_alpha); - - _cogl_bitmask_clear_all (&ctx->enable_custom_attributes_tmp); - - /* Bind the attribute pointers. We need to do this after the - * pipeline is flushed because when using GLSL that is the only - * point when we can determine the attribute locations */ - - for (i = 0; i < n_attributes; i++) - { - CoglAttribute *attribute = attributes[i]; - CoglAttributeBuffer *attribute_buffer; - CoglBuffer *buffer; - uint8_t *base; - - if (attribute->is_buffered) - { - attribute_buffer = cogl_attribute_get_buffer (attribute); - buffer = COGL_BUFFER (attribute_buffer); - - /* Note: we don't try and catch errors with binding buffers - * here since OOM errors at this point indicate that nothing - * has yet been uploaded to attribute buffer which we - * consider to be a programmer error. - */ - base = - _cogl_buffer_gl_bind (buffer, - COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER, - NULL); - - setup_generic_buffered_attribute (ctx, pipeline, attribute, base); - - _cogl_buffer_gl_unbind (buffer); - } - else - { - setup_generic_const_attribute (ctx, pipeline, attribute); - } - } - - apply_attribute_enable_updates (ctx, pipeline); - - if (copy) - cogl_object_unref (copy); -} diff --git a/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h b/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h deleted file mode 100644 index b2726c421..000000000 --- a/cogl/cogl/driver/gl/cogl-bitmap-gl-private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007 OpenedHand - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_BITMAP_GL_PRIVATE_H -#define __COGL_BITMAP_GL_PRIVATE_H - -#include "cogl-bitmap-private.h" - -/* These two are replacements for map and unmap that should used when - * the pointer is going to be passed to GL for pixel packing or - * unpacking. The address might not be valid for reading if the bitmap - * was created with new_from_buffer but it will however be good to - * pass to glTexImage2D for example. The access should be READ for - * unpacking and WRITE for packing. It can not be both - */ -uint8_t * -_cogl_bitmap_gl_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -void -_cogl_bitmap_gl_unbind (CoglBitmap *bitmap); - -#endif /* __COGL_BITMAP_GL_PRIVATE_H */ diff --git a/cogl/cogl/driver/gl/cogl-bitmap-gl.c b/cogl/cogl/driver/gl/cogl-bitmap-gl.c deleted file mode 100644 index 8011d7fc8..000000000 --- a/cogl/cogl/driver/gl/cogl-bitmap-gl.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-util.h" -#include "cogl-debug.h" -#include "cogl-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-buffer-private.h" -#include "cogl-pixel-buffer.h" -#include "cogl-context-private.h" -#include "cogl-gtype-private.h" -#include "cogl-buffer-gl-private.h" -#include "cogl-bitmap-gl-private.h" - -uint8_t * -_cogl_bitmap_gl_bind (CoglBitmap *bitmap, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - uint8_t *ptr; - GError *internal_error = NULL; - - g_return_val_if_fail (access & (COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE), - NULL); - - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - return _cogl_bitmap_gl_bind (bitmap->shared_bmp, access, hints, error); - - g_return_val_if_fail (!bitmap->bound, NULL); - - /* If the bitmap wasn't created from a buffer then the - implementation of bind is the same as map */ - if (bitmap->buffer == NULL) - { - uint8_t *data = _cogl_bitmap_map (bitmap, access, hints, error); - if (data) - bitmap->bound = TRUE; - return data; - } - - if (access == COGL_BUFFER_ACCESS_READ) - ptr = _cogl_buffer_gl_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK, - &internal_error); - else if (access == COGL_BUFFER_ACCESS_WRITE) - ptr = _cogl_buffer_gl_bind (bitmap->buffer, - COGL_BUFFER_BIND_TARGET_PIXEL_PACK, - &internal_error); - else - { - ptr = NULL; - g_assert_not_reached (); - return NULL; - } - - /* NB: _cogl_buffer_gl_bind() may return NULL in non-error - * conditions so we have to explicitly check internal_error to see - * if an exception was thrown */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return NULL; - } - - bitmap->bound = TRUE; - - /* The data pointer actually stores the offset */ - return ptr + GPOINTER_TO_INT (bitmap->data); -} - -void -_cogl_bitmap_gl_unbind (CoglBitmap *bitmap) -{ - /* Divert to another bitmap if this data is shared */ - if (bitmap->shared_bmp) - { - _cogl_bitmap_gl_unbind (bitmap->shared_bmp); - return; - } - - g_assert (bitmap->bound); - bitmap->bound = FALSE; - - /* If the bitmap wasn't created from a pixel array then the - implementation of unbind is the same as unmap */ - if (bitmap->buffer) - _cogl_buffer_gl_unbind (bitmap->buffer); - else - _cogl_bitmap_unmap (bitmap); -} diff --git a/cogl/cogl/driver/gl/cogl-buffer-gl-private.h b/cogl/cogl/driver/gl/cogl-buffer-gl-private.h deleted file mode 100644 index 61807f17e..000000000 --- a/cogl/cogl/driver/gl/cogl-buffer-gl-private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_BUFFER_GL_PRIVATE_H_ -#define _COGL_BUFFER_GL_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-context.h" -#include "cogl-buffer.h" -#include "cogl-buffer-private.h" - -void -_cogl_buffer_gl_create (CoglBuffer *buffer); - -void -_cogl_buffer_gl_destroy (CoglBuffer *buffer); - -void * -_cogl_buffer_gl_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error); - -void -_cogl_buffer_gl_unmap (CoglBuffer *buffer); - -gboolean -_cogl_buffer_gl_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error); - -void * -_cogl_buffer_gl_bind (CoglBuffer *buffer, - CoglBufferBindTarget target, - GError **error); - -void -_cogl_buffer_gl_unbind (CoglBuffer *buffer); - -#endif /* _COGL_BUFFER_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-buffer-gl.c b/cogl/cogl/driver/gl/cogl-buffer-gl.c deleted file mode 100644 index cca19719f..000000000 --- a/cogl/cogl/driver/gl/cogl-buffer-gl.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2011,2012,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Damien Lespiau <damien.lespiau@intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "driver/gl/cogl-buffer-gl-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -/* - * GL/GLES compatibility defines for the buffer API: - */ - -#ifndef GL_PIXEL_PACK_BUFFER -#define GL_PIXEL_PACK_BUFFER 0x88EB -#endif -#ifndef GL_PIXEL_UNPACK_BUFFER -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#endif -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 -#endif -#ifndef GL_ELEMENT_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8893 -#endif -#ifndef GL_READ_ONLY -#define GL_READ_ONLY 0x88B8 -#endif -#ifndef GL_WRITE_ONLY -#define GL_WRITE_ONLY 0x88B9 -#endif -#ifndef GL_READ_WRITE -#define GL_READ_WRITE 0x88BA -#endif -#ifndef GL_MAP_READ_BIT -#define GL_MAP_READ_BIT 0x0001 -#endif -#ifndef GL_MAP_WRITE_BIT -#define GL_MAP_WRITE_BIT 0x0002 -#endif -#ifndef GL_MAP_INVALIDATE_RANGE_BIT -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#endif -#ifndef GL_MAP_INVALIDATE_BUFFER_BIT -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#endif - -void -_cogl_buffer_gl_create (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - GE (ctx, glGenBuffers (1, &buffer->gl_handle)); -} - -void -_cogl_buffer_gl_destroy (CoglBuffer *buffer) -{ - GE( buffer->context, glDeleteBuffers (1, &buffer->gl_handle) ); -} - -static GLenum -update_hints_to_gl_enum (CoglBuffer *buffer) -{ - /* usage hint is always DRAW for now */ - switch (buffer->update_hint) - { - case COGL_BUFFER_UPDATE_HINT_STATIC: - return GL_STATIC_DRAW; - case COGL_BUFFER_UPDATE_HINT_DYNAMIC: - return GL_DYNAMIC_DRAW; - - case COGL_BUFFER_UPDATE_HINT_STREAM: - /* OpenGL ES 1.1 only knows about STATIC_DRAW and DYNAMIC_DRAW */ -#if defined(HAVE_COGL_GL) || defined(HAVE_COGL_GLES2) - return GL_STREAM_DRAW; -#else - return GL_DYNAMIC_DRAW; -#endif - } - - g_assert_not_reached (); - return 0; -} - -static GLenum -convert_bind_target_to_gl_target (CoglBufferBindTarget target) -{ - switch (target) - { - case COGL_BUFFER_BIND_TARGET_PIXEL_PACK: - return GL_PIXEL_PACK_BUFFER; - case COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK: - return GL_PIXEL_UNPACK_BUFFER; - case COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER: - return GL_ARRAY_BUFFER; - case COGL_BUFFER_BIND_TARGET_INDEX_BUFFER: - return GL_ELEMENT_ARRAY_BUFFER; - default: - g_return_val_if_reached (COGL_BUFFER_BIND_TARGET_PIXEL_UNPACK); - } -} - -static gboolean -recreate_store (CoglBuffer *buffer, - GError **error) -{ - CoglContext *ctx = buffer->context; - GLenum gl_target; - GLenum gl_enum; - - /* This assumes the buffer is already bound */ - - gl_target = convert_bind_target_to_gl_target (buffer->last_target); - gl_enum = update_hints_to_gl_enum (buffer); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glBufferData (gl_target, - buffer->size, - NULL, - gl_enum); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - return FALSE; - - buffer->store_created = TRUE; - return TRUE; -} - -static GLenum -_cogl_buffer_access_to_gl_enum (CoglBufferAccess access) -{ - if ((access & COGL_BUFFER_ACCESS_READ_WRITE) == COGL_BUFFER_ACCESS_READ_WRITE) - return GL_READ_WRITE; - else if (access & COGL_BUFFER_ACCESS_WRITE) - return GL_WRITE_ONLY; - else - return GL_READ_ONLY; -} - -static void * -_cogl_buffer_bind_no_create (CoglBuffer *buffer, - CoglBufferBindTarget target) -{ - CoglContext *ctx = buffer->context; - - g_return_val_if_fail (buffer != NULL, NULL); - - /* Don't allow binding the buffer to multiple targets at the same time */ - g_return_val_if_fail (ctx->current_buffer[buffer->last_target] != buffer, - NULL); - - /* Don't allow nesting binds to the same target */ - g_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; -} - -void * -_cogl_buffer_gl_map_range (CoglBuffer *buffer, - size_t offset, - size_t size, - CoglBufferAccess access, - CoglBufferMapHint hints, - GError **error) -{ - uint8_t *data; - CoglBufferBindTarget target; - GLenum gl_target; - CoglContext *ctx = buffer->context; - - if (((access & COGL_BUFFER_ACCESS_READ) && - !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) || - ((access & COGL_BUFFER_ACCESS_WRITE) && - !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE))) - { - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Tried to map a buffer with unsupported access mode"); - return NULL; - } - - target = buffer->last_target; - _cogl_buffer_bind_no_create (buffer, target); - - gl_target = convert_bind_target_to_gl_target (target); - - if ((hints & COGL_BUFFER_MAP_HINT_DISCARD_RANGE) && - offset == 0 && size >= buffer->size) - hints |= COGL_BUFFER_MAP_HINT_DISCARD; - - /* If the map buffer range extension is supported then we will - * always use it even if we are mapping the full range because the - * normal mapping function doesn't support passing the discard - * hints */ - if (ctx->glMapBufferRange) - { - GLbitfield gl_access = 0; - gboolean should_recreate_store = !buffer->store_created; - - if ((access & COGL_BUFFER_ACCESS_READ)) - gl_access |= GL_MAP_READ_BIT; - if ((access & COGL_BUFFER_ACCESS_WRITE)) - gl_access |= GL_MAP_WRITE_BIT; - - if ((hints & COGL_BUFFER_MAP_HINT_DISCARD)) - { - /* glMapBufferRange generates an error if you pass the - * discard hint along with asking for read access. However - * it can make sense to ask for both if write access is also - * requested so that the application can immediately read - * back what it just wrote. To work around the restriction - * in GL we just recreate the buffer storage in that case - * which is an alternative way to indicate that the buffer - * contents can be discarded. */ - if ((access & COGL_BUFFER_ACCESS_READ)) - should_recreate_store = TRUE; - else - gl_access |= GL_MAP_INVALIDATE_BUFFER_BIT; - } - else if ((hints & COGL_BUFFER_MAP_HINT_DISCARD_RANGE) && - !(access & COGL_BUFFER_ACCESS_READ)) - gl_access |= GL_MAP_INVALIDATE_RANGE_BIT; - - if (should_recreate_store) - { - if (!recreate_store (buffer, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - data = ctx->glMapBufferRange (gl_target, - offset, - size, - gl_access); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - - g_return_val_if_fail (data != NULL, NULL); - } - else - { - /* create an empty store if we don't have one yet. creating the store - * lazily allows the user of the CoglBuffer to set a hint before the - * store is created. */ - if (!buffer->store_created || - (hints & COGL_BUFFER_MAP_HINT_DISCARD)) - { - if (!recreate_store (buffer, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - data = ctx->glMapBuffer (gl_target, - _cogl_buffer_access_to_gl_enum (access)); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - - g_return_val_if_fail (data != NULL, NULL); - - data += offset; - } - - if (data) - buffer->flags |= COGL_BUFFER_FLAG_MAPPED; - - _cogl_buffer_gl_unbind (buffer); - - return data; -} - -void -_cogl_buffer_gl_unmap (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - _cogl_buffer_bind_no_create (buffer, buffer->last_target); - - GE( ctx, glUnmapBuffer (convert_bind_target_to_gl_target - (buffer->last_target)) ); - buffer->flags &= ~COGL_BUFFER_FLAG_MAPPED; - - _cogl_buffer_gl_unbind (buffer); -} - -gboolean -_cogl_buffer_gl_set_data (CoglBuffer *buffer, - unsigned int offset, - const void *data, - unsigned int size, - GError **error) -{ - CoglBufferBindTarget target; - GLenum gl_target; - CoglContext *ctx = buffer->context; - gboolean status = TRUE; - GError *internal_error = NULL; - - target = buffer->last_target; - - _cogl_buffer_gl_bind (buffer, target, &internal_error); - - /* NB: _cogl_buffer_gl_bind() may return NULL in non-error - * conditions so we have to explicitly check internal_error - * to see if an exception was thrown. - */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return FALSE; - } - - gl_target = convert_bind_target_to_gl_target (target); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glBufferSubData (gl_target, offset, size, data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_buffer_gl_unbind (buffer); - - return status; -} - -void * -_cogl_buffer_gl_bind (CoglBuffer *buffer, - CoglBufferBindTarget target, - GError **error) -{ - void *ret; - - ret = _cogl_buffer_bind_no_create (buffer, target); - - /* create an empty store if we don't have one yet. creating the store - * lazily allows the user of the CoglBuffer to set a hint before the - * store is created. */ - if ((buffer->flags & COGL_BUFFER_FLAG_BUFFER_OBJECT) && - !buffer->store_created) - { - if (!recreate_store (buffer, error)) - { - _cogl_buffer_gl_unbind (buffer); - return NULL; - } - } - - return ret; -} - -void -_cogl_buffer_gl_unbind (CoglBuffer *buffer) -{ - CoglContext *ctx = buffer->context; - - g_return_if_fail (buffer != NULL); - - /* the unbind should pair up with a previous bind */ - g_return_if_fail (ctx->current_buffer[buffer->last_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, 0) ); - } - - ctx->current_buffer[buffer->last_target] = NULL; -} diff --git a/cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h b/cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h deleted file mode 100644 index ff22d2660..000000000 --- a/cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_CLIP_STACK_GL_PRIVATE_H_ -#define _COGL_CLIP_STACK_GL_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-framebuffer.h" -#include "cogl-clip-stack.h" - -void -_cogl_clip_stack_gl_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer); - -#endif /* _COGL_CLIP_STACK_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c deleted file mode 100644 index a693903b3..000000000 --- a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-graphene.h" -#include "cogl-primitives-private.h" -#include "cogl-primitive-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-clip-stack-gl-private.h" - -static void -add_stencil_clip_rectangle (CoglFramebuffer *framebuffer, - CoglMatrixEntry *modelview_entry, - float x_1, - float y_1, - float x_2, - float y_2, - gboolean merge) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *old_projection_entry, *old_modelview_entry; - - /* NB: This can be called while flushing the journal so we need - * to be very conservative with what state we change. - */ - old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); - old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - - ctx->current_projection_entry = projection_stack->last_entry; - ctx->current_modelview_entry = modelview_entry; - - GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( ctx, glDepthMask (FALSE) ); - GE( ctx, glStencilMask (0x3) ); - - if (merge) - { - /* Add one to every pixel of the stencil buffer in the - rectangle */ - GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x3) ); - GE( ctx, glStencilOp (GL_INCR, GL_INCR, GL_INCR) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - x_1, y_1, x_2, y_2); - - /* Subtract one from all pixels in the stencil buffer so that - only pixels where both the original stencil buffer and the - rectangle are set will be valid */ - GE( ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR) ); - - ctx->current_projection_entry = &ctx->identity_entry; - ctx->current_modelview_entry = &ctx->identity_entry; - - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - } - else - { - GE( ctx, glEnable (GL_STENCIL_TEST) ); - - /* Initially disallow everything */ - GE( ctx, glClearStencil (0) ); - GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); - - /* Punch out a hole to allow the rectangle */ - GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - x_1, y_1, x_2, y_2); - } - - ctx->current_projection_entry = old_projection_entry; - ctx->current_modelview_entry = old_modelview_entry; - - /* Restore the stencil mode */ - GE( ctx, glDepthMask (TRUE) ); - GE( ctx, glColorMask (TRUE, TRUE, TRUE, TRUE) ); - GE( ctx, glStencilMask (0x0) ); - GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); -} - -static void -add_stencil_clip_region (CoglFramebuffer *framebuffer, - cairo_region_t *region, - gboolean merge) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *old_projection_entry, *old_modelview_entry; - graphene_matrix_t matrix; - int num_rectangles = cairo_region_num_rectangles (region); - int i; - CoglVertexP2 *vertices; - graphene_point3d_t p; - - /* NB: This can be called while flushing the journal so we need - * to be very conservative with what state we change. - */ - old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); - old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - - ctx->current_projection_entry = &ctx->identity_entry; - ctx->current_modelview_entry = &ctx->identity_entry; - - /* The coordinates in the region are meant to be window coordinates, - * make a matrix that translates those across the viewport, and into - * the default [-1, -1, 1, 1] range. - */ - graphene_point3d_init (&p, - - cogl_framebuffer_get_viewport_x (framebuffer), - - cogl_framebuffer_get_viewport_y (framebuffer), - 0); - - graphene_matrix_init_translate (&matrix, &p); - graphene_matrix_scale (&matrix, - 2.0 / cogl_framebuffer_get_viewport_width (framebuffer), - - 2.0 / cogl_framebuffer_get_viewport_height (framebuffer), - 1); - graphene_matrix_translate (&matrix, &GRAPHENE_POINT3D_INIT (-1.f, 1.f, 0.f)); - - GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( ctx, glDepthMask (FALSE) ); - GE( ctx, glStencilMask (0x3) ); - - if (merge) - { - GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x3) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_INCR) ); - } - else - { - GE( ctx, glEnable (GL_STENCIL_TEST) ); - - /* Initially disallow everything */ - GE( ctx, glClearStencil (0) ); - GE( ctx, glClear (GL_STENCIL_BUFFER_BIT) ); - - /* Punch out holes to allow the rectangles */ - GE( ctx, glStencilFunc (GL_ALWAYS, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE) ); - } - - vertices = g_alloca (sizeof (CoglVertexP2) * num_rectangles * 6); - - for (i = 0; i < num_rectangles; i++) - { - cairo_rectangle_int_t rect; - float x1, y1, z1, w1; - float x2, y2, z2, w2; - CoglVertexP2 *v = vertices + i * 6; - - cairo_region_get_rectangle (region, i, &rect); - - x1 = rect.x; - y1 = rect.y; - z1 = 0.f; - w1 = 1.f; - - x2 = rect.x + rect.width; - y2 = rect.y + rect.height; - z2 = 0.f; - w2 = 1.f; - - cogl_graphene_matrix_project_point (&matrix, &x1, &y1, &z1, &w1); - cogl_graphene_matrix_project_point (&matrix, &x2, &y2, &z2, &w2); - - v[0].x = x1; - v[0].y = y1; - v[1].x = x1; - v[1].y = y2; - v[2].x = x2; - v[2].y = y1; - v[3].x = x1; - v[3].y = y2; - v[4].x = x2; - v[4].y = y2; - v[5].x = x2; - v[5].y = y1; - } - - cogl_2d_primitives_immediate (framebuffer, - ctx->stencil_pipeline, - COGL_VERTICES_MODE_TRIANGLES, - vertices, - 6 * num_rectangles); - - if (merge) - { - /* Subtract one from all pixels in the stencil buffer so that - * only pixels where both the original stencil buffer and the - * region are set will be valid - */ - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_DECR) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - } - - ctx->current_projection_entry = old_projection_entry; - ctx->current_modelview_entry = old_modelview_entry; - - /* Restore the stencil mode */ - GE (ctx, glDepthMask (TRUE)); - GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); - GE( ctx, glStencilMask (0x0) ); - GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) ); - GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) ); -} - -typedef void (*SilhouettePaintCallback) (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - void *user_data); - -static void -add_stencil_clip_silhouette (CoglFramebuffer *framebuffer, - SilhouettePaintCallback silhouette_callback, - CoglMatrixEntry *modelview_entry, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - gboolean merge, - gboolean need_clear, - void *user_data) -{ - CoglMatrixStack *projection_stack = - _cogl_framebuffer_get_projection_stack (framebuffer); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *old_projection_entry, *old_modelview_entry; - - /* NB: This can be called while flushing the journal so we need - * to be very conservative with what state we change. - */ - old_projection_entry = g_steal_pointer (&ctx->current_projection_entry); - old_modelview_entry = g_steal_pointer (&ctx->current_modelview_entry); - - ctx->current_projection_entry = projection_stack->last_entry; - ctx->current_modelview_entry = modelview_entry; - - _cogl_pipeline_flush_gl_state (ctx, ctx->stencil_pipeline, - framebuffer, FALSE, FALSE); - - GE( ctx, glEnable (GL_STENCIL_TEST) ); - - GE( ctx, glColorMask (FALSE, FALSE, FALSE, FALSE) ); - GE( ctx, glDepthMask (FALSE) ); - - if (merge) - { - GE (ctx, glStencilMask (2)); - GE (ctx, glStencilFunc (GL_LEQUAL, 0x2, 0x6)); - } - else - { - /* If we're not using the stencil buffer for clipping then we - don't need to clear the whole stencil buffer, just the area - that will be drawn */ - if (need_clear) - /* If this is being called from the clip stack code then it - will have set up a scissor for the minimum bounding box of - all of the clips. That box will likely mean that this - _cogl_clear won't need to clear the entire - buffer. _cogl_framebuffer_clear_without_flush4f is used instead - of cogl_clear because it won't try to flush the journal */ - _cogl_framebuffer_clear_without_flush4f (framebuffer, - COGL_BUFFER_BIT_STENCIL, - 0, 0, 0, 0); - else - { - /* Just clear the bounding box */ - GE( ctx, glStencilMask (~(GLuint) 0) ); - GE( ctx, glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) ); - _cogl_rectangle_immediate (framebuffer, - ctx->stencil_pipeline, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2); - } - GE (ctx, glStencilMask (1)); - GE (ctx, glStencilFunc (GL_LEQUAL, 0x1, 0x3)); - } - - GE (ctx, glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT)); - - silhouette_callback (framebuffer, ctx->stencil_pipeline, user_data); - - if (merge) - { - /* Now we have the new stencil buffer in bit 1 and the old - stencil buffer in bit 0 so we need to intersect them */ - GE (ctx, glStencilMask (3)); - GE (ctx, glStencilFunc (GL_NEVER, 0x2, 0x3)); - GE (ctx, glStencilOp (GL_DECR, GL_DECR, GL_DECR)); - /* Decrement all of the bits twice so that only pixels where the - value is 3 will remain */ - - ctx->current_projection_entry = &ctx->identity_entry; - ctx->current_modelview_entry = &ctx->identity_entry; - - _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - _cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline, - -1.0, -1.0, 1.0, 1.0); - } - - ctx->current_projection_entry = old_projection_entry; - ctx->current_modelview_entry = old_modelview_entry; - - GE (ctx, glStencilMask (~(GLuint) 0)); - GE (ctx, glDepthMask (TRUE)); - GE (ctx, glColorMask (TRUE, TRUE, TRUE, TRUE)); - - GE (ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1)); - GE (ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP)); -} - -static void -paint_primitive_silhouette (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - void *user_data) -{ - _cogl_primitive_draw (user_data, - framebuffer, - pipeline, - COGL_DRAW_SKIP_JOURNAL_FLUSH | - COGL_DRAW_SKIP_PIPELINE_VALIDATION | - COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH); -} - -static void -add_stencil_clip_primitive (CoglFramebuffer *framebuffer, - CoglMatrixEntry *modelview_entry, - CoglPrimitive *primitive, - float bounds_x1, - float bounds_y1, - float bounds_x2, - float bounds_y2, - gboolean merge, - gboolean need_clear) -{ - add_stencil_clip_silhouette (framebuffer, - paint_primitive_silhouette, - modelview_entry, - bounds_x1, - bounds_y1, - bounds_x2, - bounds_y2, - merge, - need_clear, - primitive); -} - -void -_cogl_clip_stack_gl_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer) -{ - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - gboolean using_stencil_buffer = FALSE; - int scissor_x0; - int scissor_y0; - int scissor_x1; - int scissor_y1; - CoglClipStack *entry; - int scissor_y_start; - - /* If we have already flushed this state then we don't need to do - anything */ - if (ctx->current_clip_stack_valid) - { - if (ctx->current_clip_stack == stack) - return; - - _cogl_clip_stack_unref (ctx->current_clip_stack); - } - - ctx->current_clip_stack_valid = TRUE; - ctx->current_clip_stack = _cogl_clip_stack_ref (stack); - - GE( ctx, glDisable (GL_STENCIL_TEST) ); - - /* If the stack is empty then there's nothing else to do - */ - if (stack == NULL) - { - COGL_NOTE (CLIPPING, "Flushed empty clip stack"); - - GE (ctx, glDisable (GL_SCISSOR_TEST)); - return; - } - - /* Calculate the scissor rect first so that if we eventually have to - clear the stencil buffer then the clear will be clipped to the - intersection of all of the bounding boxes. This saves having to - clear the whole stencil buffer */ - _cogl_clip_stack_get_bounds (stack, - &scissor_x0, &scissor_y0, - &scissor_x1, &scissor_y1); - - /* Enable scissoring as soon as possible */ - if (scissor_x0 >= scissor_x1 || scissor_y0 >= scissor_y1) - scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0; - else - { - /* We store the entry coordinates in Cogl coordinate space - * but OpenGL requires the window origin to be the bottom - * left so we may need to convert the incoming coordinates. - * - * NB: Cogl forces all offscreen rendering to be done upside - * down so in this case no conversion is needed. - */ - - if (cogl_framebuffer_is_y_flipped (framebuffer)) - { - scissor_y_start = scissor_y0; - } - else - { - int framebuffer_height = - cogl_framebuffer_get_height (framebuffer); - - scissor_y_start = framebuffer_height - scissor_y1; - } - } - - COGL_NOTE (CLIPPING, "Flushing scissor to (%i, %i, %i, %i)", - scissor_x0, scissor_y0, - scissor_x1, scissor_y1); - - GE (ctx, glEnable (GL_SCISSOR_TEST)); - GE (ctx, glScissor (scissor_x0, scissor_y_start, - scissor_x1 - scissor_x0, - scissor_y1 - scissor_y0)); - - /* Add all of the entries. This will end up adding them in the - reverse order that they were specified but as all of the clips - are intersecting it should work out the same regardless of the - order */ - for (entry = stack; entry; entry = entry->parent) - { - switch (entry->type) - { - case COGL_CLIP_STACK_PRIMITIVE: - { - CoglClipStackPrimitive *primitive_entry = - (CoglClipStackPrimitive *) entry; - - COGL_NOTE (CLIPPING, "Adding stencil clip for primitive"); - - add_stencil_clip_primitive (framebuffer, - primitive_entry->matrix_entry, - primitive_entry->primitive, - primitive_entry->bounds_x1, - primitive_entry->bounds_y1, - primitive_entry->bounds_x2, - primitive_entry->bounds_y2, - using_stencil_buffer, - TRUE); - - using_stencil_buffer = TRUE; - break; - } - case COGL_CLIP_STACK_RECT: - { - CoglClipStackRect *rect = (CoglClipStackRect *) entry; - - /* We don't need to do anything extra if the clip for this - rectangle was entirely described by its scissor bounds */ - if (!rect->can_be_scissor || - G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_STENCILLING))) - { - COGL_NOTE (CLIPPING, "Adding stencil clip for rectangle"); - - add_stencil_clip_rectangle (framebuffer, - rect->matrix_entry, - rect->x0, - rect->y0, - rect->x1, - rect->y1, - using_stencil_buffer); - using_stencil_buffer = TRUE; - } - break; - } - case COGL_CLIP_STACK_REGION: - { - CoglClipStackRegion *region = (CoglClipStackRegion *) entry; - - /* If nrectangles <= 1, it can be fully represented with the - * scissor clip. - */ - if (cairo_region_num_rectangles (region->region) > 1 || - G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_STENCILLING))) - { - COGL_NOTE (CLIPPING, "Adding stencil clip for region"); - - add_stencil_clip_region (framebuffer, region->region, - using_stencil_buffer); - using_stencil_buffer = TRUE; - } - break; - } - case COGL_CLIP_STACK_WINDOW_RECT: - break; - /* We don't need to do anything for window space rectangles because - * their functionality is entirely implemented by the entry bounding - * box */ - } - } -} diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h deleted file mode 100644 index 3f3f6b7c8..000000000 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_FRAMEBUFFER_GL_PRIVATE_H__ -#define __COGL_FRAMEBUFFER_GL_PRIVATE_H__ - -#include "cogl-attribute-private.h" -#include "cogl-framebuffer-driver.h" -#include "cogl-gl-header.h" - -#define COGL_TYPE_GL_FRAMEBUFFER (cogl_gl_framebuffer_get_type ()) -G_DECLARE_DERIVABLE_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer, - COGL, GL_FRAMEBUFFER, - CoglFramebufferDriver) - -struct _CoglGlFramebufferClass -{ - CoglFramebufferDriverClass parent_class; - - void (* bind) (CoglGlFramebuffer *gl_framebuffer, - GLenum target); - - void (* flush_stereo_mode_state) (CoglGlFramebuffer *gl_framebuffer); -}; - -void -cogl_gl_framebuffer_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target); - -void -cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer, - unsigned long differences); - -#endif /* __COGL_FRAMEBUFFER_GL_PRIVATE_H__ */ - - diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c deleted file mode 100644 index de5ed30d9..000000000 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ /dev/null @@ -1,681 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-framebuffer.h" -#include "cogl-offscreen-private.h" -#include "cogl-texture-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-framebuffer-gl-private.h" -#include "driver/gl/cogl-bitmap-gl-private.h" -#include "driver/gl/cogl-buffer-gl-private.h" - -#include <glib.h> -#include <string.h> - -G_DEFINE_ABSTRACT_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer, - COGL_TYPE_FRAMEBUFFER_DRIVER) - -static CoglContext * -context_from_driver (CoglFramebufferDriver *driver) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - return cogl_framebuffer_get_context (framebuffer); -} - -static void -cogl_gl_framebuffer_flush_viewport_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - float viewport_x, viewport_y, viewport_width, viewport_height; - float gl_viewport_y; - - cogl_framebuffer_get_viewport4f (framebuffer, - &viewport_x, - &viewport_y, - &viewport_width, - &viewport_height); - - g_return_if_fail (viewport_width >= 0); - g_return_if_fail (viewport_height >= 0); - - /* Convert the Cogl viewport y offset to an OpenGL viewport y offset - * NB: OpenGL defines its window and viewport origins to be bottom - * left, while Cogl defines them to be top left. - */ - if (cogl_framebuffer_is_y_flipped (framebuffer)) - gl_viewport_y = viewport_y; - else - gl_viewport_y = - cogl_framebuffer_get_height (framebuffer) - - (viewport_y + viewport_height); - - COGL_NOTE (OPENGL, "Calling glViewport(%f, %f, %f, %f)", - viewport_x, - gl_viewport_y, - viewport_width, - viewport_height); - - GE (cogl_framebuffer_get_context (framebuffer), - glViewport (viewport_x, - gl_viewport_y, - viewport_width, - viewport_height)); -} - -static void -cogl_gl_framebuffer_flush_clip_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - _cogl_clip_stack_flush (_cogl_framebuffer_get_clip_stack (framebuffer), - framebuffer); -} - -static void -cogl_gl_framebuffer_flush_dither_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - gboolean is_dither_enabled; - - is_dither_enabled = cogl_framebuffer_get_dither_enabled (framebuffer); - if (ctx->current_gl_dither_enabled != is_dither_enabled) - { - if (is_dither_enabled) - GE (ctx, glEnable (GL_DITHER)); - else - GE (ctx, glDisable (GL_DITHER)); - ctx->current_gl_dither_enabled = is_dither_enabled; - } -} - -static void -cogl_gl_framebuffer_flush_modelview_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *modelview_entry = - _cogl_framebuffer_get_modelview_entry (framebuffer); - - _cogl_context_set_current_modelview_entry (ctx, modelview_entry); -} - -static void -cogl_gl_framebuffer_flush_projection_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglMatrixEntry *projection_entry = - _cogl_framebuffer_get_projection_entry (framebuffer); - - _cogl_context_set_current_projection_entry (ctx, projection_entry); -} - -static void -cogl_gl_framebuffer_flush_front_face_winding_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglPipelineCullFaceMode mode; - - /* NB: The face winding state is actually owned by the current - * CoglPipeline. - * - * If we don't have a current pipeline then we can just assume that - * when we later do flush a pipeline we will check the current - * framebuffer to know how to setup the winding */ - if (!context->current_pipeline) - return; - - mode = cogl_pipeline_get_cull_face_mode (context->current_pipeline); - - /* If the current CoglPipeline has a culling mode that doesn't care - * about the winding we can avoid forcing an update of the state and - * bail out. */ - if (mode == COGL_PIPELINE_CULL_FACE_MODE_NONE || - mode == COGL_PIPELINE_CULL_FACE_MODE_BOTH) - return; - - /* Since the winding state is really owned by the current pipeline - * the way we "flush" an updated winding is to dirty the pipeline - * state... */ - context->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_CULL_FACE; - context->current_pipeline_age--; -} - -static void -cogl_gl_framebuffer_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglGlFramebufferClass *klass = - COGL_GL_FRAMEBUFFER_GET_CLASS (gl_framebuffer); - - klass->flush_stereo_mode_state (gl_framebuffer); -} - -void -cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer, - unsigned long differences) -{ - int bit; - - COGL_FLAGS_FOREACH_START (&differences, 1, bit) - { - /* XXX: We considered having an array of callbacks for each state index - * that we'd call here but decided that this way the compiler is more - * likely going to be able to in-line the flush functions and use the - * index to jump straight to the required code. */ - switch (bit) - { - case COGL_FRAMEBUFFER_STATE_INDEX_VIEWPORT: - cogl_gl_framebuffer_flush_viewport_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_CLIP: - cogl_gl_framebuffer_flush_clip_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DITHER: - cogl_gl_framebuffer_flush_dither_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_MODELVIEW: - cogl_gl_framebuffer_flush_modelview_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION: - cogl_gl_framebuffer_flush_projection_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING: - cogl_gl_framebuffer_flush_front_face_winding_state (gl_framebuffer); - break; - case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE: - /* Nothing to do for depth write state change; the state will always - * be taken into account when flushing the pipeline's depth state. */ - break; - case COGL_FRAMEBUFFER_STATE_INDEX_STEREO_MODE: - cogl_gl_framebuffer_flush_stereo_mode_state (gl_framebuffer); - break; - default: - g_warn_if_reached (); - } - } - COGL_FLAGS_FOREACH_END; -} - -void -cogl_gl_framebuffer_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target) -{ - COGL_GL_FRAMEBUFFER_GET_CLASS (gl_framebuffer)->bind (gl_framebuffer, - target); -} - -static void -cogl_gl_framebuffer_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ - CoglContext *ctx = context_from_driver (driver); - GLbitfield gl_buffers = 0; - - if (buffers & COGL_BUFFER_BIT_COLOR) - { - GE( ctx, glClearColor (red, green, blue, alpha) ); - gl_buffers |= GL_COLOR_BUFFER_BIT; - } - - if (buffers & COGL_BUFFER_BIT_DEPTH) - { - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - gboolean is_depth_writing_enabled; - - gl_buffers |= GL_DEPTH_BUFFER_BIT; - - is_depth_writing_enabled = - cogl_framebuffer_get_depth_write_enabled (framebuffer); - if (ctx->depth_writing_enabled_cache != is_depth_writing_enabled) - { - GE( ctx, glDepthMask (is_depth_writing_enabled)); - - ctx->depth_writing_enabled_cache = is_depth_writing_enabled; - - /* Make sure the DepthMask is updated when the next primitive is drawn */ - ctx->current_pipeline_changes_since_flush |= - COGL_PIPELINE_STATE_DEPTH; - ctx->current_pipeline_age--; - } - } - - if (buffers & COGL_BUFFER_BIT_STENCIL) - gl_buffers |= GL_STENCIL_BUFFER_BIT; - - - GE (ctx, glClear (gl_buffers)); -} - -static void -cogl_gl_framebuffer_finish (CoglFramebufferDriver *driver) -{ - CoglContext *ctx = context_from_driver (driver); - - GE (ctx, glFinish ()); -} - -static void -cogl_gl_framebuffer_flush (CoglFramebufferDriver *driver) -{ - CoglContext *ctx = context_from_driver (driver); - - GE (ctx, glFlush ()); -} - -static void -cogl_gl_framebuffer_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - _cogl_flush_attributes_state (framebuffer, pipeline, flags, - attributes, n_attributes); - - GE (cogl_framebuffer_get_context (framebuffer), - glDrawArrays ((GLenum)mode, first_vertex, n_vertices)); -} - -static size_t -sizeof_index_type (CoglIndicesType type) -{ - switch (type) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - return 1; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - return 2; - case COGL_INDICES_TYPE_UNSIGNED_INT: - return 4; - } - g_return_val_if_reached (0); -} - -static void -cogl_gl_framebuffer_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglBuffer *buffer; - uint8_t *base; - size_t buffer_offset; - size_t index_size; - GLenum indices_gl_type = 0; - - _cogl_flush_attributes_state (framebuffer, pipeline, flags, - attributes, n_attributes); - - buffer = COGL_BUFFER (cogl_indices_get_buffer (indices)); - - /* Note: we don't try and catch errors with binding the index buffer - * here since OOM errors at this point indicate that nothing has yet - * been uploaded to the indices buffer which we consider to be a - * programmer error. - */ - base = _cogl_buffer_gl_bind (buffer, - COGL_BUFFER_BIND_TARGET_INDEX_BUFFER, NULL); - buffer_offset = cogl_indices_get_offset (indices); - index_size = sizeof_index_type (cogl_indices_get_type (indices)); - - switch (cogl_indices_get_type (indices)) - { - case COGL_INDICES_TYPE_UNSIGNED_BYTE: - indices_gl_type = GL_UNSIGNED_BYTE; - break; - case COGL_INDICES_TYPE_UNSIGNED_SHORT: - indices_gl_type = GL_UNSIGNED_SHORT; - break; - case COGL_INDICES_TYPE_UNSIGNED_INT: - indices_gl_type = GL_UNSIGNED_INT; - break; - } - - GE (cogl_framebuffer_get_context (framebuffer), - glDrawElements ((GLenum)mode, - n_vertices, - indices_gl_type, - base + buffer_offset + index_size * first_vertex)); - - _cogl_buffer_gl_unbind (buffer); -} - -static gboolean -cogl_gl_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *driver, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int width = cogl_bitmap_get_width (bitmap); - int height = cogl_bitmap_get_height (bitmap); - CoglPixelFormat format = cogl_bitmap_get_format (bitmap); - CoglPixelFormat internal_format = - cogl_framebuffer_get_internal_format (framebuffer); - CoglPixelFormat required_format; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - GLenum gl_pack_enum = GL_FALSE; - gboolean pack_invert_set; - int status = FALSE; - - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - /* The y coordinate should be given in OpenGL's coordinate system - * so 0 is the bottom row. - */ - if (!cogl_framebuffer_is_y_flipped (framebuffer)) - y = framebuffer_height - y - height; - - required_format = ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - &gl_intformat, - &gl_format, - &gl_type); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) && - (source & COGL_READ_PIXELS_NO_FLIP) == 0 && - !cogl_framebuffer_is_y_flipped (framebuffer)) - { - if (ctx->driver == COGL_DRIVER_GLES2) - gl_pack_enum = GL_PACK_REVERSE_ROW_ORDER_ANGLE; - else - gl_pack_enum = GL_PACK_INVERT_MESA; - - GE (ctx, glPixelStorei (gl_pack_enum, TRUE)); - pack_invert_set = TRUE; - } - else - pack_invert_set = FALSE; - - /* Under GLES only GL_RGBA with GL_UNSIGNED_BYTE as well as an - implementation specific format under - GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES and - GL_IMPLEMENTATION_COLOR_READ_TYPE_OES is supported. We could try - to be more clever and check if the requested type matches that - but we would need some reliable functions to convert from GL - types to Cogl types. For now, lets just always read in - GL_RGBA/GL_UNSIGNED_BYTE and convert if necessary. We also need - to use this intermediate buffer if the rowstride has padding - because GLES does not support setting GL_ROW_LENGTH */ - if ((!_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT) && - (gl_format != GL_RGBA || gl_type != GL_UNSIGNED_BYTE || - cogl_bitmap_get_rowstride (bitmap) != 4 * width)) || - (required_format & ~COGL_PREMULT_BIT) != (format & ~COGL_PREMULT_BIT)) - { - CoglBitmap *tmp_bmp; - CoglPixelFormat read_format; - int bpp, rowstride; - uint8_t *tmp_data; - gboolean succeeded; - - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT)) - read_format = required_format; - else - { - read_format = COGL_PIXEL_FORMAT_RGBA_8888; - gl_format = GL_RGBA; - gl_type = GL_UNSIGNED_BYTE; - } - - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (read_format)) - { - read_format = ((read_format & ~COGL_PREMULT_BIT) | - (internal_format & COGL_PREMULT_BIT)); - } - - tmp_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx, - width, height, - read_format, - error); - if (!tmp_bmp) - goto EXIT; - - bpp = cogl_pixel_format_get_bytes_per_pixel (read_format, 0); - rowstride = cogl_bitmap_get_rowstride (tmp_bmp); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - width, - bpp); - - /* Note: we don't worry about catching errors here since we know - * we won't be lazily allocating storage for this buffer so it - * won't fail due to lack of memory. */ - tmp_data = _cogl_bitmap_gl_bind (tmp_bmp, - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD, - NULL); - - GE( ctx, glReadPixels (x, y, width, height, - gl_format, gl_type, - tmp_data) ); - - _cogl_bitmap_gl_unbind (tmp_bmp); - - succeeded = _cogl_bitmap_convert_into_bitmap (tmp_bmp, bitmap, error); - - cogl_object_unref (tmp_bmp); - - if (!succeeded) - goto EXIT; - } - else - { - CoglBitmap *shared_bmp; - CoglPixelFormat bmp_format; - int bpp, rowstride; - gboolean succeeded = FALSE; - uint8_t *pixels; - GError *internal_error = NULL; - - rowstride = cogl_bitmap_get_rowstride (bitmap); - - /* We match the premultiplied state of the target buffer to the - * premultiplied state of the framebuffer so that it will get - * converted to the right format below */ - if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (format)) - bmp_format = ((format & ~COGL_PREMULT_BIT) | - (internal_format & COGL_PREMULT_BIT)); - else - bmp_format = format; - - if (bmp_format != format) - shared_bmp = _cogl_bitmap_new_shared (bitmap, - bmp_format, - width, height, - rowstride); - else - shared_bmp = cogl_object_ref (bitmap); - - bpp = cogl_pixel_format_get_bytes_per_pixel (bmp_format, 0); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - width, - bpp); - - pixels = _cogl_bitmap_gl_bind (shared_bmp, - COGL_BUFFER_ACCESS_WRITE, - 0, /* hints */ - &internal_error); - /* NB: _cogl_bitmap_gl_bind() can return NULL in successful - * cases so we have to explicitly check the cogl error pointer - * to know if there was a problem */ - if (internal_error) - { - cogl_object_unref (shared_bmp); - g_propagate_error (error, internal_error); - goto EXIT; - } - - GE( ctx, glReadPixels (x, y, - width, height, - gl_format, gl_type, - pixels) ); - - _cogl_bitmap_gl_unbind (shared_bmp); - - /* Convert to the premult format specified by the caller - in-place. This will do nothing if the premult status is already - correct. */ - if (_cogl_bitmap_convert_premult_status (shared_bmp, format, error)) - succeeded = TRUE; - - cogl_object_unref (shared_bmp); - - if (!succeeded) - goto EXIT; - } - - if (!cogl_framebuffer_is_y_flipped (framebuffer) && - (source & COGL_READ_PIXELS_NO_FLIP) == 0 && - !pack_invert_set) - { - uint8_t *temprow; - int rowstride; - uint8_t *pixels; - - rowstride = cogl_bitmap_get_rowstride (bitmap); - pixels = _cogl_bitmap_map (bitmap, - COGL_BUFFER_ACCESS_READ | - COGL_BUFFER_ACCESS_WRITE, - 0, /* hints */ - error); - - if (pixels == NULL) - goto EXIT; - - temprow = g_alloca (rowstride * sizeof (uint8_t)); - - /* vertically flip the buffer in-place */ - for (y = 0; y < height / 2; y++) - { - if (y != height - y - 1) /* skip center row */ - { - memcpy (temprow, - pixels + y * rowstride, rowstride); - memcpy (pixels + y * rowstride, - pixels + (height - y - 1) * rowstride, rowstride); - memcpy (pixels + (height - y - 1) * rowstride, - temprow, - rowstride); - } - } - - _cogl_bitmap_unmap (bitmap); - } - - status = TRUE; - -EXIT: - - /* Currently this function owns the pack_invert state and we don't want this - * to interfere with other Cogl components so all other code can assume that - * we leave the pack_invert state off. */ - if (pack_invert_set) - GE (ctx, glPixelStorei (gl_pack_enum, FALSE)); - - return status; -} - -static void -cogl_gl_framebuffer_init (CoglGlFramebuffer *gl_framebuffer) -{ -} - -static void -cogl_gl_framebuffer_class_init (CoglGlFramebufferClass *klass) -{ - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - - driver_class->clear = cogl_gl_framebuffer_clear; - driver_class->finish = cogl_gl_framebuffer_finish; - driver_class->flush = cogl_gl_framebuffer_flush; - driver_class->draw_attributes = cogl_gl_framebuffer_draw_attributes; - driver_class->draw_indexed_attributes = - cogl_gl_framebuffer_draw_indexed_attributes; - driver_class->read_pixels_into_bitmap = - cogl_gl_framebuffer_read_pixels_into_bitmap; -} diff --git a/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c b/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c deleted file mode 100644 index d6609bb20..000000000 --- a/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "driver/gl/cogl-gl-framebuffer-back.h" - -#include <gio/gio.h> - -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-offscreen-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -struct _CoglGlFramebufferBack -{ - CoglGlFramebuffer parent; - - gboolean dirty_bitmasks; - CoglFramebufferBits bits; -}; - -G_DEFINE_TYPE (CoglGlFramebufferBack, cogl_gl_framebuffer_back, - COGL_TYPE_GL_FRAMEBUFFER) - -static gboolean -ensure_bits_initialized (CoglGlFramebufferBack *gl_framebuffer_back) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_back); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFramebufferBits *bits = &gl_framebuffer_back->bits; - g_autoptr (GError) error = NULL; - - if (!gl_framebuffer_back->dirty_bitmasks) - return TRUE; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - -#ifdef HAVE_COGL_GL - if (ctx->driver == COGL_DRIVER_GL3) - { - const struct { - GLenum attachment, pname; - size_t offset; - } params[] = { - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, - .offset = offsetof (CoglFramebufferBits, red), - }, - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, - .offset = offsetof (CoglFramebufferBits, green), - }, - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, - .offset = offsetof (CoglFramebufferBits, blue), - }, - { - .attachment = GL_BACK_LEFT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, - .offset = offsetof (CoglFramebufferBits, alpha), - }, - { - .attachment = GL_DEPTH, - .pname = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, - .offset = offsetof (CoglFramebufferBits, depth), - }, - { - .attachment = GL_STENCIL, - .pname = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - .offset = offsetof (CoglFramebufferBits, stencil), - }, - }; - int i; - - for (i = 0; i < G_N_ELEMENTS (params); i++) - { - int *value = - (int *) ((uint8_t *) bits + params[i].offset); - - GE (ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - params[i].attachment, - params[i].pname, - value)); - } - } - else -#endif /* HAVE_COGL_GL */ - { - GE (ctx, glGetIntegerv (GL_RED_BITS, &bits->red)); - GE (ctx, glGetIntegerv (GL_GREEN_BITS, &bits->green)); - GE (ctx, glGetIntegerv (GL_BLUE_BITS, &bits->blue)); - GE (ctx, glGetIntegerv (GL_ALPHA_BITS, &bits->alpha)); - GE (ctx, glGetIntegerv (GL_DEPTH_BITS, &bits->depth)); - GE (ctx, glGetIntegerv (GL_STENCIL_BITS, &bits->stencil)); - } - - COGL_NOTE (FRAMEBUFFER, - "RGBA/D/S Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d, %d", - framebuffer, - G_OBJECT_TYPE_NAME (framebuffer), - bits->red, - bits->blue, - bits->green, - bits->alpha, - bits->depth, - bits->stencil); - - gl_framebuffer_back->dirty_bitmasks = FALSE; - - return TRUE; -} - -static void -cogl_gl_framebuffer_back_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - CoglGlFramebufferBack *gl_framebuffer_back = COGL_GL_FRAMEBUFFER_BACK (driver); - - if (!ensure_bits_initialized (gl_framebuffer_back)) - return; - - *bits = gl_framebuffer_back->bits; -} - -static void -cogl_gl_framebuffer_back_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - GLenum attachments[3]; - int i = 0; - - if (!ctx->glDiscardFramebuffer) - return; - - if (buffers & COGL_BUFFER_BIT_COLOR) - attachments[i++] = GL_COLOR; - if (buffers & COGL_BUFFER_BIT_DEPTH) - attachments[i++] = GL_DEPTH; - if (buffers & COGL_BUFFER_BIT_STENCIL) - attachments[i++] = GL_STENCIL; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments)); -} - -static void -cogl_gl_framebuffer_back_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target) -{ - CoglGlFramebufferBack *gl_framebuffer_back = - COGL_GL_FRAMEBUFFER_BACK (gl_framebuffer); - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_back); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - cogl_onscreen_bind (COGL_ONSCREEN (framebuffer)); - - GE (ctx, glBindFramebuffer (target, 0)); - - /* Initialise the glDrawBuffer state the first time the context - * is bound to the default framebuffer. If the winsys is using a - * surfaceless context for the initial make current then the - * default draw buffer will be GL_NONE so we need to correct - * that. We can't do it any earlier because binding GL_BACK when - * there is no default framebuffer won't work */ - if (!ctx->was_bound_to_onscreen) - { - if (ctx->glDrawBuffer) - { - GE (ctx, glDrawBuffer (GL_BACK)); - } - else if (ctx->glDrawBuffers) - { - /* glDrawBuffer isn't available on GLES 3.0 so we need - * to be able to use glDrawBuffers as well. On GLES 2 - * neither is available but the state should always be - * GL_BACK anyway so we don't need to set anything. On - * desktop GL this must be GL_BACK_LEFT instead of - * GL_BACK but as this code path will only be hit for - * GLES we can just use GL_BACK. */ - static const GLenum buffers[] = { GL_BACK }; - - GE (ctx, glDrawBuffers (G_N_ELEMENTS (buffers), buffers)); - } - - ctx->was_bound_to_onscreen = TRUE; - } -} - -static void -cogl_gl_framebuffer_back_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - GLenum draw_buffer = GL_BACK; - - if (!ctx->glDrawBuffer) - return; - - /* The one-shot default draw buffer setting in _cogl_framebuffer_gl_bind - * must have already happened. If not it would override what we set here. */ - g_assert (ctx->was_bound_to_onscreen); - - switch (cogl_framebuffer_get_stereo_mode (framebuffer)) - { - case COGL_STEREO_BOTH: - draw_buffer = GL_BACK; - break; - case COGL_STEREO_LEFT: - draw_buffer = GL_BACK_LEFT; - break; - case COGL_STEREO_RIGHT: - draw_buffer = GL_BACK_RIGHT; - break; - } - - if (ctx->current_gl_draw_buffer != draw_buffer) - { - GE (ctx, glDrawBuffer (draw_buffer)); - ctx->current_gl_draw_buffer = draw_buffer; - } -} - -CoglGlFramebufferBack * -cogl_gl_framebuffer_back_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - if (!COGL_IS_ONSCREEN (framebuffer)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Incompatible framebuffer"); - return NULL; - } - - return g_object_new (COGL_TYPE_GL_FRAMEBUFFER_BACK, - "framebuffer", framebuffer, - NULL); -} - -static void -cogl_gl_framebuffer_back_init (CoglGlFramebufferBack *gl_framebuffer_back) -{ - gl_framebuffer_back->dirty_bitmasks = TRUE; -} - -static void -cogl_gl_framebuffer_back_class_init (CoglGlFramebufferBackClass *klass) -{ - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - CoglGlFramebufferClass *gl_framebuffer_class = - COGL_GL_FRAMEBUFFER_CLASS (klass); - - driver_class->query_bits = cogl_gl_framebuffer_back_query_bits; - driver_class->discard_buffers = cogl_gl_framebuffer_back_discard_buffers; - - gl_framebuffer_class->bind = cogl_gl_framebuffer_back_bind; - gl_framebuffer_class->flush_stereo_mode_state = - cogl_gl_framebuffer_back_flush_stereo_mode_state; -} diff --git a/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h b/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h deleted file mode 100644 index 417f8a738..000000000 --- a/cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef COGL_GL_FRAMEBUFFER_BACK_H -#define COGL_GL_FRAMEBUFFER_BACK_H - -#include "cogl-framebuffer-gl-private.h" - -#define COGL_TYPE_GL_FRAMEBUFFER_BACK (cogl_gl_framebuffer_back_get_type ()) -G_DECLARE_FINAL_TYPE (CoglGlFramebufferBack, cogl_gl_framebuffer_back, - COGL, GL_FRAMEBUFFER_BACK, - CoglGlFramebuffer) - -CoglGlFramebufferBack * -cogl_gl_framebuffer_back_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); - -#endif /* COGL_GL_FRAMEBUFFER_BACK_H */ diff --git a/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c b/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c deleted file mode 100644 index c8db6a23a..000000000 --- a/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2012 Intel Corporation. - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "driver/gl/cogl-gl-framebuffer-fbo.h" - -#include <gio/gio.h> - -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-offscreen-private.h" -#include "driver/gl/cogl-texture-gl-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -typedef struct _CoglGlFbo -{ - GLuint fbo_handle; - GList *renderbuffers; - int samples_per_pixel; -} CoglGlFbo; - -struct _CoglGlFramebufferFbo -{ - CoglGlFramebuffer parent; - - CoglGlFbo gl_fbo; - - gboolean dirty_bitmasks; - CoglFramebufferBits bits; -}; - -G_DEFINE_TYPE (CoglGlFramebufferFbo, cogl_gl_framebuffer_fbo, - COGL_TYPE_GL_FRAMEBUFFER) - -static gboolean -ensure_bits_initialized (CoglGlFramebufferFbo *gl_framebuffer_fbo) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglFramebufferBits *bits = &gl_framebuffer_fbo->bits; - g_autoptr (GError) error = NULL; - - if (!gl_framebuffer_fbo->dirty_bitmasks) - return TRUE; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - -#ifdef HAVE_COGL_GL - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS)) - { - const struct { - GLenum attachment, pname; - size_t offset; - } params[] = { - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, - .offset = offsetof (CoglFramebufferBits, red), - }, - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, - .offset = offsetof (CoglFramebufferBits, green), - }, - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, - .offset = offsetof (CoglFramebufferBits, blue), - }, - { - .attachment = GL_COLOR_ATTACHMENT0, - .pname = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, - .offset = offsetof (CoglFramebufferBits, alpha), - }, - { - .attachment = GL_DEPTH_ATTACHMENT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, - .offset = offsetof (CoglFramebufferBits, depth), - }, - { - .attachment = GL_STENCIL_ATTACHMENT, - .pname = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - .offset = offsetof (CoglFramebufferBits, stencil), - }, - }; - int i; - - for (i = 0; i < G_N_ELEMENTS (params); i++) - { - int *value = - (int *) ((uint8_t *) bits + params[i].offset); - - GE (ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - params[i].attachment, - params[i].pname, - value)); - } - } - else -#endif /* HAVE_COGL_GL */ - { - GE (ctx, glGetIntegerv (GL_RED_BITS, &bits->red)); - GE (ctx, glGetIntegerv (GL_GREEN_BITS, &bits->green)); - GE (ctx, glGetIntegerv (GL_BLUE_BITS, &bits->blue)); - GE (ctx, glGetIntegerv (GL_ALPHA_BITS, &bits->alpha)); - GE (ctx, glGetIntegerv (GL_DEPTH_BITS, &bits->depth)); - GE (ctx, glGetIntegerv (GL_STENCIL_BITS, &bits->stencil)); - } - - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && - (cogl_framebuffer_get_internal_format (framebuffer) == - COGL_PIXEL_FORMAT_A_8)) - { - bits->alpha = bits->red; - bits->red = 0; - } - - COGL_NOTE (FRAMEBUFFER, - "RGBA/D/S Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d, %d", - framebuffer, - G_OBJECT_TYPE_NAME (framebuffer), - bits->red, - bits->blue, - bits->green, - bits->alpha, - bits->depth, - bits->stencil); - - gl_framebuffer_fbo->dirty_bitmasks = FALSE; - - return TRUE; -} - -static void -cogl_gl_framebuffer_fbo_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - CoglGlFramebufferFbo *gl_framebuffer_fbo = COGL_GL_FRAMEBUFFER_FBO (driver); - - if (!ensure_bits_initialized (gl_framebuffer_fbo)) - return; - - *bits = gl_framebuffer_fbo->bits; -} - -static void -cogl_gl_framebuffer_fbo_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - GLenum attachments[3]; - int i = 0; - - if (!ctx->glDiscardFramebuffer) - return; - - if (buffers & COGL_BUFFER_BIT_COLOR) - attachments[i++] = GL_COLOR_ATTACHMENT0; - if (buffers & COGL_BUFFER_BIT_DEPTH) - attachments[i++] = GL_DEPTH_ATTACHMENT; - if (buffers & COGL_BUFFER_BIT_STENCIL) - attachments[i++] = GL_STENCIL_ATTACHMENT; - - cogl_context_flush_framebuffer_state (ctx, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - GE (ctx, glDiscardFramebuffer (GL_FRAMEBUFFER, i, attachments)); -} - -static void -cogl_gl_framebuffer_fbo_bind (CoglGlFramebuffer *gl_framebuffer, - GLenum target) -{ - CoglGlFramebufferFbo *gl_framebuffer_fbo = - COGL_GL_FRAMEBUFFER_FBO (gl_framebuffer); - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - GE (ctx, glBindFramebuffer (target, gl_framebuffer_fbo->gl_fbo.fbo_handle)); -} - -static void -cogl_gl_framebuffer_fbo_flush_stereo_mode_state (CoglGlFramebuffer *gl_framebuffer) -{ - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - - switch (cogl_framebuffer_get_stereo_mode (framebuffer)) - { - case COGL_STEREO_BOTH: - break; - case COGL_STEREO_LEFT: - case COGL_STEREO_RIGHT: - g_warn_if_reached (); - break; - } -} - -static GList * -try_creating_renderbuffers (CoglContext *ctx, - int width, - int height, - CoglOffscreenAllocateFlags flags, - int n_samples) -{ - GList *renderbuffers = NULL; - GLuint gl_depth_stencil_handle; - - if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL) - { - GLenum format; - - /* WebGL adds a GL_DEPTH_STENCIL_ATTACHMENT and requires that we - * use the GL_DEPTH_STENCIL format. */ - /* Although GL_OES_packed_depth_stencil is mostly equivalent to - * GL_EXT_packed_depth_stencil, one notable difference is that - * GL_OES_packed_depth_stencil doesn't allow GL_DEPTH_STENCIL to - * be passed as an internal format to glRenderbufferStorage. - */ - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL)) - format = GL_DEPTH_STENCIL; - else - { - g_return_val_if_fail ( - _cogl_has_private_feature (ctx, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL), - NULL); - format = GL_DEPTH24_STENCIL8; - } - - /* Create a renderbuffer for depth and stenciling */ - GE (ctx, glGenRenderbuffers (1, &gl_depth_stencil_handle)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_stencil_handle)); - if (n_samples) - GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER, - n_samples, - format, - width, height)); - else - GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, format, - width, height)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); - - - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, - gl_depth_stencil_handle)); - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, - gl_depth_stencil_handle)); - renderbuffers = - g_list_prepend (renderbuffers, - GUINT_TO_POINTER (gl_depth_stencil_handle)); - } - - if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH) - { - GLuint gl_depth_handle; - - GE (ctx, glGenRenderbuffers (1, &gl_depth_handle)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_depth_handle)); - /* For now we just ask for GL_DEPTH_COMPONENT16 since this is all that's - * available under GLES */ - if (n_samples) - GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER, - n_samples, - GL_DEPTH_COMPONENT16, - width, height)); - else - GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, - width, height)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, gl_depth_handle)); - renderbuffers = - g_list_prepend (renderbuffers, GUINT_TO_POINTER (gl_depth_handle)); - } - - if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL) - { - GLuint gl_stencil_handle; - - GE (ctx, glGenRenderbuffers (1, &gl_stencil_handle)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, gl_stencil_handle)); - if (n_samples) - GE (ctx, glRenderbufferStorageMultisampleIMG (GL_RENDERBUFFER, - n_samples, - GL_STENCIL_INDEX8, - width, height)); - else - GE (ctx, glRenderbufferStorage (GL_RENDERBUFFER, GL_STENCIL_INDEX8, - width, height)); - GE (ctx, glBindRenderbuffer (GL_RENDERBUFFER, 0)); - GE (ctx, glFramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, gl_stencil_handle)); - renderbuffers = - g_list_prepend (renderbuffers, GUINT_TO_POINTER (gl_stencil_handle)); - } - - return renderbuffers; -} - -static void -delete_renderbuffers (CoglContext *ctx, - GList *renderbuffers) -{ - GList *l; - - for (l = renderbuffers; l; l = l->next) - { - GLuint renderbuffer = GPOINTER_TO_UINT (l->data); - GE (ctx, glDeleteRenderbuffers (1, &renderbuffer)); - } - - g_list_free (renderbuffers); -} - -/* - * NB: This function may be called with a standalone GLES2 context - * bound so we can create a shadow framebuffer that wraps the same - * CoglTexture as the given CoglOffscreen. This function shouldn't - * modify anything in - */ -static gboolean -try_creating_fbo (CoglContext *ctx, - CoglTexture *texture, - int texture_level, - int texture_level_width, - int texture_level_height, - const CoglFramebufferConfig *config, - CoglOffscreenAllocateFlags flags, - CoglGlFbo *gl_fbo) -{ - GLuint tex_gl_handle; - GLenum tex_gl_target; - GLenum status; - int n_samples; - - if (!cogl_texture_get_gl_texture (texture, &tex_gl_handle, &tex_gl_target)) - return FALSE; - - if (tex_gl_target != GL_TEXTURE_2D -#ifdef HAVE_COGL_GL - && tex_gl_target != GL_TEXTURE_RECTANGLE_ARB -#endif - ) - return FALSE; - - if (config->samples_per_pixel) - { - if (!ctx->glFramebufferTexture2DMultisampleIMG) - return FALSE; - n_samples = config->samples_per_pixel; - } - else - n_samples = 0; - - /* We are about to generate and bind a new fbo, so we pretend to - * change framebuffer state so that the old framebuffer will be - * rebound again before drawing. */ - ctx->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_BIND; - - /* Generate framebuffer */ - ctx->glGenFramebuffers (1, &gl_fbo->fbo_handle); - GE (ctx, glBindFramebuffer (GL_FRAMEBUFFER, gl_fbo->fbo_handle)); - - if (n_samples) - { - GE (ctx, glFramebufferTexture2DMultisampleIMG (GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - tex_gl_target, tex_gl_handle, - n_samples, - texture_level)); - } - else - GE (ctx, glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - tex_gl_target, tex_gl_handle, - texture_level)); - - if (flags) - { - gl_fbo->renderbuffers = - try_creating_renderbuffers (ctx, - texture_level_width, - texture_level_height, - flags, - n_samples); - } - - /* Make sure it's complete */ - status = ctx->glCheckFramebufferStatus (GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) - { - GE (ctx, glDeleteFramebuffers (1, &gl_fbo->fbo_handle)); - - delete_renderbuffers (ctx, gl_fbo->renderbuffers); - gl_fbo->renderbuffers = NULL; - - return FALSE; - } - - /* Update the real number of samples_per_pixel now that we have a - * complete framebuffer */ - if (n_samples) - { - GLenum attachment = GL_COLOR_ATTACHMENT0; - GLenum pname = GL_TEXTURE_SAMPLES_IMG; - int texture_samples; - - GE( ctx, glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, - attachment, - pname, - &texture_samples) ); - gl_fbo->samples_per_pixel = texture_samples; - } - - return TRUE; -} - -CoglGlFramebufferFbo * -cogl_gl_framebuffer_fbo_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglOffscreen *offscreen; - CoglTexture *texture; - int texture_level; - int level_width; - int level_height; - const CoglFramebufferConfig *config; - CoglGlFbo *gl_fbo; - CoglGlFramebufferFbo *gl_framebuffer_fbo; - CoglOffscreenAllocateFlags allocate_flags; - - if (!COGL_IS_OFFSCREEN (framebuffer)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Incompatible framebuffer"); - return NULL; - } - - offscreen = COGL_OFFSCREEN (framebuffer); - texture = cogl_offscreen_get_texture (offscreen); - texture_level = cogl_offscreen_get_texture_level (offscreen); - - g_return_val_if_fail (texture_level < _cogl_texture_get_n_levels (texture), - NULL); - - _cogl_texture_get_level_size (texture, - texture_level, - &level_width, - &level_height, - NULL); - - /* XXX: The framebuffer_object spec isn't clear in defining whether attaching - * a texture as a renderbuffer with mipmap filtering enabled while the - * mipmaps have not been uploaded should result in an incomplete framebuffer - * object. (different drivers make different decisions) - * - * To avoid an error with drivers that do consider this a problem we - * explicitly set non mipmapped filters here. These will later be reset when - * the texture is actually used for rendering according to the filters set on - * the corresponding CoglPipeline. - */ - _cogl_texture_gl_flush_legacy_texobj_filters (texture, - GL_NEAREST, GL_NEAREST); - - config = cogl_framebuffer_get_config (framebuffer); - - gl_framebuffer_fbo = g_object_new (COGL_TYPE_GL_FRAMEBUFFER_FBO, - "framebuffer", framebuffer, - NULL); - gl_fbo = &gl_framebuffer_fbo->gl_fbo; - - if ((driver_config->disable_depth_and_stencil && - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = 0, - gl_fbo)) || - - (context->have_last_offscreen_allocate_flags && - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = context->last_offscreen_allocate_flags, - gl_fbo)) || - - ( - /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't - * need an extension to handle _FLAG_DEPTH_STENCIL */ - (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) || - _cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) && - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL, - gl_fbo)) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH | - COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, - gl_fbo) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL, - gl_fbo) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH, - gl_fbo) || - - try_creating_fbo (context, - texture, - texture_level, - level_width, - level_height, - config, - allocate_flags = 0, - gl_fbo)) - { - cogl_framebuffer_update_samples_per_pixel (framebuffer, - gl_fbo->samples_per_pixel); - - if (!driver_config->disable_depth_and_stencil) - { - /* Record that the last set of flags succeeded so that we can - try that set first next time */ - context->last_offscreen_allocate_flags = allocate_flags; - context->have_last_offscreen_allocate_flags = TRUE; - } - - return gl_framebuffer_fbo; - } - else - { - g_object_unref (gl_framebuffer_fbo); - g_set_error (error, COGL_FRAMEBUFFER_ERROR, - COGL_FRAMEBUFFER_ERROR_ALLOCATE, - "Failed to create an OpenGL framebuffer object"); - return NULL; - } -} - -static void -cogl_gl_framebuffer_fbo_dispose (GObject *object) -{ - CoglGlFramebufferFbo *gl_framebuffer_fbo = COGL_GL_FRAMEBUFFER_FBO (object); - CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - CoglFramebuffer *framebuffer = - cogl_framebuffer_driver_get_framebuffer (driver); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - delete_renderbuffers (ctx, gl_framebuffer_fbo->gl_fbo.renderbuffers); - gl_framebuffer_fbo->gl_fbo.renderbuffers = NULL; - - if (gl_framebuffer_fbo->gl_fbo.fbo_handle) - { - GE (ctx, glDeleteFramebuffers (1, - &gl_framebuffer_fbo->gl_fbo.fbo_handle)); - gl_framebuffer_fbo->gl_fbo.fbo_handle = 0; - } - - G_OBJECT_CLASS (cogl_gl_framebuffer_fbo_parent_class)->dispose (object); -} - -static void -cogl_gl_framebuffer_fbo_init (CoglGlFramebufferFbo *gl_framebuffer_fbo) -{ - gl_framebuffer_fbo->dirty_bitmasks = TRUE; -} - -static void -cogl_gl_framebuffer_fbo_class_init (CoglGlFramebufferFboClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - CoglGlFramebufferClass *gl_framebuffer_class = - COGL_GL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_gl_framebuffer_fbo_dispose; - - driver_class->query_bits = cogl_gl_framebuffer_fbo_query_bits; - driver_class->discard_buffers = cogl_gl_framebuffer_fbo_discard_buffers; - - gl_framebuffer_class->bind = cogl_gl_framebuffer_fbo_bind; - gl_framebuffer_class->flush_stereo_mode_state = - cogl_gl_framebuffer_fbo_flush_stereo_mode_state; -} diff --git a/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h b/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h deleted file mode 100644 index 896847cf8..000000000 --- a/cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef COGL_GL_FRAMEBUFFER_FBO_H -#define COGL_GL_FRAMEBUFFER_FBO_H - -#include "driver/gl/cogl-framebuffer-gl-private.h" - -#define COGL_TYPE_GL_FRAMEBUFFER_FBO (cogl_gl_framebuffer_fbo_get_type ()) -G_DECLARE_FINAL_TYPE (CoglGlFramebufferFbo, cogl_gl_framebuffer_fbo, - COGL, GL_FRAMEBUFFER_FBO, - CoglGlFramebuffer) - -CoglGlFramebufferFbo * -cogl_gl_framebuffer_fbo_new (CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); - -#endif /* COGL_GL_FRAMEBUFFER_FBO_H */ diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h deleted file mode 100644 index 72f5928a8..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_FRAGEND_GLSL_PRIVATE_H -#define __COGL_PIPELINE_FRAGEND_GLSL_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineFragend _cogl_pipeline_glsl_fragend; - -GLuint -_cogl_pipeline_fragend_glsl_get_shader (CoglPipeline *pipeline); - -#endif /* __COGL_PIPELINE_FRAGEND_GLSL_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c deleted file mode 100644 index d932a5cf5..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c +++ /dev/null @@ -1,1120 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-pipeline-layer-private.h" -#include "cogl-blend-string.h" -#include "cogl-snippet-private.h" -#include "cogl-list.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" - -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-pipeline-cache.h" -#include "driver/gl/cogl-pipeline-fragend-glsl-private.h" -#include "deprecated/cogl-shader-private.h" -#include "deprecated/cogl-program-private.h" - -#include <glib.h> - -/* - * GL/GLES compatibility defines for pipeline thingies: - */ - -/* This might not be defined on GLES */ -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - -const CoglPipelineFragend _cogl_pipeline_glsl_backend; - -typedef struct _UnitState -{ - unsigned int sampled:1; - unsigned int combine_constant_used:1; -} UnitState; - -typedef struct _LayerData -{ - CoglList link; - - /* Layer index for the for the previous layer. This isn't - necessarily the same as this layer's index - 1 because the - indices can have gaps. If this is the first layer then it will be - -1 */ - int previous_layer_index; - - CoglPipelineLayer *layer; -} LayerData; - -typedef struct -{ - int ref_count; - - GLuint gl_shader; - GString *header, *source; - UnitState *unit_state; - - /* List of layers that we haven't generated code for yet. These are - in reverse order. As soon as we're about to generate code for - layer we'll remove it from the list so we don't generate it - again */ - CoglList layers; - - CoglPipelineCacheEntry *cache_entry; -} CoglPipelineShaderState; - -static CoglUserDataKey shader_state_key; - -static void -ensure_layer_generated (CoglPipeline *pipeline, - int layer_num); - -static CoglPipelineShaderState * -shader_state_new (int n_layers, - CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineShaderState *shader_state; - - shader_state = g_new0 (CoglPipelineShaderState, 1); - shader_state->ref_count = 1; - shader_state->unit_state = g_new0 (UnitState, n_layers); - shader_state->cache_entry = cache_entry; - - return shader_state; -} - -static CoglPipelineShaderState * -get_shader_state (CoglPipeline *pipeline) -{ - return cogl_object_get_user_data (COGL_OBJECT (pipeline), &shader_state_key); -} - -static void -destroy_shader_state (void *user_data, - void *instance) -{ - CoglPipelineShaderState *shader_state = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != instance) - shader_state->cache_entry->usage_count--; - - if (--shader_state->ref_count == 0) - { - if (shader_state->gl_shader) - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - - g_free (shader_state->unit_state); - - g_free (shader_state); - } -} - -static void -set_shader_state (CoglPipeline *pipeline, CoglPipelineShaderState *shader_state) -{ - if (shader_state) - { - shader_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != pipeline) - shader_state->cache_entry->usage_count++; - } - - _cogl_object_set_user_data (COGL_OBJECT (pipeline), - &shader_state_key, - shader_state, - destroy_shader_state); -} - -static void -dirty_shader_state (CoglPipeline *pipeline) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &shader_state_key, - NULL, - NULL); -} - -GLuint -_cogl_pipeline_fragend_glsl_get_shader (CoglPipeline *pipeline) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - - if (shader_state) - return shader_state->gl_shader; - else - return 0; -} - -static CoglPipelineSnippetList * -get_fragment_snippets (CoglPipeline *pipeline) -{ - pipeline = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS); - - return &pipeline->big_state->fragment_snippets; -} - -static CoglPipelineSnippetList * -get_layer_fragment_snippets (CoglPipelineLayer *layer) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS; - layer = _cogl_pipeline_layer_get_authority (layer, state); - - return &layer->big_state->fragment_snippets; -} - -static gboolean -has_replace_hook (CoglPipelineLayer *layer, - CoglSnippetHook hook) -{ - GList *l; - - for (l = get_layer_fragment_snippets (layer)->entries; l; l = l->next) - { - CoglSnippet *snippet = l->data; - - if (snippet->hook == hook && snippet->replace) - return TRUE; - } - - return FALSE; -} - -static gboolean -add_layer_declaration_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineShaderState *shader_state = user_data; - - g_string_append_printf (shader_state->header, - "uniform sampler2D cogl_sampler%i;\n", - layer->index); - - return TRUE; -} - -static void -add_layer_declarations (CoglPipeline *pipeline, - CoglPipelineShaderState *shader_state) -{ - /* We always emit sampler uniforms in case there will be custom - * layer snippets that want to sample arbitrary layers. */ - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_declaration_cb, - shader_state); -} - -static void -add_global_declarations (CoglPipeline *pipeline, - CoglPipelineShaderState *shader_state) -{ - CoglSnippetHook hook = COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS; - CoglPipelineSnippetList *snippets = get_fragment_snippets (pipeline); - - /* Add the global data hooks. All of the code in these snippets is - * always added and only the declarations data is used */ - - _cogl_pipeline_snippet_generate_declarations (shader_state->header, - hook, - snippets); -} - -static void -_cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglPipelineShaderState *shader_state; - CoglPipeline *authority; - CoglPipelineCacheEntry *cache_entry = NULL; - CoglProgram *user_program = cogl_pipeline_get_user_program (pipeline); - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Now lookup our glsl backend private state */ - shader_state = get_shader_state (pipeline); - - if (shader_state == NULL) - { - /* If we don't have an associated glsl shader yet then find the - * glsl-authority (the oldest ancestor whose state will result in - * the same shader being generated as for this pipeline). - * - * We always make sure to associate new shader with the - * glsl-authority to maximize the chance that other pipelines can - * share it. - */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - _cogl_pipeline_get_state_for_fragment_codegen (ctx) & - ~COGL_PIPELINE_STATE_LAYERS, - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx)); - - shader_state = get_shader_state (authority); - - /* If we don't have an existing program associated with the - * glsl-authority then start generating code for a new shader... - */ - if (shader_state == NULL) - { - /* Check if there is already a similar cached pipeline whose - shader state we can share */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_fragment_template (ctx->pipeline_cache, - authority); - - shader_state = get_shader_state (cache_entry->pipeline); - } - - if (shader_state) - shader_state->ref_count++; - else - shader_state = shader_state_new (n_layers, cache_entry); - - set_shader_state (authority, shader_state); - - shader_state->ref_count--; - - if (cache_entry) - set_shader_state (cache_entry->pipeline, shader_state); - } - - /* If the pipeline isn't actually its own glsl-authority - * then take a reference to the program state associated - * with the glsl-authority... */ - if (authority != pipeline) - set_shader_state (pipeline, shader_state); - } - - if (user_program) - { - /* If the user program contains a fragment shader then we don't need - to generate one */ - if (_cogl_program_has_fragment_shader (user_program)) - { - if (shader_state->gl_shader) - { - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - shader_state->gl_shader = 0; - } - return; - } - } - - if (shader_state->gl_shader) - return; - - /* If we make it here then we have a glsl_shader_state struct - without a gl_shader either because this is the first time we've - encountered it or because the user program has changed */ - - /* We reuse two grow-only GStrings for code-gen. One string - contains the uniform and attribute declarations while the - other contains the main function. We need two strings - because we need to dynamically declare attributes as the - add_layer callback is invoked */ - g_string_set_size (ctx->codegen_header_buffer, 0); - g_string_set_size (ctx->codegen_source_buffer, 0); - shader_state->header = ctx->codegen_header_buffer; - shader_state->source = ctx->codegen_source_buffer; - _cogl_list_init (&shader_state->layers); - - add_layer_declarations (pipeline, shader_state); - add_global_declarations (pipeline, shader_state); - - g_string_append (shader_state->source, - "void\n" - "cogl_generated_source ()\n" - "{\n"); - - for (i = 0; i < n_layers; i++) - { - shader_state->unit_state[i].sampled = FALSE; - shader_state->unit_state[i].combine_constant_used = FALSE; - } -} - -static void -add_constant_lookup (CoglPipelineShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - const char *swizzle) -{ - g_string_append_printf (shader_state->header, - "_cogl_layer_constant_%i.%s", - layer->index, swizzle); -} - -static void -ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer) -{ - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - CoglPipelineSnippetData snippet_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader_state->unit_state[unit_index].sampled) - return; - - shader_state->unit_state[unit_index].sampled = TRUE; - - g_string_append_printf (shader_state->header, - "vec4 cogl_texel%i;\n", - layer->index); - - g_string_append_printf (shader_state->source, - " cogl_texel%i = cogl_texture_lookup%i (" - "cogl_sampler%i, ", - layer->index, - layer->index, - layer->index); - - if (cogl_pipeline_get_layer_point_sprite_coords_enabled (pipeline, - layer->index)) - g_string_append_printf (shader_state->source, - "vec4 (cogl_point_coord, 0.0, 1.0)"); - else - g_string_append_printf (shader_state->source, - "cogl_tex_coord%i_in", - layer->index); - - g_string_append (shader_state->source, ");\n"); - - /* There's no need to generate the real texture lookup if it's going - to be replaced */ - if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_TEXTURE_LOOKUP)) - { - g_string_append_printf (shader_state->header, - "vec4\n" - "cogl_real_texture_lookup%i (sampler2D tex,\n" - " vec4 coords)\n" - "{\n" - " return ", - layer->index); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_TEXTURING))) - g_string_append (shader_state->header, - "vec4 (1.0, 1.0, 1.0, 1.0);\n"); - else - g_string_append (shader_state->header, - "texture2D (tex, coords.st);\n"); - - g_string_append (shader_state->header, "}\n"); - } - - /* Wrap the texture lookup in any snippets that have been hooked */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_layer_fragment_snippets (layer); - snippet_data.hook = COGL_SNIPPET_HOOK_TEXTURE_LOOKUP; - snippet_data.chain_function = g_strdup_printf ("cogl_real_texture_lookup%i", - layer->index); - snippet_data.final_name = g_strdup_printf ("cogl_texture_lookup%i", - layer->index); - snippet_data.function_prefix = g_strdup_printf ("cogl_texture_lookup_hook%i", - layer->index); - snippet_data.return_type = "vec4"; - snippet_data.return_variable = "cogl_texel"; - snippet_data.arguments = "cogl_sampler, cogl_tex_coord"; - snippet_data.argument_declarations = - g_strdup ("sampler2D cogl_sampler, vec4 cogl_tex_coord"); - snippet_data.source_buf = shader_state->header; - - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_free ((char *) snippet_data.chain_function); - g_free ((char *) snippet_data.final_name); - g_free ((char *) snippet_data.function_prefix); - g_free ((char *) snippet_data.argument_declarations); -} - -static void -add_arg (CoglPipelineShaderState *shader_state, - CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - CoglPipelineCombineSource src, - CoglPipelineCombineOp operand, - const char *swizzle) -{ - GString *shader_source = shader_state->header; - char alpha_swizzle[5] = "aaaa"; - - g_string_append_c (shader_source, '('); - - if (operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_COLOR || - operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA) - g_string_append_printf (shader_source, - "vec4(1.0, 1.0, 1.0, 1.0).%s - ", - swizzle); - - /* If the operand is reading from the alpha then replace the swizzle - with the same number of copies of the alpha */ - if (operand == COGL_PIPELINE_COMBINE_OP_SRC_ALPHA || - operand == COGL_PIPELINE_COMBINE_OP_ONE_MINUS_SRC_ALPHA) - { - alpha_swizzle[strlen (swizzle)] = '\0'; - swizzle = alpha_swizzle; - } - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - g_string_append_printf (shader_source, - "cogl_texel%i.%s", - layer->index, - swizzle); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - add_constant_lookup (shader_state, - pipeline, - layer, - swizzle); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - if (previous_layer_index >= 0) - { - g_string_append_printf (shader_source, - "cogl_layer%i.%s", - previous_layer_index, - swizzle); - break; - } - /* flow through */ - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - g_string_append_printf (shader_source, "cogl_color_in.%s", swizzle); - break; - - default: - { - int layer_num = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *other_layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); - - if (other_layer == NULL) - { - static gboolean warning_seen = FALSE; - if (!warning_seen) - { - g_warning ("The application is trying to use a texture " - "combine with a layer number that does not exist"); - warning_seen = TRUE; - } - g_string_append_printf (shader_source, - "vec4 (1.0, 1.0, 1.0, 1.0).%s", - swizzle); - } - else - g_string_append_printf (shader_source, - "cogl_texel%i.%s", - other_layer->index, - swizzle); - } - break; - } - - g_string_append_c (shader_source, ')'); -} - -static void -ensure_arg_generated (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - CoglPipelineCombineSource src) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - - switch (src) - { - case COGL_PIPELINE_COMBINE_SOURCE_PRIMARY_COLOR: - /* This doesn't involve any other layers */ - break; - - case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - /* Create a sampler uniform for this layer if we haven't already */ - if (!shader_state->unit_state[unit_index].combine_constant_used) - { - g_string_append_printf (shader_state->header, - "uniform vec4 _cogl_layer_constant_%i;\n", - layer->index); - shader_state->unit_state[unit_index].combine_constant_used = TRUE; - } - } - break; - - case COGL_PIPELINE_COMBINE_SOURCE_PREVIOUS: - if (previous_layer_index >= 0) - ensure_layer_generated (pipeline, previous_layer_index); - break; - - case COGL_PIPELINE_COMBINE_SOURCE_TEXTURE: - ensure_texture_lookup_generated (shader_state, - pipeline, - layer); - break; - - default: - if (src >= COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0) - { - int layer_num = src - COGL_PIPELINE_COMBINE_SOURCE_TEXTURE0; - CoglPipelineGetLayerFlags flags = COGL_PIPELINE_GET_LAYER_NO_CREATE; - CoglPipelineLayer *other_layer = - _cogl_pipeline_get_layer_with_flags (pipeline, layer_num, flags); - - if (other_layer) - ensure_texture_lookup_generated (shader_state, - pipeline, - other_layer); - } - break; - } -} - -static void -ensure_args_for_func (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src) -{ - int n_args = _cogl_get_n_args_for_combine_func (function); - int i; - - for (i = 0; i < n_args; i++) - ensure_arg_generated (pipeline, layer, previous_layer_index, src[i]); -} - -static void -append_masked_combine (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - int previous_layer_index, - const char *swizzle, - CoglPipelineCombineFunc function, - CoglPipelineCombineSource *src, - CoglPipelineCombineOp *op) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - GString *shader_source = shader_state->header; - - g_string_append_printf (shader_state->header, - " cogl_layer.%s = ", - swizzle); - - switch (function) - { - case COGL_PIPELINE_COMBINE_FUNC_REPLACE: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_MODULATE: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " * "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_ADD: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " + "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_ADD_SIGNED: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " + "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - g_string_append_printf (shader_source, - " - vec4(0.5, 0.5, 0.5, 0.5).%s", - swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_SUBTRACT: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " - "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - break; - - case COGL_PIPELINE_COMBINE_FUNC_INTERPOLATE: - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], swizzle); - g_string_append (shader_source, " * "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[2], op[2], swizzle); - g_string_append (shader_source, " + "); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], swizzle); - g_string_append_printf (shader_source, - " * (vec4(1.0, 1.0, 1.0, 1.0).%s - ", - swizzle); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[2], op[2], swizzle); - g_string_append_c (shader_source, ')'); - break; - - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGB: - case COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA: - g_string_append (shader_source, "vec4(4.0 * (("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], "r"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], "r"); - g_string_append (shader_source, " - 0.5) + ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], "g"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], "g"); - g_string_append (shader_source, " - 0.5) + ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[0], op[0], "b"); - g_string_append (shader_source, " - 0.5) * ("); - add_arg (shader_state, pipeline, layer, previous_layer_index, - src[1], op[1], "b"); - g_string_append_printf (shader_source, " - 0.5))).%s", swizzle); - break; - } - - g_string_append_printf (shader_source, ";\n"); -} - -static void -ensure_layer_generated (CoglPipeline *pipeline, - int layer_index) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - CoglPipelineLayer *combine_authority; - CoglPipelineLayerBigState *big_state; - CoglPipelineLayer *layer; - CoglPipelineSnippetData snippet_data; - LayerData *layer_data; - - /* Find the layer that corresponds to this layer_num */ - _cogl_list_for_each (layer_data, &shader_state->layers, link) - { - layer = layer_data->layer; - - if (layer->index == layer_index) - goto found; - } - - /* If we didn't find it then we can assume the layer has already - been generated */ - return; - - found: - - /* Remove the layer from the list so we don't generate it again */ - _cogl_list_remove (&layer_data->link); - - combine_authority = - _cogl_pipeline_layer_get_authority (layer, - COGL_PIPELINE_LAYER_STATE_COMBINE); - big_state = combine_authority->big_state; - - /* Make a global variable for the result of the layer code */ - g_string_append_printf (shader_state->header, - "vec4 cogl_layer%i;\n", - layer_index); - - /* Skip the layer generation if there is a snippet that replaces the - default layer code. This is important because generating this - code may cause the code for other layers to be generated and - stored in the global variable. If this code isn't actually used - then the global variables would be uninitialised and they may be - used from other layers */ - if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_LAYER_FRAGMENT)) - { - ensure_args_for_func (pipeline, - layer, - layer_data->previous_layer_index, - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src); - ensure_args_for_func (pipeline, - layer, - layer_data->previous_layer_index, - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src); - - g_string_append_printf (shader_state->header, - "vec4\n" - "cogl_real_generate_layer%i ()\n" - "{\n" - " vec4 cogl_layer;\n", - layer_index); - - if (!_cogl_pipeline_layer_needs_combine_separate (combine_authority) || - /* GL_DOT3_RGBA Is a bit weird as a GL_COMBINE_RGB function - * since if you use it, it overrides your ALPHA function... - */ - big_state->texture_combine_rgb_func == - COGL_PIPELINE_COMBINE_FUNC_DOT3_RGBA) - append_masked_combine (pipeline, - layer, - layer_data->previous_layer_index, - "rgba", - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - else - { - append_masked_combine (pipeline, - layer, - layer_data->previous_layer_index, - "rgb", - big_state->texture_combine_rgb_func, - big_state->texture_combine_rgb_src, - big_state->texture_combine_rgb_op); - append_masked_combine (pipeline, - layer, - layer_data->previous_layer_index, - "a", - big_state->texture_combine_alpha_func, - big_state->texture_combine_alpha_src, - big_state->texture_combine_alpha_op); - } - - g_string_append (shader_state->header, - " return cogl_layer;\n" - "}\n"); - } - - /* Wrap the layer code in any snippets that have been hooked */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_layer_fragment_snippets (layer); - snippet_data.hook = COGL_SNIPPET_HOOK_LAYER_FRAGMENT; - snippet_data.chain_function = g_strdup_printf ("cogl_real_generate_layer%i", - layer_index); - snippet_data.final_name = g_strdup_printf ("cogl_generate_layer%i", - layer_index); - snippet_data.function_prefix = g_strdup_printf ("cogl_generate_layer%i", - layer_index); - snippet_data.return_type = "vec4"; - snippet_data.return_variable = "cogl_layer"; - snippet_data.source_buf = shader_state->header; - - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_free ((char *) snippet_data.chain_function); - g_free ((char *) snippet_data.final_name); - g_free ((char *) snippet_data.function_prefix); - - g_string_append_printf (shader_state->source, - " cogl_layer%i = cogl_generate_layer%i ();\n", - layer_index, - layer_index); - - g_free (layer_data); -} - -static gboolean -_cogl_pipeline_fragend_glsl_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - LayerData *layer_data; - - if (!shader_state->source) - return TRUE; - - /* Store the layers in reverse order */ - layer_data = g_new0 (LayerData, 1); - layer_data->layer = layer; - - if (_cogl_list_empty (&shader_state->layers)) - { - layer_data->previous_layer_index = -1; - } - else - { - LayerData *first = - _cogl_container_of (shader_state->layers.next, LayerData, link); - layer_data->previous_layer_index = first->layer->index; - } - - _cogl_list_insert (&shader_state->layers, &layer_data->link); - - return TRUE; -} - -/* GLES2 and GL3 don't have alpha testing so we need to implement it - in the shader */ - -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - -static void -add_alpha_test_snippet (CoglPipeline *pipeline, - CoglPipelineShaderState *shader_state) -{ - CoglPipelineAlphaFunc alpha_func; - - alpha_func = cogl_pipeline_get_alpha_test_function (pipeline); - - if (alpha_func == COGL_PIPELINE_ALPHA_FUNC_ALWAYS) - /* Do nothing */ - return; - - if (alpha_func == COGL_PIPELINE_ALPHA_FUNC_NEVER) - { - /* Always discard the fragment */ - g_string_append (shader_state->source, - " discard;\n"); - return; - } - - /* For all of the other alpha functions we need a uniform for the - reference */ - - g_string_append (shader_state->header, - "uniform float _cogl_alpha_test_ref;\n"); - - g_string_append (shader_state->source, - " if (cogl_color_out.a "); - - switch (alpha_func) - { - case COGL_PIPELINE_ALPHA_FUNC_LESS: - g_string_append (shader_state->source, ">="); - break; - case COGL_PIPELINE_ALPHA_FUNC_EQUAL: - g_string_append (shader_state->source, "!="); - break; - case COGL_PIPELINE_ALPHA_FUNC_LEQUAL: - g_string_append (shader_state->source, ">"); - break; - case COGL_PIPELINE_ALPHA_FUNC_GREATER: - g_string_append (shader_state->source, "<="); - break; - case COGL_PIPELINE_ALPHA_FUNC_NOTEQUAL: - g_string_append (shader_state->source, "=="); - break; - case COGL_PIPELINE_ALPHA_FUNC_GEQUAL: - g_string_append (shader_state->source, "< "); - break; - - case COGL_PIPELINE_ALPHA_FUNC_ALWAYS: - case COGL_PIPELINE_ALPHA_FUNC_NEVER: - g_assert_not_reached (); - break; - } - - g_string_append (shader_state->source, - " _cogl_alpha_test_ref)\n discard;\n"); -} - -#endif /* HAVE_COGL_GLES2 */ - -static gboolean -_cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (shader_state->source) - { - const char *source_strings[2]; - GLint lengths[2]; - GLint compile_status; - GLuint shader; - CoglPipelineSnippetData snippet_data; - - COGL_STATIC_COUNTER (fragend_glsl_compile_counter, - "glsl fragment compile counter", - "Increments each time a new GLSL " - "fragment shader is compiled", - 0 /* no application private data */); - COGL_COUNTER_INC (_cogl_uprof_context, fragend_glsl_compile_counter); - - /* We only need to generate code to calculate the fragment value - for the last layer. If the value of this layer depends on any - previous layers then it will recursively generate the code - for those layers */ - if (!_cogl_list_empty (&shader_state->layers)) - { - CoglPipelineLayer *last_layer; - LayerData *layer_data, *tmp; - - layer_data = _cogl_container_of (shader_state->layers.next, - LayerData, - link); - last_layer = layer_data->layer; - - ensure_layer_generated (pipeline, last_layer->index); - g_string_append_printf (shader_state->source, - " cogl_color_out = cogl_layer%i;\n", - last_layer->index); - - _cogl_list_for_each_safe (layer_data, - tmp, - &shader_state->layers, - link) - g_free (layer_data); - } - else - g_string_append (shader_state->source, - " cogl_color_out = cogl_color_in;\n"); - - add_alpha_test_snippet (pipeline, shader_state); - - /* Close the function surrounding the generated fragment processing */ - g_string_append (shader_state->source, "}\n"); - - /* Add all of the hooks for fragment processing */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_fragment_snippets (pipeline); - snippet_data.hook = COGL_SNIPPET_HOOK_FRAGMENT; - snippet_data.chain_function = "cogl_generated_source"; - snippet_data.final_name = "main"; - snippet_data.function_prefix = "cogl_fragment_hook"; - snippet_data.source_buf = shader_state->source; - _cogl_pipeline_snippet_generate_code (&snippet_data); - - GE_RET( shader, ctx, glCreateShader (GL_FRAGMENT_SHADER) ); - - lengths[0] = shader_state->header->len; - source_strings[0] = shader_state->header->str; - lengths[1] = shader_state->source->len; - source_strings[1] = shader_state->source->str; - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader, GL_FRAGMENT_SHADER, - pipeline, - 2, /* count */ - source_strings, lengths); - - GE( ctx, glCompileShader (shader) ); - GE( ctx, glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); - - if (!compile_status) - { - GLint len = 0; - char *shader_log; - - GE( ctx, glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); - shader_log = g_alloca (len); - GE( ctx, glGetShaderInfoLog (shader, len, &len, shader_log) ); - g_warning ("Shader compilation failed:\n%s", shader_log); - } - - shader_state->header = NULL; - shader_state->source = NULL; - shader_state->gl_shader = shader; - } - - return TRUE; -} - -static void -_cogl_pipeline_fragend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_state_for_fragment_codegen (ctx))) - dirty_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_fragend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx))) - { - dirty_shader_state (owner); - return; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ -} - -const CoglPipelineFragend _cogl_pipeline_glsl_fragend = -{ - _cogl_pipeline_fragend_glsl_start, - _cogl_pipeline_fragend_glsl_add_layer, - _cogl_pipeline_fragend_glsl_end, - _cogl_pipeline_fragend_glsl_pre_change_notify, - _cogl_pipeline_fragend_glsl_layer_pre_change_notify -}; diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h deleted file mode 100644 index 3626fd16c..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_OPENGL_PRIVATE_H -#define __COGL_PIPELINE_OPENGL_PRIVATE_H - -#include "cogl-pipeline-private.h" -#include "cogl-matrix-stack.h" - -/* - * cogl-pipeline.c owns the GPU's texture unit state so we have some - * private structures for describing the current state of a texture - * unit that we track in a per context array (ctx->texture_units) that - * grows according to the largest texture unit used so far... - * - * Roughly speaking the members in this structure are of two kinds: - * either they are a low level reflection of the state we send to - * OpenGL or they are for high level meta data associated with the - * texture unit when flushing CoglPipelineLayers that is typically - * used to optimize subsequent re-flushing of the same layer. - * - * The low level members are at the top, and the high level members - * start with the .layer member. - */ -typedef struct _CoglTextureUnit -{ - /* The base 0 texture unit index which can be used with - * glActiveTexture () */ - int index; - - /* The GL target currently glEnabled or 0 if nothing is - * enabled. This is only used by the fixed pipeline fragend */ - GLenum enabled_gl_target; - - /* The raw GL texture object name for which we called glBindTexture when - * we flushed the last layer. (NB: The CoglTexture associated - * with a layer may represent more than one GL texture) */ - GLuint gl_texture; - /* The target of the GL texture object. This is just used so that we - * can quickly determine the intended target to flush when - * dirty_gl_texture == TRUE */ - GLenum gl_target; - - /* We have many components in Cogl that need to temporarily bind arbitrary - * textures e.g. to query texture object parameters and since we don't - * want that to result in too much redundant reflushing of layer state - * when all that's needed is to re-bind the layer's gl_texture we use this - * to track when the unit->gl_texture state is out of sync with the GL - * texture object really bound too (GL_TEXTURE0+unit->index). - * - * XXX: as a further optimization cogl-pipeline.c uses a convention - * of always using texture unit 1 for these transient bindings so we - * can assume this is only ever TRUE for unit 1. - */ - gboolean dirty_gl_texture; - - /* A matrix stack giving us the means to associate a texture - * transform matrix with the texture unit. */ - CoglMatrixStack *matrix_stack; - - /* - * Higher level layer state associated with the unit... - */ - - /* The CoglPipelineLayer whose state was flushed to update this - * texture unit last. - * - * This will be set to NULL if the layer is modified or freed which - * means when we come to flush a layer; if this pointer is still - * valid and == to the layer being flushed we don't need to update - * any texture unit state. */ - CoglPipelineLayer *layer; - - /* To help minimize the state changes required we track the - * difference flags associated with the layer whose state was last - * flushed to update this texture unit. - * - * Note: we track this explicitly because .layer may get invalidated - * if that layer is modified or deleted. Even if the layer is - * invalidated though these flags can be used to optimize the state - * flush of the next layer - */ - unsigned long layer_changes_since_flush; - - /* Whenever a CoglTexture's internal GL texture storage changes - * cogl-pipeline.c is notified with a call to - * _cogl_pipeline_texture_storage_change_notify which inturn sets - * this to TRUE for each texture unit that it is currently bound - * too. When we later come to flush some pipeline state then we will - * always check this to potentially force an update of the texture - * state even if the pipeline hasn't changed. */ - gboolean texture_storage_changed; - -} CoglTextureUnit; - -CoglTextureUnit * -_cogl_get_texture_unit (int index_); - -void -_cogl_destroy_texture_units (CoglContext *ctx); - -void -_cogl_set_active_texture_unit (int unit_index); - -void -_cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture); - -void -_cogl_delete_gl_texture (GLuint gl_texture); - -void -_cogl_pipeline_flush_gl_state (CoglContext *context, - CoglPipeline *pipeline, - CoglFramebuffer *framebuffer, - gboolean skip_gl_state, - gboolean unknown_color_alpha); - -void -_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, - GLuint shader_gl_handle, - GLenum shader_gl_type, - CoglPipeline *pipeline, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in); - -void -_cogl_sampler_gl_init (CoglContext *context, - CoglSamplerCacheEntry *entry); - -void -_cogl_sampler_gl_free (CoglContext *context, - CoglSamplerCacheEntry *entry); - -void -_cogl_gl_set_uniform (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value); - -#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c deleted file mode 100644 index 9d487714b..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-pipeline-private.h" -#include "cogl-context-private.h" -#include "cogl-texture-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-offscreen.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-texture-gl-private.h" - -#include "driver/gl/cogl-pipeline-progend-glsl-private.h" - -#include <test-fixtures/test-unit.h> - -#include <glib.h> -#include <string.h> - -/* - * GL/GLES compatibility defines for pipeline thingies: - */ - -/* These aren't defined in the GLES headers */ -#ifndef GL_POINT_SPRITE -#define GL_POINT_SPRITE 0x8861 -#endif -#ifndef GL_COORD_REPLACE -#define GL_COORD_REPLACE 0x8862 -#endif -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812d -#endif - -static void -texture_unit_init (CoglContext *ctx, - CoglTextureUnit *unit, - int index_) -{ - unit->index = index_; - unit->enabled_gl_target = 0; - unit->gl_texture = 0; - unit->gl_target = 0; - unit->dirty_gl_texture = FALSE; - unit->matrix_stack = cogl_matrix_stack_new (ctx); - - unit->layer = NULL; - unit->layer_changes_since_flush = 0; - unit->texture_storage_changed = FALSE; -} - -static void -texture_unit_free (CoglTextureUnit *unit) -{ - if (unit->layer) - cogl_object_unref (unit->layer); - cogl_object_unref (unit->matrix_stack); -} - -CoglTextureUnit * -_cogl_get_texture_unit (int index_) -{ - _COGL_GET_CONTEXT (ctx, NULL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - if (glctx->texture_units->len < (index_ + 1)) - { - int i; - int prev_len = glctx->texture_units->len; - glctx->texture_units = g_array_set_size (glctx->texture_units, - index_ + 1); - for (i = prev_len; i <= index_; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - texture_unit_init (ctx, unit, i); - } - } - - return &g_array_index (glctx->texture_units, CoglTextureUnit, index_); -} - -void -_cogl_destroy_texture_units (CoglContext *ctx) -{ - int i; - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - texture_unit_free (unit); - } - g_array_free (glctx->texture_units, TRUE); -} - -void -_cogl_set_active_texture_unit (int unit_index) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - if (glctx->active_texture_unit != unit_index) - { - GE (ctx, glActiveTexture (GL_TEXTURE0 + unit_index)); - glctx->active_texture_unit = unit_index; - } -} - -/* Note: _cogl_bind_gl_texture_transient conceptually has slightly - * different semantics to OpenGL's glBindTexture because Cogl never - * cares about tracking multiple textures bound to different targets - * on the same texture unit. - * - * glBindTexture lets you bind multiple textures to a single texture - * unit if they are bound to different targets. So it does something - * like: - * unit->current_texture[target] = texture; - * - * Cogl only lets you associate one texture with the currently active - * texture unit, so the target is basically a redundant parameter - * that's implicitly set on that texture. - * - * Technically this is just a thin wrapper around glBindTexture so - * actually it does have the GL semantics but it seems worth - * mentioning the conceptual difference in case anyone wonders why we - * don't associate the gl_texture with a gl_target in the - * CoglTextureUnit. - */ -void -_cogl_bind_gl_texture_transient (GLenum gl_target, - GLuint gl_texture) -{ - CoglTextureUnit *unit; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* We choose to always make texture unit 1 active for transient - * binds so that in the common case where multitexturing isn't used - * we can simply ignore the state of this texture unit. Notably we - * didn't use a large texture unit (.e.g. (GL_MAX_TEXTURE_UNITS - 1) - * in case the driver doesn't have a sparse data structure for - * texture units. - */ - _cogl_set_active_texture_unit (1); - unit = _cogl_get_texture_unit (1); - - if (unit->gl_texture == gl_texture && !unit->dirty_gl_texture) - return; - - GE (ctx, glBindTexture (gl_target, gl_texture)); - - unit->dirty_gl_texture = TRUE; -} - -void -_cogl_delete_gl_texture (GLuint gl_texture) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - if (unit->gl_texture == gl_texture) - { - unit->gl_texture = 0; - unit->gl_target = 0; - unit->dirty_gl_texture = FALSE; - } - } - - GE (ctx, glDeleteTextures (1, &gl_texture)); -} - -/* Whenever the underlying GL texture storage of a CoglTexture is - * changed (e.g. due to migration out of a texture atlas) then we are - * notified. This lets us ensure that we reflush that texture's state - * if it is reused again with the same texture unit. - */ -void -_cogl_pipeline_texture_storage_change_notify (CoglTexture *texture) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - if (unit->layer && - _cogl_pipeline_layer_get_texture (unit->layer) == texture) - unit->texture_storage_changed = TRUE; - - /* NB: the texture may be bound to multiple texture units so - * we continue to check the rest */ - } -} - -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - -static gboolean -blend_factor_uses_constant (GLenum blend_factor) -{ - return (blend_factor == GL_CONSTANT_COLOR || - blend_factor == GL_ONE_MINUS_CONSTANT_COLOR || - blend_factor == GL_CONSTANT_ALPHA || - blend_factor == GL_ONE_MINUS_CONSTANT_ALPHA); -} - -#endif - -static void -flush_depth_state (CoglContext *ctx, - CoglDepthState *depth_state) -{ - gboolean depth_writing_enabled = depth_state->write_enabled; - - if (ctx->current_draw_buffer) - { - depth_writing_enabled &= - cogl_framebuffer_get_depth_write_enabled (ctx->current_draw_buffer); - } - - if (ctx->depth_test_enabled_cache != depth_state->test_enabled) - { - if (depth_state->test_enabled == TRUE) - { - GE (ctx, glEnable (GL_DEPTH_TEST)); - if (ctx->current_draw_buffer) - cogl_framebuffer_set_depth_buffer_clear_needed (ctx->current_draw_buffer); - } - else - GE (ctx, glDisable (GL_DEPTH_TEST)); - ctx->depth_test_enabled_cache = depth_state->test_enabled; - } - - if (ctx->depth_test_function_cache != depth_state->test_function && - depth_state->test_enabled == TRUE) - { - GE (ctx, glDepthFunc (depth_state->test_function)); - ctx->depth_test_function_cache = depth_state->test_function; - } - - if (ctx->depth_writing_enabled_cache != depth_writing_enabled) - { - GE (ctx, glDepthMask (depth_writing_enabled ? - GL_TRUE : GL_FALSE)); - ctx->depth_writing_enabled_cache = depth_writing_enabled; - } - - if ((ctx->depth_range_near_cache != depth_state->range_near || - ctx->depth_range_far_cache != depth_state->range_far)) - { - if (ctx->driver == COGL_DRIVER_GLES2) - GE (ctx, glDepthRangef (depth_state->range_near, - depth_state->range_far)); - else - GE (ctx, glDepthRange (depth_state->range_near, - depth_state->range_far)); - - ctx->depth_range_near_cache = depth_state->range_near; - ctx->depth_range_far_cache = depth_state->range_far; - } -} - -UNIT_TEST (check_gl_blend_enable, - 0 /* no requirements */, - 0 /* no failure cases */) -{ - CoglPipeline *pipeline = cogl_pipeline_new (test_ctx); - - /* By default blending should be disabled */ - g_assert_cmpint (test_ctx->gl_blend_enable_cache, ==, 0); - - cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 1, 1); - _cogl_framebuffer_flush_journal (test_fb); - - /* After drawing an opaque rectangle blending should still be - * disabled */ - g_assert_cmpint (test_ctx->gl_blend_enable_cache, ==, 0); - - cogl_pipeline_set_color4f (pipeline, 0, 0, 0, 0); - cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 1, 1); - _cogl_framebuffer_flush_journal (test_fb); - - /* After drawing a transparent rectangle blending should be enabled */ - g_assert_cmpint (test_ctx->gl_blend_enable_cache, ==, 1); - - cogl_pipeline_set_blend (pipeline, "RGBA=ADD(SRC_COLOR, 0)", NULL); - cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 1, 1); - _cogl_framebuffer_flush_journal (test_fb); - - /* After setting a blend string that effectively disables blending - * then blending should be disabled */ - g_assert_cmpint (test_ctx->gl_blend_enable_cache, ==, 0); -} - -static void -_cogl_pipeline_flush_color_blend_alpha_depth_state ( - CoglPipeline *pipeline, - unsigned long pipelines_difference, - gboolean with_color_attrib) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (pipelines_difference & COGL_PIPELINE_STATE_BLEND) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_BLEND); - CoglPipelineBlendState *blend_state = - &authority->big_state->blend_state; - -#if defined(HAVE_COGL_GLES2) || defined(HAVE_COGL_GL) - if (blend_factor_uses_constant (blend_state->blend_src_factor_rgb) || - blend_factor_uses_constant (blend_state - ->blend_src_factor_alpha) || - blend_factor_uses_constant (blend_state->blend_dst_factor_rgb) || - blend_factor_uses_constant (blend_state->blend_dst_factor_alpha)) - { - float red = - cogl_color_get_red_float (&blend_state->blend_constant); - float green = - cogl_color_get_green_float (&blend_state->blend_constant); - float blue = - cogl_color_get_blue_float (&blend_state->blend_constant); - float alpha = - cogl_color_get_alpha_float (&blend_state->blend_constant); - - - GE (ctx, glBlendColor (red, green, blue, alpha)); - } - - GE (ctx, glBlendEquationSeparate (blend_state->blend_equation_rgb, - blend_state->blend_equation_alpha)); - - GE (ctx, glBlendFuncSeparate (blend_state->blend_src_factor_rgb, - blend_state->blend_dst_factor_rgb, - blend_state->blend_src_factor_alpha, - blend_state->blend_dst_factor_alpha)); - } -#endif - - if (pipelines_difference & COGL_PIPELINE_STATE_DEPTH) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_DEPTH); - CoglDepthState *depth_state = &authority->big_state->depth_state; - - flush_depth_state (ctx, depth_state); - } - - if (pipelines_difference & COGL_PIPELINE_STATE_CULL_FACE) - { - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_CULL_FACE); - CoglPipelineCullFaceState *cull_face_state - = &authority->big_state->cull_face_state; - - if (cull_face_state->mode == COGL_PIPELINE_CULL_FACE_MODE_NONE) - GE( ctx, glDisable (GL_CULL_FACE) ); - else - { - gboolean invert_winding; - - GE( ctx, glEnable (GL_CULL_FACE) ); - - switch (cull_face_state->mode) - { - case COGL_PIPELINE_CULL_FACE_MODE_NONE: - g_assert_not_reached (); - - case COGL_PIPELINE_CULL_FACE_MODE_FRONT: - GE( ctx, glCullFace (GL_FRONT) ); - break; - - case COGL_PIPELINE_CULL_FACE_MODE_BACK: - GE( ctx, glCullFace (GL_BACK) ); - break; - - case COGL_PIPELINE_CULL_FACE_MODE_BOTH: - GE( ctx, glCullFace (GL_FRONT_AND_BACK) ); - break; - } - - invert_winding = - cogl_framebuffer_is_y_flipped (ctx->current_draw_buffer); - - switch (cull_face_state->front_winding) - { - case COGL_WINDING_CLOCKWISE: - GE( ctx, glFrontFace (invert_winding ? GL_CCW : GL_CW) ); - break; - - case COGL_WINDING_COUNTER_CLOCKWISE: - GE( ctx, glFrontFace (invert_winding ? GL_CW : GL_CCW) ); - break; - } - } - } - - if (pipeline->real_blend_enable != ctx->gl_blend_enable_cache) - { - if (pipeline->real_blend_enable) - GE (ctx, glEnable (GL_BLEND)); - else - GE (ctx, glDisable (GL_BLEND)); - /* XXX: we shouldn't update any other blend state if blending - * is disabled! */ - ctx->gl_blend_enable_cache = pipeline->real_blend_enable; - } -} - -static int -get_max_activateable_texture_units (void) -{ - _COGL_GET_CONTEXT (ctx, 0); - - if (G_UNLIKELY (ctx->max_activateable_texture_units == -1)) - { - GLint values[3]; - int n_values = 0; - int i; - -#ifdef HAVE_COGL_GL - if (ctx->driver != COGL_DRIVER_GLES2) - { - /* GL_MAX_TEXTURE_COORDS defines the number of texture coordinates - * that can be uploaded (but doesn't necessarily relate to how many - * texture images can be sampled) */ - GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_COORDS, values + n_values++)); - - GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - values + n_values++)); - } -#endif /* HAVE_COGL_GL */ - -#ifdef HAVE_COGL_GLES2 - if (ctx->driver == COGL_DRIVER_GLES2) - { - GE (ctx, glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, values + n_values)); - /* Two of the vertex attribs need to be used for the position - and color */ - values[n_values++] -= 2; - - GE (ctx, glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, - values + n_values++)); - } -#endif - -#ifdef HAVE_COGL_GL - if (ctx->driver == COGL_DRIVER_GL) - { - /* GL_MAX_TEXTURE_UNITS defines the number of units that are - usable from the fixed function pipeline, therefore it isn't - available in GLES2. These are also tied to the number of - texture coordinates that can be uploaded so it should be less - than that available from the shader extensions */ - GE (ctx, glGetIntegerv (GL_MAX_TEXTURE_UNITS, - values + n_values++)); - - } -#endif - - g_assert (n_values <= G_N_ELEMENTS (values) && - n_values > 0); - - /* Use the maximum value */ - ctx->max_activateable_texture_units = values[0]; - for (i = 1; i < n_values; i++) - ctx->max_activateable_texture_units = - MAX (values[i], ctx->max_activateable_texture_units); - } - - return ctx->max_activateable_texture_units; -} - -typedef struct -{ - int i; - unsigned long *layer_differences; -} CoglPipelineFlushLayerState; - -static gboolean -flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineFlushLayerState *flush_state = user_data; - int unit_index = flush_state->i; - CoglTextureUnit *unit = _cogl_get_texture_unit (unit_index); - unsigned long layers_difference = - flush_state->layer_differences[unit_index]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* There may not be enough texture units so we can bail out if - * that's the case... - */ - if (G_UNLIKELY (unit_index >= get_max_activateable_texture_units ())) - { - static gboolean shown_warning = FALSE; - - if (!shown_warning) - { - g_warning ("Your hardware does not have enough texture units" - "to handle this many texture layers"); - shown_warning = TRUE; - } - return FALSE; - } - - if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) - { - CoglTexture *texture = _cogl_pipeline_layer_get_texture_real (layer); - GLuint gl_texture; - GLenum gl_target; - - if (texture == NULL) - texture = COGL_TEXTURE (ctx->default_gl_texture_2d_tex); - - cogl_texture_get_gl_texture (texture, - &gl_texture, - &gl_target); - - _cogl_set_active_texture_unit (unit_index); - - /* NB: There are several Cogl components and some code in - * Clutter that will temporarily bind arbitrary GL textures to - * query and modify texture object parameters. If you look at - * _cogl_bind_gl_texture_transient() you can see we make sure - * that such code always binds to texture unit 1 which means we - * can't rely on the unit->gl_texture state if unit->index == 1. - * - * Because texture unit 1 is a bit special we actually defer any - * necessary glBindTexture for it until the end of - * _cogl_pipeline_flush_gl_state(). - * - * NB: we get notified whenever glDeleteTextures is used (see - * _cogl_delete_gl_texture()) where we invalidate - * unit->gl_texture references to deleted textures so it's safe - * to compare unit->gl_texture with gl_texture. (Without the - * hook it would be possible to delete a GL texture and create a - * new one with the same name and comparing unit->gl_texture and - * gl_texture wouldn't detect that.) - * - * NB: for foreign textures we don't know how the deletion of - * the GL texture objects correspond to the deletion of the - * CoglTextures so if there was previously a foreign texture - * associated with the texture unit then we can't assume that we - * aren't seeing a recycled texture name so we have to bind. - */ - if (unit->gl_texture != gl_texture) - { - if (unit_index == 1) - unit->dirty_gl_texture = TRUE; - else - GE (ctx, glBindTexture (gl_target, gl_texture)); - unit->gl_texture = gl_texture; - unit->gl_target = gl_target; - } - - /* The texture_storage_changed boolean indicates if the - * CoglTexture's underlying GL texture storage has changed since - * it was flushed to the texture unit. We've just flushed the - * latest state so we can reset this. */ - unit->texture_storage_changed = FALSE; - } - - if ((layers_difference & COGL_PIPELINE_LAYER_STATE_SAMPLER) && - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - { - const CoglSamplerCacheEntry *sampler_state; - - sampler_state = _cogl_pipeline_layer_get_sampler_state (layer); - - GE( ctx, glBindSampler (unit_index, sampler_state->sampler_object) ); - } - - cogl_object_ref (layer); - if (unit->layer != NULL) - cogl_object_unref (unit->layer); - - unit->layer = layer; - unit->layer_changes_since_flush = 0; - - flush_state->i++; - - return TRUE; -} - -static void -_cogl_pipeline_flush_common_gl_state (CoglPipeline *pipeline, - unsigned long pipelines_difference, - unsigned long *layer_differences, - gboolean with_color_attrib) -{ - CoglPipelineFlushLayerState state; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _cogl_pipeline_flush_color_blend_alpha_depth_state (pipeline, - pipelines_difference, - with_color_attrib); - - state.i = 0; - state.layer_differences = layer_differences; - _cogl_pipeline_foreach_layer_internal (pipeline, - flush_layers_common_gl_state_cb, - &state); -} - -/* Re-assert the layer's wrap modes on the given CoglTexture. - * - * Note: we don't simply forward the wrap modes to layer->texture - * since the actual texture being used may have been overridden. - */ -static void -_cogl_pipeline_layer_forward_wrap_modes (CoglPipelineLayer *layer, - CoglTexture *texture) -{ - CoglSamplerCacheWrapMode wrap_mode_s, wrap_mode_t; - GLenum gl_wrap_mode_s, gl_wrap_mode_t; - - if (texture == NULL) - return; - - _cogl_pipeline_layer_get_wrap_modes (layer, - &wrap_mode_s, - &wrap_mode_t); - - /* Update the wrap mode on the texture object. The texture backend - should cache the value so that it will be a no-op if the object - already has the same wrap mode set. The backend is best placed to - do this because it knows how many of the coordinates will - actually be used (ie, a 1D texture only cares about the 's' - coordinate but a 3D texture would use all three). GL uses the - wrap mode as part of the texture object state but we are - pretending it's part of the per-layer environment state. This - will break if the application tries to use different modes in - different layers using the same texture. */ - - if (wrap_mode_s == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - gl_wrap_mode_s = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_s = wrap_mode_s; - - if (wrap_mode_t == COGL_SAMPLER_CACHE_WRAP_MODE_AUTOMATIC) - gl_wrap_mode_t = GL_CLAMP_TO_EDGE; - else - gl_wrap_mode_t = wrap_mode_t; - - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (texture, - gl_wrap_mode_s, - gl_wrap_mode_t); -} - -void -_cogl_sampler_gl_init (CoglContext *context, CoglSamplerCacheEntry *entry) -{ - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - { - GE( context, glGenSamplers (1, &entry->sampler_object) ); - - GE( context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_MIN_FILTER, - entry->min_filter) ); - GE( context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_MAG_FILTER, - entry->mag_filter) ); - - GE (context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_WRAP_S, - entry->wrap_mode_s) ); - GE (context, glSamplerParameteri (entry->sampler_object, - GL_TEXTURE_WRAP_T, - entry->wrap_mode_t) ); - } - else - { - CoglGLContext *gl_context = context->driver_context; - - /* If sampler objects aren't supported then we'll invent a - unique number so that pipelines can still compare the - unique state just by comparing the sampler object - numbers */ - entry->sampler_object = gl_context->next_fake_sampler_object_number++; - } -} - -void -_cogl_sampler_gl_free (CoglContext *context, CoglSamplerCacheEntry *entry) -{ - if (_cogl_has_private_feature (context, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - GE( context, glDeleteSamplers (1, &entry->sampler_object) ); -} - -/* OpenGL associates the min/mag filters and repeat modes with the - * texture object not the texture unit so we always have to re-assert - * the filter and repeat modes whenever we use a texture since it may - * be referenced by multiple pipelines with different modes. - * - * This function is bypassed in favour of sampler objects if - * GL_ARB_sampler_objects is advertised. This fallback won't work if - * the same texture is bound to multiple layers with different sampler - * state. - */ -static void -foreach_texture_unit_update_filter_and_wrap_modes (void) -{ - int i; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglGLContext *glctx = _cogl_driver_gl_context(ctx); - - for (i = 0; i < glctx->texture_units->len; i++) - { - CoglTextureUnit *unit = - &g_array_index (glctx->texture_units, CoglTextureUnit, i); - - if (unit->layer) - { - CoglTexture *texture = _cogl_pipeline_layer_get_texture (unit->layer); - - if (texture != NULL) - { - CoglPipelineFilter min; - CoglPipelineFilter mag; - - _cogl_pipeline_layer_get_filters (unit->layer, &min, &mag); - _cogl_texture_gl_flush_legacy_texobj_filters (texture, min, mag); - - _cogl_pipeline_layer_forward_wrap_modes (unit->layer, texture); - } - } - } -} - -typedef struct -{ - int i; - unsigned long *layer_differences; -} CoglPipelineCompareLayersState; - -static gboolean -compare_layer_differences_cb (CoglPipelineLayer *layer, void *user_data) -{ - CoglPipelineCompareLayersState *state = user_data; - CoglTextureUnit *unit = _cogl_get_texture_unit (state->i); - - if (unit->layer == layer) - state->layer_differences[state->i] = unit->layer_changes_since_flush; - else if (unit->layer) - { - state->layer_differences[state->i] = unit->layer_changes_since_flush; - state->layer_differences[state->i] |= - _cogl_pipeline_layer_compare_differences (layer, unit->layer); - } - else - state->layer_differences[state->i] = COGL_PIPELINE_LAYER_STATE_ALL_SPARSE; - - /* XXX: There is always a possibility that a CoglTexture's - * underlying GL texture storage has been changed since it was last - * bound to a texture unit which is why we have a callback into - * _cogl_pipeline_texture_storage_change_notify whenever a textures - * underlying GL texture storage changes which will set the - * unit->texture_intern_changed flag. If we see that's been set here - * then we force an update of the texture state... - */ - if (unit->texture_storage_changed) - state->layer_differences[state->i] |= - COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; - - state->i++; - - return TRUE; -} - -typedef struct -{ - CoglFramebuffer *framebuffer; - const CoglPipelineVertend *vertend; - const CoglPipelineFragend *fragend; - CoglPipeline *pipeline; - unsigned long *layer_differences; - gboolean error_adding_layer; - gboolean added_layer; -} CoglPipelineAddLayerState; - -static gboolean -vertend_add_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineAddLayerState *state = user_data; - const CoglPipelineVertend *vertend = state->vertend; - CoglPipeline *pipeline = state->pipeline; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - /* Either generate per layer code snippets or setup the - * fixed function glTexEnv for each layer... */ - if (G_LIKELY (vertend->add_layer (pipeline, - layer, - state->layer_differences[unit_index], - state->framebuffer))) - state->added_layer = TRUE; - else - { - state->error_adding_layer = TRUE; - return FALSE; - } - - return TRUE; -} - -static gboolean -fragend_add_layer_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineAddLayerState *state = user_data; - const CoglPipelineFragend *fragend = state->fragend; - CoglPipeline *pipeline = state->pipeline; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - - /* Either generate per layer code snippets or setup the - * fixed function glTexEnv for each layer... */ - if (G_LIKELY (fragend->add_layer (pipeline, - layer, - state->layer_differences[unit_index]))) - state->added_layer = TRUE; - else - { - state->error_adding_layer = TRUE; - return FALSE; - } - - return TRUE; -} - -/* - * _cogl_pipeline_flush_gl_state: - * - * Details of override options: - * ->fallback_mask: is a bitmask of the pipeline layers that need to be - * replaced with the default, fallback textures. The fallback textures are - * fully transparent textures so they hopefully won't contribute to the - * texture combining. - * - * The intention of fallbacks is to try and preserve - * the number of layers the user is expecting so that texture coordinates - * they gave will mostly still correspond to the textures they intended, and - * have a fighting chance of looking close to their originally intended - * result. - * - * ->disable_mask: is a bitmask of the pipeline layers that will simply have - * texturing disabled. It's only really intended for disabling all layers - * > X; i.e. we'd expect to see a contiguous run of 0 starting from the LSB - * and at some point the remaining bits flip to 1. It might work to disable - * arbitrary layers; though I'm not sure a.t.m how OpenGL would take to - * that. - * - * The intention of the disable_mask is for emitting geometry when the user - * hasn't supplied enough texture coordinates for all the layers and it's - * not possible to auto generate default texture coordinates for those - * layers. - * - * ->layer0_override_texture: forcibly tells us to bind this GL texture name for - * layer 0 instead of plucking the gl_texture from the CoglTexture of layer - * 0. - * - * The intention of this is for any primitives that supports sliced textures. - * The code will can iterate each of the slices and re-flush the pipeline - * forcing the GL texture of each slice in turn. - * - * ->wrap_mode_overrides: overrides the wrap modes set on each - * layer. This is used to implement the automatic wrap mode. - * - * XXX: It might also help if we could specify a texture matrix for code - * dealing with slicing that would be multiplied with the users own matrix. - * - * Normally texture coords in the range [0, 1] refer to the extents of the - * texture, but when your GL texture represents a slice of the real texture - * (from the users POV) then a texture matrix would be a neat way of - * transforming the mapping for each slice. - * - * Currently for textured rectangles we manually calculate the texture - * coords for each slice based on the users given coords, but this solution - * isn't ideal. - */ -void -_cogl_pipeline_flush_gl_state (CoglContext *ctx, - CoglPipeline *pipeline, - CoglFramebuffer *framebuffer, - gboolean with_color_attrib, - gboolean unknown_color_alpha) -{ - CoglPipeline *current_pipeline = ctx->current_pipeline; - unsigned long pipelines_difference; - int n_layers; - unsigned long *layer_differences; - CoglTextureUnit *unit1; - const CoglPipelineProgend *progend; - - COGL_STATIC_TIMER (pipeline_flush_timer, - "Mainloop", /* parent */ - "Material Flush", - "The time spent flushing material state", - 0 /* no application private data */); - - COGL_TIMER_START (_cogl_uprof_context, pipeline_flush_timer); - - /* Bail out asap if we've been asked to re-flush the already current - * pipeline and we can see the pipeline hasn't changed */ - if (current_pipeline == pipeline && - ctx->current_pipeline_age == pipeline->age && - ctx->current_pipeline_with_color_attrib == with_color_attrib && - ctx->current_pipeline_unknown_color_alpha == unknown_color_alpha) - goto done; - else - { - /* Update derived state (currently just the 'real_blend_enable' - * state) and determine a mask of state that differs between the - * current pipeline and the one we are flushing. - * - * Note updating the derived state is done before doing any - * pipeline comparisons so that we can correctly compare the - * 'real_blend_enable' state itself. - */ - - if (current_pipeline == pipeline) - { - pipelines_difference = ctx->current_pipeline_changes_since_flush; - - if (pipelines_difference & COGL_PIPELINE_STATE_AFFECTS_BLENDING || - pipeline->unknown_color_alpha != unknown_color_alpha) - { - gboolean save_real_blend_enable = pipeline->real_blend_enable; - - _cogl_pipeline_update_real_blend_enable (pipeline, - unknown_color_alpha); - - if (save_real_blend_enable != pipeline->real_blend_enable) - pipelines_difference |= COGL_PIPELINE_STATE_REAL_BLEND_ENABLE; - } - } - else if (current_pipeline) - { - pipelines_difference = ctx->current_pipeline_changes_since_flush; - - _cogl_pipeline_update_real_blend_enable (pipeline, - unknown_color_alpha); - - pipelines_difference |= - _cogl_pipeline_compare_differences (ctx->current_pipeline, - pipeline); - } - else - { - _cogl_pipeline_update_real_blend_enable (pipeline, - unknown_color_alpha); - - pipelines_difference = COGL_PIPELINE_STATE_ALL; - } - } - - /* Get a layer_differences mask for each layer to be flushed */ - n_layers = cogl_pipeline_get_n_layers (pipeline); - if (n_layers) - { - CoglPipelineCompareLayersState state; - layer_differences = g_alloca (sizeof (unsigned long) * n_layers); - memset (layer_differences, 0, sizeof (unsigned long) * n_layers); - state.i = 0; - state.layer_differences = layer_differences; - _cogl_pipeline_foreach_layer_internal (pipeline, - compare_layer_differences_cb, - &state); - } - else - layer_differences = NULL; - - /* First flush everything that's the same regardless of which - * pipeline backend is being used... - * - * 1) top level state: - * glColor (or skip if a vertex attribute is being used for color) - * blend state - * alpha test state (except for GLES 2.0) - * - * 2) then foreach layer: - * determine gl_target/gl_texture - * bind texture - * - * Note: After _cogl_pipeline_flush_common_gl_state you can expect - * all state of the layers corresponding texture unit to be - * updated. - */ - _cogl_pipeline_flush_common_gl_state (pipeline, - pipelines_difference, - layer_differences, - with_color_attrib); - - /* Now flush the fragment, vertex and program state according to the - * current progend backend. - * - * Note: Some backends may not support the current pipeline - * configuration and in that case it will report and error and we - * will look for a different backend. - * - * NB: if pipeline->progend != COGL_PIPELINE_PROGEND_UNDEFINED then - * we have previously managed to successfully flush this pipeline - * with the given progend so we will simply use that to avoid - * fallback code paths. - */ - - do - { - const CoglPipelineVertend *vertend; - const CoglPipelineFragend *fragend; - CoglPipelineAddLayerState state; - - progend = _cogl_pipeline_progend; - - if (G_UNLIKELY (!progend->start (pipeline))) - continue; - - vertend = _cogl_pipeline_vertend; - - vertend->start (pipeline, - n_layers, - pipelines_difference); - - state.framebuffer = framebuffer; - state.vertend = vertend; - state.pipeline = pipeline; - state.layer_differences = layer_differences; - state.error_adding_layer = FALSE; - state.added_layer = FALSE; - - _cogl_pipeline_foreach_layer_internal (pipeline, - vertend_add_layer_cb, - &state); - - if (G_UNLIKELY (state.error_adding_layer)) - continue; - - if (G_UNLIKELY (!vertend->end (pipeline, pipelines_difference))) - continue; - - /* Now prepare the fragment processing state (fragend) - * - * NB: We can't combine the setup of the vertend and fragend - * since the backends that do code generation share - * ctx->codegen_source_buffer as a scratch buffer. - */ - - fragend = _cogl_pipeline_fragend; - state.fragend = fragend; - - fragend->start (pipeline, - n_layers, - pipelines_difference); - - _cogl_pipeline_foreach_layer_internal (pipeline, - fragend_add_layer_cb, - &state); - - if (G_UNLIKELY (state.error_adding_layer)) - continue; - - if (G_UNLIKELY (!fragend->end (pipeline, pipelines_difference))) - continue; - - if (progend->end) - progend->end (pipeline, pipelines_difference); - break; - } - while (0); - - /* FIXME: This reference is actually resulting in lots of - * copy-on-write reparenting because one-shot pipelines end up - * living for longer than necessary and so any later modification of - * the parent will cause a copy-on-write. - * - * XXX: The issue should largely go away when we switch to using - * weak pipelines for overrides. - */ - cogl_object_ref (pipeline); - if (ctx->current_pipeline != NULL) - cogl_object_unref (ctx->current_pipeline); - ctx->current_pipeline = pipeline; - ctx->current_pipeline_changes_since_flush = 0; - ctx->current_pipeline_with_color_attrib = with_color_attrib; - ctx->current_pipeline_unknown_color_alpha = unknown_color_alpha; - ctx->current_pipeline_age = pipeline->age; - -done: - - progend = _cogl_pipeline_progend; - - /* We can't assume the color will be retained between flushes when - * using the glsl progend because the generic attribute values are - * not stored as part of the program object so they could be - * overridden by any attribute changes in another program */ - if (!with_color_attrib) - { - int attribute; - CoglPipeline *authority = - _cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR); - int name_index = COGL_ATTRIBUTE_COLOR_NAME_INDEX; - - attribute = - _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index); - if (attribute != -1) - GE (ctx, - glVertexAttrib4f (attribute, - cogl_color_get_red_float (&authority->color), - cogl_color_get_green_float (&authority->color), - cogl_color_get_blue_float (&authority->color), - cogl_color_get_alpha_float (&authority->color))); - } - - /* Give the progend a chance to update any uniforms that might not - * depend on the material state. This is used on GLES2 to update the - * matrices */ - if (progend->pre_paint) - progend->pre_paint (pipeline, framebuffer); - - /* Handle the fact that OpenGL associates texture filter and wrap - * modes with the texture objects not the texture units... */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS)) - foreach_texture_unit_update_filter_and_wrap_modes (); - - /* If this pipeline has more than one layer then we always need - * to make sure we rebind the texture for unit 1. - * - * NB: various components of Cogl may temporarily bind arbitrary - * textures to texture unit 1 so they can query and modify texture - * object parameters. cogl-pipeline.c (See - * _cogl_bind_gl_texture_transient) - */ - unit1 = _cogl_get_texture_unit (1); - if (cogl_pipeline_get_n_layers (pipeline) > 1 && unit1->dirty_gl_texture) - { - _cogl_set_active_texture_unit (1); - GE (ctx, glBindTexture (unit1->gl_target, unit1->gl_texture)); - unit1->dirty_gl_texture = FALSE; - } - - COGL_TIMER_STOP (_cogl_uprof_context, pipeline_flush_timer); -} - -void -_cogl_gl_set_uniform (CoglContext *ctx, - GLint location, - const CoglBoxedValue *value) -{ - switch (value->type) - { - case COGL_BOXED_NONE: - break; - - case COGL_BOXED_INT: - { - const int *ptr; - - if (value->count == 1) - ptr = value->v.int_value; - else - ptr = value->v.int_array; - - switch (value->size) - { - case 1: - GE( ctx, glUniform1iv (location, value->count, ptr) ); - break; - case 2: - GE( ctx, glUniform2iv (location, value->count, ptr) ); - break; - case 3: - GE( ctx, glUniform3iv (location, value->count, ptr) ); - break; - case 4: - GE( ctx, glUniform4iv (location, value->count, ptr) ); - break; - } - } - break; - - case COGL_BOXED_FLOAT: - { - const float *ptr; - - if (value->count == 1) - ptr = value->v.float_value; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 1: - GE( ctx, glUniform1fv (location, value->count, ptr) ); - break; - case 2: - GE( ctx, glUniform2fv (location, value->count, ptr) ); - break; - case 3: - GE( ctx, glUniform3fv (location, value->count, ptr) ); - break; - case 4: - GE( ctx, glUniform4fv (location, value->count, ptr) ); - break; - } - } - break; - - case COGL_BOXED_MATRIX: - { - const float *ptr; - - if (value->count == 1) - ptr = value->v.matrix; - else - ptr = value->v.float_array; - - switch (value->size) - { - case 2: - GE( ctx, glUniformMatrix2fv (location, value->count, - FALSE, ptr) ); - break; - case 3: - GE( ctx, glUniformMatrix3fv (location, value->count, - FALSE, ptr) ); - break; - case 4: - GE( ctx, glUniformMatrix4fv (location, value->count, - FALSE, ptr) ); - break; - } - } - break; - } -} diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h deleted file mode 100644 index d57519b80..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H -#define __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H - -#include "cogl-pipeline-private.h" -#include "cogl-attribute-private.h" - -extern const CoglPipelineProgend _cogl_pipeline_glsl_progend; - -int -_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline, - int name_index); - -#endif /* __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c deleted file mode 100644 index 9d94f12ce..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-util.h" -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "cogl-offscreen.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" - -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-pipeline-cache.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-attribute-private.h" -#include "cogl-framebuffer-private.h" -#include "driver/gl/cogl-pipeline-fragend-glsl-private.h" -#include "driver/gl/cogl-pipeline-vertend-glsl-private.h" -#include "driver/gl/cogl-pipeline-progend-glsl-private.h" -#include "deprecated/cogl-program-private.h" - -/* These are used to generalise updating some uniforms that are - required when building for drivers missing some fixed function - state that we use */ - -typedef void (* UpdateUniformFunc) (CoglPipeline *pipeline, - int uniform_location, - void *getter_func); - -static void update_float_uniform (CoglPipeline *pipeline, - int uniform_location, - void *getter_func); - -typedef struct -{ - const char *uniform_name; - void *getter_func; - UpdateUniformFunc update_func; - CoglPipelineState change; -} BuiltinUniformData; - -static BuiltinUniformData builtin_uniforms[] = - { - { "cogl_point_size_in", - cogl_pipeline_get_point_size, update_float_uniform, - COGL_PIPELINE_STATE_POINT_SIZE }, - { "_cogl_alpha_test_ref", - cogl_pipeline_get_alpha_test_reference, update_float_uniform, - COGL_PIPELINE_STATE_ALPHA_FUNC_REFERENCE }, - }; - -const CoglPipelineProgend _cogl_pipeline_glsl_progend; - -typedef struct _UnitState -{ - unsigned int dirty_combine_constant:1; - unsigned int dirty_texture_matrix:1; - - GLint combine_constant_uniform; - - GLint texture_matrix_uniform; -} UnitState; - -typedef struct -{ - unsigned int ref_count; - - /* Age that the user program had last time we generated a GL - program. If it's different then we need to relink the program */ - unsigned int user_program_age; - - GLuint program; - - unsigned long dirty_builtin_uniforms; - GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)]; - - GLint modelview_uniform; - GLint projection_uniform; - GLint mvp_uniform; - - CoglMatrixEntryCache projection_cache; - CoglMatrixEntryCache modelview_cache; - - /* We need to track the last pipeline that the program was used with - * so know if we need to update all of the uniforms */ - CoglPipeline *last_used_for_pipeline; - - /* Array of GL uniform locations indexed by Cogl's uniform - location. We are careful only to allocated this array if a custom - uniform is actually set */ - GArray *uniform_locations; - - /* Array of attribute locations. */ - GArray *attribute_locations; - - /* The 'flip' uniform is used to flip the geometry upside-down when - the framebuffer requires it only when there are vertex - snippets. Otherwise this is achieved using the projection - matrix */ - GLint flip_uniform; - int flushed_flip_state; - - UnitState *unit_state; - - CoglPipelineCacheEntry *cache_entry; -} CoglPipelineProgramState; - -static CoglUserDataKey program_state_key; - -static CoglPipelineProgramState * -get_program_state (CoglPipeline *pipeline) -{ - return cogl_object_get_user_data (COGL_OBJECT (pipeline), &program_state_key); -} - -#define UNIFORM_LOCATION_UNKNOWN -2 - -#define ATTRIBUTE_LOCATION_UNKNOWN -2 - -/* Under GLES2 the vertex attribute API needs to query the attribute - numbers because it can't used the fixed function API to set the - builtin attributes. We cache the attributes here because the - progend knows when the program is changed so it can clear the - cache. This should always be called after the pipeline is flushed - so they can assert that the gl program is valid */ - -/* All attributes names get internally mapped to a global set of - * sequential indices when they are setup which we need to need to - * then be able to map to a GL attribute location once we have - * a linked GLSL program */ - -int -_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline, - int name_index) -{ - CoglPipelineProgramState *program_state = get_program_state (pipeline); - int *locations; - - _COGL_GET_CONTEXT (ctx, -1); - - g_return_val_if_fail (program_state != NULL, -1); - g_return_val_if_fail (program_state->program != 0, -1); - - if (G_UNLIKELY (program_state->attribute_locations == NULL)) - program_state->attribute_locations = - g_array_new (FALSE, FALSE, sizeof (int)); - - if (G_UNLIKELY (program_state->attribute_locations->len <= name_index)) - { - int i = program_state->attribute_locations->len; - g_array_set_size (program_state->attribute_locations, name_index + 1); - for (; i < program_state->attribute_locations->len; i++) - g_array_index (program_state->attribute_locations, int, i) - = ATTRIBUTE_LOCATION_UNKNOWN; - } - - locations = &g_array_index (program_state->attribute_locations, int, 0); - - if (locations[name_index] == ATTRIBUTE_LOCATION_UNKNOWN) - { - CoglAttributeNameState *name_state = - g_array_index (ctx->attribute_name_index_map, - CoglAttributeNameState *, name_index); - - g_return_val_if_fail (name_state != NULL, 0); - - GE_RET( locations[name_index], - ctx, glGetAttribLocation (program_state->program, - name_state->name) ); - } - - return locations[name_index]; -} - -static void -clear_attribute_cache (CoglPipelineProgramState *program_state) -{ - if (program_state->attribute_locations) - { - g_array_free (program_state->attribute_locations, TRUE); - program_state->attribute_locations = NULL; - } -} - -static void -clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state) -{ - _cogl_matrix_entry_cache_destroy (&program_state->projection_cache); - _cogl_matrix_entry_cache_init (&program_state->projection_cache); - _cogl_matrix_entry_cache_destroy (&program_state->modelview_cache); - _cogl_matrix_entry_cache_init (&program_state->modelview_cache); -} - -static CoglPipelineProgramState * -program_state_new (int n_layers, - CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineProgramState *program_state; - - program_state = g_new0 (CoglPipelineProgramState, 1); - program_state->ref_count = 1; - program_state->program = 0; - program_state->unit_state = g_new (UnitState, n_layers); - program_state->uniform_locations = NULL; - program_state->attribute_locations = NULL; - program_state->cache_entry = cache_entry; - _cogl_matrix_entry_cache_init (&program_state->modelview_cache); - _cogl_matrix_entry_cache_init (&program_state->projection_cache); - - return program_state; -} - -static void -destroy_program_state (void *user_data, - void *instance) -{ - CoglPipelineProgramState *program_state = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* If the program state was last used for this pipeline then clear - it so that if same address gets used again for a new pipeline - then we won't think it's the same pipeline and avoid updating the - uniforms */ - if (program_state->last_used_for_pipeline == instance) - program_state->last_used_for_pipeline = NULL; - - if (program_state->cache_entry && - program_state->cache_entry->pipeline != instance) - program_state->cache_entry->usage_count--; - - if (--program_state->ref_count == 0) - { - clear_attribute_cache (program_state); - - _cogl_matrix_entry_cache_destroy (&program_state->projection_cache); - _cogl_matrix_entry_cache_destroy (&program_state->modelview_cache); - - if (program_state->program) - GE( ctx, glDeleteProgram (program_state->program) ); - - g_free (program_state->unit_state); - - if (program_state->uniform_locations) - g_array_free (program_state->uniform_locations, TRUE); - - g_free (program_state); - } -} - -static void -set_program_state (CoglPipeline *pipeline, - CoglPipelineProgramState *program_state) -{ - if (program_state) - { - program_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (program_state->cache_entry && - program_state->cache_entry->pipeline != pipeline) - program_state->cache_entry->usage_count++; - } - - _cogl_object_set_user_data (COGL_OBJECT (pipeline), - &program_state_key, - program_state, - destroy_program_state); -} - -static void -dirty_program_state (CoglPipeline *pipeline) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &program_state_key, - NULL, - NULL); -} - -static void -link_program (GLint gl_program) -{ - GLint link_status; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - GE( ctx, glLinkProgram (gl_program) ); - - GE( ctx, glGetProgramiv (gl_program, GL_LINK_STATUS, &link_status) ); - - if (!link_status) - { - GLint log_length; - GLsizei out_log_length; - char *log; - - GE( ctx, glGetProgramiv (gl_program, GL_INFO_LOG_LENGTH, &log_length) ); - - log = g_malloc (log_length); - - GE( ctx, glGetProgramInfoLog (gl_program, log_length, - &out_log_length, log) ); - - g_warning ("Failed to link GLSL program:\n%.*s\n", - log_length, log); - - g_free (log); - } -} - -typedef struct -{ - int unit; - GLuint gl_program; - gboolean update_all; - CoglPipelineProgramState *program_state; -} UpdateUniformsState; - -static gboolean -get_uniform_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateUniformsState *state = user_data; - CoglPipelineProgramState *program_state = state->program_state; - UnitState *unit_state = &program_state->unit_state[state->unit]; - GLint uniform_location; - - _COGL_GET_CONTEXT (ctx, FALSE); - - /* We can reuse the source buffer to create the uniform name because - the program has now been linked */ - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "cogl_sampler%i", layer_index); - - GE_RET( uniform_location, - ctx, glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - /* We can set the uniform immediately because the samplers are the - unit index not the texture object number so it will never - change. Unfortunately GL won't let us use a constant instead of a - uniform */ - if (uniform_location != -1) - GE( ctx, glUniform1i (uniform_location, state->unit) ); - - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "_cogl_layer_constant_%i", layer_index); - - GE_RET( uniform_location, - ctx, glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - unit_state->combine_constant_uniform = uniform_location; - - g_string_set_size (ctx->codegen_source_buffer, 0); - g_string_append_printf (ctx->codegen_source_buffer, - "cogl_texture_matrix[%i]", layer_index); - - GE_RET( uniform_location, - ctx, glGetUniformLocation (state->gl_program, - ctx->codegen_source_buffer->str) ); - - unit_state->texture_matrix_uniform = uniform_location; - - state->unit++; - - return TRUE; -} - -static gboolean -update_constants_cb (CoglPipeline *pipeline, - int layer_index, - void *user_data) -{ - UpdateUniformsState *state = user_data; - CoglPipelineProgramState *program_state = state->program_state; - UnitState *unit_state = &program_state->unit_state[state->unit++]; - - _COGL_GET_CONTEXT (ctx, FALSE); - - if (unit_state->combine_constant_uniform != -1 && - (state->update_all || unit_state->dirty_combine_constant)) - { - float constant[4]; - _cogl_pipeline_get_layer_combine_constant (pipeline, - layer_index, - constant); - GE (ctx, glUniform4fv (unit_state->combine_constant_uniform, - 1, constant)); - unit_state->dirty_combine_constant = FALSE; - } - - if (unit_state->texture_matrix_uniform != -1 && - (state->update_all || unit_state->dirty_texture_matrix)) - { - const graphene_matrix_t *matrix; - float array[16]; - - matrix = _cogl_pipeline_get_layer_matrix (pipeline, layer_index); - graphene_matrix_to_float (matrix, array); - GE (ctx, glUniformMatrix4fv (unit_state->texture_matrix_uniform, - 1, FALSE, array)); - unit_state->dirty_texture_matrix = FALSE; - } - - return TRUE; -} - -static void -update_builtin_uniforms (CoglContext *context, - CoglPipeline *pipeline, - GLuint gl_program, - CoglPipelineProgramState *program_state) -{ - int i; - - if (program_state->dirty_builtin_uniforms == 0) - return; - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if ((program_state->dirty_builtin_uniforms & (1 << i)) && - program_state->builtin_uniform_locations[i] != -1) - builtin_uniforms[i].update_func (pipeline, - program_state - ->builtin_uniform_locations[i], - builtin_uniforms[i].getter_func); - - program_state->dirty_builtin_uniforms = 0; -} - -typedef struct -{ - CoglPipelineProgramState *program_state; - unsigned long *uniform_differences; - int n_differences; - CoglContext *ctx; - const CoglBoxedValue *values; - int value_index; -} FlushUniformsClosure; - -static gboolean -flush_uniform_cb (int uniform_num, void *user_data) -{ - FlushUniformsClosure *data = user_data; - - if (COGL_FLAGS_GET (data->uniform_differences, uniform_num)) - { - GArray *uniform_locations; - GLint uniform_location; - - if (data->program_state->uniform_locations == NULL) - data->program_state->uniform_locations = - g_array_new (FALSE, FALSE, sizeof (GLint)); - - uniform_locations = data->program_state->uniform_locations; - - if (uniform_locations->len <= uniform_num) - { - unsigned int old_len = uniform_locations->len; - - g_array_set_size (uniform_locations, uniform_num + 1); - - while (old_len <= uniform_num) - { - g_array_index (uniform_locations, GLint, old_len) = - UNIFORM_LOCATION_UNKNOWN; - old_len++; - } - } - - uniform_location = g_array_index (uniform_locations, GLint, uniform_num); - - if (uniform_location == UNIFORM_LOCATION_UNKNOWN) - { - const char *uniform_name = - g_ptr_array_index (data->ctx->uniform_names, uniform_num); - - uniform_location = - data->ctx->glGetUniformLocation (data->program_state->program, - uniform_name); - g_array_index (uniform_locations, GLint, uniform_num) = - uniform_location; - } - - if (uniform_location != -1) - _cogl_boxed_value_set_uniform (data->ctx, - uniform_location, - data->values + data->value_index); - - data->n_differences--; - COGL_FLAGS_SET (data->uniform_differences, uniform_num, FALSE); - } - - data->value_index++; - - return data->n_differences > 0; -} - -static void -_cogl_pipeline_progend_glsl_flush_uniforms (CoglPipeline *pipeline, - CoglPipelineProgramState * - program_state, - GLuint gl_program, - gboolean program_changed) -{ - CoglPipelineUniformsState *uniforms_state; - FlushUniformsClosure data; - int n_uniform_longs; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) - uniforms_state = &pipeline->big_state->uniforms_state; - else - uniforms_state = NULL; - - data.program_state = program_state; - data.ctx = ctx; - - n_uniform_longs = COGL_FLAGS_N_LONGS_FOR_SIZE (ctx->n_uniform_names); - - data.uniform_differences = g_newa (unsigned long, n_uniform_longs); - - /* Try to find a common ancestor for the values that were already - flushed on the pipeline that this program state was last used for - so we can avoid flushing those */ - - if (program_changed || program_state->last_used_for_pipeline == NULL) - { - if (program_changed) - { - /* The program has changed so all of the uniform locations - are invalid */ - if (program_state->uniform_locations) - g_array_set_size (program_state->uniform_locations, 0); - } - - /* We need to flush everything so mark all of the uniforms as - dirty */ - memset (data.uniform_differences, 0xff, - n_uniform_longs * sizeof (unsigned long)); - data.n_differences = G_MAXINT; - } - else if (program_state->last_used_for_pipeline) - { - int i; - - memset (data.uniform_differences, 0, - n_uniform_longs * sizeof (unsigned long)); - _cogl_pipeline_compare_uniform_differences - (data.uniform_differences, - program_state->last_used_for_pipeline, - pipeline); - - /* We need to be sure to flush any uniforms that have changed - since the last flush */ - if (uniforms_state) - _cogl_bitmask_set_flags (&uniforms_state->changed_mask, - data.uniform_differences); - - /* Count the number of differences. This is so we can stop early - when we've flushed all of them */ - data.n_differences = 0; - - for (i = 0; i < n_uniform_longs; i++) - data.n_differences += - _cogl_util_popcountl (data.uniform_differences[i]); - } - - while (pipeline && data.n_differences > 0) - { - if (pipeline->differences & COGL_PIPELINE_STATE_UNIFORMS) - { - const CoglPipelineUniformsState *parent_uniforms_state = - &pipeline->big_state->uniforms_state; - - data.values = parent_uniforms_state->override_values; - data.value_index = 0; - - _cogl_bitmask_foreach (&parent_uniforms_state->override_mask, - flush_uniform_cb, - &data); - } - - pipeline = _cogl_pipeline_get_parent (pipeline); - } - - if (uniforms_state) - _cogl_bitmask_clear_all (&uniforms_state->changed_mask); -} - -static gboolean -_cogl_pipeline_progend_glsl_start (CoglPipeline *pipeline) -{ - return TRUE; -} - -static void -_cogl_shader_compile_real (CoglHandle handle, - CoglPipeline *pipeline) -{ - CoglShader *shader = handle; - GLenum gl_type; - GLint status; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - 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; - - GE (ctx, glDeleteShader (shader->gl_handle)); - shader->gl_handle = 0; - - if (shader->compilation_pipeline) - { - cogl_object_unref (shader->compilation_pipeline); - shader->compilation_pipeline = NULL; - } - } - - 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); - } -} - -static void -_cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineProgramState *program_state; - GLuint gl_program; - gboolean program_changed = FALSE; - UpdateUniformsState state; - CoglProgram *user_program; - CoglPipelineCacheEntry *cache_entry = NULL; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - program_state = get_program_state (pipeline); - - user_program = cogl_pipeline_get_user_program (pipeline); - - if (program_state == NULL) - { - CoglPipeline *authority; - - /* Get the authority for anything affecting program state. This - should include both fragment codegen state and vertex codegen - state */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - (_cogl_pipeline_get_state_for_vertex_codegen (ctx) | - _cogl_pipeline_get_state_for_fragment_codegen (ctx)) & - ~COGL_PIPELINE_STATE_LAYERS, - _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) | - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); - - program_state = get_program_state (authority); - - if (program_state == NULL) - { - /* Check if there is already a similar cached pipeline whose - program state we can share */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_combined_template (ctx->pipeline_cache, - authority); - - program_state = get_program_state (cache_entry->pipeline); - } - - if (program_state) - program_state->ref_count++; - else - program_state - = program_state_new (cogl_pipeline_get_n_layers (authority), - cache_entry); - - set_program_state (authority, program_state); - - program_state->ref_count--; - - if (cache_entry) - set_program_state (cache_entry->pipeline, program_state); - } - - if (authority != pipeline) - set_program_state (pipeline, program_state); - } - - /* If the program has changed since the last link then we do - * need to relink */ - if (program_state->program && user_program && - user_program->age != program_state->user_program_age) - { - GE( ctx, glDeleteProgram (program_state->program) ); - program_state->program = 0; - } - - if (program_state->program == 0) - { - GLuint backend_shader; - GSList *l; - - GE_RET( program_state->program, ctx, glCreateProgram () ); - - /* Attach all of the shader from the user program */ - if (user_program) - { - for (l = user_program->attached_shaders; l; l = l->next) - { - CoglShader *shader = l->data; - - _cogl_shader_compile_real (shader, pipeline); - - GE( ctx, glAttachShader (program_state->program, - shader->gl_handle) ); - } - - program_state->user_program_age = user_program->age; - } - - /* Attach any shaders from the GLSL backends */ - if ((backend_shader = _cogl_pipeline_fragend_glsl_get_shader (pipeline))) - GE( ctx, glAttachShader (program_state->program, backend_shader) ); - if ((backend_shader = _cogl_pipeline_vertend_glsl_get_shader (pipeline))) - GE( ctx, glAttachShader (program_state->program, backend_shader) ); - - /* XXX: OpenGL as a special case requires the vertex position to - * be bound to generic attribute 0 so for simplicity we - * unconditionally bind the cogl_position_in attribute here... - */ - GE( ctx, glBindAttribLocation (program_state->program, - 0, "cogl_position_in")); - - link_program (program_state->program); - - program_changed = TRUE; - } - - gl_program = program_state->program; - - if (ctx->current_gl_program != gl_program) - { - _cogl_gl_util_clear_gl_errors (ctx); - ctx->glUseProgram (gl_program); - if (_cogl_gl_util_get_error (ctx) == GL_NO_ERROR) - ctx->current_gl_program = gl_program; - else - { - GE( ctx, glUseProgram (0) ); - ctx->current_gl_program = 0; - } - } - - state.unit = 0; - state.gl_program = gl_program; - state.program_state = program_state; - - if (program_changed) - { - cogl_pipeline_foreach_layer (pipeline, - get_uniform_cb, - &state); - clear_attribute_cache (program_state); - - GE_RET (program_state->flip_uniform, - ctx, glGetUniformLocation (gl_program, "_cogl_flip_vector")); - program_state->flushed_flip_state = -1; - } - - state.unit = 0; - state.update_all = (program_changed || - program_state->last_used_for_pipeline != pipeline); - - cogl_pipeline_foreach_layer (pipeline, - update_constants_cb, - &state); - - if (program_changed) - { - int i; - - clear_flushed_matrix_stacks (program_state); - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - GE_RET( program_state->builtin_uniform_locations[i], ctx, - glGetUniformLocation (gl_program, - builtin_uniforms[i].uniform_name) ); - - GE_RET( program_state->modelview_uniform, ctx, - glGetUniformLocation (gl_program, - "cogl_modelview_matrix") ); - - GE_RET( program_state->projection_uniform, ctx, - glGetUniformLocation (gl_program, - "cogl_projection_matrix") ); - - GE_RET( program_state->mvp_uniform, ctx, - glGetUniformLocation (gl_program, - "cogl_modelview_projection_matrix") ); - } - - if (program_changed || - program_state->last_used_for_pipeline != pipeline) - program_state->dirty_builtin_uniforms = ~(unsigned long) 0; - - update_builtin_uniforms (ctx, pipeline, gl_program, program_state); - - _cogl_pipeline_progend_glsl_flush_uniforms (pipeline, - program_state, - gl_program, - program_changed); - - if (user_program) - _cogl_program_flush_uniforms (user_program, - gl_program, - program_changed); - - /* We need to track the last pipeline that the program was used with - * so know if we need to update all of the uniforms */ - program_state->last_used_for_pipeline = pipeline; -} - -static void -_cogl_pipeline_progend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & (_cogl_pipeline_get_state_for_vertex_codegen (ctx) | - _cogl_pipeline_get_state_for_fragment_codegen (ctx)))) - { - dirty_program_state (pipeline); - } - else - { - int i; - - for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++) - if (change & builtin_uniforms[i].change) - { - CoglPipelineProgramState *program_state - = get_program_state (pipeline); - if (program_state) - program_state->dirty_builtin_uniforms |= 1 << i; - return; - } - } -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_progend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - CoglTextureUnit *unit; - - if ((change & (_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) | - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN))) - { - dirty_program_state (owner); - } - else if (change & COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT) - { - CoglPipelineProgramState *program_state = get_program_state (owner); - if (program_state) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - program_state->unit_state[unit_index].dirty_combine_constant = TRUE; - } - } - else if (change & COGL_PIPELINE_LAYER_STATE_USER_MATRIX) - { - CoglPipelineProgramState *program_state = get_program_state (owner); - if (program_state) - { - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - program_state->unit_state[unit_index].dirty_texture_matrix = TRUE; - } - } - - /* If the layer being changed is the same as the last layer we - * flushed to the corresponding texture unit then we keep a track of - * the changes so we can try to minimize redundant OpenGL calls if - * the same layer is flushed again. - */ - unit = _cogl_get_texture_unit (_cogl_pipeline_layer_get_unit_index (layer)); - if (unit->layer == layer) - unit->layer_changes_since_flush |= change; -} - -static void -_cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline, - CoglFramebuffer *framebuffer) -{ - gboolean needs_flip; - CoglMatrixEntry *projection_entry; - CoglMatrixEntry *modelview_entry; - CoglPipelineProgramState *program_state; - gboolean modelview_changed; - gboolean projection_changed; - gboolean need_modelview; - gboolean need_projection; - graphene_matrix_t modelview, projection; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - program_state = get_program_state (pipeline); - - projection_entry = ctx->current_projection_entry; - modelview_entry = ctx->current_modelview_entry; - - /* An initial pipeline is flushed while creating the context. At - this point there are no matrices selected so we can't do - anything */ - if (modelview_entry == NULL || projection_entry == NULL) - return; - - needs_flip = cogl_framebuffer_is_y_flipped (ctx->current_draw_buffer); - - projection_changed = - _cogl_matrix_entry_cache_maybe_update (&program_state->projection_cache, - projection_entry, - (needs_flip && - program_state->flip_uniform == - -1)); - - modelview_changed = - _cogl_matrix_entry_cache_maybe_update (&program_state->modelview_cache, - modelview_entry, - /* never flip modelview */ - FALSE); - - if (modelview_changed || projection_changed) - { - float v[16]; - - if (program_state->mvp_uniform != -1) - need_modelview = need_projection = TRUE; - else - { - need_projection = (program_state->projection_uniform != -1 && - projection_changed); - need_modelview = (program_state->modelview_uniform != -1 && - modelview_changed); - } - - if (need_modelview) - cogl_matrix_entry_get (modelview_entry, &modelview); - if (need_projection) - { - if (needs_flip && program_state->flip_uniform == -1) - { - graphene_matrix_t tmp_matrix; - cogl_matrix_entry_get (projection_entry, &tmp_matrix); - graphene_matrix_multiply (&tmp_matrix, - &ctx->y_flip_matrix, - &projection); - } - else - cogl_matrix_entry_get (projection_entry, &projection); - } - - if (projection_changed && program_state->projection_uniform != -1) - { - graphene_matrix_to_float (&projection, v); - GE (ctx, glUniformMatrix4fv (program_state->projection_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - - if (modelview_changed && program_state->modelview_uniform != -1) - { - graphene_matrix_to_float (&modelview,v); - GE (ctx, glUniformMatrix4fv (program_state->modelview_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - - if (program_state->mvp_uniform != -1) - { - /* The journal usually uses an identity matrix for the - modelview so we can optimise this common case by - avoiding the matrix multiplication */ - if (cogl_matrix_entry_is_identity (modelview_entry)) - { - graphene_matrix_to_float (&projection, v); - GE (ctx, - glUniformMatrix4fv (program_state->mvp_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - else - { - graphene_matrix_t combined; - - graphene_matrix_multiply (&modelview, &projection, &combined); - graphene_matrix_to_float (&combined, v); - - GE (ctx, - glUniformMatrix4fv (program_state->mvp_uniform, - 1, /* count */ - FALSE, /* transpose */ - v)); - } - } - } - - if (program_state->flip_uniform != -1 - && program_state->flushed_flip_state != needs_flip) - { - static const float do_flip[4] = { 1.0f, -1.0f, 1.0f, 1.0f }; - static const float dont_flip[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - GE( ctx, glUniform4fv (program_state->flip_uniform, - 1, /* count */ - needs_flip ? do_flip : dont_flip) ); - program_state->flushed_flip_state = needs_flip; - } -} - -static void -update_float_uniform (CoglPipeline *pipeline, - int uniform_location, - void *getter_func) -{ - float (* float_getter_func) (CoglPipeline *) = getter_func; - float value; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - value = float_getter_func (pipeline); - GE( ctx, glUniform1f (uniform_location, value) ); -} - -const CoglPipelineProgend _cogl_pipeline_glsl_progend = - { - _cogl_pipeline_progend_glsl_start, - _cogl_pipeline_progend_glsl_end, - _cogl_pipeline_progend_glsl_pre_change_notify, - _cogl_pipeline_progend_glsl_layer_pre_change_notify, - _cogl_pipeline_progend_glsl_pre_paint - }; diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h deleted file mode 100644 index 4bd3823d0..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef __COGL_PIPELINE_VERTEND_GLSL_PRIVATE_H -#define __COGL_PIPELINE_VERTEND_GLSL_PRIVATE_H - -#include "cogl-pipeline-private.h" - -extern const CoglPipelineVertend _cogl_pipeline_glsl_vertend; - -GLuint -_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline); - -#endif /* __COGL_PIPELINE_VERTEND_GLSL_PRIVATE_H */ - diff --git a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c b/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c deleted file mode 100644 index 28b5d5d76..000000000 --- a/cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include <test-fixtures/test-unit.h> - -#include "cogl-context-private.h" -#include "cogl-pipeline-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" - -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "cogl-pipeline-state-private.h" -#include "cogl-glsl-shader-boilerplate.h" -#include "driver/gl/cogl-pipeline-vertend-glsl-private.h" -#include "deprecated/cogl-program-private.h" - -const CoglPipelineVertend _cogl_pipeline_glsl_vertend; - -typedef struct -{ - unsigned int ref_count; - - GLuint gl_shader; - GString *header, *source; - - CoglPipelineCacheEntry *cache_entry; -} CoglPipelineShaderState; - -static CoglUserDataKey shader_state_key; - -static CoglPipelineShaderState * -shader_state_new (CoglPipelineCacheEntry *cache_entry) -{ - CoglPipelineShaderState *shader_state; - - shader_state = g_new0 (CoglPipelineShaderState, 1); - shader_state->ref_count = 1; - shader_state->cache_entry = cache_entry; - - return shader_state; -} - -static CoglPipelineShaderState * -get_shader_state (CoglPipeline *pipeline) -{ - return cogl_object_get_user_data (COGL_OBJECT (pipeline), &shader_state_key); -} - -static void -destroy_shader_state (void *user_data, - void *instance) -{ - CoglPipelineShaderState *shader_state = user_data; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != instance) - shader_state->cache_entry->usage_count--; - - if (--shader_state->ref_count == 0) - { - if (shader_state->gl_shader) - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - - g_free (shader_state); - } -} - -static void -set_shader_state (CoglPipeline *pipeline, - CoglPipelineShaderState *shader_state) -{ - if (shader_state) - { - shader_state->ref_count++; - - /* If we're not setting the state on the template pipeline then - * mark it as a usage of the pipeline cache entry */ - if (shader_state->cache_entry && - shader_state->cache_entry->pipeline != pipeline) - shader_state->cache_entry->usage_count++; - } - - _cogl_object_set_user_data (COGL_OBJECT (pipeline), - &shader_state_key, - shader_state, - destroy_shader_state); -} - -static void -dirty_shader_state (CoglPipeline *pipeline) -{ - cogl_object_set_user_data (COGL_OBJECT (pipeline), - &shader_state_key, - NULL, - NULL); -} - -static gboolean -add_layer_vertex_boilerplate_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GString *layer_declarations = user_data; - int unit_index = _cogl_pipeline_layer_get_unit_index (layer); - g_string_append_printf (layer_declarations, - "attribute vec4 cogl_tex_coord%d_in;\n" - "#define cogl_texture_matrix%i cogl_texture_matrix[%i]\n" - "#define cogl_tex_coord%i_out _cogl_tex_coord[%i]\n", - layer->index, - layer->index, - unit_index, - layer->index, - unit_index); - return TRUE; -} - -static gboolean -add_layer_fragment_boilerplate_cb (CoglPipelineLayer *layer, - void *user_data) -{ - GString *layer_declarations = user_data; - g_string_append_printf (layer_declarations, - "#define cogl_tex_coord%i_in _cogl_tex_coord[%i]\n", - layer->index, - _cogl_pipeline_layer_get_unit_index (layer)); - return TRUE; -} - -void -_cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx, - GLuint shader_gl_handle, - GLenum shader_gl_type, - CoglPipeline *pipeline, - GLsizei count_in, - const char **strings_in, - const GLint *lengths_in) -{ - const char *vertex_boilerplate; - const char *fragment_boilerplate; - - const char **strings = g_alloca (sizeof (char *) * (count_in + 4)); - GLint *lengths = g_alloca (sizeof (GLint) * (count_in + 4)); - char *version_string; - int count = 0; - - int n_layers; - - vertex_boilerplate = _COGL_VERTEX_SHADER_BOILERPLATE; - fragment_boilerplate = _COGL_FRAGMENT_SHADER_BOILERPLATE; - - version_string = g_strdup_printf ("#version %i\n\n", - ctx->glsl_version_to_use); - strings[count] = version_string; - lengths[count++] = -1; - - if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL)) - { - static const char image_external_extension[] = - "#extension GL_OES_EGL_image_external : require\n"; - strings[count] = image_external_extension; - lengths[count++] = sizeof (image_external_extension) - 1; - } - - if (shader_gl_type == GL_VERTEX_SHADER) - { - strings[count] = vertex_boilerplate; - lengths[count++] = strlen (vertex_boilerplate); - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - strings[count] = fragment_boilerplate; - lengths[count++] = strlen (fragment_boilerplate); - } - - n_layers = cogl_pipeline_get_n_layers (pipeline); - if (n_layers) - { - GString *layer_declarations = ctx->codegen_boilerplate_buffer; - g_string_set_size (layer_declarations, 0); - - g_string_append_printf (layer_declarations, - "varying vec4 _cogl_tex_coord[%d];\n", - n_layers); - - if (shader_gl_type == GL_VERTEX_SHADER) - { - g_string_append_printf (layer_declarations, - "uniform mat4 cogl_texture_matrix[%d];\n", - n_layers); - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_vertex_boilerplate_cb, - layer_declarations); - } - else if (shader_gl_type == GL_FRAGMENT_SHADER) - { - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_fragment_boilerplate_cb, - layer_declarations); - } - - strings[count] = layer_declarations->str; - lengths[count++] = -1; /* null terminated */ - } - - memcpy (strings + count, strings_in, sizeof (char *) * count_in); - if (lengths_in) - memcpy (lengths + count, lengths_in, sizeof (GLint) * count_in); - else - { - int i; - - for (i = 0; i < count_in; i++) - lengths[count + i] = -1; /* null terminated */ - } - count += count_in; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_SHOW_SOURCE))) - { - GString *buf = g_string_new (NULL); - int i; - - g_string_append_printf (buf, - "%s shader:\n", - shader_gl_type == GL_VERTEX_SHADER ? - "vertex" : "fragment"); - for (i = 0; i < count; i++) - if (lengths[i] != -1) - g_string_append_len (buf, strings[i], lengths[i]); - else - g_string_append (buf, strings[i]); - - g_message ("%s", buf->str); - - g_string_free (buf, TRUE); - } - - GE( ctx, glShaderSource (shader_gl_handle, count, - (const char **) strings, lengths) ); - - g_free (version_string); -} -GLuint -_cogl_pipeline_vertend_glsl_get_shader (CoglPipeline *pipeline) -{ - CoglPipelineShaderState *shader_state = get_shader_state (pipeline); - - if (shader_state) - return shader_state->gl_shader; - else - return 0; -} - -static CoglPipelineSnippetList * -get_vertex_snippets (CoglPipeline *pipeline) -{ - pipeline = - _cogl_pipeline_get_authority (pipeline, - COGL_PIPELINE_STATE_VERTEX_SNIPPETS); - - return &pipeline->big_state->vertex_snippets; -} - -static CoglPipelineSnippetList * -get_layer_vertex_snippets (CoglPipelineLayer *layer) -{ - unsigned long state = COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS; - layer = _cogl_pipeline_layer_get_authority (layer, state); - - return &layer->big_state->vertex_snippets; -} - -static gboolean -add_layer_declaration_cb (CoglPipelineLayer *layer, - void *user_data) -{ - CoglPipelineShaderState *shader_state = user_data; - - g_string_append_printf (shader_state->header, - "uniform sampler2D cogl_sampler%i;\n", - layer->index); - - return TRUE; -} - -static void -add_layer_declarations (CoglPipeline *pipeline, - CoglPipelineShaderState *shader_state) -{ - /* We always emit sampler uniforms in case there will be custom - * layer snippets that want to sample arbitrary layers. */ - - _cogl_pipeline_foreach_layer_internal (pipeline, - add_layer_declaration_cb, - shader_state); -} - -static void -add_global_declarations (CoglPipeline *pipeline, - CoglPipelineShaderState *shader_state) -{ - CoglSnippetHook hook = COGL_SNIPPET_HOOK_VERTEX_GLOBALS; - CoglPipelineSnippetList *snippets = get_vertex_snippets (pipeline); - - /* Add the global data hooks. All of the code in these snippets is - * always added and only the declarations data is used */ - - _cogl_pipeline_snippet_generate_declarations (shader_state->header, - hook, - snippets); -} - -static void -_cogl_pipeline_vertend_glsl_start (CoglPipeline *pipeline, - int n_layers, - unsigned long pipelines_difference) -{ - CoglPipelineShaderState *shader_state; - CoglPipelineCacheEntry *cache_entry = NULL; - CoglProgram *user_program = cogl_pipeline_get_user_program (pipeline); - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - /* Now lookup our glsl backend private state (allocating if - * necessary) */ - shader_state = get_shader_state (pipeline); - - if (shader_state == NULL) - { - CoglPipeline *authority; - - /* Get the authority for anything affecting vertex shader - state */ - authority = _cogl_pipeline_find_equivalent_parent - (pipeline, - _cogl_pipeline_get_state_for_vertex_codegen (ctx) & - ~COGL_PIPELINE_STATE_LAYERS, - COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN); - - shader_state = get_shader_state (authority); - - if (shader_state == NULL) - { - /* Check if there is already a similar cached pipeline whose - shader state we can share */ - if (G_LIKELY (!(COGL_DEBUG_ENABLED - (COGL_DEBUG_DISABLE_PROGRAM_CACHES)))) - { - cache_entry = - _cogl_pipeline_cache_get_vertex_template (ctx->pipeline_cache, - authority); - - shader_state = get_shader_state (cache_entry->pipeline); - } - - if (shader_state) - shader_state->ref_count++; - else - shader_state = shader_state_new (cache_entry); - - set_shader_state (authority, shader_state); - - shader_state->ref_count--; - - if (cache_entry) - set_shader_state (cache_entry->pipeline, shader_state); - } - - if (authority != pipeline) - set_shader_state (pipeline, shader_state); - } - - if (user_program) - { - /* If the user program contains a vertex shader then we don't need - to generate one */ - if (_cogl_program_has_vertex_shader (user_program)) - { - if (shader_state->gl_shader) - { - GE( ctx, glDeleteShader (shader_state->gl_shader) ); - shader_state->gl_shader = 0; - } - return; - } - } - - if (shader_state->gl_shader) - return; - - /* If we make it here then we have a shader_state struct without a gl_shader - either because this is the first time we've encountered it or - because the user program has changed */ - - /* We reuse two grow-only GStrings for code-gen. One string - contains the uniform and attribute declarations while the - other contains the main function. We need two strings - because we need to dynamically declare attributes as the - add_layer callback is invoked */ - g_string_set_size (ctx->codegen_header_buffer, 0); - g_string_set_size (ctx->codegen_source_buffer, 0); - shader_state->header = ctx->codegen_header_buffer; - shader_state->source = ctx->codegen_source_buffer; - - add_layer_declarations (pipeline, shader_state); - add_global_declarations (pipeline, shader_state); - - g_string_append (shader_state->source, - "void\n" - "cogl_generated_source ()\n" - "{\n"); - - if (cogl_pipeline_get_per_vertex_point_size (pipeline)) - g_string_append (shader_state->header, - "attribute float cogl_point_size_in;\n"); - else - { - /* There is no builtin uniform for the point size on GLES2 so we - need to copy it from the custom uniform in the vertex shader - if we're not using per-vertex point sizes, however we'll only - do this if the point-size is non-zero. Toggle the point size - between zero and non-zero causes a state change which - generates a new program */ - if (cogl_pipeline_get_point_size (pipeline) > 0.0f) - { - g_string_append (shader_state->header, - "uniform float cogl_point_size_in;\n"); - g_string_append (shader_state->source, - " cogl_point_size_out = cogl_point_size_in;\n"); - } - } -} - -static gboolean -_cogl_pipeline_vertend_glsl_add_layer (CoglPipeline *pipeline, - CoglPipelineLayer *layer, - unsigned long layers_difference, - CoglFramebuffer *framebuffer) -{ - CoglPipelineShaderState *shader_state; - CoglPipelineSnippetData snippet_data; - int layer_index = layer->index; - - _COGL_GET_CONTEXT (ctx, FALSE); - - shader_state = get_shader_state (pipeline); - - if (shader_state->source == NULL) - return TRUE; - - /* Transform the texture coordinates by the layer's user matrix. - * - * FIXME: this should avoid doing the transform if there is no user - * matrix set. This might need a separate layer state flag for - * whether there is a user matrix - * - * FIXME: we could be more clever here and try to detect if the - * fragment program is going to use the texture coordinates and - * avoid setting them if not - */ - - g_string_append_printf (shader_state->header, - "vec4\n" - "cogl_real_transform_layer%i (mat4 matrix, " - "vec4 tex_coord)\n" - "{\n" - " return matrix * tex_coord;\n" - "}\n", - layer_index); - - /* Wrap the layer code in any snippets that have been hooked */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = get_layer_vertex_snippets (layer); - snippet_data.hook = COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM; - snippet_data.chain_function = g_strdup_printf ("cogl_real_transform_layer%i", - layer_index); - snippet_data.final_name = g_strdup_printf ("cogl_transform_layer%i", - layer_index); - snippet_data.function_prefix = g_strdup_printf ("cogl_transform_layer%i", - layer_index); - snippet_data.return_type = "vec4"; - snippet_data.return_variable = "cogl_tex_coord"; - snippet_data.return_variable_is_argument = TRUE; - snippet_data.arguments = "cogl_matrix, cogl_tex_coord"; - snippet_data.argument_declarations = "mat4 cogl_matrix, vec4 cogl_tex_coord"; - snippet_data.source_buf = shader_state->header; - - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_free ((char *) snippet_data.chain_function); - g_free ((char *) snippet_data.final_name); - g_free ((char *) snippet_data.function_prefix); - - g_string_append_printf (shader_state->source, - " cogl_tex_coord%i_out = " - "cogl_transform_layer%i (cogl_texture_matrix%i,\n" - " " - " cogl_tex_coord%i_in);\n", - layer_index, - layer_index, - layer_index, - layer_index); - - return TRUE; -} - -static gboolean -_cogl_pipeline_vertend_glsl_end (CoglPipeline *pipeline, - unsigned long pipelines_difference) -{ - CoglPipelineShaderState *shader_state; - - _COGL_GET_CONTEXT (ctx, FALSE); - - shader_state = get_shader_state (pipeline); - - if (shader_state->source) - { - const char *source_strings[2]; - GLint lengths[2]; - GLint compile_status; - GLuint shader; - CoglPipelineSnippetData snippet_data; - CoglPipelineSnippetList *vertex_snippets; - gboolean has_per_vertex_point_size = - cogl_pipeline_get_per_vertex_point_size (pipeline); - - COGL_STATIC_COUNTER (vertend_glsl_compile_counter, - "glsl vertex compile counter", - "Increments each time a new GLSL " - "vertex shader is compiled", - 0 /* no application private data */); - COGL_COUNTER_INC (_cogl_uprof_context, vertend_glsl_compile_counter); - - g_string_append (shader_state->header, - "void\n" - "cogl_real_vertex_transform ()\n" - "{\n" - " cogl_position_out = " - "cogl_modelview_projection_matrix * " - "cogl_position_in;\n" - "}\n"); - - g_string_append (shader_state->source, - " cogl_vertex_transform ();\n"); - - if (has_per_vertex_point_size) - { - g_string_append (shader_state->header, - "void\n" - "cogl_real_point_size_calculation ()\n" - "{\n" - " cogl_point_size_out = cogl_point_size_in;\n" - "}\n"); - g_string_append (shader_state->source, - " cogl_point_size_calculation ();\n"); - } - - g_string_append (shader_state->source, - " cogl_color_out = cogl_color_in;\n" - "}\n"); - - vertex_snippets = get_vertex_snippets (pipeline); - - /* Add hooks for the vertex transform part */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = vertex_snippets; - snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX_TRANSFORM; - snippet_data.chain_function = "cogl_real_vertex_transform"; - snippet_data.final_name = "cogl_vertex_transform"; - snippet_data.function_prefix = "cogl_vertex_transform"; - snippet_data.source_buf = shader_state->header; - _cogl_pipeline_snippet_generate_code (&snippet_data); - - /* Add hooks for the point size calculation part */ - if (has_per_vertex_point_size) - { - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = vertex_snippets; - snippet_data.hook = COGL_SNIPPET_HOOK_POINT_SIZE; - snippet_data.chain_function = "cogl_real_point_size_calculation"; - snippet_data.final_name = "cogl_point_size_calculation"; - snippet_data.function_prefix = "cogl_point_size_calculation"; - snippet_data.source_buf = shader_state->header; - _cogl_pipeline_snippet_generate_code (&snippet_data); - } - - /* Add all of the hooks for vertex processing */ - memset (&snippet_data, 0, sizeof (snippet_data)); - snippet_data.snippets = vertex_snippets; - snippet_data.hook = COGL_SNIPPET_HOOK_VERTEX; - snippet_data.chain_function = "cogl_generated_source"; - snippet_data.final_name = "cogl_vertex_hook"; - snippet_data.function_prefix = "cogl_vertex_hook"; - snippet_data.source_buf = shader_state->source; - _cogl_pipeline_snippet_generate_code (&snippet_data); - - g_string_append (shader_state->source, - "void\n" - "main ()\n" - "{\n" - " cogl_vertex_hook ();\n"); - - /* If there are any snippets then we can't rely on the - projection matrix to flip the rendering for offscreen buffers - so we'll need to flip it using an extra statement and a - uniform */ - if (_cogl_pipeline_has_vertex_snippets (pipeline)) - { - g_string_append (shader_state->header, - "uniform vec4 _cogl_flip_vector;\n"); - g_string_append (shader_state->source, - " cogl_position_out *= _cogl_flip_vector;\n"); - } - - g_string_append (shader_state->source, - "}\n"); - - GE_RET( shader, ctx, glCreateShader (GL_VERTEX_SHADER) ); - - lengths[0] = shader_state->header->len; - source_strings[0] = shader_state->header->str; - lengths[1] = shader_state->source->len; - source_strings[1] = shader_state->source->str; - - _cogl_glsl_shader_set_source_with_boilerplate (ctx, - shader, GL_VERTEX_SHADER, - pipeline, - 2, /* count */ - source_strings, lengths); - - GE( ctx, glCompileShader (shader) ); - GE( ctx, glGetShaderiv (shader, GL_COMPILE_STATUS, &compile_status) ); - - if (!compile_status) - { - GLint len = 0; - char *shader_log; - - GE( ctx, glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &len) ); - shader_log = g_alloca (len); - GE( ctx, glGetShaderInfoLog (shader, len, &len, shader_log) ); - g_warning ("Shader compilation failed:\n%s", shader_log); - } - - shader_state->header = NULL; - shader_state->source = NULL; - shader_state->gl_shader = shader; - } - - return TRUE; -} - -static void -_cogl_pipeline_vertend_glsl_pre_change_notify (CoglPipeline *pipeline, - CoglPipelineState change, - const CoglColor *new_color) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if ((change & _cogl_pipeline_get_state_for_vertex_codegen (ctx))) - dirty_shader_state (pipeline); -} - -/* NB: layers are considered immutable once they have any dependants - * so although multiple pipelines can end up depending on a single - * static layer, we can guarantee that if a layer is being *changed* - * then it can only have one pipeline depending on it. - * - * XXX: Don't forget this is *pre* change, we can't read the new value - * yet! - */ -static void -_cogl_pipeline_vertend_glsl_layer_pre_change_notify ( - CoglPipeline *owner, - CoglPipelineLayer *layer, - CoglPipelineLayerState change) -{ - CoglPipelineShaderState *shader_state; - - shader_state = get_shader_state (owner); - if (!shader_state) - return; - - if ((change & COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN)) - { - dirty_shader_state (owner); - return; - } - - /* TODO: we could be saving snippets of texture combine code along - * with each layer and then when a layer changes we would just free - * the snippet. */ -} - -const CoglPipelineVertend _cogl_pipeline_glsl_vertend = - { - _cogl_pipeline_vertend_glsl_start, - _cogl_pipeline_vertend_glsl_add_layer, - _cogl_pipeline_vertend_glsl_end, - _cogl_pipeline_vertend_glsl_pre_change_notify, - _cogl_pipeline_vertend_glsl_layer_pre_change_notify - }; - -UNIT_TEST (check_point_size_shader, - 0 /* no requirements */, - 0 /* no failure cases */) -{ - CoglPipeline *pipelines[4]; - CoglPipelineShaderState *shader_states[G_N_ELEMENTS (pipelines)]; - int i; - - /* Default pipeline with zero point size */ - pipelines[0] = cogl_pipeline_new (test_ctx); - - /* Point size 1 */ - pipelines[1] = cogl_pipeline_new (test_ctx); - cogl_pipeline_set_point_size (pipelines[1], 1.0f); - - /* Point size 2 */ - pipelines[2] = cogl_pipeline_new (test_ctx); - cogl_pipeline_set_point_size (pipelines[2], 2.0f); - - /* Same as the first pipeline, but reached by restoring the old - * state from a copy */ - pipelines[3] = cogl_pipeline_copy (pipelines[1]); - cogl_pipeline_set_point_size (pipelines[3], 0.0f); - - /* Draw something with all of the pipelines to make sure their state - * is flushed */ - for (i = 0; i < G_N_ELEMENTS (pipelines); i++) - cogl_framebuffer_draw_rectangle (test_fb, - pipelines[i], - 0.0f, 0.0f, - 10.0f, 10.0f); - cogl_framebuffer_finish (test_fb); - - /* Get all of the shader states. These might be NULL if the driver - * is not using GLSL */ - for (i = 0; i < G_N_ELEMENTS (pipelines); i++) - shader_states[i] = get_shader_state (pipelines[i]); - - /* If the first two pipelines are using GLSL then they should have - * the same shader unless there is no builtin uniform for the point - * size */ - if (shader_states[0]) - { - g_assert (shader_states[0] != shader_states[1]); - } - - /* The second and third pipelines should always have the same shader - * state because only toggling between zero and non-zero should - * change the shader */ - g_assert (shader_states[1] == shader_states[2]); - - /* The fourth pipeline should be exactly the same as the first */ - g_assert (shader_states[0] == shader_states[3]); -} diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h b/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h deleted file mode 100644 index c10637627..000000000 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_TEXTURE_2D_GL_PRIVATE_H_ -#define _COGL_TEXTURE_2D_GL_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-context-private.h" -#include "cogl-texture.h" - -void -_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_gl_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format); - -void -_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_gl_allocate (CoglTexture *tex, - GError **error); - -CoglTexture2D * -_cogl_texture_2d_gl_new_from_bitmap (CoglBitmap *bmp, - CoglPixelFormat internal_format, - gboolean can_convert_in_place, - GError **error); - -#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) -CoglTexture2D * -_cogl_egl_texture_2d_gl_new_from_image (CoglContext *ctx, - int width, - int height, - CoglPixelFormat format, - EGLImageKHR image, - GError **error); -#endif - -void -_cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter); - -void -_cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t); - -void -_cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - -unsigned int -_cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d); - -void -_cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error); - -gboolean -_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d); - -void -_cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, - CoglPixelFormat format, - int rowstride, - uint8_t *data); - -#endif /* _COGL_TEXTURE_2D_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c deleted file mode 100644 index 4862dbe2e..000000000 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-2d-private.h" -#include "driver/gl/cogl-texture-2d-gl-private.h" -#include "driver/gl/cogl-texture-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -#if defined (COGL_HAS_EGL_SUPPORT) - -/* We need this define from GLES2, but can't include the header - as its type definitions may conflict with the GL ones - */ -#ifndef GL_OES_EGL_image_external -#define GL_OES_EGL_image_external 1 -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#endif /* GL_OES_EGL_image_external */ - -#endif /* defined (COGL_HAS_EGL_SUPPORT) */ - -void -_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d) -{ - if (tex_2d->gl_texture) - _cogl_delete_gl_texture (tex_2d->gl_texture); - -#if defined (COGL_HAS_EGL_SUPPORT) - g_clear_pointer (&tex_2d->egl_image_external.user_data, - tex_2d->egl_image_external.destroy); -#endif -} - -gboolean -_cogl_texture_2d_gl_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - /* We only support single plane formats for now */ - if (cogl_pixel_format_get_n_planes (internal_format) != 1) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - /* Check that the driver can create a texture with that size */ - if (!ctx->texture_driver->size_supported (ctx, - GL_TEXTURE_2D, - gl_intformat, - gl_format, - gl_type, - width, - height)) - return FALSE; - - return TRUE; -} - -void -_cogl_texture_2d_gl_init (CoglTexture2D *tex_2d) -{ - tex_2d->gl_texture = 0; - - /* We default to GL_LINEAR for both filters */ - tex_2d->gl_legacy_texobj_min_filter = GL_LINEAR; - tex_2d->gl_legacy_texobj_mag_filter = GL_LINEAR; - - /* Wrap mode not yet set */ - tex_2d->gl_legacy_texobj_wrap_mode_s = GL_FALSE; - tex_2d->gl_legacy_texobj_wrap_mode_t = GL_FALSE; - - tex_2d->egl_image_external.user_data = NULL; - tex_2d->egl_image_external.destroy = NULL; -} - -static gboolean -allocate_with_size (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglPixelFormat internal_format; - int width = loader->src.sized.width; - int height = loader->src.sized.height; - CoglContext *ctx = tex->context; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - GLenum gl_texture; - - internal_format = - _cogl_texture_determine_internal_format (tex, COGL_PIXEL_FORMAT_ANY); - - if (!_cogl_texture_2d_gl_can_create (ctx, - width, - height, - internal_format)) - { - g_set_error_literal (error, COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Failed to create texture 2d due to size/format" - " constraints"); - return FALSE; - } - - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - &gl_format, - &gl_type); - - gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); - - tex_2d->gl_internal_format = gl_intformat; - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - gl_texture); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, - width, height, 0, gl_format, gl_type, NULL); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - { - GE( ctx, glDeleteTextures (1, &gl_texture) ); - return FALSE; - } - - tex_2d->gl_texture = gl_texture; - tex_2d->gl_internal_format = gl_intformat; - - tex_2d->internal_format = internal_format; - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -static gboolean -allocate_from_bitmap (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglBitmap *bmp = loader->src.bitmap.bitmap; - CoglContext *ctx = _cogl_bitmap_get_context (bmp); - CoglPixelFormat internal_format; - int width = cogl_bitmap_get_width (bmp); - int height = cogl_bitmap_get_height (bmp); - gboolean can_convert_in_place = loader->src.bitmap.can_convert_in_place; - CoglBitmap *upload_bmp; - GLenum gl_intformat; - GLenum gl_format; - GLenum gl_type; - - internal_format = - _cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp)); - - if (!_cogl_texture_2d_gl_can_create (ctx, - width, - height, - internal_format)) - { - g_set_error_literal (error, COGL_TEXTURE_ERROR, - COGL_TEXTURE_ERROR_SIZE, - "Failed to create texture 2d due to size/format" - " constraints"); - return FALSE; - } - - upload_bmp = _cogl_bitmap_convert_for_upload (bmp, - internal_format, - can_convert_in_place, - error); - if (upload_bmp == NULL) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - cogl_bitmap_get_format (upload_bmp), - NULL, /* internal format */ - &gl_format, - &gl_type); - ctx->driver_vtable->pixel_format_to_gl (ctx, - internal_format, - &gl_intformat, - NULL, - NULL); - - tex_2d->gl_texture = - ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); - if (!ctx->texture_driver->upload_to_gl (ctx, - GL_TEXTURE_2D, - tex_2d->gl_texture, - upload_bmp, - gl_intformat, - gl_format, - gl_type, - error)) - { - cogl_object_unref (upload_bmp); - return FALSE; - } - - tex_2d->gl_internal_format = gl_intformat; - - cogl_object_unref (upload_bmp); - - tex_2d->internal_format = internal_format; - - _cogl_texture_set_allocated (tex, internal_format, width, height); - - return TRUE; -} - -#if defined (COGL_HAS_EGL_SUPPORT) && defined (EGL_KHR_image_base) -static gboolean -allocate_from_egl_image (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **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); - _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) - { - g_set_error_literal (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; - tex_2d->is_get_data_supported = - !(loader->src.egl_image.flags & COGL_EGL_IMAGE_FLAG_NO_GET_DATA); - - _cogl_texture_set_allocated (tex, - internal_format, - loader->src.egl_image.width, - loader->src.egl_image.height); - - return TRUE; -} -#endif - -#if defined (COGL_HAS_EGL_SUPPORT) -static gboolean -allocate_custom_egl_image_external (CoglTexture2D *tex_2d, - CoglTextureLoader *loader, - GError **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) - { - g_set_error_literal (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; - tex_2d->is_get_data_supported = FALSE; - - return TRUE; -} - -CoglTexture2D * -cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx, - int width, - int height, - CoglTexture2DEGLImageExternalAlloc alloc, - gpointer user_data, - GDestroyNotify destroy, - GError **error) -{ - CoglTextureLoader *loader; - CoglTexture2D *tex_2d; - CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY; - - g_return_val_if_fail (_cogl_context_get_winsys (ctx)->constraints & - COGL_RENDERER_CONSTRAINT_USES_EGL, - NULL); - - g_return_val_if_fail (cogl_has_feature (ctx, - COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL), - NULL); - - loader = _cogl_texture_create_loader (); - loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL; - loader->src.egl_image_external.width = width; - loader->src.egl_image_external.height = height; - loader->src.egl_image_external.alloc = alloc; - loader->src.egl_image_external.format = internal_format; - - tex_2d = _cogl_texture_2d_create_base (ctx, width, height, - internal_format, loader); - - - tex_2d->egl_image_external.user_data = user_data; - tex_2d->egl_image_external.destroy = destroy; - - return tex_2d; -} -#endif /* defined (COGL_HAS_EGL_SUPPORT) */ - -gboolean -_cogl_texture_2d_gl_allocate (CoglTexture *tex, - GError **error) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglTextureLoader *loader = tex->loader; - - g_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_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); -} - -void -_cogl_texture_2d_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglContext *ctx = tex->context; - - if (min_filter == tex_2d->gl_legacy_texobj_min_filter - && mag_filter == tex_2d->gl_legacy_texobj_mag_filter) - return; - - /* Store new values */ - tex_2d->gl_legacy_texobj_min_filter = min_filter; - tex_2d->gl_legacy_texobj_mag_filter = mag_filter; - - /* Apply new filters to the texture */ - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter) ); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter) ); -} - -void -_cogl_texture_2d_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexture2D *tex_2d = COGL_TEXTURE_2D (tex); - CoglContext *ctx = tex->context; - - /* Only set the wrap mode if it's different from the current value - to avoid too many GL calls. Texture 2D doesn't make use of the r - coordinate so we can ignore its wrap mode */ - if (tex_2d->gl_legacy_texobj_wrap_mode_s != wrap_mode_s || - tex_2d->gl_legacy_texobj_wrap_mode_t != wrap_mode_t) - { - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, - GL_TEXTURE_WRAP_S, - wrap_mode_s) ); - GE( ctx, glTexParameteri (GL_TEXTURE_2D, - GL_TEXTURE_WRAP_T, - wrap_mode_t) ); - - tex_2d->gl_legacy_texobj_wrap_mode_s = wrap_mode_s; - tex_2d->gl_legacy_texobj_wrap_mode_t = wrap_mode_t; - } -} - -void -_cogl_texture_2d_gl_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = tex->context; - - /* Make sure the current framebuffers are bound, though we don't need to - * flush the clip state here since we aren't going to draw to the - * framebuffer. */ - cogl_context_flush_framebuffer_state (ctx, - ctx->current_draw_buffer, - src_fb, - (COGL_FRAMEBUFFER_STATE_ALL & - ~COGL_FRAMEBUFFER_STATE_CLIP)); - - _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, - tex_2d->gl_texture); - - ctx->glCopyTexSubImage2D (GL_TEXTURE_2D, - 0, /* level */ - dst_x, dst_y, - src_x, src_y, - width, height); -} - -unsigned int -_cogl_texture_2d_gl_get_gl_handle (CoglTexture2D *tex_2d) -{ - return tex_2d->gl_texture; -} - -void -_cogl_texture_2d_gl_generate_mipmap (CoglTexture2D *tex_2d) -{ - _cogl_texture_gl_generate_mipmaps (COGL_TEXTURE (tex_2d)); -} - -gboolean -_cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bmp, - int dst_x, - int dst_y, - int level, - GError **error) -{ - CoglTexture *tex = COGL_TEXTURE (tex_2d); - CoglContext *ctx = tex->context; - CoglBitmap *upload_bmp; - CoglPixelFormat upload_format; - GLenum gl_format; - GLenum gl_type; - gboolean status = TRUE; - - upload_bmp = - _cogl_bitmap_convert_for_upload (bmp, - _cogl_texture_get_format (tex), - FALSE, /* can't convert in place */ - error); - if (upload_bmp == NULL) - return FALSE; - - upload_format = cogl_bitmap_get_format (upload_bmp); - - /* Only support single plane formats */ - if (upload_format == COGL_PIXEL_FORMAT_ANY || - cogl_pixel_format_get_n_planes (upload_format) != 1) - return FALSE; - - ctx->driver_vtable->pixel_format_to_gl (ctx, - upload_format, - NULL, /* internal gl format */ - &gl_format, - &gl_type); - - if (tex->max_level_set < level) - cogl_texture_gl_set_max_level (tex, level); - - status = ctx->texture_driver->upload_subregion_to_gl (ctx, - tex, - src_x, src_y, - dst_x, dst_y, - width, height, - level, - upload_bmp, - gl_format, - gl_type, - error); - - cogl_object_unref (upload_bmp); - - return status; -} - -gboolean -_cogl_texture_2d_gl_is_get_data_supported (CoglTexture2D *tex_2d) -{ - return tex_2d->is_get_data_supported; -} - -void -_cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglContext *ctx = COGL_TEXTURE (tex_2d)->context; - uint8_t bpp; - int width = COGL_TEXTURE (tex_2d)->width; - GLenum gl_format; - GLenum gl_type; - - g_return_if_fail (format != COGL_PIXEL_FORMAT_ANY); - g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1); - - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - - ctx->driver_vtable->pixel_format_to_gl (ctx, - format, - NULL, /* internal format */ - &gl_format, - &gl_type); - - ctx->texture_driver->prep_gl_for_pixels_download (ctx, - rowstride, - width, - bpp); - - _cogl_bind_gl_texture_transient (tex_2d->gl_target, - tex_2d->gl_texture); - - ctx->texture_driver->gl_get_tex_image (ctx, - tex_2d->gl_target, - gl_format, - gl_type, - data); -} diff --git a/cogl/cogl/driver/gl/cogl-texture-gl-private.h b/cogl/cogl/driver/gl/cogl-texture-gl-private.h deleted file mode 100644 index a8fbd2866..000000000 --- a/cogl/cogl/driver/gl/cogl-texture-gl-private.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef _COGL_TEXTURE_GL_PRIVATE_H_ -#define _COGL_TEXTURE_GL_PRIVATE_H_ - -#include "cogl-context.h" - -void -_cogl_texture_gl_prep_alignment_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride); - -void -_cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, - int bpp, - int width, - int rowstride); - -void -_cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, - unsigned int wrap_mode_s, - unsigned int wrap_mode_t); - -void -_cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, - unsigned int min_filter, - unsigned int mag_filter); - -void -cogl_texture_gl_set_max_level (CoglTexture *texture, - int max_level); - -void -_cogl_texture_gl_generate_mipmaps (CoglTexture *texture); - -GLenum -_cogl_texture_gl_get_format (CoglTexture *texture); - -#endif /* _COGL_TEXTURE_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-texture-gl.c b/cogl/cogl/driver/gl/cogl-texture-gl.c deleted file mode 100644 index f1367b0db..000000000 --- a/cogl/cogl/driver/gl/cogl-texture-gl.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include <strings.h> - -#include "cogl-context-private.h" -#include "cogl-util.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-texture-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" - -static inline int -calculate_alignment (int rowstride) -{ - int alignment = 1 << (ffs (rowstride) - 1); - - return MIN (alignment, 8); -} - -void -_cogl_texture_gl_prep_alignment_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride) -{ - GE( ctx, glPixelStorei (GL_UNPACK_ALIGNMENT, - calculate_alignment (pixels_rowstride)) ); -} - -void -_cogl_texture_gl_prep_alignment_for_pixels_download (CoglContext *ctx, - int bpp, - int width, - int rowstride) -{ - int alignment; - - /* If no padding is needed then we can always use an alignment of 1. - * We want to do this even though it is equivalent to the alignment - * of the rowstride because the Intel driver in Mesa currently has - * an optimisation when reading data into a PBO that only works if - * the alignment is exactly 1. - * - * https://bugs.freedesktop.org/show_bug.cgi?id=46632 - */ - - if (rowstride == bpp * width) - alignment = 1; - else - alignment = calculate_alignment (rowstride); - - GE( ctx, glPixelStorei (GL_PACK_ALIGNMENT, alignment) ); -} - -void -_cogl_texture_gl_flush_legacy_texobj_wrap_modes (CoglTexture *texture, - unsigned int wrap_mode_s, - unsigned int wrap_mode_t) -{ - texture->vtable->gl_flush_legacy_texobj_wrap_modes (texture, - wrap_mode_s, - wrap_mode_t); -} - -void -_cogl_texture_gl_flush_legacy_texobj_filters (CoglTexture *texture, - unsigned int min_filter, - unsigned int mag_filter) -{ - texture->vtable->gl_flush_legacy_texobj_filters (texture, - min_filter, mag_filter); -} - -/* GL and GLES3 have this by default, but GLES2 does not except via extension. - * So really it's probably always available. Even if we used it and it wasn't - * available in some driver then there are no adverse consequences to the - * command simply being ignored... - */ -#ifndef GL_TEXTURE_MAX_LEVEL -#define GL_TEXTURE_MAX_LEVEL 0x813D -#endif - -void -cogl_texture_gl_set_max_level (CoglTexture *texture, - int max_level) -{ - CoglContext *ctx = texture->context; - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL)) - { - GLuint gl_handle; - GLenum gl_target; - - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - texture->max_level_set = max_level; - - _cogl_bind_gl_texture_transient (gl_target, - gl_handle); - - GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MAX_LEVEL, texture->max_level_set)); - } -} - -void -_cogl_texture_gl_generate_mipmaps (CoglTexture *texture) -{ - CoglContext *ctx = texture->context; - int n_levels = _cogl_texture_get_n_levels (texture); - GLuint gl_handle; - GLenum gl_target; - - if (texture->max_level_set != n_levels - 1) - cogl_texture_gl_set_max_level (texture, n_levels - 1); - - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - _cogl_bind_gl_texture_transient (gl_target, - gl_handle); - GE( ctx, glGenerateMipmap (gl_target) ); -} - -GLenum -_cogl_texture_gl_get_format (CoglTexture *texture) -{ - return texture->vtable->get_gl_format (texture); -} diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h deleted file mode 100644 index be8fa1eeb..000000000 --- a/cogl/cogl/driver/gl/cogl-util-gl-private.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_UTIL_GL_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-context.h" -#include "cogl-gl-header.h" -#include "cogl-texture.h" - -/* In OpenGL ES context, GL_CONTEXT_LOST has a _KHR prefix */ -#ifndef GL_CONTEXT_LOST -#define GL_CONTEXT_LOST GL_CONTEXT_LOST_KHR -#endif - -#ifdef COGL_GL_DEBUG - -const char * -_cogl_gl_error_to_string (GLenum error_code); - -#define GE(ctx, x) G_STMT_START { \ - GLenum __err; \ - (ctx)->x; \ - while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR && __err != GL_CONTEXT_LOST) \ - { \ - g_warning ("%s: GL error (%d): %s\n", \ - G_STRLOC, \ - __err, \ - _cogl_gl_error_to_string (__err)); \ - } } G_STMT_END - -#define GE_RET(ret, ctx, x) G_STMT_START { \ - GLenum __err; \ - ret = (ctx)->x; \ - while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR && __err != GL_CONTEXT_LOST) \ - { \ - g_warning ("%s: GL error (%d): %s\n", \ - G_STRLOC, \ - __err, \ - _cogl_gl_error_to_string (__err)); \ - } } G_STMT_END - -#else /* !COGL_GL_DEBUG */ - -#define GE(ctx, x) ((ctx)->x) -#define GE_RET(ret, ctx, x) (ret = ((ctx)->x)) - -#endif /* COGL_GL_DEBUG */ - -typedef struct _CoglGLContext { - GArray *texture_units; - int active_texture_unit; - - /* This is used for generated fake unique sampler object numbers - when the sampler object extension is not supported */ - GLuint next_fake_sampler_object_number; -} CoglGLContext; - -CoglGLContext * -_cogl_driver_gl_context (CoglContext *context); - -gboolean -_cogl_driver_gl_context_init (CoglContext *context); - -void -_cogl_driver_gl_context_deinit (CoglContext *context); - -void -_cogl_driver_gl_flush_framebuffer_state (CoglContext *context, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state); - -CoglFramebufferDriver * -_cogl_driver_gl_create_framebuffer_driver (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error); - -GLenum -_cogl_gl_util_get_error (CoglContext *ctx); - -void -_cogl_gl_util_clear_gl_errors (CoglContext *ctx); - -gboolean -_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error); - -gboolean -_cogl_driver_gl_is_hardware_accelerated (CoglContext *context); - -/* - * _cogl_context_get_gl_extensions: - * @context: A CoglContext - * - * Return value: a NULL-terminated array of strings representing the - * supported extensions by the current driver. This array is owned - * by the caller and should be freed with g_strfreev(). - */ -char ** -_cogl_context_get_gl_extensions (CoglContext *context); - -const char * -_cogl_context_get_gl_version (CoglContext *context); - -/* Parses a GL version number stored in a string. @version_string must - * point to the beginning of the version number (ie, it can't point to - * the "OpenGL ES" part on GLES). The version number can be followed - * by the end of the string, a space or a full stop. Anything else - * will be treated as invalid. Returns TRUE and sets major_out and - * minor_out if it is successfully parsed or FALSE otherwise. */ -gboolean -_cogl_gl_util_parse_gl_version (const char *version_string, - int *major_out, - int *minor_out); - -CoglGraphicsResetStatus -_cogl_gl_get_graphics_reset_status (CoglContext *context); - -CoglTimestampQuery * -cogl_gl_create_timestamp_query (CoglContext *context); - -void -cogl_gl_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query); - -int64_t -cogl_gl_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query); - -int64_t -cogl_gl_get_gpu_time_ns (CoglContext *context); - -#ifndef GL_FRAMEBUFFER -#define GL_FRAMEBUFFER 0x8D40 -#endif -#ifndef GL_RENDERBUFFER -#define GL_RENDERBUFFER 0x8D41 -#endif -#ifndef GL_STENCIL_ATTACHMENT -#define GL_STENCIL_ATTACHMENT 0x8D00 -#endif -#ifndef GL_COLOR_ATTACHMENT0 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#endif -#ifndef GL_FRAMEBUFFER_COMPLETE -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#endif -#ifndef GL_STENCIL_INDEX8 -#define GL_STENCIL_INDEX8 0x8D48 -#endif -#ifndef GL_DEPTH_STENCIL -#define GL_DEPTH_STENCIL 0x84F9 -#endif -#ifndef GL_DEPTH24_STENCIL8 -#define GL_DEPTH24_STENCIL8 0x88F0 -#endif -#ifndef GL_DEPTH_ATTACHMENT -#define GL_DEPTH_ATTACHMENT 0x8D00 -#endif -#ifndef GL_DEPTH_STENCIL_ATTACHMENT -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#endif -#ifndef GL_DEPTH_COMPONENT16 -#define GL_DEPTH_COMPONENT16 0x81A5 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#endif -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif -#ifndef GL_TEXTURE_SAMPLES_IMG -#define GL_TEXTURE_SAMPLES_IMG 0x9136 -#endif -#ifndef GL_PACK_INVERT_MESA -#define GL_PACK_INVERT_MESA 0x8758 -#endif -#ifndef GL_PACK_REVERSE_ROW_ORDER_ANGLE -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 -#endif -#ifndef GL_BACK_LEFT -#define GL_BACK_LEFT 0x0402 -#endif -#ifndef GL_BACK_RIGHT -#define GL_BACK_RIGHT 0x0403 -#endif - -#ifndef GL_COLOR -#define GL_COLOR 0x1800 -#endif -#ifndef GL_DEPTH -#define GL_DEPTH 0x1801 -#endif -#ifndef GL_STENCIL -#define GL_STENCIL 0x1802 -#endif - -#ifndef GL_TIMESTAMP -#define GL_TIMESTAMP 0x8E28 -#endif -#ifndef GL_QUERY_RESULT -#define GL_QUERY_RESULT 0x8866 -#endif - -#endif /* _COGL_UTIL_GL_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c deleted file mode 100644 index 80c417913..000000000 --- a/cogl/cogl/driver/gl/cogl-util-gl.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012, 2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-types.h" -#include "cogl-context-private.h" -#include "driver/gl/cogl-framebuffer-gl-private.h" -#include "driver/gl/cogl-gl-framebuffer-fbo.h" -#include "driver/gl/cogl-gl-framebuffer-back.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-util-gl-private.h" - -/* This is a relatively new extension */ -#ifndef GL_PURGED_CONTEXT_RESET_NV -#define GL_PURGED_CONTEXT_RESET_NV 0x92BB -#endif - -/* These aren't defined in the GLES2 headers */ -#ifndef GL_GUILTY_CONTEXT_RESET_ARB -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#endif - -#ifndef GL_INNOCENT_CONTEXT_RESET_ARB -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#endif - -#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#endif - -#ifdef COGL_GL_DEBUG -/* GL error to string conversion */ -static const struct { - GLuint error_code; - const char *error_string; -} gl_errors[] = { - { GL_NO_ERROR, "No error" }, - { GL_INVALID_ENUM, "Invalid enumeration value" }, - { GL_INVALID_VALUE, "Invalid value" }, - { GL_INVALID_OPERATION, "Invalid operation" }, -#ifdef HAVE_COGL_GL - { GL_STACK_OVERFLOW, "Stack overflow" }, - { GL_STACK_UNDERFLOW, "Stack underflow" }, -#endif - { GL_OUT_OF_MEMORY, "Out of memory" }, - -#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT - { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "Invalid framebuffer operation" } -#endif -}; - -static const unsigned int n_gl_errors = G_N_ELEMENTS (gl_errors); - -const char * -_cogl_gl_error_to_string (GLenum error_code) -{ - int i; - - for (i = 0; i < n_gl_errors; i++) - { - if (gl_errors[i].error_code == error_code) - return gl_errors[i].error_string; - } - - return "Unknown GL error"; -} -#endif /* COGL_GL_DEBUG */ - -CoglGLContext * -_cogl_driver_gl_context (CoglContext *context) -{ - return context->driver_context; -} - -gboolean -_cogl_driver_gl_context_init (CoglContext *context) -{ - CoglGLContext *gl_context; - - if (!context->driver_context) - context->driver_context = g_new0 (CoglContext, 1); - - gl_context = _cogl_driver_gl_context (context); - if (!gl_context) - return FALSE; - - gl_context->next_fake_sampler_object_number = 1; - gl_context->texture_units = - g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit)); - - /* See cogl-pipeline.c for more details about why we leave texture unit 1 - * active by default... */ - gl_context->active_texture_unit = 1; - GE (context, glActiveTexture (GL_TEXTURE1)); - - return TRUE; -} - -void -_cogl_driver_gl_context_deinit (CoglContext *context) -{ - _cogl_destroy_texture_units (context); - g_free (context->driver_context); -} - -CoglFramebufferDriver * -_cogl_driver_gl_create_framebuffer_driver (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - g_return_val_if_fail (driver_config, NULL); - - switch (driver_config->type) - { - case COGL_FRAMEBUFFER_DRIVER_TYPE_FBO: - { - CoglGlFramebufferFbo *gl_framebuffer_fbo; - - gl_framebuffer_fbo = cogl_gl_framebuffer_fbo_new (framebuffer, - driver_config, - error); - if (!gl_framebuffer_fbo) - return NULL; - - return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_fbo); - } - case COGL_FRAMEBUFFER_DRIVER_TYPE_BACK: - { - CoglGlFramebufferBack *gl_framebuffer_back; - - gl_framebuffer_back = cogl_gl_framebuffer_back_new (framebuffer, - driver_config, - error); - if (!gl_framebuffer_back) - return NULL; - - return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer_back); - } - } - - g_assert_not_reached (); - return NULL; -} - -void -_cogl_driver_gl_flush_framebuffer_state (CoglContext *ctx, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state) -{ - CoglGlFramebuffer *draw_gl_framebuffer; - CoglGlFramebuffer *read_gl_framebuffer; - unsigned long differences; - - /* We can assume that any state that has changed for the current - * framebuffer is different to the currently flushed value. */ - differences = ctx->current_draw_buffer_changes; - - /* Any state of the current framebuffer that hasn't already been - * flushed is assumed to be unknown so we will always flush that - * state if asked. */ - differences |= ~ctx->current_draw_buffer_state_flushed; - - /* We only need to consider the state we've been asked to flush */ - differences &= state; - - if (ctx->current_draw_buffer != draw_buffer) - { - /* If the previous draw buffer is NULL then we'll assume - everything has changed. This can happen if a framebuffer is - destroyed while it is the last flushed draw buffer. In that - case the framebuffer destructor will set - ctx->current_draw_buffer to NULL */ - if (ctx->current_draw_buffer == NULL) - differences |= state; - else - /* NB: we only need to compare the state we're being asked to flush - * and we don't need to compare the state we've already decided - * we will definitely flush... */ - differences |= _cogl_framebuffer_compare (ctx->current_draw_buffer, - draw_buffer, - state & ~differences); - - /* NB: we don't take a reference here, to avoid a circular - * reference. */ - ctx->current_draw_buffer = draw_buffer; - ctx->current_draw_buffer_state_flushed = 0; - } - - if (ctx->current_read_buffer != read_buffer && - state & COGL_FRAMEBUFFER_STATE_BIND) - { - differences |= COGL_FRAMEBUFFER_STATE_BIND; - /* NB: we don't take a reference here, to avoid a circular - * reference. */ - ctx->current_read_buffer = read_buffer; - } - - if (!differences) - return; - - /* Lazily ensure the framebuffers have been allocated */ - if (G_UNLIKELY (!cogl_framebuffer_is_allocated (draw_buffer))) - cogl_framebuffer_allocate (draw_buffer, NULL); - if (G_UNLIKELY (!cogl_framebuffer_is_allocated (read_buffer))) - cogl_framebuffer_allocate (read_buffer, NULL); - - draw_gl_framebuffer = - COGL_GL_FRAMEBUFFER (cogl_framebuffer_get_driver (draw_buffer)); - read_gl_framebuffer = - COGL_GL_FRAMEBUFFER (cogl_framebuffer_get_driver (read_buffer)); - - /* We handle buffer binding separately since the method depends on whether - * we are binding the same buffer for read and write or not unlike all - * other state that only relates to the draw_buffer. */ - if (differences & COGL_FRAMEBUFFER_STATE_BIND) - { - if (draw_buffer == read_buffer) - { - cogl_gl_framebuffer_bind (draw_gl_framebuffer, GL_FRAMEBUFFER); - } - else - { - /* NB: Currently we only take advantage of binding separate - * read/write buffers for framebuffer blit purposes. */ - g_return_if_fail (cogl_has_feature - (ctx, COGL_FEATURE_ID_BLIT_FRAMEBUFFER)); - - cogl_gl_framebuffer_bind (draw_gl_framebuffer, GL_DRAW_FRAMEBUFFER); - cogl_gl_framebuffer_bind (read_gl_framebuffer, GL_READ_FRAMEBUFFER); - } - - differences &= ~COGL_FRAMEBUFFER_STATE_BIND; - } - - cogl_gl_framebuffer_flush_state_differences (draw_gl_framebuffer, - differences); - - ctx->current_draw_buffer_state_flushed |= state; - ctx->current_draw_buffer_changes &= ~state; -} - -GLenum -_cogl_gl_util_get_error (CoglContext *ctx) -{ - GLenum gl_error = ctx->glGetError (); - - if (gl_error != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) - return gl_error; - else - return GL_NO_ERROR; -} - -void -_cogl_gl_util_clear_gl_errors (CoglContext *ctx) -{ - GLenum gl_error; - - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) - ; -} - -gboolean -_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, GError **error) -{ - GLenum gl_error; - gboolean out_of_memory = FALSE; - - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) - { - if (gl_error == GL_OUT_OF_MEMORY) - out_of_memory = TRUE; -#ifdef COGL_GL_DEBUG - else - { - g_warning ("%s: GL error (%d): %s\n", - G_STRLOC, - gl_error, - _cogl_gl_error_to_string (gl_error)); - } -#endif - } - - if (out_of_memory) - { - g_set_error_literal (error, COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_NO_MEMORY, - "Out of memory"); - return TRUE; - } - - return FALSE; -} - -char ** -_cogl_context_get_gl_extensions (CoglContext *context) -{ - const char *env_disabled_extensions; - char **ret; - - /* In GL 3, querying GL_EXTENSIONS is deprecated so we have to build - * the array using glGetStringi instead */ -#ifdef HAVE_COGL_GL - if (context->driver == COGL_DRIVER_GL3) - { - int num_extensions, i; - - context->glGetIntegerv (GL_NUM_EXTENSIONS, &num_extensions); - - ret = g_malloc (sizeof (char *) * (num_extensions + 1)); - - for (i = 0; i < num_extensions; i++) - { - const char *ext = - (const char *) context->glGetStringi (GL_EXTENSIONS, i); - ret[i] = g_strdup (ext); - } - - ret[num_extensions] = NULL; - } - else -#endif - { - const char *all_extensions = - (const char *) context->glGetString (GL_EXTENSIONS); - - ret = g_strsplit (all_extensions, " ", 0 /* max tokens */); - } - - if ((env_disabled_extensions = g_getenv ("COGL_DISABLE_GL_EXTENSIONS"))) - { - char **split_env_disabled_extensions; - char **src, **dst; - - if (env_disabled_extensions) - split_env_disabled_extensions = - g_strsplit (env_disabled_extensions, - ",", - 0 /* no max tokens */); - else - split_env_disabled_extensions = NULL; - - for (dst = ret, src = ret; - *src; - src++) - { - char **d; - - if (split_env_disabled_extensions) - for (d = split_env_disabled_extensions; *d; d++) - if (!strcmp (*src, *d)) - goto disabled; - - *(dst++) = *src; - continue; - - disabled: - g_free (*src); - continue; - } - - *dst = NULL; - - if (split_env_disabled_extensions) - g_strfreev (split_env_disabled_extensions); - } - - return ret; -} - -const char * -_cogl_context_get_gl_version (CoglContext *context) -{ - const char *version_override; - - if ((version_override = g_getenv ("COGL_OVERRIDE_GL_VERSION"))) - return version_override; - else - return (const char *) context->glGetString (GL_VERSION); - -} - -gboolean -_cogl_gl_util_parse_gl_version (const char *version_string, - int *major_out, - int *minor_out) -{ - const char *major_end, *minor_end; - int major = 0, minor = 0; - - /* Extract the major number */ - for (major_end = version_string; *major_end >= '0' - && *major_end <= '9'; major_end++) - major = (major * 10) + *major_end - '0'; - /* If there were no digits or the major number isn't followed by a - dot then it is invalid */ - if (major_end == version_string || *major_end != '.') - return FALSE; - - /* Extract the minor number */ - for (minor_end = major_end + 1; *minor_end >= '0' - && *minor_end <= '9'; minor_end++) - minor = (minor * 10) + *minor_end - '0'; - /* If there were no digits or there is an unexpected character then - it is invalid */ - if (minor_end == major_end + 1 - || (*minor_end && *minor_end != ' ' && *minor_end != '.')) - return FALSE; - - *major_out = major; - *minor_out = minor; - - return TRUE; -} - -/* - * This should arguably use something like GLX_MESA_query_renderer, but - * a) that's GLX-only, and you could add it to EGL too but - * b) that'd make this a winsys query when really it's not a property of - * the winsys but the renderer, and - * c) only Mesa really supports it anyway, and - * d) Mesa is the only software renderer of interest. - * - * So instead just check a list of known software renderer strings. - */ -gboolean -_cogl_driver_gl_is_hardware_accelerated (CoglContext *ctx) -{ - const char *renderer = (const char *) ctx->glGetString (GL_RENDERER); - gboolean software; - - if (!renderer) - { - g_warning ("OpenGL driver returned NULL as the renderer, " - "something is wrong"); - return TRUE; - } - - software = strstr (renderer, "llvmpipe") != NULL || - strstr (renderer, "softpipe") != NULL || - strstr (renderer, "software rasterizer") != NULL || - strstr (renderer, "Software Rasterizer") != NULL || - strstr (renderer, "SWR"); - - return !software; -} - -CoglGraphicsResetStatus -_cogl_gl_get_graphics_reset_status (CoglContext *context) -{ - if (!context->glGetGraphicsResetStatus) - return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; - - switch (context->glGetGraphicsResetStatus ()) - { - case GL_GUILTY_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET; - - case GL_INNOCENT_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET; - - case GL_UNKNOWN_CONTEXT_RESET_ARB: - return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET; - - case GL_PURGED_CONTEXT_RESET_NV: - return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET; - - default: - return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; - } -} - -CoglTimestampQuery * -cogl_gl_create_timestamp_query (CoglContext *context) -{ - CoglTimestampQuery *query; - - g_return_val_if_fail (cogl_has_feature (context, - COGL_FEATURE_ID_TIMESTAMP_QUERY), - NULL); - - query = g_new0 (CoglTimestampQuery, 1); - - GE (context, glGenQueries (1, &query->id)); - GE (context, glQueryCounter (query->id, GL_TIMESTAMP)); - - /* Flush right away so GL knows about our timestamp query. - * - * E.g. the direct scanout path doesn't call SwapBuffers or any other - * glFlush-inducing operation, and skipping explicit glFlush here results in - * the timestamp query being placed at the point of glGetQueryObject much - * later, resulting in a GPU timestamp much later on in time. - */ - GE (context, glFlush ()); - - return query; -} - -void -cogl_gl_free_timestamp_query (CoglContext *context, - CoglTimestampQuery *query) -{ - GE (context, glDeleteQueries (1, &query->id)); - g_free (query); -} - -int64_t -cogl_gl_timestamp_query_get_time_ns (CoglContext *context, - CoglTimestampQuery *query) -{ - int64_t query_time_ns; - - GE (context, glGetQueryObjecti64v (query->id, - GL_QUERY_RESULT, - &query_time_ns)); - - return query_time_ns; -} - -int64_t -cogl_gl_get_gpu_time_ns (CoglContext *context) -{ - int64_t gpu_time_ns; - - g_return_val_if_fail (cogl_has_feature (context, - COGL_FEATURE_ID_GET_GPU_TIME), - 0); - - GE (context, glGetInteger64v (GL_TIMESTAMP, &gpu_time_ns)); - return gpu_time_ns; -} diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c deleted file mode 100644 index ef4a61a09..000000000 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-private.h" -#include "cogl-context-private.h" -#include "cogl-feature-private.h" -#include "cogl-renderer-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-framebuffer-gl-private.h" -#include "driver/gl/cogl-texture-2d-gl-private.h" -#include "driver/gl/cogl-attribute-gl-private.h" -#include "driver/gl/cogl-clip-stack-gl-private.h" -#include "driver/gl/cogl-buffer-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" - -static gboolean -_cogl_driver_gl_real_context_init (CoglContext *context) -{ - - _cogl_driver_gl_context_init (context); - - if ((context->driver == COGL_DRIVER_GL3)) - { - GLuint vertex_array; - - /* In a forward compatible context, GL 3 doesn't support rendering - * using the default vertex array object. Cogl doesn't use vertex - * array objects yet so for now we just create a dummy array - * object that we will use as our own default object. Eventually - * it could be good to attach the vertex array objects to - * CoglPrimitives */ - context->glGenVertexArrays (1, &vertex_array); - context->glBindVertexArray (vertex_array); - } - - /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect - unless GL_COORD_REPLACE is enabled for an individual layer. - Therefore it seems like it should be ok to just leave it enabled - all the time instead of having to have a set property on each - pipeline to track whether any layers have point sprite coords - enabled. We don't need to do this for GL3 or GLES2 because point - sprites are handled using a builtin varying in the shader. */ - if (context->driver == COGL_DRIVER_GL) - GE (context, glEnable (GL_POINT_SPRITE)); - - /* There's no enable for this in GLES2, it's always on */ - if (context->driver == COGL_DRIVER_GL || - context->driver == COGL_DRIVER_GL3) - GE (context, glEnable (GL_PROGRAM_POINT_SIZE) ); - - return TRUE; -} - -static gboolean -_cogl_driver_pixel_format_from_gl_internal (CoglContext *context, - GLenum gl_int_format, - CoglPixelFormat *out_format) -{ - /* It doesn't really matter we convert to exact same - format (some have no cogl match anyway) since format - is re-matched against cogl when getting or setting - texture image data. - */ - - switch (gl_int_format) - { - case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8: - case GL_ALPHA12: case GL_ALPHA16: - /* Cogl only supports one single-component texture so if we have - * ended up with a red texture then it is probably being used as - * a component-alpha texture */ - case GL_RED: - - *out_format = COGL_PIXEL_FORMAT_A_8; - return TRUE; - - case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8: - case GL_LUMINANCE12: case GL_LUMINANCE16: - - *out_format = COGL_PIXEL_FORMAT_G_8; - return TRUE; - - case GL_RG: - *out_format = COGL_PIXEL_FORMAT_RG_88; - return TRUE; - - case GL_RGB: case GL_RGB4: case GL_RGB5: case GL_RGB8: - case GL_RGB10: case GL_RGB12: case GL_RGB16: case GL_R3_G3_B2: - - *out_format = COGL_PIXEL_FORMAT_RGB_888; - return TRUE; - - case GL_RGBA: case GL_RGBA2: case GL_RGBA4: case GL_RGB5_A1: - case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - - *out_format = COGL_PIXEL_FORMAT_RGBA_8888; - return TRUE; - } - - return FALSE; -} - -static CoglPixelFormat -_cogl_driver_pixel_format_to_gl (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat required_format; - GLenum glintformat = 0; - GLenum glformat = 0; - GLenum gltype = 0; - - required_format = format; - - /* Find GL equivalents */ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - /* If the driver doesn't natively support alpha textures then we - * will use a red component texture with a swizzle to implement - * the texture */ - if (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) == 0) - { - glintformat = GL_RED; - glformat = GL_RED; - } - else - { - glintformat = GL_ALPHA; - glformat = GL_ALPHA; - } - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_G_8: - glintformat = GL_LUMINANCE; - glformat = GL_LUMINANCE; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RG_88: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG)) - { - glintformat = GL_RG; - glformat = GL_RG; - } - else - { - /* If red-green textures aren't supported then we'll use RGB - * as an internal format. Note this should only end up - * mattering for downloading the data because Cogl will - * refuse to allocate a texture with RG components if RG - * textures aren't supported */ - glintformat = GL_RGB; - glformat = GL_RGB; - required_format = COGL_PIXEL_FORMAT_RGB_888; - } - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RGB_888: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGR_888: - glintformat = GL_RGB; - glformat = GL_BGR; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - glintformat = GL_RGBA; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_BYTE; - break; - - /* The following two types of channel ordering - * have no GL equivalent unless defined using - * system word byte ordering */ - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - glintformat = GL_RGBA; - glformat = GL_BGRA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - gltype = GL_UNSIGNED_INT_8_8_8_8; -#else - gltype = GL_UNSIGNED_INT_8_8_8_8_REV; -#endif - break; - - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_10_10_10_2; - break; - - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - glintformat = GL_RGBA; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_INT_10_10_10_2; - break; - - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - glintformat = GL_RGBA; - glformat = GL_BGRA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - - /* The following three types of channel ordering - * are always defined using system word byte - * ordering (even according to GLES spec) */ - case COGL_PIXEL_FORMAT_RGB_565: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_SHORT_5_6_5; - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_5_5_5_1; - break; - - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - glintformat = GL_RGBA; - glformat = GL_BGRA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - glintformat = GL_RGBA; - glformat = GL_BGRA; - gltype = GL_HALF_FLOAT; - break; - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT; - break; - - case COGL_PIXEL_FORMAT_DEPTH_16: - glintformat = GL_DEPTH_COMPONENT16; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_SHORT; - break; - case COGL_PIXEL_FORMAT_DEPTH_32: - glintformat = GL_DEPTH_COMPONENT32; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_INT; - break; - - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - glintformat = GL_DEPTH_STENCIL; - glformat = GL_DEPTH_STENCIL; - gltype = GL_UNSIGNED_INT_24_8; - break; - - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - break; - } - - /* All of the pixel formats are handled above so if this hits then - we've been given an invalid pixel format */ - g_assert (glformat != 0); - - if (out_glintformat != NULL) - *out_glintformat = glintformat; - if (out_glformat != NULL) - *out_glformat = glformat; - if (out_gltype != NULL) - *out_gltype = gltype; - - return required_format; -} - -static gboolean -_cogl_get_gl_version (CoglContext *ctx, - int *major_out, - int *minor_out) -{ - const char *version_string; - - /* Get the OpenGL version number */ - if ((version_string = _cogl_context_get_gl_version (ctx)) == NULL) - return FALSE; - - return _cogl_gl_util_parse_gl_version (version_string, major_out, minor_out); -} - -static gboolean -check_gl_version (CoglContext *ctx, - char **gl_extensions, - GError **error) -{ - int major, minor; - - if (!_cogl_get_gl_version (ctx, &major, &minor)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_UNKNOWN_VERSION, - "The OpenGL version could not be determined"); - return FALSE; - } - - /* We require GLSL 1.20, which is implied by OpenGL 2.1. */ - if (!COGL_CHECK_GL_VERSION (major, minor, 2, 1)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "OpenGL 2.1 or better is required"); - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_driver_update_features (CoglContext *ctx, - GError **error) -{ - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 }; - char **gl_extensions; - const char *glsl_version; - int gl_major = 0, gl_minor = 0; - int i; - - /* We have to special case getting the pointer to the glGetString* - functions because we need to use them to determine what functions - we can expect */ - ctx->glGetString = - (void *) _cogl_renderer_get_proc_address (ctx->display->renderer, - "glGetString", - TRUE); - ctx->glGetStringi = - (void *) _cogl_renderer_get_proc_address (ctx->display->renderer, - "glGetStringi", - TRUE); - ctx->glGetIntegerv = - (void *) _cogl_renderer_get_proc_address (ctx->display->renderer, - "glGetIntegerv", - TRUE); - - gl_extensions = _cogl_context_get_gl_extensions (ctx); - - if (!check_gl_version (ctx, gl_extensions, error)) - return FALSE; - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS))) - { - char *all_extensions = g_strjoinv (" ", gl_extensions); - - COGL_NOTE (WINSYS, - "Checking features\n" - " GL_VENDOR: %s\n" - " GL_RENDERER: %s\n" - " GL_VERSION: %s\n" - " GL_EXTENSIONS: %s", - ctx->glGetString (GL_VENDOR), - ctx->glGetString (GL_RENDERER), - _cogl_context_get_gl_version (ctx), - all_extensions); - - g_free (all_extensions); - } - - _cogl_get_gl_version (ctx, &gl_major, &gl_minor); - - ctx->glsl_major = 1; - ctx->glsl_minor = 2; - ctx->glsl_version_to_use = 120; - - glsl_version = (char *)ctx->glGetString (GL_SHADING_LANGUAGE_VERSION); - _cogl_gl_util_parse_gl_version (glsl_version, - &ctx->glsl_major, - &ctx->glsl_minor); - - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); - - _cogl_feature_check_ext_functions (ctx, - gl_major, - gl_minor, - gl_extensions); - - if (_cogl_check_extension ("GL_MESA_pack_invert", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE); - - if (!ctx->glGenRenderbuffers) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, - "Framebuffer objects are required to use the GL driver"); - return FALSE; - } - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS, - TRUE); - - if (ctx->glBlitFramebuffer) - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE); - - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_PBOS, TRUE); - - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE); - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - - if (ctx->glEGLImageTargetTexture2D) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE); - - if (_cogl_check_extension ("GL_EXT_packed_depth_stencil", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL, TRUE); - - if (ctx->glGenSamplers) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 3) || - _cogl_check_extension ("GL_ARB_texture_swizzle", gl_extensions) || - _cogl_check_extension ("GL_EXT_texture_swizzle", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE, TRUE); - - if (ctx->driver == COGL_DRIVER_GL) - { - /* Features which are not available in GL 3 */ - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE); - } - - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_READ_PIXELS_ANY_FORMAT, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_FORMAT_CONVERSION, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS, TRUE); - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL, TRUE); - - if (ctx->glFenceSync) - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) || - _cogl_check_extension ("GL_ARB_texture_rg", gl_extensions)) - COGL_FLAGS_SET (ctx->features, - COGL_FEATURE_ID_TEXTURE_RG, - TRUE); - - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, TRUE); - - if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, - TRUE); - - if (ctx->glGenQueries && ctx->glQueryCounter) - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE); - - if (ctx->glGetInteger64v) - COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GET_GPU_TIME, TRUE); - - /* Cache features */ - for (i = 0; i < G_N_ELEMENTS (private_features); i++) - ctx->private_features[i] |= private_features[i]; - - g_strfreev (gl_extensions); - - if (!COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && - !COGL_FLAGS_GET (private_features, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_NO_SUITABLE_DRIVER_FOUND, - "The GL_ARB_texture_swizzle extension is required " - "to use the GL3 driver"); - return FALSE; - } - - return TRUE; -} - -const CoglDriverVtable -_cogl_driver_gl = - { - _cogl_driver_gl_real_context_init, - _cogl_driver_gl_context_deinit, - _cogl_driver_gl_is_hardware_accelerated, - _cogl_gl_get_graphics_reset_status, - _cogl_driver_pixel_format_from_gl_internal, - _cogl_driver_pixel_format_to_gl, - _cogl_driver_update_features, - _cogl_driver_gl_create_framebuffer_driver, - _cogl_driver_gl_flush_framebuffer_state, - _cogl_texture_2d_gl_free, - _cogl_texture_2d_gl_can_create, - _cogl_texture_2d_gl_init, - _cogl_texture_2d_gl_allocate, - _cogl_texture_2d_gl_copy_from_framebuffer, - _cogl_texture_2d_gl_get_gl_handle, - _cogl_texture_2d_gl_generate_mipmap, - _cogl_texture_2d_gl_copy_from_bitmap, - _cogl_texture_2d_gl_is_get_data_supported, - _cogl_texture_2d_gl_get_data, - _cogl_gl_flush_attributes_state, - _cogl_clip_stack_gl_flush, - _cogl_buffer_gl_create, - _cogl_buffer_gl_destroy, - _cogl_buffer_gl_map_range, - _cogl_buffer_gl_unmap, - _cogl_buffer_gl_set_data, - _cogl_sampler_gl_init, - _cogl_sampler_gl_free, - _cogl_gl_set_uniform, /* XXX name is weird... */ - cogl_gl_create_timestamp_query, - cogl_gl_free_timestamp_query, - cogl_gl_timestamp_query_get_time_ns, - cogl_gl_get_gpu_time_ns, - }; diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c deleted file mode 100644 index 5e95d05a7..000000000 --- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum <mallum@openedhand.com> - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-texture-gl-private.h" -#include "driver/gl/cogl-bitmap-gl-private.h" - -#include <string.h> -#include <stdlib.h> -#include <math.h> - -#ifndef GL_TEXTURE_SWIZZLE_RGBA -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#endif - -static GLuint -_cogl_texture_driver_gen (CoglContext *ctx, - GLenum gl_target, - CoglPixelFormat internal_format) -{ - GLuint tex; - - GE (ctx, glGenTextures (1, &tex)); - - _cogl_bind_gl_texture_transient (gl_target, tex); - - switch (gl_target) - { - case GL_TEXTURE_2D: - /* In case automatic mipmap generation gets disabled for this - * texture but a minification filter depending on mipmap - * interpolation is selected then we initialize the max mipmap - * level to 0 so OpenGL will consider the texture storage to be - * "complete". - */ -#ifdef HAVE_COGL_GL - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL)) - GE( ctx, glTexParameteri (gl_target, GL_TEXTURE_MAX_LEVEL, 0)); -#endif - - /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */ - GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR) ); - break; - - case GL_TEXTURE_RECTANGLE_ARB: - /* Texture rectangles already default to GL_LINEAR so nothing - needs to be done */ - break; - - default: - g_assert_not_reached(); - } - - /* If the driver doesn't support alpha textures directly then we'll - * fake them by setting the swizzle parameters */ - if (internal_format == COGL_PIXEL_FORMAT_A_8 && - !_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) && - _cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE)) - { - static const GLint red_swizzle[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; - - GE( ctx, glTexParameteriv (gl_target, - GL_TEXTURE_SWIZZLE_RGBA, - red_swizzle) ); - } - - return tex; -} - -/* OpenGL - unlike GLES - can upload a sub region of pixel data from a larger - * source buffer */ -static void -prep_gl_for_pixels_upload_full (CoglContext *ctx, - int pixels_rowstride, - int image_height, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - GE( ctx, glPixelStorei (GL_UNPACK_ROW_LENGTH, - pixels_rowstride / pixels_bpp) ); - - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); - - _cogl_texture_gl_prep_alignment_for_pixels_upload (ctx, pixels_rowstride); -} - -/* OpenGL - unlike GLES - can download pixel data into a sub region of - * a larger destination buffer */ -static void -prep_gl_for_pixels_download_full (CoglContext *ctx, - int image_width, - int pixels_rowstride, - int image_height, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - GE( ctx, glPixelStorei (GL_PACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) ); - - GE( ctx, glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) ); - GE( ctx, glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) ); - - _cogl_texture_gl_prep_alignment_for_pixels_download (ctx, - pixels_bpp, - image_width, - pixels_rowstride); -} - -static void -_cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx, - int image_width, - int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_download_full (ctx, - pixels_rowstride, - image_width, - 0 /* image height */, - 0, 0, /* pixels_src_x/y */ - pixels_bpp); -} - -static gboolean -_cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, - CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - GLenum gl_target; - GLuint gl_handle; - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - gboolean status = TRUE; - GError *internal_error = NULL; - int level_width; - int level_height; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return FALSE; - } - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, - cogl_bitmap_get_rowstride (source_bmp), - 0, - src_x, - src_y, - bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - _cogl_texture_get_level_size (texture, - level, - &level_width, - &level_height, - NULL); - - if (level_width == width && level_height == height) - { - /* GL gets upset if you use glTexSubImage2D to initialize the - * contents of a mipmap level so we make sure to use - * glTexImage2D if we are uploading a full mipmap level. - */ - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - width, - height, - 0, - source_gl_format, - source_gl_type, - data); - - } - else - { - /* GL gets upset if you use glTexSubImage2D to initialize the - * contents of a mipmap level so if this is the first time - * we've seen a request to upload to this level we call - * glTexImage2D first to assert that the storage for this - * level exists. - */ - if (texture->max_level_set < level) - { - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - level_width, - level_height, - 0, - source_gl_format, - source_gl_type, - NULL); - } - - ctx->glTexSubImage2D (gl_target, - level, - dst_x, dst_y, - width, height, - source_gl_format, - source_gl_type, - data); - } - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (source_bmp); - - return status; -} - -static gboolean -_cogl_texture_driver_upload_to_gl (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - gboolean status = TRUE; - GError *internal_error = NULL; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - data = _cogl_bitmap_gl_bind (source_bmp, - COGL_BUFFER_ACCESS_READ, - 0, /* hints */ - &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_propagate_error (error, internal_error); - return FALSE; - } - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, - cogl_bitmap_get_rowstride (source_bmp), - 0, 0, 0, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (gl_target, 0, - internal_gl_format, - cogl_bitmap_get_width (source_bmp), - cogl_bitmap_get_height (source_bmp), - 0, - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (source_bmp); - - return status; -} - -static gboolean -_cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, - GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - uint8_t *dest) -{ - GE (ctx, glGetTexImage (gl_target, - 0, /* level */ - dest_gl_format, - dest_gl_type, - (GLvoid *)dest)); - return TRUE; -} - -static gboolean -_cogl_texture_driver_size_supported (CoglContext *ctx, - GLenum gl_target, - GLenum gl_intformat, - GLenum gl_format, - GLenum gl_type, - int width, - int height) -{ - GLenum proxy_target; - GLint new_width = 0; - - if (gl_target == GL_TEXTURE_2D) - proxy_target = GL_PROXY_TEXTURE_2D; -#ifdef HAVE_COGL_GL - else if (gl_target == GL_TEXTURE_RECTANGLE_ARB) - proxy_target = GL_PROXY_TEXTURE_RECTANGLE_ARB; -#endif - else - /* Unknown target, assume it's not supported */ - return FALSE; - - /* Proxy texture allows for a quick check for supported size */ - GE( ctx, glTexImage2D (proxy_target, 0, gl_intformat, - width, height, 0 /* border */, - gl_format, gl_type, NULL) ); - - GE( ctx, glGetTexLevelParameteriv (proxy_target, 0, - GL_TEXTURE_WIDTH, &new_width) ); - - return new_width != 0; -} - -static gboolean -_cogl_texture_driver_upload_supported (CoglContext *ctx, - CoglPixelFormat format) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_G_8: - case COGL_PIXEL_FORMAT_RG_88: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - return TRUE; - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT)) - return TRUE; - else - return FALSE; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_32: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - return TRUE; - } - - g_assert_not_reached (); - return FALSE; -} - -static CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format - (CoglContext *context, - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type) -{ - return context->driver_vtable->pixel_format_to_gl (context, - format, - NULL, /* don't need */ - closest_gl_format, - closest_gl_type); -} - -const CoglTextureDriver -_cogl_texture_driver_gl = - { - _cogl_texture_driver_gen, - _cogl_texture_driver_upload_subregion_to_gl, - _cogl_texture_driver_upload_to_gl, - _cogl_texture_driver_prep_gl_for_pixels_download, - _cogl_texture_driver_gl_get_tex_image, - _cogl_texture_driver_size_supported, - _cogl_texture_driver_upload_supported, - _cogl_texture_driver_find_best_gl_get_data_format - }; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c deleted file mode 100644 index 633e2c415..000000000 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-context-private.h" -#include "cogl-feature-private.h" -#include "cogl-renderer-private.h" -#include "cogl-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-framebuffer-gl-private.h" -#include "driver/gl/cogl-texture-2d-gl-private.h" -#include "driver/gl/cogl-attribute-gl-private.h" -#include "driver/gl/cogl-clip-stack-gl-private.h" -#include "driver/gl/cogl-buffer-gl-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" - -#ifndef GL_UNSIGNED_INT_24_8 -#define GL_UNSIGNED_INT_24_8 0x84FA -#endif -#ifndef GL_DEPTH_STENCIL -#define GL_DEPTH_STENCIL 0x84F9 -#endif -#ifndef GL_RG -#define GL_RG 0x8227 -#endif -#ifndef GL_RG8 -#define GL_RG8 0x822B -#endif -#ifndef GL_UNSIGNED_INT_2_10_10_10_REV_EXT -#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 -#endif -#ifndef GL_HALF_FLOAT_OES -#define GL_HALF_FLOAT_OES 0x8D61 -#endif - -static gboolean -_cogl_driver_pixel_format_from_gl_internal (CoglContext *context, - GLenum gl_int_format, - CoglPixelFormat *out_format) -{ - return TRUE; -} - -static CoglPixelFormat -_cogl_driver_pixel_format_to_gl (CoglContext *context, - CoglPixelFormat format, - GLenum *out_glintformat, - GLenum *out_glformat, - GLenum *out_gltype) -{ - CoglPixelFormat required_format; - GLenum glintformat; - GLenum glformat = 0; - GLenum gltype; - - required_format = format; - - /* Find GL equivalents */ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - glintformat = GL_ALPHA; - glformat = GL_ALPHA; - gltype = GL_UNSIGNED_BYTE; - break; - case COGL_PIXEL_FORMAT_G_8: - glintformat = GL_LUMINANCE; - glformat = GL_LUMINANCE; - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_RG_88: - if (cogl_has_feature (context, COGL_FEATURE_ID_TEXTURE_RG)) - { - glintformat = GL_RG8; - glformat = GL_RG; - } - else - { - /* If red-green textures aren't supported then we'll use RGB - * as an internal format. Note this should only end up - * mattering for downloading the data because Cogl will - * refuse to allocate a texture with RG components if RG - * textures aren't supported */ - glintformat = GL_RGB; - glformat = GL_RGB; - required_format = COGL_PIXEL_FORMAT_RGB_888; - } - gltype = GL_UNSIGNED_BYTE; - break; - - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - /* There is an extension to support this format */ - if (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888)) - { - /* For some reason the extension says you have to specify - BGRA for the internal format too */ - glintformat = GL_BGRA_EXT; - glformat = GL_BGRA_EXT; - gltype = GL_UNSIGNED_BYTE; - required_format = format; - break; - } - /* flow through */ - - /* Just one 24-bit ordering supported */ - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_BYTE; - required_format = COGL_PIXEL_FORMAT_RGB_888; - break; - - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102)) - { - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV_EXT; - break; - } -#endif - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102)) - { - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_INT_2_10_10_10_REV_EXT; - required_format = COGL_PIXEL_FORMAT_RGBA_1010102; - required_format |= (format & COGL_PREMULT_BIT); - break; - } -#endif - - G_GNUC_FALLTHROUGH; - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_BYTE; - required_format = COGL_PIXEL_FORMAT_RGBA_8888; - required_format |= (format & COGL_PREMULT_BIT); - break; - - /* The following three types of channel ordering - * are always defined using system word byte - * ordering (even according to GLES spec) */ - case COGL_PIXEL_FORMAT_RGB_565: - glintformat = GL_RGB; - glformat = GL_RGB; - gltype = GL_UNSIGNED_SHORT_5_6_5; - break; - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_UNSIGNED_SHORT_5_5_5_1; - break; - - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - g_warning ("Unhandled 16 bpc pixel format used"); - - G_GNUC_FALLTHROUGH; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - if (!_cogl_has_private_feature - (context, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT)) - g_warning ("Missing 16 bpc half float extension"); - - glintformat = GL_RGBA; - glformat = GL_RGBA; - gltype = GL_HALF_FLOAT_OES; - break; - - case COGL_PIXEL_FORMAT_DEPTH_16: - glintformat = GL_DEPTH_COMPONENT; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_SHORT; - break; - case COGL_PIXEL_FORMAT_DEPTH_32: - glintformat = GL_DEPTH_COMPONENT; - glformat = GL_DEPTH_COMPONENT; - gltype = GL_UNSIGNED_INT; - break; - - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - glintformat = GL_DEPTH_STENCIL; - glformat = GL_DEPTH_STENCIL; - gltype = GL_UNSIGNED_INT_24_8; - break; - - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - g_assert_not_reached (); - break; - } - - /* All of the pixel formats are handled above so if this hits then - we've been given an invalid pixel format */ - g_assert (glformat != 0); - - if (out_glintformat != NULL) - *out_glintformat = glintformat; - if (out_glformat != NULL) - *out_glformat = glformat; - if (out_gltype != NULL) - *out_gltype = gltype; - - return required_format; -} - -static gboolean -_cogl_get_gl_version (CoglContext *ctx, - int *major_out, - int *minor_out) -{ - const char *version_string; - - /* Get the OpenGL version number */ - if ((version_string = _cogl_context_get_gl_version (ctx)) == NULL) - return FALSE; - - if (!g_str_has_prefix (version_string, "OpenGL ES ")) - return FALSE; - - return _cogl_gl_util_parse_gl_version (version_string + 10, - major_out, - minor_out); -} - -static gboolean -_cogl_driver_update_features (CoglContext *context, - GError **error) -{ - unsigned long private_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_N_PRIVATE_FEATURES)] = { 0 }; - char **gl_extensions; - int gl_major, gl_minor; - int i; - - /* We have to special case getting the pointer to the glGetString - function because we need to use it to determine what functions we - can expect */ - context->glGetString = - (void *) _cogl_renderer_get_proc_address (context->display->renderer, - "glGetString", - TRUE); - context->glGetStringi = - (void *) _cogl_renderer_get_proc_address (context->display->renderer, - "glGetStringi", - TRUE); - - gl_extensions = _cogl_context_get_gl_extensions (context); - - if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WINSYS))) - { - char *all_extensions = g_strjoinv (" ", gl_extensions); - - COGL_NOTE (WINSYS, - "Checking features\n" - " GL_VENDOR: %s\n" - " GL_RENDERER: %s\n" - " GL_VERSION: %s\n" - " GL_EXTENSIONS: %s", - context->glGetString (GL_VENDOR), - context->glGetString (GL_RENDERER), - _cogl_context_get_gl_version (context), - all_extensions); - - g_free (all_extensions); - } - - context->glsl_major = 1; - context->glsl_minor = 0; - context->glsl_version_to_use = 100; - - if (!_cogl_get_gl_version (context, &gl_major, &gl_minor)) - { - gl_major = 1; - gl_minor = 1; - } - - if (!COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 0)) - { - g_set_error (error, - COGL_DRIVER_ERROR, - COGL_DRIVER_ERROR_INVALID_VERSION, - "OpenGL ES 2.0 or better is required"); - return FALSE; - } - - _cogl_feature_check_ext_functions (context, - gl_major, - gl_minor, - gl_extensions); - - if (_cogl_check_extension ("GL_ANGLE_pack_reverse_row_order", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_MESA_PACK_INVERT, TRUE); - - /* Note GLES 2 core doesn't support mipmaps for npot textures or - * repeat modes other than CLAMP_TO_EDGE. */ - - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ANY_GL, TRUE); - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES, TRUE); - - if (context->glGenSamplers) - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_SAMPLER_OBJECTS, TRUE); - - if (context->glBlitFramebuffer) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_BLIT_FRAMEBUFFER, TRUE); - - if (_cogl_check_extension ("GL_OES_element_index_uint", gl_extensions)) - { - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); - } - - if (context->glMapBuffer) - { - /* The GL_OES_mapbuffer extension doesn't support mapping for - read */ - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - } - - if (context->glMapBufferRange) - { - /* MapBufferRange in ES3+ does support mapping for read */ - COGL_FLAGS_SET(context->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, TRUE); - COGL_FLAGS_SET(context->features, - COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, TRUE); - } - - if (context->glEGLImageTargetTexture2D) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE, TRUE); - - if (_cogl_check_extension ("GL_OES_packed_depth_stencil", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL, TRUE); - - if (_cogl_check_extension ("GL_EXT_texture_format_BGRA8888", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_BGRA8888, TRUE); - - if (_cogl_check_extension ("GL_EXT_texture_type_2_10_10_10_REV", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102, TRUE); - - if (_cogl_check_extension ("GL_OES_texture_half_float", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT, TRUE); - - if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions)) - COGL_FLAGS_SET (private_features, - COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE, TRUE); - - /* A nameless vendor implemented the extension, but got the case wrong - * per the spec. */ - if (_cogl_check_extension ("GL_OES_EGL_sync", gl_extensions) || - _cogl_check_extension ("GL_OES_egl_sync", gl_extensions)) - COGL_FLAGS_SET (private_features, COGL_PRIVATE_FEATURE_OES_EGL_SYNC, TRUE); - -#ifdef GL_ARB_sync - if (context->glFenceSync) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE); -#endif - - if (_cogl_check_extension ("GL_EXT_texture_rg", gl_extensions)) - COGL_FLAGS_SET (context->features, - COGL_FEATURE_ID_TEXTURE_RG, - TRUE); - - if (context->glGenQueries && context->glQueryCounter) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_TIMESTAMP_QUERY, TRUE); - - if (context->glGetInteger64v) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_GET_GPU_TIME, TRUE); - - /* Cache features */ - for (i = 0; i < G_N_ELEMENTS (private_features); i++) - context->private_features[i] |= private_features[i]; - - g_strfreev (gl_extensions); - - return TRUE; -} - -static gboolean -_cogl_driver_texture_2d_is_get_data_supported (CoglTexture2D *tex_2d) -{ - return FALSE; -} - -const CoglDriverVtable -_cogl_driver_gles = - { - _cogl_driver_gl_context_init, - _cogl_driver_gl_context_deinit, - _cogl_driver_gl_is_hardware_accelerated, - _cogl_gl_get_graphics_reset_status, - _cogl_driver_pixel_format_from_gl_internal, - _cogl_driver_pixel_format_to_gl, - _cogl_driver_update_features, - _cogl_driver_gl_create_framebuffer_driver, - _cogl_driver_gl_flush_framebuffer_state, - _cogl_texture_2d_gl_free, - _cogl_texture_2d_gl_can_create, - _cogl_texture_2d_gl_init, - _cogl_texture_2d_gl_allocate, - _cogl_texture_2d_gl_copy_from_framebuffer, - _cogl_texture_2d_gl_get_gl_handle, - _cogl_texture_2d_gl_generate_mipmap, - _cogl_texture_2d_gl_copy_from_bitmap, - _cogl_driver_texture_2d_is_get_data_supported, - NULL, /* texture_2d_get_data */ - _cogl_gl_flush_attributes_state, - _cogl_clip_stack_gl_flush, - _cogl_buffer_gl_create, - _cogl_buffer_gl_destroy, - _cogl_buffer_gl_map_range, - _cogl_buffer_gl_unmap, - _cogl_buffer_gl_set_data, - _cogl_sampler_gl_init, - _cogl_sampler_gl_free, - _cogl_gl_set_uniform, - cogl_gl_create_timestamp_query, - cogl_gl_free_timestamp_query, - cogl_gl_timestamp_query_get_time_ns, - cogl_gl_get_gpu_time_ns, - }; diff --git a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c deleted file mode 100644 index 904d39d34..000000000 --- a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Matthew Allum <mallum@openedhand.com> - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-private.h" -#include "cogl-util.h" -#include "cogl-bitmap.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-pipeline.h" -#include "cogl-context-private.h" -#include "cogl-object-private.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "driver/gl/cogl-util-gl-private.h" -#include "driver/gl/cogl-texture-gl-private.h" -#include "driver/gl/cogl-bitmap-gl-private.h" - -#include <string.h> -#include <stdlib.h> -#include <math.h> - -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif -#ifndef GL_MAX_3D_TEXTURE_SIZE_OES -#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 -#endif - -/* This extension isn't available for GLES 1.1 so these won't be - defined */ -#ifndef GL_UNPACK_ROW_LENGTH -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#endif -#ifndef GL_UNPACK_SKIP_ROWS -#define GL_UNPACK_SKIP_ROWS 0x0CF3 -#endif -#ifndef GL_UNPACK_SKIP_PIXELS -#define GL_UNPACK_SKIP_PIXELS 0x0CF4 -#endif - -static GLuint -_cogl_texture_driver_gen (CoglContext *ctx, - GLenum gl_target, - CoglPixelFormat internal_format) -{ - GLuint tex; - - GE (ctx, glGenTextures (1, &tex)); - - _cogl_bind_gl_texture_transient (gl_target, tex); - - switch (gl_target) - { - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* GL_TEXTURE_MAG_FILTER defaults to GL_LINEAR, no need to set it */ - GE( ctx, glTexParameteri (gl_target, - GL_TEXTURE_MIN_FILTER, - GL_LINEAR) ); - break; - - default: - g_assert_not_reached(); - } - - return tex; -} - -static void -prep_gl_for_pixels_upload_full (CoglContext *ctx, - int pixels_rowstride, - int pixels_src_x, - int pixels_src_y, - int pixels_bpp) -{ - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE)) - { - GE( ctx, glPixelStorei (GL_UNPACK_ROW_LENGTH, - pixels_rowstride / pixels_bpp) ); - - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) ); - GE( ctx, glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) ); - } - else - { - g_assert (pixels_src_x == 0); - g_assert (pixels_src_y == 0); - } - - _cogl_texture_gl_prep_alignment_for_pixels_upload (ctx, pixels_rowstride); -} - -static void -_cogl_texture_driver_prep_gl_for_pixels_upload (CoglContext *ctx, - int pixels_rowstride, - int pixels_bpp) -{ - prep_gl_for_pixels_upload_full (ctx, - pixels_rowstride, - 0, 0, /* src_x/y */ - pixels_bpp); -} - -static void -_cogl_texture_driver_prep_gl_for_pixels_download (CoglContext *ctx, - int pixels_rowstride, - int image_width, - int pixels_bpp) -{ - _cogl_texture_gl_prep_alignment_for_pixels_download (ctx, - pixels_bpp, - image_width, - pixels_rowstride); -} - -static CoglBitmap * -prepare_bitmap_alignment_for_upload (CoglContext *ctx, - CoglBitmap *src_bmp, - GError **error) -{ - CoglPixelFormat format = cogl_bitmap_get_format (src_bmp); - int bpp; - int src_rowstride = cogl_bitmap_get_rowstride (src_bmp); - int width = cogl_bitmap_get_width (src_bmp); - int alignment = 1; - - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0); - - if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) || - src_rowstride == 0) - return cogl_object_ref (src_bmp); - - /* Work out the alignment of the source rowstride */ - alignment = 1 << (ffs (src_rowstride) - 1); - alignment = MIN (alignment, 8); - - /* If the aligned data equals the rowstride then we can upload from - the bitmap directly using GL_UNPACK_ALIGNMENT */ - if (((width * bpp + alignment - 1) & ~(alignment - 1)) == src_rowstride) - return cogl_object_ref (src_bmp); - /* Otherwise we need to copy the bitmap to pack the alignment - because GLES has no GL_ROW_LENGTH */ - else - return _cogl_bitmap_copy (src_bmp, error); -} - -static gboolean -_cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, - CoglTexture *texture, - int src_x, - int src_y, - int dst_x, - int dst_y, - int width, - int height, - int level, - CoglBitmap *source_bmp, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - GLenum gl_target; - GLuint gl_handle; - uint8_t *data; - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - CoglBitmap *slice_bmp; - int rowstride; - gboolean status = TRUE; - GError *internal_error = NULL; - int level_width; - int level_height; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target); - - /* If we have the GL_EXT_unpack_subimage extension then we can - upload from subregions directly. Otherwise we may need to copy - the bitmap */ - if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) && - (src_x != 0 || src_y != 0 || - width != cogl_bitmap_get_width (source_bmp) || - height != cogl_bitmap_get_height (source_bmp))) - { - slice_bmp = - _cogl_bitmap_new_with_malloc_buffer (ctx, - width, height, - source_format, - error); - if (!slice_bmp) - return FALSE; - - if (!_cogl_bitmap_copy_subregion (source_bmp, - slice_bmp, - src_x, src_y, - 0, 0, /* dst_x/y */ - width, height, - error)) - { - cogl_object_unref (slice_bmp); - return FALSE; - } - - src_x = src_y = 0; - } - else - { - slice_bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error); - if (!slice_bmp) - return FALSE; - } - - rowstride = cogl_bitmap_get_rowstride (slice_bmp); - - /* Setup gl alignment to match rowstride and top-left corner */ - prep_gl_for_pixels_upload_full (ctx, rowstride, src_x, src_y, bpp); - - data = _cogl_bitmap_gl_bind (slice_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - g_propagate_error (error, internal_error); - cogl_object_unref (slice_bmp); - return FALSE; - } - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - _cogl_texture_get_level_size (texture, - level, - &level_width, - &level_height, - NULL); - - if (level_width == width && level_height == height) - { - /* GL gets upset if you use glTexSubImage2D to define the - * contents of a mipmap level so we make sure to use - * glTexImage2D if we are uploading a full mipmap level. - */ - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - width, - height, - 0, - source_gl_format, - source_gl_type, - data); - } - else - { - /* GL gets upset if you use glTexSubImage2D to initialize the - * contents of a mipmap level so if this is the first time - * we've seen a request to upload to this level we call - * glTexImage2D first to assert that the storage for this - * level exists. - */ - if (texture->max_level_set < level) - { - ctx->glTexImage2D (gl_target, - level, - _cogl_texture_gl_get_format (texture), - level_width, - level_height, - 0, - source_gl_format, - source_gl_type, - NULL); - } - - ctx->glTexSubImage2D (gl_target, - level, - dst_x, dst_y, - width, height, - source_gl_format, - source_gl_type, - data); - } - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (slice_bmp); - - cogl_object_unref (slice_bmp); - - return status; -} - -static gboolean -_cogl_texture_driver_upload_to_gl (CoglContext *ctx, - GLenum gl_target, - GLuint gl_handle, - CoglBitmap *source_bmp, - GLint internal_gl_format, - GLuint source_gl_format, - GLuint source_gl_type, - GError **error) -{ - CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp; - int rowstride; - int bmp_width = cogl_bitmap_get_width (source_bmp); - int bmp_height = cogl_bitmap_get_height (source_bmp); - CoglBitmap *bmp; - uint8_t *data; - GError *internal_error = NULL; - gboolean status = TRUE; - - g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE); - g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1, - FALSE); - - bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0); - - bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error); - if (!bmp) - return FALSE; - - rowstride = cogl_bitmap_get_rowstride (bmp); - - /* Setup gl alignment to match rowstride and top-left corner */ - _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - data = _cogl_bitmap_gl_bind (bmp, - COGL_BUFFER_ACCESS_READ, - 0, /* hints */ - &internal_error); - - /* NB: _cogl_bitmap_gl_bind() may return NULL when successful so we - * have to explicitly check the cogl error pointer to catch - * problems... */ - if (internal_error) - { - cogl_object_unref (bmp); - g_propagate_error (error, internal_error); - return FALSE; - } - - /* Clear any GL errors */ - _cogl_gl_util_clear_gl_errors (ctx); - - ctx->glTexImage2D (gl_target, 0, - internal_gl_format, - bmp_width, bmp_height, - 0, - source_gl_format, - source_gl_type, - data); - - if (_cogl_gl_util_catch_out_of_memory (ctx, error)) - status = FALSE; - - _cogl_bitmap_gl_unbind (bmp); - - cogl_object_unref (bmp); - - return status; -} - -/* NB: GLES doesn't support glGetTexImage2D, so cogl-texture will instead - * fallback to a generic render + readpixels approach to downloading - * texture data. (See _cogl_texture_draw_and_read() ) */ -static gboolean -_cogl_texture_driver_gl_get_tex_image (CoglContext *ctx, - GLenum gl_target, - GLenum dest_gl_format, - GLenum dest_gl_type, - uint8_t *dest) -{ - return FALSE; -} - -static gboolean -_cogl_texture_driver_size_supported (CoglContext *ctx, - GLenum gl_target, - GLenum gl_intformat, - GLenum gl_format, - GLenum gl_type, - int width, - int height) -{ - GLint max_size; - - /* GLES doesn't support a proxy texture target so let's at least - check whether the size is greater than GL_MAX_TEXTURE_SIZE */ - GE( ctx, glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_size) ); - - return width <= max_size && height <= max_size; -} - -static gboolean -_cogl_texture_driver_upload_supported (CoglContext *ctx, - CoglPixelFormat format) -{ - switch (format) - { - case COGL_PIXEL_FORMAT_A_8: - case COGL_PIXEL_FORMAT_G_8: - case COGL_PIXEL_FORMAT_RG_88: - case COGL_PIXEL_FORMAT_BGRA_8888: - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_888: - case COGL_PIXEL_FORMAT_BGR_888: - return TRUE; - case COGL_PIXEL_FORMAT_RGBA_1010102: - case COGL_PIXEL_FORMAT_RGBA_1010102_PRE: - case COGL_PIXEL_FORMAT_BGRA_1010102: - case COGL_PIXEL_FORMAT_BGRA_1010102_PRE: - case COGL_PIXEL_FORMAT_ABGR_2101010: - case COGL_PIXEL_FORMAT_ABGR_2101010_PRE: - case COGL_PIXEL_FORMAT_ARGB_2101010: - case COGL_PIXEL_FORMAT_ARGB_2101010_PRE: -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_RGBA1010102)) - return TRUE; - else - return FALSE; -#else - return FALSE; -#endif - case COGL_PIXEL_FORMAT_RGBA_8888: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_ABGR_8888: - case COGL_PIXEL_FORMAT_ABGR_8888_PRE: - case COGL_PIXEL_FORMAT_RGB_565: - case COGL_PIXEL_FORMAT_RGBA_4444: - case COGL_PIXEL_FORMAT_RGBA_4444_PRE: - case COGL_PIXEL_FORMAT_RGBA_5551: - case COGL_PIXEL_FORMAT_RGBA_5551_PRE: - return TRUE; - case COGL_PIXEL_FORMAT_BGRA_FP_16161616: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616: - case COGL_PIXEL_FORMAT_BGRA_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ARGB_FP_16161616_PRE: - case COGL_PIXEL_FORMAT_ABGR_FP_16161616_PRE: - return FALSE; - case COGL_PIXEL_FORMAT_RGBA_FP_16161616: - case COGL_PIXEL_FORMAT_RGBA_FP_16161616_PRE: - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_FORMAT_HALF_FLOAT)) - return TRUE; - else - return FALSE; - case COGL_PIXEL_FORMAT_DEPTH_16: - case COGL_PIXEL_FORMAT_DEPTH_32: - case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: - case COGL_PIXEL_FORMAT_ANY: - case COGL_PIXEL_FORMAT_YUV: - return TRUE; - } - - g_assert_not_reached (); - return FALSE; -} - -static CoglPixelFormat -_cogl_texture_driver_find_best_gl_get_data_format - (CoglContext *context, - CoglPixelFormat format, - GLenum *closest_gl_format, - GLenum *closest_gl_type) -{ - /* Find closest format that's supported by GL - (Can't use _cogl_pixel_format_to_gl since available formats - when reading pixels on GLES are severely limited) */ - *closest_gl_format = GL_RGBA; - *closest_gl_type = GL_UNSIGNED_BYTE; - return COGL_PIXEL_FORMAT_RGBA_8888; -} - -const CoglTextureDriver -_cogl_texture_driver_gles = - { - _cogl_texture_driver_gen, - _cogl_texture_driver_upload_subregion_to_gl, - _cogl_texture_driver_upload_to_gl, - _cogl_texture_driver_prep_gl_for_pixels_download, - _cogl_texture_driver_gl_get_tex_image, - _cogl_texture_driver_size_supported, - _cogl_texture_driver_upload_supported, - _cogl_texture_driver_find_best_gl_get_data_format - }; diff --git a/cogl/cogl/driver/nop/cogl-attribute-nop-private.h b/cogl/cogl/driver/nop/cogl-attribute-nop-private.h deleted file mode 100644 index 9c8547dad..000000000 --- a/cogl/cogl/driver/nop/cogl-attribute-nop-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_ATTRIBUTE_NOP_PRIVATE_H_ -#define _COGL_ATTRIBUTE_NOP_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-context-private.h" - -void -_cogl_nop_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes); - -#endif /* _COGL_ATTRIBUTE_NOP_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/nop/cogl-attribute-nop.c b/cogl/cogl/driver/nop/cogl-attribute-nop.c deleted file mode 100644 index 40b6d5e7c..000000000 --- a/cogl/cogl/driver/nop/cogl-attribute-nop.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-types.h" -#include "cogl-framebuffer.h" -#include "cogl-attribute.h" -#include "cogl-attribute-private.h" -#include "cogl-attribute-nop-private.h" - -void -_cogl_nop_flush_attributes_state (CoglFramebuffer *framebuffer, - CoglPipeline *pipeline, - CoglFlushLayerState *layers_state, - CoglDrawFlags flags, - CoglAttribute **attributes, - int n_attributes) -{ -} diff --git a/cogl/cogl/driver/nop/cogl-clip-stack-nop-private.h b/cogl/cogl/driver/nop/cogl-clip-stack-nop-private.h deleted file mode 100644 index 4d8513b06..000000000 --- a/cogl/cogl/driver/nop/cogl-clip-stack-nop-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_CLIP_STACK_NOP_PRIVATE_H_ -#define _COGL_CLIP_STACK_NOP_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-context-private.h" - -void -_cogl_clip_stack_nop_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer); - -#endif /* _COGL_CLIP_STACK_NOP_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/nop/cogl-clip-stack-nop.c b/cogl/cogl/driver/nop/cogl-clip-stack-nop.c deleted file mode 100644 index 3469965fb..000000000 --- a/cogl/cogl/driver/nop/cogl-clip-stack-nop.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-clip-stack.h" -#include "cogl-clip-stack-nop-private.h" -#include "cogl-framebuffer-private.h" - -void -_cogl_clip_stack_nop_flush (CoglClipStack *stack, - CoglFramebuffer *framebuffer) -{ -} diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c deleted file mode 100644 index 2cde8576b..000000000 --- a/cogl/cogl/driver/nop/cogl-driver-nop.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-private.h" -#include "cogl-context-private.h" -#include "cogl-feature-private.h" -#include "cogl-renderer-private.h" -#include "cogl-texture-2d-nop-private.h" -#include "cogl-attribute-nop-private.h" -#include "cogl-clip-stack-nop-private.h" -#include "driver/nop/cogl-nop-framebuffer.h" - -static gboolean -_cogl_driver_update_features (CoglContext *ctx, - GError **error) -{ - memset (ctx->private_features, 0, sizeof (ctx->private_features)); - - return TRUE; -} - -static gboolean -_cogl_driver_nop_context_init (CoglContext *context) -{ - return TRUE; -} - -static void -_cogl_driver_nop_context_deinit (CoglContext *context) -{ -} - -static gboolean -_cogl_driver_nop_is_hardware_accelerated (CoglContext *context) -{ - return FALSE; -} - -static CoglFramebufferDriver * -_cogl_driver_nop_create_framebuffer_driver (CoglContext *context, - CoglFramebuffer *framebuffer, - const CoglFramebufferDriverConfig *driver_config, - GError **error) -{ - return g_object_new (COGL_TYPE_NOP_FRAMEBUFFER, - "framebuffer", framebuffer, - NULL); -} - -static void -_cogl_driver_nop_flush_framebuffer_state (CoglContext *ctx, - CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer, - CoglFramebufferState state) -{ -} - -const CoglDriverVtable -_cogl_driver_nop = - { - _cogl_driver_nop_context_init, - _cogl_driver_nop_context_deinit, - _cogl_driver_nop_is_hardware_accelerated, - NULL, /* get_graphics_reset_status */ - NULL, /* pixel_format_from_gl_internal */ - NULL, /* pixel_format_to_gl */ - _cogl_driver_update_features, - _cogl_driver_nop_create_framebuffer_driver, - _cogl_driver_nop_flush_framebuffer_state, - _cogl_texture_2d_nop_free, - _cogl_texture_2d_nop_can_create, - _cogl_texture_2d_nop_init, - _cogl_texture_2d_nop_allocate, - _cogl_texture_2d_nop_copy_from_framebuffer, - _cogl_texture_2d_nop_get_gl_handle, - _cogl_texture_2d_nop_generate_mipmap, - _cogl_texture_2d_nop_copy_from_bitmap, - NULL, /* texture_2d_is_get_data_supported */ - NULL, /* texture_2d_get_data */ - _cogl_nop_flush_attributes_state, - _cogl_clip_stack_nop_flush, - }; diff --git a/cogl/cogl/driver/nop/cogl-nop-framebuffer.c b/cogl/cogl/driver/nop/cogl-nop-framebuffer.c deleted file mode 100644 index 3ab05338e..000000000 --- a/cogl/cogl/driver/nop/cogl-nop-framebuffer.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "cogl-nop-framebuffer.h" - -#include "cogl-framebuffer-private.h" - -struct _CoglNopFramebuffer -{ - CoglFramebufferDriver parent; -}; - -G_DEFINE_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer, - COGL_TYPE_FRAMEBUFFER_DRIVER) - -static void -cogl_nop_framebuffer_query_bits (CoglFramebufferDriver *driver, - CoglFramebufferBits *bits) -{ - memset (bits, 0, sizeof (CoglFramebufferBits)); -} - -static void -cogl_nop_framebuffer_clear (CoglFramebufferDriver *driver, - unsigned long buffers, - float red, - float green, - float blue, - float alpha) -{ -} - -static void -cogl_nop_framebuffer_finish (CoglFramebufferDriver *driver) -{ -} - -static void -cogl_nop_framebuffer_flush (CoglFramebufferDriver *driver) -{ -} - -static void -cogl_nop_framebuffer_discard_buffers (CoglFramebufferDriver *driver, - unsigned long buffers) -{ -} - -static void -cogl_nop_framebuffer_draw_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ -} - -static void -cogl_nop_framebuffer_draw_indexed_attributes (CoglFramebufferDriver *driver, - CoglPipeline *pipeline, - CoglVerticesMode mode, - int first_vertex, - int n_vertices, - CoglIndices *indices, - CoglAttribute **attributes, - int n_attributes, - CoglDrawFlags flags) -{ -} - -static gboolean -cogl_nop_framebuffer_read_pixels_into_bitmap (CoglFramebufferDriver *framebuffer, - int x, - int y, - CoglReadPixelsFlags source, - CoglBitmap *bitmap, - GError **error) -{ - return TRUE; -} - -static void -cogl_nop_framebuffer_init (CoglNopFramebuffer *nop_framebuffer) -{ -} - -static void -cogl_nop_framebuffer_class_init (CoglNopFramebufferClass *klass) -{ - CoglFramebufferDriverClass *driver_class = - COGL_FRAMEBUFFER_DRIVER_CLASS (klass); - - driver_class->query_bits = cogl_nop_framebuffer_query_bits; - driver_class->clear = cogl_nop_framebuffer_clear; - driver_class->finish = cogl_nop_framebuffer_finish; - driver_class->flush = cogl_nop_framebuffer_flush; - driver_class->discard_buffers = cogl_nop_framebuffer_discard_buffers; - driver_class->draw_attributes = cogl_nop_framebuffer_draw_attributes; - driver_class->draw_indexed_attributes = - cogl_nop_framebuffer_draw_indexed_attributes; - driver_class->read_pixels_into_bitmap = - cogl_nop_framebuffer_read_pixels_into_bitmap; -} diff --git a/cogl/cogl/driver/nop/cogl-nop-framebuffer.h b/cogl/cogl/driver/nop/cogl-nop-framebuffer.h deleted file mode 100644 index 7c9f729a6..000000000 --- a/cogl/cogl/driver/nop/cogl-nop-framebuffer.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef COGL_NOP_FRAMEBUFFER_H -#define COGL_NOP_FRAMEBUFFER_H - -#include "cogl-framebuffer-driver.h" - -#define COGL_TYPE_NOP_FRAMEBUFFER (cogl_nop_framebuffer_get_type ()) -G_DECLARE_FINAL_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer, - COGL, NOP_FRAMEBUFFER_DRIVER, - CoglFramebufferDriver) - -#endif /* COGL_NOP_FRAMEBUFFER_H */ diff --git a/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h b/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h deleted file mode 100644 index dce8b689d..000000000 --- a/cogl/cogl/driver/nop/cogl-texture-2d-nop-private.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef _COGL_TEXTURE_2D_NOP_PRIVATE_H_ -#define _COGL_TEXTURE_2D_NOP_PRIVATE_H_ - -#include "cogl-types.h" -#include "cogl-context-private.h" -#include "cogl-texture.h" - -void -_cogl_texture_2d_nop_free (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_nop_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format); - -void -_cogl_texture_2d_nop_init (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_nop_allocate (CoglTexture *tex, - GError **error); - -void -_cogl_texture_2d_nop_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter); - -void -_cogl_texture_2d_nop_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t); - -void -_cogl_texture_2d_nop_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level); - -unsigned int -_cogl_texture_2d_nop_get_gl_handle (CoglTexture2D *tex_2d); - -void -_cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d); - -gboolean -_cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error); - -void -_cogl_texture_2d_nop_get_data (CoglTexture2D *tex_2d, - CoglPixelFormat format, - size_t rowstride, - uint8_t *data); - -#endif /* _COGL_TEXTURE_2D_NOP_PRIVATE_H_ */ diff --git a/cogl/cogl/driver/nop/cogl-texture-2d-nop.c b/cogl/cogl/driver/nop/cogl-texture-2d-nop.c deleted file mode 100644 index 4a9989553..000000000 --- a/cogl/cogl/driver/nop/cogl-texture-2d-nop.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009,2010,2011,2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <string.h> - -#include "cogl-private.h" -#include "cogl-texture-2d-nop-private.h" -#include "cogl-texture-2d-private.h" - -void -_cogl_texture_2d_nop_free (CoglTexture2D *tex_2d) -{ -} - -gboolean -_cogl_texture_2d_nop_can_create (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - return TRUE; -} - -void -_cogl_texture_2d_nop_init (CoglTexture2D *tex_2d) -{ -} - -gboolean -_cogl_texture_2d_nop_allocate (CoglTexture *tex, - GError **error) -{ - return TRUE; -} - -void -_cogl_texture_2d_nop_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ -} - -void -_cogl_texture_2d_nop_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ -} - -void -_cogl_texture_2d_nop_copy_from_framebuffer (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglFramebuffer *src_fb, - int dst_x, - int dst_y, - int level) -{ -} - -unsigned int -_cogl_texture_2d_nop_get_gl_handle (CoglTexture2D *tex_2d) -{ - return 0; -} - -void -_cogl_texture_2d_nop_generate_mipmap (CoglTexture2D *tex_2d) -{ -} - -gboolean -_cogl_texture_2d_nop_copy_from_bitmap (CoglTexture2D *tex_2d, - int src_x, - int src_y, - int width, - int height, - CoglBitmap *bitmap, - int dst_x, - int dst_y, - int level, - GError **error) -{ - return TRUE; -} - -void -_cogl_texture_2d_nop_get_data (CoglTexture2D *tex_2d, - CoglPixelFormat format, - size_t rowstride, - uint8_t *data) -{ -} diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h deleted file mode 100644 index 3a31a610a..000000000 --- a/cogl/cogl/gl-prototypes/cogl-all-functions.h +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * Copyright (C) 2019 DisplayLink (UK) Ltd. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* The functions in this file are part of the core GL,GLES1 and GLES2 apis */ -#include "cogl-core-functions.h" - -/* The functions in this file are core to GLES2 only but - * may be extensions for GLES1 and GL */ -#include "cogl-in-gles2-core-functions.h" - -/* The functions in this file are core to GLES1 and GLES2 but not core - * to GL but they may be extensions available for GL */ -#include "cogl-in-gles-core-functions.h" - -/* These are GLSL shader APIs core to GL 2.0 and GLES2 */ -#include "cogl-glsl-functions.h" - -/* These are the core GL functions which are only available in big - GL */ -COGL_EXT_BEGIN (only_in_big_gl, - 0, 0, - 0, /* not in GLES */ - "\0", - "\0") -COGL_EXT_FUNCTION (void, glGetTexLevelParameteriv, - (GLenum target, GLint level, - GLenum pname, GLint *params)) -COGL_EXT_FUNCTION (void, glGetTexImage, - (GLenum target, GLint level, - GLenum format, GLenum type, - GLvoid *pixels)) -COGL_EXT_FUNCTION (void, glDepthRange, - (double near_val, double far_val)) -COGL_EXT_FUNCTION (void, glDrawBuffer, - (GLenum mode)) -COGL_EXT_END () - - -/* GLES doesn't support mapping buffers in core so this has to be a - separate check */ -COGL_EXT_BEGIN (map_vbos, 1, 5, - 0, /* not in GLES core */ - "ARB\0OES\0", - "vertex_buffer_object\0mapbuffer\0") -COGL_EXT_FUNCTION (void *, glMapBuffer, - (GLenum target, - GLenum access)) -COGL_EXT_FUNCTION (GLboolean, glUnmapBuffer, - (GLenum target)) -COGL_EXT_END () - - -COGL_EXT_BEGIN (offscreen_blit, 3, 0, - COGL_EXT_IN_GLES3, - "EXT\0NV\0", - "framebuffer_blit\0") -COGL_EXT_FUNCTION (void, glBlitFramebuffer, - (GLint srcX0, - GLint srcY0, - GLint srcX1, - GLint srcY1, - GLint dstX0, - GLint dstY0, - GLint dstX1, - GLint dstY1, - GLbitfield mask, - GLenum filter)) -COGL_EXT_END () - -COGL_EXT_BEGIN (EGL_image, 255, 255, - 0, /* not in either GLES */ - "OES\0", - "EGL_image\0") -COGL_EXT_FUNCTION (void, glEGLImageTargetTexture2D, - (GLenum target, - GLeglImageOES image)) -COGL_EXT_END () - -COGL_EXT_BEGIN (framebuffer_discard, 255, 255, - 0, /* not in either GLES */ - "EXT\0", - "framebuffer_discard\0") -COGL_EXT_FUNCTION (void, glDiscardFramebuffer, - (GLenum target, - GLsizei numAttachments, - const GLenum *attachments)) -COGL_EXT_END () - -COGL_EXT_BEGIN (IMG_multisampled_render_to_texture, 255, 255, - 0, /* not in either GLES */ - "\0", - "IMG_multisampled_render_to_texture\0") -COGL_EXT_FUNCTION (void, glRenderbufferStorageMultisampleIMG, - (GLenum target, - GLsizei samples, - GLenum internal_format, - GLsizei width, - GLsizei height)) -COGL_EXT_FUNCTION (void, glFramebufferTexture2DMultisampleIMG, - (GLenum target, - GLenum attachment, - GLenum textarget, - GLuint texture, - GLint level, - GLsizei samples)) -COGL_EXT_END () - -COGL_EXT_BEGIN (ARB_sampler_objects, 3, 3, - COGL_EXT_IN_GLES3, - "ARB:\0", - "sampler_objects\0") -COGL_EXT_FUNCTION (void, glGenSamplers, - (GLsizei count, - GLuint *samplers)) -COGL_EXT_FUNCTION (void, glDeleteSamplers, - (GLsizei count, - const GLuint *samplers)) -COGL_EXT_FUNCTION (void, glBindSampler, - (GLuint unit, - GLuint sampler)) -COGL_EXT_FUNCTION (void, glSamplerParameteri, - (GLuint sampler, - GLenum pname, - GLint param)) -COGL_EXT_END () - -COGL_EXT_BEGIN (only_gl3, 3, 0, - COGL_EXT_IN_GLES3, - "\0", - "\0") -COGL_EXT_FUNCTION (const GLubyte *, glGetStringi, - (GLenum name, GLuint index)) -COGL_EXT_END () - -COGL_EXT_BEGIN (vertex_array_object, 3, 0, - COGL_EXT_IN_GLES3, - "ARB\0OES\0", - "vertex_array_object\0") -COGL_EXT_FUNCTION (void, glBindVertexArray, - (GLuint array)) -COGL_EXT_FUNCTION (void, glGenVertexArrays, - (GLsizei n, - GLuint *arrays)) -COGL_EXT_END () - -COGL_EXT_BEGIN (map_region, 3, 0, - COGL_EXT_IN_GLES3, - "ARB:\0", - "map_buffer_range\0") -COGL_EXT_FUNCTION (GLvoid *, glMapBufferRange, - (GLenum target, - GLintptr offset, - GLsizeiptr length, - GLbitfield access)) -COGL_EXT_END () - -#ifdef GL_ARB_sync -COGL_EXT_BEGIN (sync, 3, 2, - COGL_EXT_IN_GLES3, - "ARB:\0", - "sync\0") -COGL_EXT_FUNCTION (GLsync, glFenceSync, - (GLenum condition, GLbitfield flags)) -COGL_EXT_FUNCTION (GLenum, glClientWaitSync, - (GLsync sync, GLbitfield flags, GLuint64 timeout)) -COGL_EXT_FUNCTION (void, glDeleteSync, - (GLsync sync)) -COGL_EXT_END () -#endif - -COGL_EXT_BEGIN (sync_get_int64, 3, 2, - 0, - "ARB:\0", - "sync\0") -COGL_EXT_FUNCTION (void, glGetInteger64v, - (GLenum pname, GLint64 *params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (draw_buffers, 2, 0, - COGL_EXT_IN_GLES3, - "ARB\0EXT\0", - "draw_buffers\0") -COGL_EXT_FUNCTION (void, glDrawBuffers, - (GLsizei n, const GLenum *bufs)) -COGL_EXT_END () - -COGL_EXT_BEGIN (robustness, 255, 255, - 0, - "ARB\0", - "robustness\0") -COGL_EXT_FUNCTION (GLenum, glGetGraphicsResetStatus, - (void)) -COGL_EXT_END () - -COGL_EXT_BEGIN (multitexture_part1, 1, 3, - 0, - "ARB\0", - "multitexture\0") -COGL_EXT_FUNCTION (void, glClientActiveTexture, - (GLenum texture)) -COGL_EXT_END () - -COGL_EXT_BEGIN (query_counter, 3, 3, - 0, - "ARB:\0", - "timer_query\0") -COGL_EXT_FUNCTION (void, glQueryCounter, - (GLuint id, GLenum target)) -COGL_EXT_FUNCTION (void, glGetQueryObjecti64v, - (GLuint id, GLenum pname, GLint64 *params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (queries, 1, 5, - 0, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glGenQueries, - (GLsizei n, GLuint *ids)) -COGL_EXT_FUNCTION (void, glDeleteQueries, - (GLsizei n, const GLuint *ids)) -COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-core-functions.h b/cogl/cogl/gl-prototypes/cogl-core-functions.h deleted file mode 100644 index e04b443ae..000000000 --- a/cogl/cogl/gl-prototypes/cogl-core-functions.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* These are the core GL functions which we assume will always be - available */ -COGL_EXT_BEGIN (core, - 0, 0, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glActiveTexture, - (GLenum texture)) -COGL_EXT_FUNCTION (void, glBindBuffer, - (GLenum target, - GLuint buffer)) -COGL_EXT_FUNCTION (void, glBindTexture, - (GLenum target, GLuint texture)) -COGL_EXT_FUNCTION (void, glBufferData, - (GLenum target, - GLsizeiptr size, - const GLvoid *data, - GLenum usage)) -COGL_EXT_FUNCTION (void, glBufferSubData, - (GLenum target, - GLintptr offset, - GLsizeiptr size, - const GLvoid *data)) -COGL_EXT_FUNCTION (void, glClear, - (GLbitfield mask)) -COGL_EXT_FUNCTION (void, glClearColor, - (GLclampf red, - GLclampf green, - GLclampf blue, - GLclampf alpha)) -COGL_EXT_FUNCTION (void, glClearStencil, - (GLint s)) -COGL_EXT_FUNCTION (void, glColorMask, - (GLboolean red, - GLboolean green, - GLboolean blue, - GLboolean alpha)) -COGL_EXT_FUNCTION (void, glCopyTexSubImage2D, - (GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint x, - GLint y, - GLsizei width, - GLsizei height)) -COGL_EXT_FUNCTION (void, glDeleteBuffers, - (GLsizei n, - const GLuint *buffers)) -COGL_EXT_FUNCTION (void, glDeleteTextures, - (GLsizei n, const GLuint* textures)) -COGL_EXT_FUNCTION (void, glDepthFunc, - (GLenum func)) -COGL_EXT_FUNCTION (void, glDepthMask, - (GLboolean flag)) -COGL_EXT_FUNCTION (void, glDisable, - (GLenum cap)) -COGL_EXT_FUNCTION (void, glDrawArrays, - (GLenum mode, GLint first, GLsizei count)) -COGL_EXT_FUNCTION (void, glDrawElements, - (GLenum mode, - GLsizei count, - GLenum type, - const GLvoid* indices)) -COGL_EXT_FUNCTION (void, glEnable, - (GLenum cap)) -COGL_EXT_FUNCTION (void, glFinish, - (void)) -COGL_EXT_FUNCTION (void, glFlush, - (void)) -COGL_EXT_FUNCTION (void, glFrontFace, - (GLenum mode)) -COGL_EXT_FUNCTION (void, glCullFace, - (GLenum mode)) -COGL_EXT_FUNCTION (void, glGenBuffers, - (GLsizei n, - GLuint *buffers)) -COGL_EXT_FUNCTION (void, glGenTextures, - (GLsizei n, GLuint* textures)) -COGL_EXT_FUNCTION (GLenum, glGetError, - (void)) -COGL_EXT_FUNCTION (void, glGetIntegerv, - (GLenum pname, GLint* params)) -COGL_EXT_FUNCTION (const GLubyte*, glGetString, - (GLenum name)) -COGL_EXT_FUNCTION (GLboolean, glIsTexture, - (GLuint texture)) -COGL_EXT_FUNCTION (void, glPixelStorei, - (GLenum pname, GLint param)) -COGL_EXT_FUNCTION (void, glReadPixels, - (GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glScissor, - (GLint x, GLint y, GLsizei width, GLsizei height)) -COGL_EXT_FUNCTION (void, glStencilFunc, - (GLenum func, GLint ref, GLuint mask)) -COGL_EXT_FUNCTION (void, glStencilMask, - (GLuint mask)) -COGL_EXT_FUNCTION (void, glStencilOp, - (GLenum fail, GLenum zfail, GLenum zpass)) -COGL_EXT_FUNCTION (void, glTexImage2D, - (GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLint border, - GLenum format, - GLenum type, - const GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glTexParameteri, - (GLenum target, GLenum pname, GLint param)) -COGL_EXT_FUNCTION (void, glTexParameteriv, - (GLenum target, GLenum pname, const GLint* params)) -COGL_EXT_FUNCTION (void, glTexSubImage2D, - (GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid* pixels)) -COGL_EXT_FUNCTION (void, glViewport, - (GLint x, GLint y, GLsizei width, GLsizei height)) -COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-gles2-functions.h b/cogl/cogl/gl-prototypes/cogl-gles2-functions.h deleted file mode 100644 index aeb57a487..000000000 --- a/cogl/cogl/gl-prototypes/cogl-gles2-functions.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* The functions in this file are part of the core GL,GLES1 and GLES2 apis */ -#include "cogl-core-functions.h" - -/* The functions in this file are core to GLES1 and GLES2 but not core - * to GL but they may be extensions available for GL */ -#include "cogl-in-gles-core-functions.h" - -/* The functions in this file are core to GLES2 only but - * may be extensions for GLES1 and GL */ -#include "cogl-in-gles2-core-functions.h" - -/* These are APIs for using GLSL used by GL and GLES2 */ -#include "cogl-glsl-functions.h" diff --git a/cogl/cogl/gl-prototypes/cogl-glsl-functions.h b/cogl/cogl/gl-prototypes/cogl-glsl-functions.h deleted file mode 100644 index a918ad866..000000000 --- a/cogl/cogl/gl-prototypes/cogl-glsl-functions.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -/* This lists functions that are unique to GL 2.0 or GLES 2.0 and are - * not in the old GLSL extensions */ -COGL_EXT_BEGIN (shaders_glsl_2_only, 2, 0, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (GLuint, glCreateProgram, - (void)) -COGL_EXT_FUNCTION (GLuint, glCreateShader, - (GLenum shaderType)) -COGL_EXT_FUNCTION (void, glDeleteShader, - (GLuint shader)) -COGL_EXT_FUNCTION (void, glAttachShader, - (GLuint program, - GLuint shader)) -COGL_EXT_FUNCTION (void, glUseProgram, - (GLuint program)) -COGL_EXT_FUNCTION (void, glDeleteProgram, - (GLuint program)) -COGL_EXT_FUNCTION (void, glGetShaderInfoLog, - (GLuint shader, - GLsizei maxLength, - GLsizei *length, - char *infoLog)) -COGL_EXT_FUNCTION (void, glGetProgramInfoLog, - (GLuint program, - GLsizei bufSize, - GLsizei *length, - char *infoLog)) -COGL_EXT_FUNCTION (void, glGetShaderiv, - (GLuint shader, - GLenum pname, - GLint *params)) -COGL_EXT_FUNCTION (void, glGetProgramiv, - (GLuint program, - GLenum pname, - GLint *params)) -COGL_EXT_END () - -/* These functions are provided by GL_ARB_shader_objects or are in GL - * 2.0 core */ -COGL_EXT_BEGIN (shader_objects_or_gl2, 2, 0, - COGL_EXT_IN_GLES2, - "ARB\0", - "shader_objects\0") -COGL_EXT_FUNCTION (void, glShaderSource, - (GLuint shader, - GLsizei count, - const char * const *string, - const GLint *length)) -COGL_EXT_FUNCTION (void, glCompileShader, - (GLuint shader)) -COGL_EXT_FUNCTION (void, glLinkProgram, - (GLuint program)) -COGL_EXT_FUNCTION (GLint, glGetUniformLocation, - (GLuint program, - const char *name)) -COGL_EXT_FUNCTION (void, glUniform1f, - (GLint location, - GLfloat v0)) -COGL_EXT_FUNCTION (void, glUniform1fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform2fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform3fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform4fv, - (GLint location, - GLsizei count, - const GLfloat * value)) -COGL_EXT_FUNCTION (void, glUniform1i, - (GLint location, - GLint v0)) -COGL_EXT_FUNCTION (void, glUniform1iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniform2iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniform3iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniform4iv, - (GLint location, - GLsizei count, - const GLint * value)) -COGL_EXT_FUNCTION (void, glUniformMatrix2fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_EXT_FUNCTION (void, glUniformMatrix3fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_EXT_FUNCTION (void, glUniformMatrix4fv, - (GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value)) -COGL_EXT_END () - -/* These functions are provided by GL_ARB_vertex_shader or are in GL - * 2.0 core */ -COGL_EXT_BEGIN (vertex_shaders, 2, 0, - COGL_EXT_IN_GLES2, - "ARB\0", - "vertex_shader\0") -COGL_EXT_FUNCTION (void, glVertexAttribPointer, - (GLuint index, - GLint size, - GLenum type, - GLboolean normalized, - GLsizei stride, - const GLvoid *pointer)) -COGL_EXT_FUNCTION (void, glEnableVertexAttribArray, - (GLuint index)) -COGL_EXT_FUNCTION (void, glDisableVertexAttribArray, - (GLuint index)) -COGL_EXT_FUNCTION (void, glVertexAttrib1fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib2fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib3fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (void, glVertexAttrib4f, - (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)) -COGL_EXT_FUNCTION (void, glVertexAttrib4fv, - (GLuint indx, const GLfloat* values)) -COGL_EXT_FUNCTION (GLint, glGetAttribLocation, - (GLuint program, const char *name)) -COGL_EXT_FUNCTION (void, glBindAttribLocation, - (GLuint program, - GLuint index, - const GLchar* name)) -COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h b/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h deleted file mode 100644 index b298bceb8..000000000 --- a/cogl/cogl/gl-prototypes/cogl-in-gles-core-functions.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -COGL_EXT_BEGIN (only_in_both_gles, - 4, 1, - COGL_EXT_IN_GLES2, - "ARB\0", - "ES2_compatibility\0") -COGL_EXT_FUNCTION (void, glDepthRangef, - (GLfloat near_val, GLfloat far_val)) -COGL_EXT_END () diff --git a/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h b/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h deleted file mode 100644 index 113b99b86..000000000 --- a/cogl/cogl/gl-prototypes/cogl-in-gles2-core-functions.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2009, 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This is included multiple times with different definitions for - * these macros. The macros are given the following arguments: - * - * COGL_EXT_BEGIN: - * - * @name: a unique symbol name for this feature - * - * @min_gl_major: the major part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * @min_gl_minor: the minor part of the minimum GL version where these - * functions are available in core, or 255 if it isn't available in - * any version. - * - * @gles_availability: flags to specify which versions of GLES the - * functions are available in. Should be a combination of - * COGL_EXT_IN_GLES and COGL_EXT_IN_GLES2. - * - * @extension_suffixes: A zero-separated list of suffixes in a - * string. These are appended to the extension name to get a complete - * extension name to try. The suffix is also appended to all of the - * function names. The suffix can optionally include a ':' to specify - * an alternate suffix for the function names. - * - * @extension_names: A list of extension names to try. If any of these - * extensions match then it will be used. - */ - -COGL_EXT_BEGIN (offscreen, - 3, 0, - COGL_EXT_IN_GLES2, - /* for some reason the ARB version of this - extension doesn't have an ARB suffix for the - functions */ - "ARB:\0EXT\0OES\0", - "framebuffer_object\0") -COGL_EXT_FUNCTION (void, glGenRenderbuffers, - (GLsizei n, - GLuint *renderbuffers)) -COGL_EXT_FUNCTION (void, glDeleteRenderbuffers, - (GLsizei n, - const GLuint *renderbuffers)) -COGL_EXT_FUNCTION (void, glBindRenderbuffer, - (GLenum target, - GLuint renderbuffer)) -COGL_EXT_FUNCTION (void, glRenderbufferStorage, - (GLenum target, - GLenum internalformat, - GLsizei width, - GLsizei height)) -COGL_EXT_FUNCTION (void, glGenFramebuffers, - (GLsizei n, - GLuint *framebuffers)) -COGL_EXT_FUNCTION (void, glBindFramebuffer, - (GLenum target, - GLuint framebuffer)) -COGL_EXT_FUNCTION (void, glFramebufferTexture2D, - (GLenum target, - GLenum attachment, - GLenum textarget, - GLuint texture, - GLint level)) -COGL_EXT_FUNCTION (void, glFramebufferRenderbuffer, - (GLenum target, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer)) -COGL_EXT_FUNCTION (GLenum, glCheckFramebufferStatus, - (GLenum target)) -COGL_EXT_FUNCTION (void, glDeleteFramebuffers, - (GLsizei n, - const GLuint *framebuffers)) -COGL_EXT_FUNCTION (void, glGenerateMipmap, - (GLenum target)) -COGL_EXT_FUNCTION (void, glGetFramebufferAttachmentParameteriv, - (GLenum target, - GLenum attachment, - GLenum pname, - GLint *params)) -COGL_EXT_END () - -COGL_EXT_BEGIN (blending, 1, 2, - COGL_EXT_IN_GLES2, - "\0", - "\0") -COGL_EXT_FUNCTION (void, glBlendColor, - (GLclampf red, - GLclampf green, - GLclampf blue, - GLclampf alpha)) -COGL_EXT_END () - -/* Optional, declared in 1.4 or GLES 1.2 */ -COGL_EXT_BEGIN (blend_func_separate, 1, 4, - COGL_EXT_IN_GLES2, - "EXT\0", - "blend_func_separate\0") -COGL_EXT_FUNCTION (void, glBlendFuncSeparate, - (GLenum srcRGB, - GLenum dstRGB, - GLenum srcAlpha, - GLenum dstAlpha)) -COGL_EXT_END () - -/* Optional, declared in 2.0 */ -COGL_EXT_BEGIN (blend_equation_separate, 2, 0, - COGL_EXT_IN_GLES2, - "EXT\0", - "blend_equation_separate\0") -COGL_EXT_FUNCTION (void, glBlendEquationSeparate, - (GLenum modeRGB, - GLenum modeAlpha)) -COGL_EXT_END () diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build deleted file mode 100644 index a76b9685c..000000000 --- a/cogl/cogl/meson.build +++ /dev/null @@ -1,514 +0,0 @@ -cogl_cogl_includesubdir = join_paths(cogl_includesubdir, 'cogl') -cogl_cogl_includedir = join_paths(cogl_includedir, 'cogl') - -cdata = configuration_data() -cdata.set('COGL_HAS_GL', have_gl) -cdata.set('CLUTTER_COGL_HAS_GL', have_gl) -cdata.set('COGL_HAS_GLX_SUPPORT', have_glx) -cdata.set('COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT', have_wayland) -cdata.set('COGL_HAS_EGL_PLATFORM_XLIB_SUPPORT', have_egl_xlib) -cdata.set('COGL_HAS_EGL_SUPPORT', have_egl) -cdata.set('COGL_HAS_X11', have_x11) -cdata.set('COGL_HAS_X11_SUPPORT', have_x11) -cdata.set('COGL_HAS_XLIB', have_x11) -cdata.set('COGL_HAS_XLIB_SUPPORT', have_x11) -cdata.set('COGL_HAS_TRACING', have_profiler) - -cogl_defines_h = configure_file( - input: 'cogl-defines.h.meson', - output: 'cogl-defines.h', - configuration: cdata, - install_dir: cogl_cogl_includedir, - install: true, -) - -if have_gl - cogl_gl_header_includes = ['GL/gl.h'] -elif have_gles2 - cogl_gl_header_includes = ['GLES2/gl2.h', 'GLES2/gl2ext.h'] -else - error('Neither GLES2 or OpenGL was enabled') -endif - -cogl_gl_header_includes_string = '' -foreach gl_header : cogl_gl_header_includes - cogl_gl_header_includes_string += '#include <@0@>\n'.format(gl_header) -endforeach - -built_headers = [] - -cdata = configuration_data() -cdata.set('COGL_GL_HEADER_INCLUDES', cogl_gl_header_includes_string) - -cogl_gl_header_h = configure_file( - input: 'cogl-gl-header.h.in', - output: 'cogl-gl-header.h', - configuration: cdata, - install: false, -) -built_headers += [cogl_gl_header_h] - -if have_egl - cogl_egl_includes_string = '#include <EGL/egl.h>\n#include <EGL/eglext.h>\n#include <EGL/eglmesaext.h>' -else - cogl_egl_includes_string = '' -endif - -cdata = configuration_data() -cdata.set('COGL_EGL_INCLUDES', cogl_egl_includes_string) -cogl_egl_defines_h = configure_file( - input: 'cogl-egl-defines.h.in', - output: 'cogl-egl-defines.h', - configuration: cdata, - install: false, -) -built_headers += [cogl_gl_header_h] - -cogl_deprecated_headers = [ - 'deprecated/cogl-material-compat.h', - 'deprecated/cogl-shader.h', - 'deprecated/cogl-clutter.h', - 'deprecated/cogl-type-casts.h', - 'deprecated/cogl-auto-texture.h', -] - -cogl_headers = [ - 'cogl1-context.h', - 'cogl-bitmap.h', - 'cogl-color.h', - 'cogl-context.h', - 'cogl-frame-info.h', - 'cogl-framebuffer.h', - 'cogl-object.h', - 'cogl-offscreen.h', - 'cogl-onscreen.h', - 'cogl-pipeline.h', - 'cogl-pipeline-state.h', - 'cogl-pipeline-layer-state.h', - 'cogl-pixel-format.h', - 'cogl-texture.h', - 'cogl-texture-2d.h', - 'cogl-texture-2d-sliced.h', - 'cogl-types.h', - 'cogl-trace.h', - 'cogl.h', -] - -cogl_nonintrospected_headers = [ - 'cogl-renderer.h', - 'cogl-swap-chain.h', - 'cogl-onscreen-template.h', - 'cogl-dma-buf-handle.h', - 'cogl-display.h', - 'cogl-snippet.h', - 'cogl-index-buffer.h', - 'cogl-attribute-buffer.h', - 'cogl-indices.h', - 'cogl-attribute.h', - 'cogl-primitive.h', - 'cogl-output.h', - 'cogl-matrix-stack.h', - 'cogl-poll.h', - 'cogl-sub-texture.h', - 'cogl-atlas-texture.h', - 'cogl-meta-texture.h', - 'cogl-primitive-texture.h', - 'cogl-depth-state.h', - 'cogl-buffer.h', - 'cogl-pixel-buffer.h', - 'cogl-macros.h', - 'cogl-fence.h', - 'cogl-version.h', - 'cogl-gtype-private.h', - 'cogl-glib-source.h', - 'cogl-scanout.h', - 'cogl-graphene.h', -] - -cogl_nodist_headers = [ -] - -cogl_noop_driver_sources = [ - 'driver/nop/cogl-driver-nop.c', - 'driver/nop/cogl-nop-framebuffer.c', - 'driver/nop/cogl-nop-framebuffer.h', - 'driver/nop/cogl-attribute-nop-private.h', - 'driver/nop/cogl-attribute-nop.c', - 'driver/nop/cogl-clip-stack-nop-private.h', - 'driver/nop/cogl-clip-stack-nop.c', - 'driver/nop/cogl-texture-2d-nop-private.h', - 'driver/nop/cogl-texture-2d-nop.c', -] - -cogl_gl_prototype_headers = [ - 'gl-prototypes/cogl-gles2-functions.h', - 'gl-prototypes/cogl-core-functions.h', - 'gl-prototypes/cogl-in-gles-core-functions.h', - 'gl-prototypes/cogl-in-gles2-core-functions.h', - 'gl-prototypes/cogl-glsl-functions.h', -] - -cogl_common_driver_sources = [ - 'driver/gl/cogl-util-gl-private.h', - 'driver/gl/cogl-util-gl.c', - 'driver/gl/cogl-framebuffer-gl-private.h', - 'driver/gl/cogl-framebuffer-gl.c', - 'driver/gl/cogl-gl-framebuffer-back.c', - 'driver/gl/cogl-gl-framebuffer-back.h', - 'driver/gl/cogl-gl-framebuffer-fbo.c', - 'driver/gl/cogl-gl-framebuffer-fbo.h', - 'driver/gl/cogl-texture-gl-private.h', - 'driver/gl/cogl-texture-gl.c', - 'driver/gl/cogl-texture-2d-gl-private.h', - 'driver/gl/cogl-texture-2d-gl.c', - 'driver/gl/cogl-attribute-gl-private.h', - 'driver/gl/cogl-attribute-gl.c', - 'driver/gl/cogl-clip-stack-gl-private.h', - 'driver/gl/cogl-clip-stack-gl.c', - 'driver/gl/cogl-buffer-gl-private.h', - 'driver/gl/cogl-buffer-gl.c', - 'driver/gl/cogl-bitmap-gl-private.h', - 'driver/gl/cogl-bitmap-gl.c', - 'driver/gl/cogl-pipeline-opengl.c', - 'driver/gl/cogl-pipeline-opengl-private.h', - 'driver/gl/cogl-pipeline-fragend-glsl.c', - 'driver/gl/cogl-pipeline-fragend-glsl-private.h', - 'driver/gl/cogl-pipeline-vertend-glsl.c', - 'driver/gl/cogl-pipeline-vertend-glsl-private.h', - 'driver/gl/cogl-pipeline-progend-glsl.c', - 'driver/gl/cogl-pipeline-progend-glsl-private.h', -] - -gl_driver_sources = [ - 'driver/gl/gl/cogl-driver-gl.c', - 'driver/gl/gl/cogl-texture-driver-gl.c', -] - -gles_driver_sources = [ - 'driver/gl/gles/cogl-driver-gles.c', - 'driver/gl/gles/cogl-texture-driver-gles.c', -] - -cogl_driver_sources = [ - cogl_noop_driver_sources, - cogl_common_driver_sources, -] - -if have_gl - cogl_driver_sources += gl_driver_sources -endif - -if have_gles2 - cogl_driver_sources += gles_driver_sources -endif - -cogl_sources = [ - cogl_driver_sources, - - 'winsys/cogl-winsys-private.h', - 'winsys/cogl-winsys.c', - 'cogl-private.h', - 'cogl-i18n-private.h', - 'cogl-debug.h', - 'cogl-debug-options.h', - 'cogl-dma-buf-handle.c', - 'cogl-context-private.h', - 'cogl-context.c', - 'cogl-renderer-private.h', - 'cogl-renderer.h', - 'cogl-renderer.c', - 'cogl-swap-chain-private.h', - 'cogl-swap-chain.h', - 'cogl-swap-chain.c', - 'cogl-onscreen-template-private.h', - 'cogl-onscreen-template.h', - 'cogl-onscreen-template.c', - 'cogl-display-private.h', - 'cogl-display.h', - 'cogl-display.c', - 'cogl-driver.h', - 'cogl.c', - 'cogl-pixel-format.c', - 'cogl-object-private.h', - 'cogl-object.h', - 'cogl-object.c', - 'cogl-util.h', - 'cogl-util.c', - 'cogl-bitmap-private.h', - 'cogl-bitmap.c', - 'cogl-bitmap-conversion.c', - 'cogl-bitmap-packing.h', - 'cogl-primitives-private.h', - 'cogl-primitives.c', - 'cogl-bitmap-pixbuf.c', - 'cogl-clip-stack.h', - 'cogl-clip-stack.c', - 'cogl-feature-private.h', - 'cogl-feature-private.c', - 'cogl-color-private.h', - 'cogl-color.c', - 'cogl-buffer-private.h', - 'cogl-buffer.c', - 'cogl-pixel-buffer-private.h', - 'cogl-pixel-buffer.c', - 'cogl-index-buffer-private.h', - 'cogl-index-buffer.c', - 'cogl-attribute-buffer-private.h', - 'cogl-attribute-buffer.c', - 'cogl-indices-private.h', - 'cogl-indices.c', - 'cogl-attribute-private.h', - 'cogl-attribute.c', - 'cogl-primitive-private.h', - 'cogl-primitive.c', - 'cogl-matrix-stack.c', - 'cogl-matrix-stack-private.h', - 'cogl-depth-state.c', - 'cogl-depth-state-private.h', - 'cogl-node.c', - 'cogl-node-private.h', - 'cogl-pipeline.c', - 'cogl-pipeline-private.h', - 'cogl-pipeline-layer.c', - 'cogl-pipeline-layer-private.h', - 'cogl-pipeline-state.c', - 'cogl-pipeline-layer-state-private.h', - 'cogl-pipeline-layer-state.c', - 'cogl-pipeline-state-private.h', - 'cogl-pipeline-debug.c', - 'cogl-glsl-shader-boilerplate.h', - 'cogl-pipeline-snippet-private.h', - 'cogl-pipeline-snippet.c', - 'cogl-pipeline-cache.h', - 'cogl-pipeline-cache.c', - 'cogl-pipeline-hash-table.h', - 'cogl-pipeline-hash-table.c', - 'cogl-sampler-cache.c', - 'cogl-sampler-cache-private.h', - 'cogl-blend-string.c', - 'cogl-blend-string.h', - 'cogl-debug.c', - 'cogl-trace.c', - 'cogl-sub-texture-private.h', - 'cogl-texture-private.h', - 'cogl-texture-2d-private.h', - 'cogl-texture-2d-sliced-private.h', - 'cogl-texture-driver.h', - 'cogl-sub-texture.c', - 'cogl-texture.c', - 'cogl-texture-2d.c', - 'cogl-texture-2d-sliced.c', - 'cogl-rectangle-map.h', - 'cogl-rectangle-map.c', - 'cogl-atlas.h', - 'cogl-atlas.c', - 'cogl-atlas-texture-private.h', - 'cogl-atlas-texture.c', - 'cogl-meta-texture.c', - 'cogl-primitive-texture.c', - 'cogl-blit.h', - 'cogl-blit.c', - 'cogl-spans.h', - 'cogl-spans.c', - 'cogl-journal-private.h', - 'cogl-journal.c', - 'cogl-offscreen-private.h', - 'cogl-offscreen.c', - 'cogl-frame-info-private.h', - 'cogl-frame-info.c', - 'cogl-framebuffer-driver.c', - 'cogl-framebuffer-driver.h', - 'cogl-framebuffer-private.h', - 'cogl-framebuffer.c', - 'cogl-onscreen-private.h', - 'cogl-onscreen.c', - 'cogl-output-private.h', - 'cogl-output.c', - 'cogl-profile.h', - 'cogl-profile.c', - 'cogl-flags.h', - 'cogl-bitmask.h', - 'cogl-bitmask.c', - 'cogl-gtype.c', - 'cogl-gtype-private.h', - 'cogl-point-in-poly-private.h', - 'cogl-point-in-poly.c', - 'cogl-list.c', - 'cogl-list.h', - 'cogl-boxed-value.h', - 'cogl-boxed-value.c', - 'cogl-snippet-private.h', - 'cogl-snippet.c', - 'cogl-poll-private.h', - 'cogl-poll.c', - 'gl-prototypes/cogl-all-functions.h', - 'cogl-memory-stack-private.h', - 'cogl-memory-stack.c', - 'cogl-magazine-private.h', - 'cogl-magazine.c', - 'cogl-closure-list-private.h', - 'cogl-closure-list.c', - 'cogl-fence.c', - 'cogl-fence-private.h', - 'cogl-scanout.c', - 'deprecated/cogl-material-compat.c', - 'deprecated/cogl-program.c', - 'deprecated/cogl-program-private.h', - 'deprecated/cogl-auto-texture.c', - 'deprecated/cogl-shader-private.h', - 'deprecated/cogl-shader.c', - 'deprecated/cogl-clutter.c', - 'cogl-glib-source.c', - 'cogl-mutter.h', - 'cogl-graphene.c', -] - -if have_x11 - cogl_nonintrospected_headers += [ - 'winsys/cogl-texture-pixmap-x11.h', - 'cogl-xlib.h', - ] - cogl_sources += [ - 'cogl-x11-onscreen.c', - 'cogl-x11-onscreen.h', - 'cogl-x11-renderer-private.h', - 'cogl-xlib-private.h', - 'cogl-xlib-renderer-private.h', - 'cogl-xlib-renderer.c', - 'winsys/cogl-texture-pixmap-x11-private.h', - 'winsys/cogl-texture-pixmap-x11.c', - ] - cogl_headers += [ - 'cogl-xlib-renderer.h' - ] -endif - -if have_glx - cogl_nonintrospected_headers += [ - 'winsys/cogl-glx.h', - ] - cogl_sources += [ - 'winsys/cogl-glx-display-private.h', - 'winsys/cogl-glx-renderer-private.h', - 'winsys/cogl-onscreen-glx.c', - 'winsys/cogl-onscreen-glx.h', - 'winsys/cogl-winsys-glx-feature-functions.h', - 'winsys/cogl-winsys-glx-private.h', - 'winsys/cogl-winsys-glx.c', - ] -endif - -if have_wayland - cogl_nonintrospected_headers += [ - 'cogl-wayland-server.h', - ] -endif - -if have_egl - cogl_nonintrospected_headers += [ - 'cogl-egl.h', - cogl_egl_defines_h, - ] - cogl_sources += [ - 'cogl-egl-private.h', - 'winsys/cogl-onscreen-egl.c', - 'winsys/cogl-onscreen-egl.h', - 'winsys/cogl-winsys-egl.c', - 'winsys/cogl-winsys-egl-feature-functions.h', - 'winsys/cogl-winsys-egl-private.h', - ] -endif - -if have_egl_xlib - cogl_sources += [ - 'winsys/cogl-onscreen-xlib.c', - 'winsys/cogl-onscreen-xlib.h', - 'winsys/cogl-winsys-egl-x11.c', - 'winsys/cogl-winsys-egl-x11-private.h', - ] -endif - -cogl_introspected_headers = [ - cogl_headers, - cogl_deprecated_headers, -] - -cogl_headers_all = [ - cogl_introspected_headers, - cogl_nonintrospected_headers, - cogl_deprecated_headers, -] - -cogl_test_deps = [] - -if have_cogl_tests - cogl_test_deps += [libmutter_cogl_test_fixtures_dep] -endif - -libmutter_cogl_name = 'mutter-cogl-' + libmutter_api_version -libmutter_cogl = shared_library(libmutter_cogl_name, - sources: [cogl_sources, cogl_headers_all], - version: '0.0.0', - soversion: 0, - c_args: cogl_c_args, - include_directories: cogl_includepath, - dependencies: [cogl_deps, cogl_test_deps], - gnu_symbol_visibility: 'hidden', - install_rpath: pkglibdir, - install_dir: pkglibdir, - install: true, -) -libmutter_cogl_dep = declare_dependency( - dependencies: [cogl_deps], - link_with: libmutter_cogl, -) - -if have_introspection - libmutter_cogl_gir = gnome.generate_gir(libmutter_cogl, - sources: cogl_introspected_headers, - nsversion: libmutter_api_version, - namespace: 'Cogl', - includes: ['cairo-1.0', 'GL-1.0', 'GObject-2.0', 'Graphene-1.0'], - dependencies: [cogl_deps], - extra_args: introspection_args + [ - '-UCOGL_COMPILATION', - '-D__COGL_H_INSIDE__', - '-D__COGL_XLIB_H_INSIDE__', - '-D__COGL_EGL_H_INSIDE__', - '-D__COGL_GLX_H_INSIDE__', - '-DCOGL_GIR_SCANNING', - ], - header: 'cogl/cogl.h', - install_dir_gir: pkglibdir, - install_dir_typelib: pkglibdir, - install: true - ) -endif - -install_headers([ - cogl_headers, - cogl_nonintrospected_headers, - ], - subdir: cogl_cogl_includesubdir) - -install_headers([ - cogl_deprecated_headers, - ], - subdir: join_paths(cogl_cogl_includesubdir, 'deprecated')) - -install_headers(cogl_gl_prototype_headers, - subdir: join_paths(cogl_cogl_includesubdir, 'gl-prototypes')) - -pkg.generate(libmutter_cogl, - name: 'Cogl', - filebase: libmutter_cogl_name, - description: 'An object oriented GL/GLES Abstraction/Utility Layer in mutter', - libraries: [m_dep], - subdirs: join_paths(pkgname, 'cogl'), - requires: [cogl_pkg_deps], - version: meson.project_version(), - variables: [ - 'apiversion=' + libmutter_api_version, - ], - install_dir: pcdir, -) diff --git a/cogl/cogl/mutter-cogl.pc.in b/cogl/cogl/mutter-cogl.pc.in deleted file mode 100644 index 797eef3d2..000000000 --- a/cogl/cogl/mutter-cogl.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -apiversion=@LIBMUTTER_API_VERSION@ -libdir=@libdir@/mutter-${apiversion} -includedir=@includedir@/mutter-${apiversion} -requires=@COGL_PKG_REQUIRES@ - -Name: Cogl -Description: An object oriented GL/GLES Abstraction/Utility Layer -Version: @MUTTER_VERSION@ -Libs: -L${libdir} -lmutter-cogl-${apiversion} -Cflags: -I${includedir}/cogl -Requires: ${requires} diff --git a/cogl/cogl/winsys/cogl-glx-display-private.h b/cogl/cogl/winsys/cogl-glx-display-private.h deleted file mode 100644 index f931b1764..000000000 --- a/cogl/cogl/winsys/cogl-glx-display-private.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_DISPLAY_GLX_PRIVATE_H -#define __COGL_DISPLAY_GLX_PRIVATE_H - -#include "cogl-object-private.h" - -typedef struct _CoglGLXCachedConfig -{ - /* This will be -1 if there is no cached config in this slot */ - int depth; - gboolean found; - GLXFBConfig fb_config; - gboolean stereo; - gboolean can_mipmap; -} CoglGLXCachedConfig; - -#define COGL_GLX_N_CACHED_CONFIGS 6 - -typedef struct _CoglGLXDisplay -{ - CoglGLXCachedConfig glx_cached_configs[COGL_GLX_N_CACHED_CONFIGS]; - - gboolean found_fbconfig; - gboolean is_direct; - gboolean have_vblank_counter; - gboolean can_vblank_wait; - GLXFBConfig fbconfig; - - /* Single context for all wins */ - GLXContext glx_context; - GLXWindow dummy_glxwin; - Window dummy_xwin; -} CoglGLXDisplay; - -#endif /* __COGL_DISPLAY_GLX_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-glx-renderer-private.h b/cogl/cogl/winsys/cogl-glx-renderer-private.h deleted file mode 100644 index 64ccf7c90..000000000 --- a/cogl/cogl/winsys/cogl-glx-renderer-private.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_RENDERER_GLX_PRIVATE_H -#define __COGL_RENDERER_GLX_PRIVATE_H - -#include <gmodule.h> -#include "cogl-object-private.h" -#include "cogl-xlib-renderer-private.h" - -typedef struct _CoglGLXRenderer -{ - int glx_major; - int glx_minor; - - int glx_error_base; - int glx_event_base; - - /* Vblank stuff */ - int dri_fd; - - /* enumeration with relatioship between OML_sync_control - * UST (unadjusted-system-time) and the system clock */ - enum -{ - COGL_GLX_UST_IS_UNKNOWN, - COGL_GLX_UST_IS_GETTIMEOFDAY, - COGL_GLX_UST_IS_MONOTONIC_TIME, - COGL_GLX_UST_IS_OTHER - } ust_type; - - /* GModule pointing to libGL which we use to get glX functions out of */ - GModule *libgl_module; - - CoglClosure *flush_notifications_idle; - - /* Copy of the winsys features that are based purely on the - * information we can get without using a GL context. We want to - * determine this before we have a context so that we can use the - * function pointers from the extensions earlier. This is necessary - * to use the glXCreateContextAttribs function. */ - unsigned long base_winsys_features - [COGL_FLAGS_N_LONGS_FOR_SIZE (COGL_WINSYS_FEATURE_N_FEATURES)]; - - /* Function pointers for core GLX functionality. We can't just link - against these directly because we need to conditionally load - libGL when we are using GLX so that it won't conflict with a GLES - library if we are using EGL + GLES. These are just the functions - that we want to use before calling glXGetProcAddress */ - Bool - (* glXQueryExtension) (Display *dpy, int *errorb, int *event); - const char * - (* glXQueryExtensionsString) (Display *dpy, int screen); - Bool - (* glXQueryVersion) (Display *dpy, int *maj, int *min); - void * - (* glXGetProcAddress) (const GLubyte *procName); - - int - (* glXQueryDrawable) (Display *dpy, GLXDrawable drawable, - int attribute, unsigned int *value); - - /* Function pointers for GLX specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "winsys/cogl-winsys-glx-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglGLXRenderer; - -#endif /* __COGL_RENDERER_GLX_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-glx.h b/cogl/cogl/winsys/cogl-glx.h deleted file mode 100644 index b04656981..000000000 --- a/cogl/cogl/winsys/cogl-glx.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Cogl - * - * A Low-Level GPU Graphics and Utilities API - * - * Copyright (C) 2014 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_GLX_H__ -#define __COGL_GLX_H__ - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_GLX_H_INSIDE__ */ -#ifndef __COGL_GLX_H_INSIDE__ -#define __COGL_GLX_H_INSIDE__ -#endif - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#endif - -#endif /* COGL_COMPILATION */ - - -#include <GL/glx.h> -#include <cogl/cogl-types.h> - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#warning -#undef __COGL_H_INSIDE__ -#undef __COGL_GLX_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_GLX_ -#endif - -#endif /* __COGL_GLX_H__ */ diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.c b/cogl/cogl/winsys/cogl-onscreen-egl.c deleted file mode 100644 index 20b3c60ef..000000000 --- a/cogl/cogl/winsys/cogl-onscreen-egl.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "cogl-config.h" - -#include "winsys/cogl-onscreen-egl.h" - -#include "cogl-context-private.h" -#include "cogl-frame-info-private.h" -#include "cogl-renderer-private.h" -#include "cogl-trace.h" -#include "winsys/cogl-winsys-egl-private.h" - -typedef struct _CoglOnscreenEglPrivate -{ - EGLSurface egl_surface; -} CoglOnscreenEglPrivate; - -G_DEFINE_TYPE_WITH_PRIVATE (CoglOnscreenEgl, cogl_onscreen_egl, - COGL_TYPE_ONSCREEN) - -gboolean -cogl_onscreen_egl_choose_config (CoglOnscreenEgl *onscreen_egl, - EGLConfig *out_egl_config, - GError **error) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen_egl); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - const CoglFramebufferConfig *config; - EGLint attributes[MAX_EGL_CONFIG_ATTRIBS]; - EGLConfig egl_config; - EGLint config_count = 0; - EGLBoolean status; - - config = cogl_framebuffer_get_config (framebuffer); - cogl_display_egl_determine_attributes (display, config, attributes); - - status = eglChooseConfig (egl_renderer->edpy, - attributes, - &egl_config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Failed to find a suitable EGL configuration"); - return FALSE; - } - - if (config->samples_per_pixel) - { - EGLint samples; - status = eglGetConfigAttrib (egl_renderer->edpy, - egl_config, - EGL_SAMPLES, &samples); - g_return_val_if_fail (status == EGL_TRUE, TRUE); - cogl_framebuffer_update_samples_per_pixel (framebuffer, samples); - } - - *out_egl_config = egl_config; - return TRUE; -} - -static void -cogl_onscreen_egl_dispose (GObject *object) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (object); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplayEGL *egl_display = context->display->winsys; - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - G_OBJECT_CLASS (cogl_onscreen_egl_parent_class)->dispose (object); - - if (priv->egl_surface != EGL_NO_SURFACE) - { - /* Cogl always needs a valid context bound to something so if we - * are destroying the onscreen that is currently bound we'll - * switch back to the dummy drawable. */ - if ((egl_display->dummy_surface != EGL_NO_SURFACE || - (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) != 0) && - (egl_display->current_draw_surface == priv->egl_surface || - egl_display->current_read_surface == priv->egl_surface)) - { - _cogl_winsys_egl_make_current (context->display, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->current_context); - } - - if (eglDestroySurface (egl_renderer->edpy, priv->egl_surface) - == EGL_FALSE) - g_warning ("Failed to destroy EGL surface"); - priv->egl_surface = EGL_NO_SURFACE; - } -} - -static void -bind_onscreen_with_context (CoglOnscreen *onscreen, - EGLContext egl_context) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - - gboolean status = _cogl_winsys_egl_make_current (context->display, - priv->egl_surface, - priv->egl_surface, - egl_context); - if (status) - { - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - eglSwapInterval (egl_renderer->edpy, 1); - } -} - -static void -cogl_onscreen_egl_bind (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplayEGL *egl_display = context->display->winsys; - - bind_onscreen_with_context (onscreen, egl_display->egl_context); -} - -#ifndef EGL_BUFFER_AGE_EXT -#define EGL_BUFFER_AGE_EXT 0x313D -#endif - -static int -cogl_onscreen_egl_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - CoglDisplayEGL *egl_display = context->display->winsys; - EGLSurface surface = priv->egl_surface; - static gboolean warned = FALSE; - int age = 0; - - if (!(egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)) - return 0; - - if (!_cogl_winsys_egl_make_current (context->display, - surface, surface, - egl_display->egl_context)) - return 0; - - if (!eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age)) - { - if (!warned) - g_critical ("Failed to query buffer age, got error %x", eglGetError ()); - warned = TRUE; - } - else - { - warned = FALSE; - } - - return age; -} - -static void -cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen, - const int *user_rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); - int i; - - /* eglSwapBuffersRegion expects rectangles relative to the - * bottom left corner but we are given rectangles relative to - * the top left so we need to flip them... */ - memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - rect[1] = framebuffer_height - rect[1] - rect[3]; - } - - /* At least for eglSwapBuffers the EGL spec says that the surface to - swap must be bound to the current context. It looks like Mesa - also validates that this is the case for eglSwapBuffersRegion so - we must bind here too */ - cogl_context_flush_framebuffer_state (context, - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER_STATE_BIND); - - if (egl_renderer->pf_eglSwapBuffersRegion (egl_renderer->edpy, - priv->egl_surface, - n_rectangles, - rectangles) == EGL_FALSE) - g_warning ("Error reported by eglSwapBuffersRegion"); -} - -static void -cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen); - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - COGL_TRACE_BEGIN_SCOPED (CoglOnscreenEGLSwapBuffersWithDamage, - "Onscreen (eglSwapBuffers)"); - - /* The specification for EGL (at least in 1.4) says that the surface - needs to be bound to the current context for the swap to work - although it may change in future. Mesa explicitly checks for this - and just returns an error if this is not the case so we can't - just pretend this isn't in the spec. */ - cogl_context_flush_framebuffer_state (context, - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER (onscreen), - COGL_FRAMEBUFFER_STATE_BIND); - - if (cogl_has_feature (context, COGL_FEATURE_ID_GET_GPU_TIME)) - { - info->gpu_time_before_buffer_swap_ns = - cogl_context_get_gpu_time_ns (context); - } - - info->cpu_time_before_buffer_swap_us = g_get_monotonic_time (); - - /* Set up a timestamp query for when all rendering will be finished. */ - if (cogl_has_feature (context, COGL_FEATURE_ID_TIMESTAMP_QUERY)) - { - info->timestamp_query = - cogl_framebuffer_create_timestamp_query (COGL_FRAMEBUFFER (onscreen)); - } - - if (n_rectangles && egl_renderer->pf_eglSwapBuffersWithDamage) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - size_t size = n_rectangles * sizeof (int) * 4; - int *flipped = alloca (size); - int i; - - memcpy (flipped, rectangles, size); - for (i = 0; i < n_rectangles; i++) - { - const int *rect = rectangles + 4 * i; - int *flip_rect = flipped + 4 * i; - - flip_rect[1] = - cogl_framebuffer_get_height (framebuffer) - rect[1] - rect[3]; - } - - if (egl_renderer->pf_eglSwapBuffersWithDamage (egl_renderer->edpy, - priv->egl_surface, - flipped, - n_rectangles) == EGL_FALSE) - g_warning ("Error reported by eglSwapBuffersWithDamage"); - } - else - eglSwapBuffers (egl_renderer->edpy, priv->egl_surface); -} - -void -cogl_onscreen_egl_set_egl_surface (CoglOnscreenEgl *onscreen_egl, - EGLSurface egl_surface) -{ - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - - priv->egl_surface = egl_surface; -} - -EGLSurface -cogl_onscreen_egl_get_egl_surface (CoglOnscreenEgl *onscreen_egl) -{ - CoglOnscreenEglPrivate *priv = - cogl_onscreen_egl_get_instance_private (onscreen_egl); - - return priv->egl_surface; -} - -static void -cogl_onscreen_egl_init (CoglOnscreenEgl *onscreen_egl) -{ -} - -static void -cogl_onscreen_egl_class_init (CoglOnscreenEglClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass); - - object_class->dispose = cogl_onscreen_egl_dispose; - - onscreen_class->bind = cogl_onscreen_egl_bind; - onscreen_class->swap_buffers_with_damage = - cogl_onscreen_egl_swap_buffers_with_damage; - onscreen_class->swap_region = cogl_onscreen_egl_swap_region; - onscreen_class->get_buffer_age = cogl_onscreen_egl_get_buffer_age; -} diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.h b/cogl/cogl/winsys/cogl-onscreen-egl.h deleted file mode 100644 index 08e798da0..000000000 --- a/cogl/cogl/winsys/cogl-onscreen-egl.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef COGL_ONSCREEN_EGL_H -#define COGL_ONSCREEN_EGL_H - -#include "cogl-onscreen.h" -#include "winsys/cogl-winsys-egl-private.h" - -#define COGL_TYPE_ONSCREEN_EGL (cogl_onscreen_egl_get_type ()) -COGL_EXPORT -G_DECLARE_DERIVABLE_TYPE (CoglOnscreenEgl, cogl_onscreen_egl, - COGL, ONSCREEN_EGL, - CoglOnscreen) - -struct _CoglOnscreenEglClass -{ - /*< private >*/ - CoglOnscreenClass parent_class; -}; - -COGL_EXPORT void -cogl_onscreen_egl_set_egl_surface (CoglOnscreenEgl *onscreen_egl, - EGLSurface egl_surface); - -COGL_EXPORT EGLSurface -cogl_onscreen_egl_get_egl_surface (CoglOnscreenEgl *onscreen_egl); - -gboolean -cogl_onscreen_egl_choose_config (CoglOnscreenEgl *onscreen_egl, - EGLConfig *out_egl_config, - GError **error); - -#endif /* COGL_ONSCREEN_EGL_H */ diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c deleted file mode 100644 index 8bbb508b7..000000000 --- a/cogl/cogl/winsys/cogl-onscreen-glx.c +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "cogl-config.h" - -#include "winsys/cogl-onscreen-glx.h" - -#include <GL/glx.h> -#include <sys/time.h> - -#include "cogl-context-private.h" -#include "cogl-frame-info-private.h" -#include "cogl-renderer-private.h" -#include "cogl-x11-onscreen.h" -#include "cogl-xlib-renderer-private.h" -#include "winsys/cogl-glx-display-private.h" -#include "winsys/cogl-glx-renderer-private.h" -#include "winsys/cogl-winsys-glx-private.h" - -struct _CoglOnscreenGlx -{ - CoglOnscreen parent; - - Window xwin; - int x, y; - CoglOutput *output; - - GLXDrawable glxwin; - uint32_t last_swap_vsync_counter; - uint32_t pending_sync_notify; - uint32_t pending_complete_notify; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL_TYPE_ONSCREEN, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - -static gboolean -cogl_onscreen_glx_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - Window xwin; - const CoglFramebufferConfig *config; - GLXFBConfig fbconfig; - GError *fbconfig_error = NULL; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - config = cogl_framebuffer_get_config (framebuffer); - if (!cogl_display_glx_find_fbconfig (display, config, - &fbconfig, - &fbconfig_error)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - /* Update the real number of samples_per_pixel now that we have - * found an fbconfig... */ - if (config->samples_per_pixel) - { - int samples; - int status = glx_renderer->glXGetFBConfigAttrib (xlib_renderer->xdpy, - fbconfig, - GLX_SAMPLES, - &samples); - g_return_val_if_fail (status == Success, TRUE); - cogl_framebuffer_update_samples_per_pixel (framebuffer, samples); - } - - /* FIXME: We need to explicitly Select for ConfigureNotify events. - * We need to document that for windows we create then toolkits - * must be careful not to clear event mask bits that we select. - */ - { - int width; - int height; - CoglXlibTrapState state; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - _cogl_xlib_renderer_trap_errors (display->renderer, &state); - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - fbconfig); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - return FALSE; - } - - /* window attributes */ - xattr.background_pixel = WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = _cogl_xlib_renderer_untrap_errors (display->renderer, &state); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return FALSE; - } - } - - onscreen_glx->xwin = xwin; - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - onscreen_glx->glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - fbconfig, - onscreen_glx->xwin, - NULL); - } - -#ifdef GLX_INTEL_swap_event - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - GLXDrawable drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - /* similarly to above, we unconditionally select this event - * because we rely on it to advance the master clock, and - * drive redraw/relayout, animations and event handling. - */ - glx_renderer->glXSelectEvent (xlib_renderer->xdpy, - drawable, - GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK); - } -#endif /* GLX_INTEL_swap_event */ - - return TRUE; -} - -static void -cogl_onscreen_glx_dispose (GObject *object) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (object); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglXlibTrapState old_state; - GLXDrawable drawable; - - G_OBJECT_CLASS (cogl_onscreen_glx_parent_class)->dispose (object); - - cogl_clear_object (&onscreen_glx->output); - - if (onscreen_glx->glxwin != None || - onscreen_glx->xwin != None) - { - _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state); - - drawable = - onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin; - - /* Cogl always needs a valid context bound to something so if we are - * destroying the onscreen that is currently bound we'll switch back - * to the dummy drawable. Although the documentation for - * glXDestroyWindow states that a currently bound window won't - * actually be destroyed until it is unbound, it looks like this - * doesn't work if the X window itself is destroyed */ - if (drawable == cogl_context_glx_get_current_drawable (context)) - { - GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ? - glx_display->dummy_xwin : - glx_display->dummy_glxwin); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - cogl_context_glx_set_current_drawable (context, dummy_drawable); - } - - if (onscreen_glx->glxwin != None) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - onscreen_glx->glxwin); - onscreen_glx->glxwin = None; - } - - if (onscreen_glx->xwin != None) - { - XDestroyWindow (xlib_renderer->xdpy, onscreen_glx->xwin); - onscreen_glx->xwin = None; - } - else - { - onscreen_glx->xwin = None; - } - - XSync (xlib_renderer->xdpy, False); - - _cogl_xlib_renderer_untrap_errors (context->display->renderer, - &old_state); - } -} - -static void -cogl_onscreen_glx_bind (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglGLXDisplay *glx_display = context->display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglXlibTrapState old_state; - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - if (cogl_context_glx_get_current_drawable (context) == drawable) - return; - - _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state); - - COGL_NOTE (WINSYS, - "MakeContextCurrent dpy: %p, window: 0x%x, context: %p", - xlib_renderer->xdpy, - (unsigned int) drawable, - glx_display->glx_context); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - drawable, - drawable, - glx_display->glx_context); - - /* In case we are using GLX_SGI_swap_control for vblank syncing - * we need call glXSwapIntervalSGI here to make sure that it - * affects the current drawable. - * - * Note: we explicitly set to 0 when we aren't using the swap - * interval to synchronize since some drivers have a default - * swap interval of 1. Sadly some drivers even ignore requests - * to disable the swap interval. - * - * NB: glXSwapIntervalSGI applies to the context not the - * drawable which is why we can't just do this once when the - * framebuffer is allocated. - * - * FIXME: We should check for GLX_EXT_swap_control which allows - * per framebuffer swap intervals. GLX_MESA_swap_control also - * allows per-framebuffer swap intervals but the semantics tend - * to be more muddled since Mesa drivers tend to expose both the - * MESA and SGI extensions which should technically be mutually - * exclusive. - */ - if (glx_renderer->glXSwapInterval) - glx_renderer->glXSwapInterval (1); - - XSync (xlib_renderer->xdpy, False); - - /* FIXME: We should be reporting a GError here */ - if (_cogl_xlib_renderer_untrap_errors (context->display->renderer, - &old_state)) - { - g_warning ("X Error received while making drawable 0x%08lX current", - drawable); - return; - } - - cogl_context_glx_set_current_drawable (context, drawable); -} - -static void -_cogl_winsys_wait_for_gpu (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - - ctx->glFinish (); -} - -static void -ensure_ust_type (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - int64_t ust; - int64_t msc; - int64_t sbc; - struct timeval tv; - int64_t current_system_time; - int64_t current_monotonic_time; - - if (glx_renderer->ust_type != COGL_GLX_UST_IS_UNKNOWN) - return; - - glx_renderer->ust_type = COGL_GLX_UST_IS_OTHER; - - if (glx_renderer->glXGetSyncValues == NULL) - goto out; - - if (!glx_renderer->glXGetSyncValues (xlib_renderer->xdpy, drawable, - &ust, &msc, &sbc)) - goto out; - - /* This is the time source that existing (buggy) linux drm drivers - * use */ - gettimeofday (&tv, NULL); - current_system_time = (tv.tv_sec * G_GINT64_CONSTANT (1000000)) + tv.tv_usec; - - if (current_system_time > ust - 1000000 && - current_system_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_GETTIMEOFDAY; - goto out; - } - - /* This is the time source that the newer (fixed) linux drm - * drivers use (Linux >= 3.8) */ - current_monotonic_time = g_get_monotonic_time (); - - if (current_monotonic_time > ust - 1000000 && - current_monotonic_time < ust + 1000000) - { - glx_renderer->ust_type = COGL_GLX_UST_IS_MONOTONIC_TIME; - goto out; - } - - out: - COGL_NOTE (WINSYS, "Classified OML system time as: %s", - glx_renderer->ust_type == COGL_GLX_UST_IS_GETTIMEOFDAY ? "gettimeofday" : - (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME ? "monotonic" : - "other")); - return; -} - -static int64_t -ust_to_microseconds (CoglRenderer *renderer, - GLXDrawable drawable, - int64_t ust) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - ensure_ust_type (renderer, drawable); - - switch (glx_renderer->ust_type) - { - case COGL_GLX_UST_IS_UNKNOWN: - g_assert_not_reached (); - break; - case COGL_GLX_UST_IS_GETTIMEOFDAY: - case COGL_GLX_UST_IS_MONOTONIC_TIME: - return ust; - case COGL_GLX_UST_IS_OTHER: - /* In this case the scale of UST is undefined so we can't easily - * scale to microseconds. - * - * For example the driver may be reporting the rdtsc CPU counter - * as UST values and so the scale would need to be determined - * empirically. - * - * Potentially we could block for a known duration within - * ensure_ust_type() to measure the timescale of UST but for now - * we just ignore unknown time sources */ - return 0; - } - - return 0; -} - -static gboolean -is_ust_monotonic (CoglRenderer *renderer, - GLXDrawable drawable) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - ensure_ust_type (renderer, drawable); - - return (glx_renderer->ust_type == COGL_GLX_UST_IS_MONOTONIC_TIME); -} - -static void -_cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *ctx = cogl_framebuffer_get_context (framebuffer); - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXDisplay *glx_display; - - glx_renderer = ctx->display->renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (ctx->display->renderer); - glx_display = ctx->display->winsys; - - if (glx_display->can_vblank_wait) - { - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - if (glx_renderer->glXWaitForMsc) - { - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - Drawable drawable = onscreen_glx->glxwin; - int64_t ust; - int64_t msc; - int64_t sbc; - - glx_renderer->glXWaitForMsc (xlib_renderer->xdpy, drawable, - 0, 1, 0, - &ust, &msc, &sbc); - - if (is_ust_monotonic (ctx->display->renderer, drawable)) - { - info->presentation_time_us = - ust_to_microseconds (ctx->display->renderer, - drawable, - ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - else - { - info->presentation_time_us = g_get_monotonic_time (); - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = msc; - } - else - { - uint32_t current_count; - - glx_renderer->glXGetVideoSync (¤t_count); - glx_renderer->glXWaitVideoSync (2, - (current_count + 1) % 2, - ¤t_count); - - info->presentation_time_us = g_get_monotonic_time (); - } - } -} - -static uint32_t -_cogl_winsys_get_vsync_counter (CoglContext *ctx) -{ - uint32_t video_sync_count; - CoglGLXRenderer *glx_renderer; - - glx_renderer = ctx->display->renderer->winsys; - - glx_renderer->glXGetVideoSync (&video_sync_count); - - return video_sync_count; -} - -#ifndef GLX_BACK_BUFFER_AGE_EXT -#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 -#endif - -static int -cogl_onscreen_glx_get_buffer_age (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - GLXDrawable drawable; - unsigned int age; - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE)) - return 0; - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - glx_renderer->glXQueryDrawable (xlib_renderer->xdpy, drawable, GLX_BACK_BUFFER_AGE_EXT, &age); - - return age; -} - -static void -set_frame_info_output (CoglOnscreen *onscreen, - CoglOutput *output) -{ - CoglFrameInfo *info = cogl_onscreen_peek_tail_frame_info (onscreen); - - if (output) - { - float refresh_rate = cogl_output_get_refresh_rate (output); - if (refresh_rate != 0.0) - info->refresh_rate = refresh_rate; - } -} - -static void -cogl_onscreen_glx_flush_notification (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - while (onscreen_glx->pending_sync_notify > 0 || - onscreen_glx->pending_complete_notify > 0) - { - if (onscreen_glx->pending_sync_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_peek_head_frame_info (onscreen); - _cogl_onscreen_notify_frame_sync (onscreen, info); - onscreen_glx->pending_sync_notify--; - } - - if (onscreen_glx->pending_complete_notify > 0) - { - CoglFrameInfo *info; - - info = cogl_onscreen_pop_head_frame_info (onscreen); - _cogl_onscreen_notify_complete (onscreen, info); - cogl_object_unref (info); - onscreen_glx->pending_complete_notify--; - } - } -} - -static void -flush_pending_notifications_cb (void *data, - void *user_data) -{ - CoglFramebuffer *framebuffer = data; - - if (COGL_IS_ONSCREEN (framebuffer)) - { - CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); - - cogl_onscreen_glx_flush_notification (onscreen); - } -} - -static void -flush_pending_notifications_idle (void *user_data) -{ - CoglContext *context = user_data; - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* This needs to be disconnected before invoking the callbacks in - * case the callbacks cause it to be queued again */ - _cogl_closure_disconnect (glx_renderer->flush_notifications_idle); - glx_renderer->flush_notifications_idle = NULL; - - g_list_foreach (context->framebuffers, - flush_pending_notifications_cb, - NULL); -} - -static void -set_sync_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* We only want to dispatch sync events when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - onscreen_glx->pending_sync_notify++; -} - -static void -set_complete_pending (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* We only want to notify swap completion when the application calls - * cogl_context_dispatch so instead of immediately notifying we - * queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - onscreen_glx->pending_complete_notify++; -} - -static void -cogl_onscreen_glx_swap_region (CoglOnscreen *onscreen, - const int *user_rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglGLXDisplay *glx_display = context->display->winsys; - uint32_t end_frame_vsync_counter = 0; - gboolean have_counter; - gboolean can_wait; - int x_min = 0, x_max = 0, y_min = 0, y_max = 0; - - /* - * We assume that glXCopySubBuffer is synchronized which means it won't prevent multiple - * blits per retrace if they can all be performed in the blanking period. If that's the - * case then we still want to use the vblank sync menchanism but - * we only need it to throttle redraws. - */ - gboolean blit_sub_buffer_is_synchronized = - _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED); - - int framebuffer_width = cogl_framebuffer_get_width (framebuffer); - int framebuffer_height = cogl_framebuffer_get_height (framebuffer); - int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4); - int i; - - /* glXCopySubBuffer expects rectangles relative to the bottom left corner but - * we are given rectangles relative to the top left so we need to flip - * them... */ - memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - - if (i == 0) - { - x_min = rect[0]; - x_max = rect[0] + rect[2]; - y_min = rect[1]; - y_max = rect[1] + rect[3]; - } - else - { - x_min = MIN (x_min, rect[0]); - x_max = MAX (x_max, rect[0] + rect[2]); - y_min = MIN (y_min, rect[1]); - y_max = MAX (y_max, rect[1] + rect[3]); - } - - rect[1] = framebuffer_height - rect[1] - rect[3]; - - } - - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - have_counter = glx_display->have_vblank_counter; - can_wait = glx_display->can_vblank_wait; - - /* We need to ensure that all the rendering is done, otherwise - * redraw operations that are slower than the framerate can - * queue up in the pipeline during a heavy animation, causing a - * larger and larger backlog of rendering visible as lag to the - * user. - * - * For an exaggerated example consider rendering at 60fps (so 16ms - * per frame) and you have a really slow frame that takes 160ms to - * render, even though painting the scene and issuing the commands - * to the GPU takes no time at all. If all we did was use the - * video_sync extension to throttle the painting done by the CPU - * then every 16ms we would have another frame queued up even though - * the GPU has only rendered one tenth of the current frame. By the - * time the GPU would get to the 2nd frame there would be 9 frames - * waiting to be rendered. - * - * The problem is that we don't currently have a good way to throttle - * the GPU, only the CPU so we have to resort to synchronizing the - * GPU with the CPU to throttle it. - * - * Note: since calling glFinish() and synchronizing the CPU with - * the GPU is far from ideal, we hope that this is only a short - * term solution. - * - One idea is to using sync objects to track render - * completion so we can throttle the backlog (ideally with an - * additional extension that lets us get notifications in our - * mainloop instead of having to busy wait for the - * completion.) - * - Another option is to support clipped redraws by reusing the - * contents of old back buffers such that we can flip instead - * of using a blit and then we can use GLX_INTEL_swap_events - * to throttle. For this though we would still probably want an - * additional extension so we can report the limited region of - * the window damage to X/compositors. - */ - _cogl_winsys_wait_for_gpu (onscreen); - - if (blit_sub_buffer_is_synchronized && have_counter && can_wait) - { - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we have the GLX_SGI_video_sync extension then we can - * be a bit smarter about how we throttle blits by avoiding - * any waits if we can see that the video sync count has - * already progressed. */ - if (onscreen_glx->last_swap_vsync_counter == end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - - if (glx_renderer->glXCopySubBuffer) - { - Display *xdpy = xlib_renderer->xdpy; - GLXDrawable drawable; - - drawable = - onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - int i; - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - glx_renderer->glXCopySubBuffer (xdpy, drawable, - rect[0], rect[1], rect[2], rect[3]); - } - } - else if (context->glBlitFramebuffer) - { - int i; - /* XXX: checkout how this state interacts with the code to use - * glBlitFramebuffer in Neil's texture atlasing branch */ - - /* glBlitFramebuffer is affected by the scissor so we need to - * ensure we have flushed an empty clip stack to get rid of it. - * We also mark that the clip state is dirty so that it will be - * flushed to the correct state the next time something is - * drawn */ - _cogl_clip_stack_flush (NULL, framebuffer); - context->current_draw_buffer_changes |= COGL_FRAMEBUFFER_STATE_CLIP; - - context->glDrawBuffer (GL_FRONT); - for (i = 0; i < n_rectangles; i++) - { - int *rect = &rectangles[4 * i]; - int x2 = rect[0] + rect[2]; - int y2 = rect[1] + rect[3]; - context->glBlitFramebuffer (rect[0], rect[1], x2, y2, - rect[0], rect[1], x2, y2, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - context->glDrawBuffer (context->current_gl_draw_buffer); - } - - /* NB: unlike glXSwapBuffers, glXCopySubBuffer and - * glBlitFramebuffer don't issue an implicit glFlush() so we - * have to flush ourselves if we want the request to complete in - * a finite amount of time since otherwise the driver can batch - * the command indefinitely. */ - context->glFlush (); - - /* NB: It's important we save the counter we read before acting on - * the swap request since if we are mixing and matching different - * swap methods between frames we don't want to read the timer e.g. - * after calling glFinish() some times and not for others. - * - * In other words; this way we consistently save the time at the end - * of the applications frame such that the counter isn't muddled by - * the varying costs of different swap methods. - */ - if (have_counter) - onscreen_glx->last_swap_vsync_counter = end_frame_vsync_counter; - - { - CoglOutput *output; - - x_min = CLAMP (x_min, 0, framebuffer_width); - x_max = CLAMP (x_max, 0, framebuffer_width); - y_min = CLAMP (y_min, 0, framebuffer_width); - y_max = CLAMP (y_max, 0, framebuffer_height); - - output = - _cogl_xlib_renderer_output_for_rectangle (context->display->renderer, - onscreen_glx->x + x_min, - onscreen_glx->y + y_min, - x_max - x_min, - y_max - y_min); - - set_frame_info_output (onscreen, output); - } - - /* XXX: we don't get SwapComplete events based on how we implement - * the _swap_region() API but if cogl-onscreen.c knows we are - * handling _SYNC and _COMPLETE events in the winsys then we need to - * send fake events in this case. - */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - set_sync_pending (onscreen); - set_complete_pending (onscreen); - } -} - -static void -cogl_onscreen_glx_swap_buffers_with_damage (CoglOnscreen *onscreen, - const int *rectangles, - int n_rectangles, - CoglFrameInfo *info, - gpointer user_data) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (context->display->renderer); - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - CoglGLXDisplay *glx_display = context->display->winsys; - gboolean have_counter; - GLXDrawable drawable; - - /* XXX: theoretically this shouldn't be necessary but at least with - * the Intel drivers we have see that if we don't call - * glXMakeContextCurrent for the drawable we are swapping then - * we get a BadDrawable error from the X server. */ - cogl_context_flush_framebuffer_state (context, - framebuffer, - framebuffer, - COGL_FRAMEBUFFER_STATE_BIND); - - drawable = onscreen_glx->glxwin ? onscreen_glx->glxwin : onscreen_glx->xwin; - - have_counter = glx_display->have_vblank_counter; - - if (!glx_renderer->glXSwapInterval) - { - gboolean can_wait = have_counter || glx_display->can_vblank_wait; - - uint32_t end_frame_vsync_counter = 0; - - /* If the swap_region API is also being used then we need to track - * the vsync counter for each swap request so we can manually - * throttle swap_region requests. */ - if (have_counter) - end_frame_vsync_counter = _cogl_winsys_get_vsync_counter (context); - - /* If we are going to wait for VBLANK manually, we not only - * need to flush out pending drawing to the GPU before we - * sleep, we need to wait for it to finish. Otherwise, we - * may end up with the situation: - * - * - We finish drawing - GPU drawing continues - * - We go to sleep - GPU drawing continues - * VBLANK - We call glXSwapBuffers - GPU drawing continues - * - GPU drawing continues - * - Swap buffers happens - * - * Producing a tear. Calling glFinish() first will cause us - * to properly wait for the next VBLANK before we swap. This - * obviously does not happen when we use _GLX_SWAP and let - * the driver do the right thing - */ - _cogl_winsys_wait_for_gpu (onscreen); - - if (have_counter && can_wait) - { - if (onscreen_glx->last_swap_vsync_counter == - end_frame_vsync_counter) - _cogl_winsys_wait_for_vblank (onscreen); - } - else if (can_wait) - _cogl_winsys_wait_for_vblank (onscreen); - } - - glx_renderer->glXSwapBuffers (xlib_renderer->xdpy, drawable); - - if (have_counter) - onscreen_glx->last_swap_vsync_counter = - _cogl_winsys_get_vsync_counter (context); - - set_frame_info_output (onscreen, onscreen_glx->output); -} - -static Window -cogl_onscreen_glx_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (x11_onscreen); - - return onscreen_glx->xwin; -} - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - gboolean ust_is_monotonic; - CoglFrameInfo *info; - - /* We only want to notify that the swap is complete when the - application calls cogl_context_dispatch so instead of immediately - notifying we'll set a flag to remember to notify later */ - set_sync_pending (onscreen); - - info = cogl_onscreen_peek_head_frame_info (onscreen); - info->flags |= COGL_FRAME_INFO_FLAG_VSYNC; - - ust_is_monotonic = is_ust_monotonic (context->display->renderer, - onscreen_glx->glxwin); - - if (swap_event->ust != 0 && ust_is_monotonic) - { - info->presentation_time_us = - ust_to_microseconds (context->display->renderer, - onscreen_glx->glxwin, - swap_event->ust); - info->flags |= COGL_FRAME_INFO_FLAG_HW_CLOCK; - } - - /* Intentionally truncating to lower 32 bits, same as DRM. */ - info->sequence = swap_event->msc; - - set_complete_pending (onscreen); -} - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglOutput *output; - int width, height; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - output = _cogl_xlib_renderer_output_for_rectangle (display->renderer, - onscreen_glx->x, - onscreen_glx->y, - width, height); - if (onscreen_glx->output != output) - { - if (onscreen_glx->output) - cogl_object_unref (onscreen_glx->output); - - onscreen_glx->output = output; - - if (output) - cogl_object_ref (onscreen_glx->output); - } -} - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglGLXRenderer *glx_renderer = renderer->winsys; - int x, y; - - - _cogl_framebuffer_winsys_update_size (framebuffer, - configure_event->width, - configure_event->height); - - /* We only want to notify that a resize happened when the - * application calls cogl_context_dispatch so instead of immediately - * notifying we queue an idle callback */ - if (!glx_renderer->flush_notifications_idle) - { - glx_renderer->flush_notifications_idle = - _cogl_poll_renderer_add_idle (renderer, - flush_pending_notifications_idle, - context, - NULL); - } - - if (configure_event->send_event) - { - x = configure_event->x; - y = configure_event->y; - } - else - { - Window child; - XTranslateCoordinates (configure_event->display, - configure_event->window, - DefaultRootWindow (configure_event->display), - 0, 0, &x, &y, &child); - } - - onscreen_glx->x = x; - onscreen_glx->y = y; - - cogl_onscreen_glx_update_output (onscreen); -} - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen); - - return onscreen_glx->xwin == window; -} - -CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_GLX, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_glx_init (CoglOnscreenGlx *onscreen_glx) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_glx_get_x11_window; -} - -static void -cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - CoglOnscreenClass *onscreen_class = COGL_ONSCREEN_CLASS (klass); - - object_class->dispose = cogl_onscreen_glx_dispose; - - framebuffer_class->allocate = cogl_onscreen_glx_allocate; - - onscreen_class->bind = cogl_onscreen_glx_bind; - onscreen_class->swap_buffers_with_damage = - cogl_onscreen_glx_swap_buffers_with_damage; - onscreen_class->swap_region = cogl_onscreen_glx_swap_region; - onscreen_class->get_buffer_age = cogl_onscreen_glx_get_buffer_age; -} diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.h b/cogl/cogl/winsys/cogl-onscreen-glx.h deleted file mode 100644 index 1051cb231..000000000 --- a/cogl/cogl/winsys/cogl-onscreen-glx.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * Copyright (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef COGL_ONSCREEN_GLX_H -#define COGL_ONSCREEN_GLX_H - -#include <GL/glx.h> -#include <X11/Xlib.h> - -#include "cogl-onscreen.h" - -#define COGL_TYPE_ONSCREEN_GLX (cogl_onscreen_glx_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenGlx, cogl_onscreen_glx, - COGL, ONSCREEN_GLX, - CoglOnscreen) - -COGL_EXPORT CoglOnscreenGlx * -cogl_onscreen_glx_new (CoglContext *context, - int width, - int height); - -void -cogl_onscreen_glx_resize (CoglOnscreen *onscreen, - XConfigureEvent *configure_event); - -void -cogl_onscreen_glx_update_output (CoglOnscreen *onscreen); - -void -cogl_onscreen_glx_notify_swap_buffers (CoglOnscreen *onscreen, - GLXBufferSwapComplete *swap_event); - -gboolean -cogl_onscreen_glx_is_for_window (CoglOnscreen *onscreen, - Window window); - -#endif /* COGL_ONSCREEN_GLX_H */ diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.c b/cogl/cogl/winsys/cogl-onscreen-xlib.c deleted file mode 100644 index 9030fd07d..000000000 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2011,2013 Intel Corporation. - * Copyrigth (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include "cogl-config.h" - -#include "winsys/cogl-onscreen-xlib.h" - -#include "cogl-context-private.h" -#include "cogl-renderer-private.h" -#include "cogl-x11-onscreen.h" -#include "cogl-xlib-renderer-private.h" -#include "winsys/cogl-onscreen-egl.h" -#include "winsys/cogl-winsys-egl-x11-private.h" - -struct _CoglOnscreenXlib -{ - CoglOnscreenEgl parent; - - Window xwin; -}; - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL_TYPE_ONSCREEN_EGL, - G_IMPLEMENT_INTERFACE (COGL_TYPE_X11_ONSCREEN, - x11_onscreen_init_iface)) - -#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) - - -static Window -create_xwindow (CoglOnscreenXlib *onscreen_xlib, - EGLConfig egl_config, - GError **error) -{ - CoglOnscreen *onscreen = COGL_ONSCREEN (onscreen_xlib); - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - Window xwin; - int width; - int height; - CoglXlibTrapState state; - XVisualInfo *xvisinfo; - XSetWindowAttributes xattr; - unsigned long mask; - int xerror; - - width = cogl_framebuffer_get_width (framebuffer); - height = cogl_framebuffer_get_height (framebuffer); - - _cogl_xlib_renderer_trap_errors (display->renderer, &state); - - xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config); - if (xvisinfo == NULL) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "Unable to retrieve the X11 visual of context's " - "fbconfig"); - return None; - } - - /* window attributes */ - xattr.background_pixel = - WhitePixel (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)); - xattr.border_pixel = 0; - /* XXX: is this an X resource that we are leaking‽... */ - xattr.colormap = - XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK; - - mask = CWBorderPixel | CWColormap | CWEventMask; - - xwin = XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - 0, 0, - width, height, - 0, - xvisinfo->depth, - InputOutput, - xvisinfo->visual, - mask, &xattr); - - XFree (xvisinfo); - - XSync (xlib_renderer->xdpy, False); - xerror = - _cogl_xlib_renderer_untrap_errors (display->renderer, &state); - if (xerror) - { - char message[1000]; - XGetErrorText (xlib_renderer->xdpy, xerror, - message, sizeof (message)); - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - "X error while creating Window for CoglOnscreen: %s", - message); - return None; - } - - return xwin; -} - -static gboolean -cogl_onscreen_xlib_allocate (CoglFramebuffer *framebuffer, - GError **error) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (framebuffer); - CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (framebuffer); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglDisplay *display = context->display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLConfig egl_config; - Window xwin; - EGLSurface egl_surface; - CoglFramebufferClass *parent_class; - - if (!cogl_onscreen_egl_choose_config (onscreen_egl, &egl_config, error)) - return FALSE; - - xwin = create_xwindow (onscreen_xlib, egl_config, error); - if (xwin == None) - return FALSE; - - onscreen_xlib->xwin = xwin; - - egl_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_config, - (EGLNativeWindowType) onscreen_xlib->xwin, - NULL); - cogl_onscreen_egl_set_egl_surface (onscreen_egl, - egl_surface); - - parent_class = COGL_FRAMEBUFFER_CLASS (cogl_onscreen_xlib_parent_class); - return parent_class->allocate (framebuffer, error); -} - -static void -cogl_onscreen_xlib_dispose (GObject *object) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (object); - - G_OBJECT_CLASS (cogl_onscreen_xlib_parent_class)->dispose (object); - - if (onscreen_xlib->xwin != None) - { - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object); - CoglContext *context = cogl_framebuffer_get_context (framebuffer); - CoglRenderer *renderer = context->display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglXlibTrapState old_state; - - _cogl_xlib_renderer_trap_errors (renderer, &old_state); - - XDestroyWindow (xlib_renderer->xdpy, onscreen_xlib->xwin); - onscreen_xlib->xwin = None; - XSync (xlib_renderer->xdpy, False); - - if (_cogl_xlib_renderer_untrap_errors (renderer, - &old_state) != Success) - g_warning ("X Error while destroying X window"); - - onscreen_xlib->xwin = None; - } -} - -static Window -cogl_onscreen_xlib_get_x11_window (CoglX11Onscreen *x11_onscreen) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (x11_onscreen); - - return onscreen_xlib->xwin; -} - -gboolean -cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, - Window window) -{ - CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen); - - return onscreen_xlib->xwin == window; -} - -void -cogl_onscreen_xlib_resize (CoglOnscreen *onscreen, - int width, - int height) -{ - CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); - - _cogl_framebuffer_winsys_update_size (framebuffer, width, height); -} - -CoglOnscreenXlib * -cogl_onscreen_xlib_new (CoglContext *context, - int width, - int height) -{ - CoglFramebufferDriverConfig driver_config; - - driver_config = (CoglFramebufferDriverConfig) { - .type = COGL_FRAMEBUFFER_DRIVER_TYPE_BACK, - }; - return g_object_new (COGL_TYPE_ONSCREEN_XLIB, - "context", context, - "driver-config", &driver_config, - "width", width, - "height", height, - NULL); -} - -static void -cogl_onscreen_xlib_init (CoglOnscreenXlib *onscreen_xlib) -{ -} - -static void -x11_onscreen_init_iface (CoglX11OnscreenInterface *iface) -{ - iface->get_x11_window = cogl_onscreen_xlib_get_x11_window; -} - -static void -cogl_onscreen_xlib_class_init (CoglOnscreenXlibClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass); - - object_class->dispose = cogl_onscreen_xlib_dispose; - - framebuffer_class->allocate = cogl_onscreen_xlib_allocate; -} diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.h b/cogl/cogl/winsys/cogl-onscreen-xlib.h deleted file mode 100644 index 07a1ceaa0..000000000 --- a/cogl/cogl/winsys/cogl-onscreen-xlib.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2011,2013 Intel Corporation. - * Copyrigth (C) 2020 Red Hat - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef COGL_ONSCREEN_XLIB_H -#define COGL_ONSCREEN_XLIB_H - -#include "cogl-onscreen.h" -#include "winsys/cogl-onscreen-egl.h" -#include "winsys/cogl-winsys-egl-private.h" - -#define COGL_TYPE_ONSCREEN_XLIB (cogl_onscreen_xlib_get_type ()) -G_DECLARE_FINAL_TYPE (CoglOnscreenXlib, cogl_onscreen_xlib, - COGL, ONSCREEN_XLIB, - CoglOnscreenEgl) - -gboolean -_cogl_winsys_egl_onscreen_xlib_init (CoglOnscreen *onscreen, - EGLConfig egl_config, - GError **error); - -COGL_EXPORT CoglOnscreenXlib * -cogl_onscreen_xlib_new (CoglContext *context, - int width, - int height); - -void -_cogl_winsys_egl_onscreen_xlib_deinit (CoglOnscreen *onscreen); - -gboolean -cogl_onscreen_xlib_is_for_window (CoglOnscreen *onscreen, - Window window); - -void -cogl_onscreen_xlib_resize (CoglOnscreen *onscreen, - int width, - int height); - -#endif /* COGL_ONSCREEN_XLIB_H */ diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h deleted file mode 100644 index c1d6d9361..000000000 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11-private.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H -#define __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H - -#include <X11/Xlib.h> -#include <X11/extensions/XShm.h> -#include <X11/extensions/Xdamage.h> - -#include <sys/shm.h> - -#ifdef COGL_HAS_GLX_SUPPORT -#include <GL/glx.h> -#endif - -#include "cogl-object-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-pixmap-x11.h" - -typedef struct _CoglDamageRectangle CoglDamageRectangle; - -struct _CoglDamageRectangle -{ - unsigned int x1; - unsigned int y1; - unsigned int x2; - unsigned int y2; -}; - -/* For stereo, there are a pair of textures, but we want to share most - * other state (the GLXPixmap, visual, etc.) The way we do this is that - * the left-eye texture has all the state (there is in fact, no internal - * difference between the a MONO and a LEFT texture ), and the - * right-eye texture simply points to the left eye texture, with all - * other fields ignored. - */ -typedef enum -{ - COGL_TEXTURE_PIXMAP_MONO, - COGL_TEXTURE_PIXMAP_LEFT, - COGL_TEXTURE_PIXMAP_RIGHT -} CoglTexturePixmapStereoMode; - -struct _CoglTexturePixmapX11 -{ - CoglTexture _parent; - - CoglTexturePixmapStereoMode stereo_mode; - CoglTexturePixmapX11 *left; /* Set only if stereo_mode=RIGHT */ - - Pixmap pixmap; - CoglTexture *tex; - - unsigned int depth; - Visual *visual; - - XImage *image; - - XShmSegmentInfo shm_info; - - Damage damage; - CoglTexturePixmapX11ReportLevel damage_report_level; - gboolean damage_owned; - CoglDamageRectangle damage_rect; - - void *winsys; - - /* During the pre_paint method, this will be set to TRUE if we - should use the winsys texture, otherwise we will use the regular - texture */ - gboolean use_winsys_texture; -}; - - -#endif /* __COGL_TEXTURE_PIXMAP_X11_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c deleted file mode 100644 index 05c6439dd..000000000 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c +++ /dev/null @@ -1,1096 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * - * Authors: - * Neil Roberts <neil@linux.intel.com> - * Johan Bilien <johan.bilien@nokia.com> - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-debug.h" -#include "cogl-util.h" -#include "cogl-texture-pixmap-x11.h" -#include "cogl-texture-pixmap-x11-private.h" -#include "cogl-bitmap-private.h" -#include "cogl-texture-private.h" -#include "cogl-texture-driver.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-2d-sliced.h" -#include "cogl-context-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-object-private.h" -#include "cogl-xlib.h" -#include "cogl-xlib-renderer-private.h" -#include "cogl-x11-renderer-private.h" -#include "cogl-private.h" -#include "cogl-gtype-private.h" -#include "driver/gl/cogl-texture-gl-private.h" -#include "winsys/cogl-winsys-private.h" - -#include <X11/Xlib.h> -#include <X11/Xutil.h> - -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> - -#include <string.h> -#include <math.h> - -static void _cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap); - -COGL_TEXTURE_DEFINE (TexturePixmapX11, texture_pixmap_x11); -COGL_GTYPE_DEFINE_CLASS (TexturePixmapX11, texture_pixmap_x11); - -static const CoglTextureVtable cogl_texture_pixmap_x11_vtable; - -uint32_t -cogl_texture_pixmap_x11_error_quark (void) -{ - return g_quark_from_static_string ("cogl-texture-pixmap-error-quark"); -} - -static void -cogl_damage_rectangle_union (CoglDamageRectangle *damage_rect, - int x, - int y, - int width, - int height) -{ - /* If the damage region is empty then we'll just copy the new - rectangle directly */ - if (damage_rect->x1 == damage_rect->x2 || - damage_rect->y1 == damage_rect->y2) - { - damage_rect->x1 = x; - damage_rect->y1 = y; - damage_rect->x2 = x + width; - damage_rect->y2 = y + height; - } - else - { - if (damage_rect->x1 > x) - damage_rect->x1 = x; - if (damage_rect->y1 > y) - damage_rect->y1 = y; - if (damage_rect->x2 < x + width) - damage_rect->x2 = x + width; - if (damage_rect->y2 < y + height) - damage_rect->y2 = y + height; - } -} - -static gboolean -cogl_damage_rectangle_is_whole (const CoglDamageRectangle *damage_rect, - unsigned int width, - unsigned int height) -{ - return (damage_rect->x1 == 0 && damage_rect->y1 == 0 - && damage_rect->x2 == width && damage_rect->y2 == height); -} - -static const CoglWinsysVtable * -_cogl_texture_pixmap_x11_get_winsys (CoglTexturePixmapX11 *tex_pixmap) -{ - /* FIXME: A CoglContext should be reachable from a CoglTexture - * pointer */ - _COGL_GET_CONTEXT (ctx, NULL); - - return ctx->display->renderer->winsys_vtable; -} - -static void -process_damage_event (CoglTexturePixmapX11 *tex_pixmap, - XDamageNotifyEvent *damage_event) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - Display *display; - enum -{ DO_NOTHING, NEEDS_SUBTRACT, NEED_BOUNDING_BOX } handle_mode; - const CoglWinsysVtable *winsys; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - display = cogl_xlib_renderer_get_display (ctxt->display->renderer); - - COGL_NOTE (TEXTURE_PIXMAP, "Damage event received for %p", tex_pixmap); - - switch (tex_pixmap->damage_report_level) - { - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES: - /* For raw rectangles we don't need do look at the damage region - at all because the damage area is directly given in the event - struct and the reporting of events is not affected by - clearing the damage region */ - handle_mode = DO_NOTHING; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES: - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY: - /* For delta rectangles and non empty we'll query the damage - region for the bounding box */ - handle_mode = NEED_BOUNDING_BOX; - break; - - case COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX: - /* For bounding box we need to clear the damage region but we - don't actually care what it was because the damage event - itself contains the bounding box of the region */ - handle_mode = NEEDS_SUBTRACT; - break; - - default: - g_assert_not_reached (); - } - - /* If the damage already covers the whole rectangle then we don't - need to request the bounding box of the region because we're - going to update the whole texture anyway. */ - if (cogl_damage_rectangle_is_whole (&tex_pixmap->damage_rect, - tex->width, - tex->height)) - { - if (handle_mode != DO_NOTHING) - XDamageSubtract (display, tex_pixmap->damage, None, None); - } - else if (handle_mode == NEED_BOUNDING_BOX) - { - XserverRegion parts; - int r_count; - XRectangle r_bounds; - XRectangle *r_damage; - - /* We need to extract the damage region so we can get the - bounding box */ - - parts = XFixesCreateRegion (display, 0, 0); - XDamageSubtract (display, tex_pixmap->damage, None, parts); - r_damage = XFixesFetchRegionAndBounds (display, - parts, - &r_count, - &r_bounds); - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - r_bounds.x, - r_bounds.y, - r_bounds.width, - r_bounds.height); - if (r_damage) - XFree (r_damage); - - XFixesDestroyRegion (display, parts); - } - else - { - if (handle_mode == NEEDS_SUBTRACT) - /* We still need to subtract from the damage region but we - don't care what the region actually was */ - XDamageSubtract (display, tex_pixmap->damage, None, None); - - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - damage_event->area.x, - damage_event->area.y, - damage_event->area.width, - damage_event->area.height); - } - - if (tex_pixmap->winsys) - { - /* If we're using the texture from pixmap extension then there's no - point in getting the region and we can just mark that the texture - needs updating */ - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - } -} - -static int -_cogl_xlib_get_damage_base (void) -{ - CoglX11Renderer *x11_renderer; - _COGL_GET_CONTEXT (ctxt, -1); - - x11_renderer = - (CoglX11Renderer *) _cogl_xlib_renderer_get_data (ctxt->display->renderer); - return x11_renderer->damage_base; -} - -static CoglFilterReturn -_cogl_texture_pixmap_x11_filter (XEvent *event, void *data) -{ - CoglTexturePixmapX11 *tex_pixmap = data; - int damage_base; - - _COGL_GET_CONTEXT (ctxt, COGL_FILTER_CONTINUE); - - damage_base = _cogl_xlib_get_damage_base (); - if (event->type == damage_base + XDamageNotify) - { - XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) event; - - if (damage_event->damage == tex_pixmap->damage) - process_damage_event (tex_pixmap, damage_event); - } - - return COGL_FILTER_CONTINUE; -} - -static void -set_damage_object_internal (CoglContext *ctx, - CoglTexturePixmapX11 *tex_pixmap, - Damage damage, - CoglTexturePixmapX11ReportLevel report_level) -{ - Display *display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - if (tex_pixmap->damage) - { - cogl_xlib_renderer_remove_filter (ctx->display->renderer, - _cogl_texture_pixmap_x11_filter, - tex_pixmap); - - if (tex_pixmap->damage_owned) - { - XDamageDestroy (display, tex_pixmap->damage); - tex_pixmap->damage_owned = FALSE; - } - } - - tex_pixmap->damage = damage; - tex_pixmap->damage_report_level = report_level; - - if (damage) - cogl_xlib_renderer_add_filter (ctx->display->renderer, - _cogl_texture_pixmap_x11_filter, - tex_pixmap); -} - -static CoglTexturePixmapX11 * -_cogl_texture_pixmap_x11_new (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - CoglTexturePixmapStereoMode stereo_mode, - GError **error) -{ - CoglTexturePixmapX11 *tex_pixmap = g_new (CoglTexturePixmapX11, 1); - Display *display = cogl_xlib_renderer_get_display (ctxt->display->renderer); - Window pixmap_root_window; - int pixmap_x, pixmap_y; - unsigned int pixmap_width, pixmap_height; - unsigned int pixmap_border_width; - CoglPixelFormat internal_format; - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - XWindowAttributes window_attributes; - int damage_base; - const CoglWinsysVtable *winsys; - - if (!XGetGeometry (display, pixmap, &pixmap_root_window, - &pixmap_x, &pixmap_y, - &pixmap_width, &pixmap_height, - &pixmap_border_width, &tex_pixmap->depth)) - { - g_free (tex_pixmap); - g_set_error_literal (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query pixmap size"); - return NULL; - } - - /* Note: the detailed pixel layout doesn't matter here, we are just - * interested in RGB vs RGBA... */ - internal_format = (tex_pixmap->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - _cogl_texture_init (tex, ctxt, pixmap_width, pixmap_height, - internal_format, - NULL, /* no loader */ - &cogl_texture_pixmap_x11_vtable); - - tex_pixmap->pixmap = pixmap; - tex_pixmap->stereo_mode = stereo_mode; - tex_pixmap->left = NULL; - tex_pixmap->image = NULL; - tex_pixmap->shm_info.shmid = -1; - tex_pixmap->tex = NULL; - tex_pixmap->damage_owned = FALSE; - tex_pixmap->damage = 0; - - /* We need a visual to use for shared memory images so we'll query - it from the pixmap's root window */ - if (!XGetWindowAttributes (display, pixmap_root_window, &window_attributes)) - { - g_free (tex_pixmap); - g_set_error_literal (error, - COGL_TEXTURE_PIXMAP_X11_ERROR, - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, - "Unable to query root window attributes"); - return NULL; - } - - tex_pixmap->visual = window_attributes.visual; - - /* If automatic updates are requested and the Xlib connection - supports damage events then we'll register a damage object on the - pixmap */ - damage_base = _cogl_xlib_get_damage_base (); - if (automatic_updates && damage_base >= 0) - { - Damage damage = XDamageCreate (display, - pixmap, - XDamageReportBoundingBox); - set_damage_object_internal (ctxt, - tex_pixmap, - damage, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX); - tex_pixmap->damage_owned = TRUE; - } - - /* Assume the entire pixmap is damaged to begin with */ - tex_pixmap->damage_rect.x1 = 0; - tex_pixmap->damage_rect.x2 = pixmap_width; - tex_pixmap->damage_rect.y1 = 0; - tex_pixmap->damage_rect.y2 = pixmap_height; - - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - if (winsys->texture_pixmap_x11_create) - { - tex_pixmap->use_winsys_texture = - winsys->texture_pixmap_x11_create (tex_pixmap); - } - else - tex_pixmap->use_winsys_texture = FALSE; - - if (!tex_pixmap->use_winsys_texture) - tex_pixmap->winsys = NULL; - - _cogl_texture_set_allocated (tex, internal_format, - pixmap_width, pixmap_height); - - return _cogl_texture_pixmap_x11_object_new (tex_pixmap); -} - -CoglTexturePixmapX11 * -cogl_texture_pixmap_x11_new (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - GError **error) - -{ - return _cogl_texture_pixmap_x11_new (ctxt, pixmap, - automatic_updates, COGL_TEXTURE_PIXMAP_MONO, - error); -} - -CoglTexturePixmapX11 * -cogl_texture_pixmap_x11_new_left (CoglContext *ctxt, - uint32_t pixmap, - gboolean automatic_updates, - GError **error) -{ - return _cogl_texture_pixmap_x11_new (ctxt, pixmap, - automatic_updates, COGL_TEXTURE_PIXMAP_LEFT, - error); -} - -CoglTexturePixmapX11 * -cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *tfp_left) -{ - CoglTexture *texture_left = COGL_TEXTURE (tfp_left); - CoglTexturePixmapX11 *tfp_right; - CoglPixelFormat internal_format; - - g_return_val_if_fail (tfp_left->stereo_mode == COGL_TEXTURE_PIXMAP_LEFT, NULL); - - tfp_right = g_new0 (CoglTexturePixmapX11, 1); - tfp_right->stereo_mode = COGL_TEXTURE_PIXMAP_RIGHT; - tfp_right->left = cogl_object_ref (tfp_left); - - internal_format = (tfp_left->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - _cogl_texture_init (COGL_TEXTURE (tfp_right), - texture_left->context, - texture_left->width, - texture_left->height, - internal_format, - NULL, /* no loader */ - &cogl_texture_pixmap_x11_vtable); - - _cogl_texture_set_allocated (COGL_TEXTURE (tfp_right), internal_format, - texture_left->width, texture_left->height); - - return _cogl_texture_pixmap_x11_object_new (tfp_right); -} - -static gboolean -_cogl_texture_pixmap_x11_allocate (CoglTexture *tex, - GError **error) -{ - return TRUE; -} - -/* Tries to allocate enough shared mem to handle a full size - * update size of the X Pixmap. */ -static void -try_alloc_shm (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - XImage *dummy_image; - Display *display; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - - if (!XShmQueryExtension (display)) - return; - - /* We are creating a dummy_image so we can have Xlib calculate - * image->bytes_per_line - including any magic padding it may - * want - for the largest possible ximage we might need to use - * when handling updates to the texture. - * - * Note: we pass a NULL shminfo here, but that has no bearing - * on the setup of the XImage, except that ximage->obdata will - * == NULL. - */ - dummy_image = - XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - NULL, /* shminfo, */ - tex->width, - tex->height); - if (!dummy_image) - goto failed_image_create; - - tex_pixmap->shm_info.shmid = shmget (IPC_PRIVATE, - dummy_image->bytes_per_line - * dummy_image->height, - IPC_CREAT | 0777); - if (tex_pixmap->shm_info.shmid == -1) - goto failed_shmget; - - tex_pixmap->shm_info.shmaddr = shmat (tex_pixmap->shm_info.shmid, 0, 0); - if (tex_pixmap->shm_info.shmaddr == (void *) -1) - goto failed_shmat; - - tex_pixmap->shm_info.readOnly = False; - - if (XShmAttach (display, &tex_pixmap->shm_info) == 0) - goto failed_xshmattach; - - XDestroyImage (dummy_image); - - return; - - failed_xshmattach: - g_warning ("XShmAttach failed"); - shmdt (tex_pixmap->shm_info.shmaddr); - - failed_shmat: - g_warning ("shmat failed"); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - - failed_shmget: - g_warning ("shmget failed"); - XDestroyImage (dummy_image); - - failed_image_create: - tex_pixmap->shm_info.shmid = -1; -} - -void -cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *tex_pixmap, - int x, - int y, - int width, - int height) -{ - /* We'll queue the update for both the GLX texture and the regular - texture because we can't determine which will be needed until we - actually render something */ - - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys; - winsys = _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_damage_notify (tex_pixmap); - } - - cogl_damage_rectangle_union (&tex_pixmap->damage_rect, - x, y, width, height); -} - -gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *tex_pixmap) -{ - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - return !!tex_pixmap->winsys; -} - -static CoglTexture * -create_fallback_texture (CoglContext *ctx, - int width, - int height, - CoglPixelFormat internal_format) -{ - CoglTexture *tex; - GError *skip_error = NULL; - - /* First try creating a fast-path non-sliced texture */ - tex = COGL_TEXTURE (cogl_texture_2d_new_with_size (ctx, width, height)); - - _cogl_texture_set_internal_format (tex, internal_format); - - /* TODO: instead of allocating storage here it would be better - * if we had some api that let us just check that the size is - * supported by the hardware so storage could be allocated - * lazily when uploading data. */ - if (!cogl_texture_allocate (tex, &skip_error)) - { - g_error_free (skip_error); - cogl_object_unref (tex); - tex = NULL; - } - - if (!tex) - { - CoglTexture2DSliced *tex_2ds = - cogl_texture_2d_sliced_new_with_size (ctx, - width, - height, - COGL_TEXTURE_MAX_WASTE); - tex = COGL_TEXTURE (tex_2ds); - - _cogl_texture_set_internal_format (tex, internal_format); - } - - return tex; -} - -static void -_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - Display *display; - Visual *visual; - CoglPixelFormat image_format; - XImage *image; - int src_x, src_y; - int x, y, width, height; - int bpp; - int offset; - GError *ignore = NULL; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - display = cogl_xlib_renderer_get_display (ctx->display->renderer); - visual = tex_pixmap->visual; - - /* If the damage region is empty then there's nothing to do */ - if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1) - return; - - x = tex_pixmap->damage_rect.x1; - y = tex_pixmap->damage_rect.y1; - width = tex_pixmap->damage_rect.x2 - x; - height = tex_pixmap->damage_rect.y2 - y; - - /* We lazily create the texture the first time it is needed in case - this texture can be entirely handled using the GLX texture - instead */ - if (tex_pixmap->tex == NULL) - { - CoglPixelFormat texture_format; - - texture_format = (tex_pixmap->depth >= 32 - ? COGL_PIXEL_FORMAT_RGBA_8888_PRE - : COGL_PIXEL_FORMAT_RGB_888); - - tex_pixmap->tex = create_fallback_texture (ctx, - tex->width, - tex->height, - texture_format); - } - - if (tex_pixmap->image == NULL) - { - /* If we also haven't got a shm segment then this must be the - first time we've tried to update, so lets try allocating shm - first */ - if (tex_pixmap->shm_info.shmid == -1) - try_alloc_shm (tex_pixmap); - - if (tex_pixmap->shm_info.shmid == -1) - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap); - - /* We'll fallback to using a regular XImage. We'll download - the entire area instead of a sub region because presumably - if this is the first update then the entire pixmap is - needed anyway and it saves trying to manually allocate an - XImage at the right size */ - tex_pixmap->image = XGetImage (display, - tex_pixmap->pixmap, - 0, 0, - tex->width, tex->height, - AllPlanes, ZPixmap); - image = tex_pixmap->image; - src_x = x; - src_y = y; - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage", - tex_pixmap); - - /* Create a temporary image using the beginning of the - shared memory segment and the right size for the region - we want to update. We need to reallocate the XImage every - time because there is no XShmGetSubImage. */ - image = XShmCreateImage (display, - tex_pixmap->visual, - tex_pixmap->depth, - ZPixmap, - NULL, - &tex_pixmap->shm_info, - width, - height); - image->data = tex_pixmap->shm_info.shmaddr; - src_x = 0; - src_y = 0; - - XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes); - } - } - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap); - - image = tex_pixmap->image; - src_x = x; - src_y = y; - - XGetSubImage (display, - tex_pixmap->pixmap, - x, y, width, height, - AllPlanes, ZPixmap, - image, - x, y); - } - - image_format = - _cogl_util_pixel_format_from_masks (visual->red_mask, - visual->green_mask, - visual->blue_mask, - image->depth, - image->bits_per_pixel, - image->byte_order == LSBFirst); - g_return_if_fail (cogl_pixel_format_get_n_planes (image_format) == 1); - - bpp = cogl_pixel_format_get_bytes_per_pixel (image_format, 0); - offset = image->bytes_per_line * src_y + bpp * src_x; - - _cogl_texture_set_region (tex_pixmap->tex, - width, - height, - image_format, - image->bytes_per_line, - ((const uint8_t *) image->data) + offset, - x, y, - 0, /* level */ - &ignore); - - /* If we have a shared memory segment then the XImage would be a - temporary one with no data allocated so we can just XFree it */ - if (tex_pixmap->shm_info.shmid != -1) - XFree (image); - - memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle)); -} - -static void -_cogl_texture_pixmap_x11_set_use_winsys_texture (CoglTexturePixmapX11 *tex_pixmap, - gboolean new_value) -{ - if (tex_pixmap->use_winsys_texture != new_value) - { - /* Notify cogl-pipeline.c that the texture's underlying GL texture - * storage is changing so it knows it may need to bind a new texture - * if the CoglTexture is reused with the same texture unit. */ - _cogl_pipeline_texture_storage_change_notify (COGL_TEXTURE (tex_pixmap)); - - tex_pixmap->use_winsys_texture = new_value; - } -} - -static void -_cogl_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - gboolean needs_mipmap) -{ - CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - - if (winsys->texture_pixmap_x11_update (tex_pixmap, stereo_mode, needs_mipmap)) - { - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, TRUE); - return; - } - } - - /* If it didn't work then fallback to using XGetImage. This may be - temporary */ - _cogl_texture_pixmap_x11_set_use_winsys_texture (tex_pixmap, FALSE); - - _cogl_texture_pixmap_x11_update_image_texture (tex_pixmap); -} - -static CoglTexture * -_cogl_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapX11 *original_pixmap = tex_pixmap; - CoglTexture *tex; - int i; - CoglTexturePixmapStereoMode stereo_mode = tex_pixmap->stereo_mode; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - tex_pixmap = tex_pixmap->left; - - /* We try getting the texture twice, once without flushing the - updates and once with. If pre_paint has been called already then - we should have a good idea of which texture to use so we don't - want to mess with that by ensuring the updates. However, if we - couldn't find a texture then we'll just make a best guess by - flushing without expecting mipmap support and try again. This - would happen for example if an application calls - get_gl_texture before the first paint */ - - for (i = 0; i < 2; i++) - { - if (tex_pixmap->use_winsys_texture) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - tex = winsys->texture_pixmap_x11_get_texture (tex_pixmap, stereo_mode); - } - else - tex = tex_pixmap->tex; - - if (tex) - return tex; - - _cogl_texture_pixmap_x11_update (original_pixmap, FALSE); - } - - g_assert_not_reached (); - - return NULL; -} - -static gboolean -_cogl_texture_pixmap_x11_set_region (CoglTexture *tex, - int src_x, - int src_y, - int dst_x, - int dst_y, - int dst_width, - int dst_height, - int level, - CoglBitmap *bmp, - GError **error) -{ - /* This doesn't make much sense for texture from pixmap so it's not - supported */ - g_set_error_literal (error, - COGL_SYSTEM_ERROR, - COGL_SYSTEM_ERROR_UNSUPPORTED, - "Explicitly setting a region of a TFP texture " - "unsupported"); - return FALSE; -} - -static gboolean -_cogl_texture_pixmap_x11_get_data (CoglTexture *tex, - CoglPixelFormat format, - int rowstride, - uint8_t *data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_data (child_tex, format, rowstride, data); -} - -static void -_cogl_texture_pixmap_x11_foreach_sub_texture_in_region - (CoglTexture *tex, - float virtual_tx_1, - float virtual_ty_1, - float virtual_tx_2, - float virtual_ty_2, - CoglMetaTextureCallback callback, - void *user_data) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (child_tex), - virtual_tx_1, - virtual_ty_1, - virtual_tx_2, - virtual_ty_2, - COGL_PIPELINE_WRAP_MODE_REPEAT, - COGL_PIPELINE_WRAP_MODE_REPEAT, - callback, - user_data); -} - -static int -_cogl_texture_pixmap_x11_get_max_waste (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_get_max_waste (child_tex); -} - -static gboolean -_cogl_texture_pixmap_x11_is_sliced (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return cogl_texture_is_sliced (child_tex); -} - -static gboolean -_cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_can_hardware_repeat (child_tex); -} - -static void -_cogl_texture_pixmap_x11_transform_coords_to_gl (CoglTexture *tex, - float *s, - float *t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_transform_coords_to_gl (child_tex, s, t); -} - -static CoglTransformResult -_cogl_texture_pixmap_x11_transform_quad_coords_to_gl (CoglTexture *tex, - float *coords) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return _cogl_texture_transform_quad_coords_to_gl (child_tex, coords); -} - -static gboolean -_cogl_texture_pixmap_x11_get_gl_texture (CoglTexture *tex, - GLuint *out_gl_handle, - GLenum *out_gl_target) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return cogl_texture_get_gl_texture (child_tex, - out_gl_handle, - out_gl_target); -} - -static void -_cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters (CoglTexture *tex, - GLenum min_filter, - GLenum mag_filter) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_gl_flush_legacy_texobj_filters (child_tex, - min_filter, mag_filter); -} - -static void -_cogl_texture_pixmap_x11_pre_paint (CoglTexture *tex, - CoglTexturePrePaintFlags flags) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex; - - _cogl_texture_pixmap_x11_update (tex_pixmap, - !!(flags & COGL_TEXTURE_NEEDS_MIPMAP)); - - child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - _cogl_texture_pre_paint (child_tex, flags); -} - -static void -_cogl_texture_pixmap_x11_ensure_non_quad_rendering (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_ensure_non_quad_rendering (child_tex); -} - -static void -_cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes (CoglTexture *tex, - GLenum wrap_mode_s, - GLenum wrap_mode_t) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - _cogl_texture_gl_flush_legacy_texobj_wrap_modes (child_tex, - wrap_mode_s, - wrap_mode_t); -} - -static CoglPixelFormat -_cogl_texture_pixmap_x11_get_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - /* Forward on to the child texture */ - return _cogl_texture_get_format (child_tex); -} - -static GLenum -_cogl_texture_pixmap_x11_get_gl_format (CoglTexture *tex) -{ - CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); - CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); - - return _cogl_texture_gl_get_format (child_tex); -} - -static void -_cogl_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - Display *display; - - _COGL_GET_CONTEXT (ctxt, NO_RETVAL); - - if (tex_pixmap->stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - cogl_object_unref (tex_pixmap->left); - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_pixmap)); - - return; - } - - display = cogl_xlib_renderer_get_display (ctxt->display->renderer); - - set_damage_object_internal (ctxt, tex_pixmap, 0, 0); - - if (tex_pixmap->image) - XDestroyImage (tex_pixmap->image); - - if (tex_pixmap->shm_info.shmid != -1) - { - XShmDetach (display, &tex_pixmap->shm_info); - shmdt (tex_pixmap->shm_info.shmaddr); - shmctl (tex_pixmap->shm_info.shmid, IPC_RMID, 0); - } - - if (tex_pixmap->tex) - cogl_object_unref (tex_pixmap->tex); - - if (tex_pixmap->winsys) - { - const CoglWinsysVtable *winsys = - _cogl_texture_pixmap_x11_get_winsys (tex_pixmap); - winsys->texture_pixmap_x11_free (tex_pixmap); - } - - /* Chain up */ - _cogl_texture_free (COGL_TEXTURE (tex_pixmap)); -} - -static const CoglTextureVtable -cogl_texture_pixmap_x11_vtable = - { - FALSE, /* not primitive */ - _cogl_texture_pixmap_x11_allocate, - _cogl_texture_pixmap_x11_set_region, - NULL, /* is_get_data_supported */ - _cogl_texture_pixmap_x11_get_data, - _cogl_texture_pixmap_x11_foreach_sub_texture_in_region, - _cogl_texture_pixmap_x11_get_max_waste, - _cogl_texture_pixmap_x11_is_sliced, - _cogl_texture_pixmap_x11_can_hardware_repeat, - _cogl_texture_pixmap_x11_transform_coords_to_gl, - _cogl_texture_pixmap_x11_transform_quad_coords_to_gl, - _cogl_texture_pixmap_x11_get_gl_texture, - _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_filters, - _cogl_texture_pixmap_x11_pre_paint, - _cogl_texture_pixmap_x11_ensure_non_quad_rendering, - _cogl_texture_pixmap_x11_gl_flush_legacy_texobj_wrap_modes, - _cogl_texture_pixmap_x11_get_format, - _cogl_texture_pixmap_x11_get_gl_format, - NULL /* set_auto_mipmap */ - }; diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.h b/cogl/cogl/winsys/cogl-texture-pixmap-x11.h deleted file mode 100644 index 8103cf379..000000000 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_TEXTURE_PIXMAP_X11_H -#define __COGL_TEXTURE_PIXMAP_X11_H - -/* NB: this is a top-level header that can be included directly but we - * want to be careful not to define __COGL_H_INSIDE__ when this is - * included internally while building Cogl itself since - * __COGL_H_INSIDE__ is used in headers to guard public vs private api - * definitions - */ -#ifndef COGL_COMPILATION - -/* Note: When building Cogl .gir we explicitly define - * __COGL_H_INSIDE__ */ -#ifndef __COGL_H_INSIDE__ -#define __COGL_H_INSIDE__ -#define __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#endif - -#endif /* COGL_COMPILATION */ - -#include <cogl/cogl-context.h> - -#include <glib-object.h> - -G_BEGIN_DECLS - -/** - * SECTION:cogl-texture-pixmap-x11 - * @short_description: Functions for creating and manipulating 2D meta - * textures derived from X11 pixmaps. - * - * These functions allow high-level meta textures (See the - * #CoglMetaTexture interface) that derive their contents from an X11 - * pixmap. - */ - -typedef struct _CoglTexturePixmapX11 CoglTexturePixmapX11; - -#define COGL_TEXTURE_PIXMAP_X11(X) ((CoglTexturePixmapX11 *)X) - -/** - * cogl_texture_pixmap_x11_get_gtype: - * - * Returns: a #GType that can be used with the GLib type system. - */ -COGL_EXPORT -GType cogl_texture_pixmap_x11_get_gtype (void); - -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_DAMAGE_RAW_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_DELTA_RECTANGLES, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_BOUNDING_BOX, - COGL_TEXTURE_PIXMAP_X11_DAMAGE_NON_EMPTY -} CoglTexturePixmapX11ReportLevel; - -/** - * COGL_TEXTURE_PIXMAP_X11_ERROR: - * - * #GError domain for texture-pixmap-x11 errors. - * - * Since: 1.10 - */ -#define COGL_TEXTURE_PIXMAP_X11_ERROR (cogl_texture_pixmap_x11_error_quark ()) - -/** - * CoglTexturePixmapX11Error: - * @COGL_TEXTURE_PIXMAP_X11_ERROR_X11: An X11 protocol error - * - * Error codes that can be thrown when performing texture-pixmap-x11 - * operations. - * - * Since: 1.10 - */ -typedef enum -{ - COGL_TEXTURE_PIXMAP_X11_ERROR_X11, -} CoglTexturePixmapX11Error; - -COGL_EXPORT -uint32_t cogl_texture_pixmap_x11_error_quark (void); - -/** - * cogl_texture_pixmap_x11_new: - * @context: A #CoglContext - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * @error: A #GError for exceptions - * - * Creates a texture that contains the contents of @pixmap. If - * @automatic_updates is %TRUE then Cogl will attempt to listen for - * damage events on the pixmap and automatically update the texture - * when it changes. - * - * Return value: a new #CoglTexturePixmapX11 instance - * - * Since: 1.10 - * Stability: Unstable - */ -COGL_EXPORT CoglTexturePixmapX11 * -cogl_texture_pixmap_x11_new (CoglContext *context, - uint32_t pixmap, - gboolean automatic_updates, - GError **error); - -/** - * cogl_texture_pixmap_x11_new_left: - * @context: A #CoglContext - * @pixmap: A X11 pixmap ID - * @automatic_updates: Whether to automatically copy the contents of - * the pixmap to the texture. - * @error: A #GError for exceptions - * - * Creates one of a pair of textures to contain the contents of @pixmap, - * which has stereo content. (Different images for the right and left eyes.) - * The left image is drawn using this texture; the right image is drawn - * using a texture created by calling - * cogl_texture_pixmap_x11_new_right() and passing in this texture as an - * argument. - * - * In general, you should not use this function unless you have - * queried the %GLX_STEREO_TREE_EXT attribute of the corresponding - * window using glXQueryDrawable() and determined that the window is - * stereo. Note that this attribute can change over time and - * notification is also provided through events defined in the - * EXT_stereo_tree GLX extension. As long as the system has support for - * stereo content, drawing using the left and right pixmaps will not - * produce an error even if the window doesn't have stereo - * content any more, but drawing with the right pixmap will produce - * undefined output, so you need to listen for these events and - * re-render to avoid race conditions. (Recreating a non-stereo - * pixmap is not necessary, but may save resources.) - * - * Return value: a new #CoglTexturePixmapX11 instance - * - * Since: 1.20 - * Stability: Unstable - */ -COGL_EXPORT CoglTexturePixmapX11 * -cogl_texture_pixmap_x11_new_left (CoglContext *context, - uint32_t pixmap, - gboolean automatic_updates, - GError **error); - -/** - * cogl_texture_pixmap_x11_new_right: - * @left_texture: A #CoglTexturePixmapX11 instance created with - * cogl_texture_pixmap_x11_new_left(). - * - * Creates a texture object that corresponds to the right-eye image - * of a pixmap with stereo content. @left_texture must have been - * created using cogl_texture_pixmap_x11_new_left(). - * - * Return value: a new #CoglTexturePixmapX11 instance - * - * Since: 1.20 - * Stability: Unstable - */ -COGL_EXPORT CoglTexturePixmapX11 * -cogl_texture_pixmap_x11_new_right (CoglTexturePixmapX11 *left_texture); - -/** - * cogl_texture_pixmap_x11_update_area: - * @texture: A #CoglTexturePixmapX11 instance - * @x: x coordinate of the area to update - * @y: y coordinate of the area to update - * @width: width of the area to update - * @height: height of the area to update - * - * Forces an update of the given @texture so that it is refreshed with - * the contents of the pixmap that was given to - * cogl_texture_pixmap_x11_new(). - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT void -cogl_texture_pixmap_x11_update_area (CoglTexturePixmapX11 *texture, - int x, - int y, - int width, - int height); - -/** - * cogl_texture_pixmap_x11_is_using_tfp_extension: - * @texture: A #CoglTexturePixmapX11 instance - * - * Checks whether the given @texture is using the - * GLX_EXT_texture_from_pixmap or similar extension to copy the - * contents of the pixmap to the texture. This extension is usually - * implemented as zero-copy operation so it implies the updates are - * working efficiently. - * - * Return value: %TRUE if the texture is using an efficient extension - * and %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_texture_pixmap_x11_is_using_tfp_extension (CoglTexturePixmapX11 *texture); - -/** - * cogl_is_texture_pixmap_x11: - * @object: A pointer to a #CoglObject - * - * Checks whether @object points to a #CoglTexturePixmapX11 instance. - * - * Return value: %TRUE if the object is a #CoglTexturePixmapX11, and - * %FALSE otherwise - * - * Since: 1.4 - * Stability: Unstable - */ -COGL_EXPORT gboolean -cogl_is_texture_pixmap_x11 (void *object); - -G_END_DECLS - -/* The gobject introspection scanner seems to parse public headers in - * isolation which means we need to be extra careful about how we - * define and undefine __COGL_H_INSIDE__ used to detect when internal - * headers are incorrectly included by developers. In the gobject - * introspection case we have to manually define __COGL_H_INSIDE__ as - * a commandline argument for the scanner which means we must be - * careful not to undefine it in a header... - */ -#ifdef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#undef __COGL_H_INSIDE__ -#undef __COGL_MUST_UNDEF_COGL_H_INSIDE_COGL_TEXTURE_PIXMAP_X11_ -#endif - -#endif /* __COGL_TEXTURE_PIXMAP_X11_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h deleted file mode 100644 index e10c01938..000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl-feature-functions.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (name, namespaces, extension_names, - * implied_private_egl_feature_flags) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics across - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -COGL_WINSYS_FEATURE_BEGIN (swap_region, - "NOK\0", - "swap_region\0", - COGL_EGL_WINSYS_FEATURE_SWAP_REGION) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersRegion, - (EGLDisplay dpy, - EGLSurface surface, - EGLint numRects, - const EGLint *rects)) -COGL_WINSYS_FEATURE_END () -/* XXX: These macros can't handle falling back to looking for - * EGL_KHR_image if EGL_KHR_image_base and EGL_KHR_image_pixmap aren't - * found... */ -#ifdef EGL_KHR_image_base -COGL_WINSYS_FEATURE_BEGIN (image_base, - "KHR\0", - "image_base\0", - 0) -COGL_WINSYS_FEATURE_FUNCTION (EGLImageKHR, eglCreateImage, - (EGLDisplay dpy, - EGLContext ctx, - EGLenum target, - EGLClientBuffer buffer, - const EGLint *attrib_list)) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroyImage, - (EGLDisplay dpy, - EGLImageKHR image)) -COGL_WINSYS_FEATURE_END () -#endif -COGL_WINSYS_FEATURE_BEGIN (image_pixmap, - "KHR\0", - "image_pixmap\0", - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) -COGL_WINSYS_FEATURE_END () -#ifdef EGL_WL_bind_wayland_display -COGL_WINSYS_FEATURE_BEGIN (bind_wayland_display, - "WL\0", - "bind_wayland_display\0", - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglQueryWaylandBuffer, - (EGLDisplay dpy, - struct wl_resource *buffer, - EGLint attribute, EGLint *value)) -COGL_WINSYS_FEATURE_END () -#endif /* EGL_WL_bind_wayland_display */ - -COGL_WINSYS_FEATURE_BEGIN (create_context, - "KHR\0", - "create_context\0", - COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (buffer_age, - "EXT\0", - "buffer_age\0", - COGL_EGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (swap_buffers_with_damage, - "EXT\0", - "swap_buffers_with_damage\0", - 0) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamage, - (EGLDisplay dpy, - EGLSurface surface, - const EGLint *rects, - EGLint n_rects)) -COGL_WINSYS_FEATURE_END () - -#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) -COGL_WINSYS_FEATURE_BEGIN (fence_sync, - "KHR\0", - "fence_sync\0", - COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) -COGL_WINSYS_FEATURE_FUNCTION (EGLSyncKHR, eglCreateSync, - (EGLDisplay dpy, - EGLenum type, - const EGLint *attrib_list)) -COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglClientWaitSync, - (EGLDisplay dpy, - EGLSyncKHR sync, - EGLint flags, - EGLTimeKHR timeout)) -COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync, - (EGLDisplay dpy, - EGLSyncKHR sync)) -COGL_WINSYS_FEATURE_END () -#endif - -COGL_WINSYS_FEATURE_BEGIN (surfaceless_context, - "KHR\0", - "surfaceless_context\0", - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (context_priority, - "IMG\0", - "context_priority\0", - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) -COGL_WINSYS_FEATURE_END () diff --git a/cogl/cogl/winsys/cogl-winsys-egl-private.h b/cogl/cogl/winsys/cogl-winsys-egl-private.h deleted file mode 100644 index 9d6fa5cfb..000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl-private.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_WINSYS_EGL_PRIVATE_H -#define __COGL_WINSYS_EGL_PRIVATE_H - -#include "cogl-defines.h" -#include "cogl-context.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer-private.h" -#include "winsys/cogl-winsys-private.h" - -/* XXX: depending on what version of Mesa you have then - * eglQueryWaylandBuffer may take a wl_buffer or wl_resource argument - * and the EGL header will only forward declare the corresponding - * type. - * - * The use of wl_buffer has been deprecated and so internally we - * assume that eglQueryWaylandBuffer takes a wl_resource but for - * compatibility we forward declare wl_resource in case we are - * building with EGL headers that still use wl_buffer. - * - * Placing the forward declaration here means it comes before we - * #include cogl-winsys-egl-feature-functions.h bellow which - * declares lots of function pointers for accessing EGL extensions - * and cogl-winsys-egl.c will include this header before it also - * includes cogl-winsys-egl-feature-functions.h that may depend - * on this type. - */ -#ifdef EGL_WL_bind_wayland_display -struct wl_resource; -#endif - -typedef struct _CoglWinsysEGLVtable -{ - gboolean - (* display_setup) (CoglDisplay *display, - GError **error); - void - (* display_destroy) (CoglDisplay *display); - - gboolean - (* context_created) (CoglDisplay *display, - GError **error); - - void - (* cleanup_context) (CoglDisplay *display); - - gboolean - (* context_init) (CoglContext *context, GError **error); - - void - (* context_deinit) (CoglContext *context); - - int - (* add_config_attributes) (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes); - gboolean - (* choose_config) (CoglDisplay *display, - EGLint *attributes, - EGLConfig *out_config, - GError **error); -} CoglWinsysEGLVtable; - -#define MAX_EGL_CONFIG_ATTRIBS 30 - -typedef enum _CoglEGLWinsysFeature -{ - COGL_EGL_WINSYS_FEATURE_SWAP_REGION =1L<<0, - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP =1L<<1, - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2, - COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT =1L<<3, - COGL_EGL_WINSYS_FEATURE_BUFFER_AGE =1L<<4, - COGL_EGL_WINSYS_FEATURE_FENCE_SYNC =1L<<5, - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT =1L<<6, - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY =1L<<7, -} CoglEGLWinsysFeature; - -typedef struct _CoglRendererEGL -{ - CoglEGLWinsysFeature private_features; - - EGLDisplay edpy; - - EGLint egl_version_major; - EGLint egl_version_minor; - - CoglClosure *resize_notify_idle; - - /* Data specific to the EGL platform */ - void *platform; - /* vtable for platform specific parts */ - const CoglWinsysEGLVtable *platform_vtable; - - /* Function pointers for EGL specific extensions */ -#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d) - -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - ret (APIENTRY * pf_ ## name) args; - -#define COGL_WINSYS_FEATURE_END() - -#include "winsys/cogl-winsys-egl-feature-functions.h" - -#undef COGL_WINSYS_FEATURE_BEGIN -#undef COGL_WINSYS_FEATURE_FUNCTION -#undef COGL_WINSYS_FEATURE_END -} CoglRendererEGL; - -typedef struct _CoglDisplayEGL -{ - EGLContext egl_context; - EGLSurface dummy_surface; - EGLSurface egl_surface; - - EGLConfig egl_config; - gboolean found_egl_config; - - EGLSurface current_read_surface; - EGLSurface current_draw_surface; - EGLContext current_context; - - /* Platform specific display data */ - void *platform; -} CoglDisplayEGL; - -typedef struct _CoglContextEGL -{ - EGLSurface saved_draw_surface; - EGLSurface saved_read_surface; -} CoglContextEGL; - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_get_vtable (void); - -COGL_EXPORT EGLBoolean -_cogl_winsys_egl_make_current (CoglDisplay *display, - EGLSurface draw, - EGLSurface read, - EGLContext context); - -COGL_EXPORT EGLBoolean -_cogl_winsys_egl_ensure_current (CoglDisplay *display); - -#ifdef EGL_KHR_image_base -EGLImageKHR -_cogl_egl_create_image (CoglContext *ctx, - EGLenum target, - EGLClientBuffer buffer, - const EGLint *attribs); - -void -_cogl_egl_destroy_image (CoglContext *ctx, - EGLImageKHR image); -#endif - -#ifdef EGL_WL_bind_wayland_display -gboolean -_cogl_egl_query_wayland_buffer (CoglContext *ctx, - struct wl_resource *buffer, - int attribute, - int *value); -#endif - -COGL_EXPORT gboolean -_cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, - GError **error); - -void -cogl_display_egl_determine_attributes (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes); - -#endif /* __COGL_WINSYS_EGL_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h b/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h deleted file mode 100644 index 7d4218c0d..000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11-private.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_WINSYS_EGL_X11_PRIVATE_H -#define __COGL_WINSYS_EGL_X11_PRIVATE_H - -#include "winsys/cogl-winsys-private.h" - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_xlib_get_vtable (void); - -XVisualInfo * -cogl_display_xlib_get_visual_info (CoglDisplay *display, - EGLConfig egl_config); - -#endif /* __COGL_WINSYS_EGL_X11_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c deleted file mode 100644 index 2c8141fae..000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - * Neil Roberts <neil@linux.intel.com> - */ - -#include "cogl-config.h" - -#include <X11/Xlib.h> - -#include "cogl-xlib-renderer-private.h" -#include "cogl-xlib-renderer.h" -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-private.h" -#include "cogl-display-private.h" -#include "cogl-renderer-private.h" -#include "cogl-texture-pixmap-x11-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-texture-2d.h" -#include "cogl-poll-private.h" -#include "winsys/cogl-onscreen-egl.h" -#include "winsys/cogl-onscreen-xlib.h" -#include "winsys/cogl-winsys-egl-x11-private.h" -#include "winsys/cogl-winsys-egl-private.h" - -static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable; - -typedef struct _CoglDisplayXlib -{ - Window dummy_xwin; -} CoglDisplayXlib; - -#ifdef EGL_KHR_image_pixmap -typedef struct _CoglTexturePixmapEGL -{ - EGLImageKHR image; - CoglTexture *texture; -} CoglTexturePixmapEGL; -#endif - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_xlib_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_resize (CoglContext *context, - Window drawable, - int width, - int height) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, drawable); - if (!onscreen) - return; - - cogl_onscreen_xlib_resize (onscreen, width, height); -} - -static CoglFilterReturn -event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - xevent->xconfigure.window, - xevent->xconfigure.width, - xevent->xconfigure.height); - } - else if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - CoglOnscreenDirtyInfo info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - } - - return COGL_FILTER_CONTINUE; -} - -XVisualInfo * -cogl_display_xlib_get_visual_info (CoglDisplay *display, - EGLConfig egl_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglRendererEGL *egl_renderer = display->renderer->winsys; - XVisualInfo visinfo_template; - int template_mask = 0; - XVisualInfo *visinfo = NULL; - int visinfos_count; - EGLint visualid, red_size, green_size, blue_size, alpha_size; - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_NATIVE_VISUAL_ID, &visualid); - - if (visualid != 0) - { - visinfo_template.visualid = visualid; - template_mask |= VisualIDMask; - } - else - { - /* some EGL drivers don't implement the EGL_NATIVE_VISUAL_ID - * attribute, so attempt to find the closest match. */ - - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_RED_SIZE, &red_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_GREEN_SIZE, &green_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_BLUE_SIZE, &blue_size); - eglGetConfigAttrib (egl_renderer->edpy, egl_config, - EGL_ALPHA_SIZE, &alpha_size); - - visinfo_template.depth = red_size + green_size + blue_size + alpha_size; - template_mask |= VisualDepthMask; - - visinfo_template.screen = DefaultScreen (xlib_renderer->xdpy); - template_mask |= VisualScreenMask; - } - - visinfo = XGetVisualInfo (xlib_renderer->xdpy, - template_mask, - &visinfo_template, - &visinfos_count); - - return visinfo; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - - _cogl_xlib_renderer_disconnect (renderer); - - eglTerminate (egl_renderer->edpy); - - g_free (egl_renderer); -} - -static EGLDisplay -_cogl_winsys_egl_get_display (void *native) -{ - EGLDisplay dpy = NULL; - const char *client_exts = eglQueryString (NULL, EGL_EXTENSIONS); - - if (g_strstr_len (client_exts, -1, "EGL_KHR_platform_base")) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = - (void *) eglGetProcAddress ("eglGetPlatformDisplay"); - - if (get_platform_display) - dpy = get_platform_display (EGL_PLATFORM_X11_KHR, native, NULL); - - if (dpy) - return dpy; - } - - if (g_strstr_len (client_exts, -1, "EGL_EXT_platform_base")) - { - PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = - (void *) eglGetProcAddress ("eglGetPlatformDisplayEXT"); - - if (get_platform_display) - dpy = get_platform_display (EGL_PLATFORM_X11_KHR, native, NULL); - - if (dpy) - return dpy; - } - - return eglGetDisplay ((EGLNativeDisplayType) native); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglRendererEGL *egl_renderer; - CoglXlibRenderer *xlib_renderer; - - renderer->winsys = g_new0 (CoglRendererEGL, 1); - egl_renderer = renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - egl_renderer->edpy = _cogl_winsys_egl_get_display (xlib_renderer->xdpy); - - if (!_cogl_winsys_egl_renderer_connect_common (renderer, error)) - goto error; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static int -_cogl_winsys_egl_add_config_attributes (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes) -{ - int i = 0; - - attributes[i++] = EGL_SURFACE_TYPE; - attributes[i++] = EGL_WINDOW_BIT; - - return i; -} - -static gboolean -_cogl_winsys_egl_choose_config (CoglDisplay *display, - EGLint *attributes, - EGLConfig *out_config, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLint config_count = 0; - EGLBoolean status; - - status = eglChooseConfig (egl_renderer->edpy, - attributes, - out_config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "No compatible EGL configs found"); - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_egl_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglDisplayXlib *xlib_display; - - xlib_display = g_new0 (CoglDisplayXlib, 1); - egl_display->platform = xlib_display; - - return TRUE; -} - -static void -_cogl_winsys_egl_display_destroy (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - - g_free (egl_display->platform); -} - -static gboolean -_cogl_winsys_egl_context_init (CoglContext *context, - GError **error) -{ - cogl_xlib_renderer_add_filter (context->display->renderer, - event_filter_cb, - context); - - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, - TRUE); - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - return TRUE; -} - -static void -_cogl_winsys_egl_context_deinit (CoglContext *context) -{ - cogl_xlib_renderer_remove_filter (context->display->renderer, - event_filter_cb, - context); -} - -static gboolean -_cogl_winsys_egl_context_created (CoglDisplay *display, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglDisplayXlib *xlib_display = egl_display->platform; - XVisualInfo *xvisinfo; - XSetWindowAttributes attrs; - const char *error_message; - - xvisinfo = cogl_display_xlib_get_visual_info (display, - egl_display->egl_config); - if (xvisinfo == NULL) - { - error_message = "Unable to find suitable X visual"; - goto fail; - } - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - if ((egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0) - { - xlib_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | - CWColormap | - CWBorderPixel, - &attrs); - - egl_display->dummy_surface = - eglCreateWindowSurface (egl_renderer->edpy, - egl_display->egl_config, - (EGLNativeWindowType) xlib_display->dummy_xwin, - NULL); - - if (egl_display->dummy_surface == EGL_NO_SURFACE) - { - error_message = "Unable to create an EGL surface"; - XFree (xvisinfo); - goto fail; - } - } - - xlib_renderer->xvisinfo = xvisinfo; - - if (!_cogl_winsys_egl_make_current (display, - egl_display->dummy_surface, - egl_display->dummy_surface, - egl_display->egl_context)) - { - if (egl_display->dummy_surface == EGL_NO_SURFACE) - error_message = "Unable to eglMakeCurrent with no surface"; - else - error_message = "Unable to eglMakeCurrent with dummy surface"; - goto fail; - } - - return TRUE; - -fail: - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - return FALSE; -} - -static void -_cogl_winsys_egl_cleanup_context (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglDisplayXlib *xlib_display = egl_display->platform; - CoglRenderer *renderer = display->renderer; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_display->dummy_surface != EGL_NO_SURFACE) - { - eglDestroySurface (egl_renderer->edpy, egl_display->dummy_surface); - egl_display->dummy_surface = EGL_NO_SURFACE; - } - - if (xlib_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, xlib_display->dummy_xwin); - xlib_display->dummy_xwin = None; - } -} - -#ifdef EGL_KHR_image_pixmap - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = tex->context; - CoglTexturePixmapEGL *egl_tex_pixmap; - EGLint attribs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; - CoglPixelFormat texture_format; - CoglRendererEGL *egl_renderer; - - egl_renderer = ctx->display->renderer->winsys; - - if (!(egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP) || - !_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - egl_tex_pixmap = g_new0 (CoglTexturePixmapEGL, 1); - - egl_tex_pixmap->image = - _cogl_egl_create_image (ctx, - EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)tex_pixmap->pixmap, - attribs); - if (egl_tex_pixmap->image == EGL_NO_IMAGE_KHR) - { - g_free (egl_tex_pixmap); - return FALSE; - } - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - egl_tex_pixmap->texture = COGL_TEXTURE ( - cogl_egl_texture_2d_new_from_image (ctx, - tex->width, - tex->height, - texture_format, - egl_tex_pixmap->image, - COGL_EGL_IMAGE_FLAG_NONE, - NULL)); - - tex_pixmap->winsys = egl_tex_pixmap; - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapEGL *egl_tex_pixmap; - - /* FIXME: It should be possible to get to a CoglContext from any - * CoglTexture pointer. */ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (!tex_pixmap->winsys) - return; - - egl_tex_pixmap = tex_pixmap->winsys; - - if (egl_tex_pixmap->texture) - cogl_object_unref (egl_tex_pixmap->texture); - - if (egl_tex_pixmap->image != EGL_NO_IMAGE_KHR) - _cogl_egl_destroy_image (ctx, egl_tex_pixmap->image); - - tex_pixmap->winsys = NULL; - g_free (egl_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - if (needs_mipmap) - return FALSE; - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapEGL *egl_tex_pixmap = tex_pixmap->winsys; - - return egl_tex_pixmap->texture; -} - -#endif /* EGL_KHR_image_pixmap */ - -static const CoglWinsysEGLVtable -_cogl_winsys_egl_vtable = - { - .add_config_attributes = _cogl_winsys_egl_add_config_attributes, - .choose_config = _cogl_winsys_egl_choose_config, - .display_setup = _cogl_winsys_egl_display_setup, - .display_destroy = _cogl_winsys_egl_display_destroy, - .context_created = _cogl_winsys_egl_context_created, - .cleanup_context = _cogl_winsys_egl_cleanup_context, - .context_init = _cogl_winsys_egl_context_init, - .context_deinit = _cogl_winsys_egl_context_deinit, - }; - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_egl_xlib_get_vtable (void) -{ - static gboolean vtable_inited = FALSE; - static CoglWinsysVtable vtable; - - if (!vtable_inited) - { - /* The EGL_X11 winsys is a subclass of the EGL winsys so we - start by copying its vtable */ - - vtable = *_cogl_winsys_egl_get_vtable (); - - vtable.id = COGL_WINSYS_ID_EGL_XLIB; - vtable.name = "EGL_XLIB"; - vtable.constraints |= (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB); - - vtable.renderer_connect = _cogl_winsys_renderer_connect; - vtable.renderer_disconnect = _cogl_winsys_renderer_disconnect; - -#ifdef EGL_KHR_image_pixmap - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - vtable.texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create; - vtable.texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free; - vtable.texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update; - vtable.texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify; - vtable.texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture; -#endif /* EGL_KHR_image_pixmap) */ - - vtable_inited = TRUE; - } - - return &vtable; -} diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c deleted file mode 100644 index 8ea1008b5..000000000 --- a/cogl/cogl/winsys/cogl-winsys-egl.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-i18n-private.h" -#include "cogl-util.h" -#include "cogl-feature-private.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer.h" -#include "cogl-onscreen-private.h" -#include "cogl-swap-chain-private.h" -#include "cogl-renderer-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-egl.h" -#include "cogl-private.h" -#include "cogl-trace.h" -#include "winsys/cogl-winsys-egl-private.h" -#include "winsys/cogl-winsys-private.h" -#include "winsys/cogl-onscreen-egl.h" - -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - - -#ifndef EGL_KHR_create_context -#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 -#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB -#define EGL_CONTEXT_FLAGS_KHR 0x30FC -#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD -#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD -#define EGL_OPENGL_ES3_BIT_KHR 0x0040 -#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE -#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF -#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 -#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 -#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 -#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 -#endif - -#ifndef EGL_IMG_context_priority -#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100 -#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101 -#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102 -#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 -#endif - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - egl_private_flags) \ - static const CoglFeatureFunction \ - cogl_egl_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglRendererEGL, pf_ ## name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "winsys/cogl-winsys-egl-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \ - egl_private_flags) \ - { 255, 255, 0, namespaces, extension_names, \ - egl_private_flags, \ - 0, \ - cogl_egl_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "winsys/cogl-winsys-egl-feature-functions.h" - }; - -static GCallback -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name, - gboolean in_core) -{ - void *ptr = NULL; - - if (!in_core) - ptr = eglGetProcAddress (name); - - /* eglGetProcAddress doesn't support fetching core API so we need to - get that separately with GModule */ - if (ptr == NULL) - g_module_symbol (renderer->libgl_module, name, &ptr); - - return ptr; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - /* This function must be overridden by a platform winsys */ - g_assert_not_reached (); -} - -static void -_cogl_winsys_renderer_bind_api (CoglRenderer *renderer) -{ - if (renderer->driver == COGL_DRIVER_GL || - renderer->driver == COGL_DRIVER_GL3) - eglBindAPI (EGL_OPENGL_API); - else if (renderer->driver == COGL_DRIVER_GLES2) - eglBindAPI (EGL_OPENGL_ES_API); -} - -/* Updates all the function pointers */ -static void -check_egl_extensions (CoglRenderer *renderer) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - const char *egl_extensions; - char **split_extensions; - int i; - - egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS); - split_extensions = g_strsplit (egl_extensions, " ", 0 /* max_tokens */); - - COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions); - - egl_renderer->private_features = 0; - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check (renderer, - "EGL", winsys_feature_data + i, 0, 0, - COGL_DRIVER_GL, /* the driver isn't used */ - split_extensions, - egl_renderer)) - { - egl_renderer->private_features |= - winsys_feature_data[i].feature_flags_private; - } - - g_strfreev (split_extensions); -} - -gboolean -_cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, - GError **error) -{ - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (!eglInitialize (egl_renderer->edpy, - &egl_renderer->egl_version_major, - &egl_renderer->egl_version_minor)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Couldn't initialize EGL"); - return FALSE; - } - - check_egl_extensions (renderer); - - return TRUE; -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - /* This function must be overridden by a platform winsys */ - g_assert_not_reached (); - return FALSE; -} - -void -cogl_display_egl_determine_attributes (CoglDisplay *display, - const CoglFramebufferConfig *config, - EGLint *attributes) -{ - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - int i = 0; - - /* Let the platform add attributes first, including setting the - * EGL_SURFACE_TYPE */ - i = egl_renderer->platform_vtable->add_config_attributes (display, - config, - attributes); - - if (config->need_stencil) - { - attributes[i++] = EGL_STENCIL_SIZE; - attributes[i++] = 2; - } - - attributes[i++] = EGL_RED_SIZE; - attributes[i++] = 1; - attributes[i++] = EGL_GREEN_SIZE; - attributes[i++] = 1; - attributes[i++] = EGL_BLUE_SIZE; - attributes[i++] = 1; - - attributes[i++] = EGL_ALPHA_SIZE; - attributes[i++] = EGL_DONT_CARE; - - attributes[i++] = EGL_DEPTH_SIZE; - attributes[i++] = 1; - - attributes[i++] = EGL_BUFFER_SIZE; - attributes[i++] = EGL_DONT_CARE; - - attributes[i++] = EGL_RENDERABLE_TYPE; - attributes[i++] = ((renderer->driver == COGL_DRIVER_GL || - renderer->driver == COGL_DRIVER_GL3) ? - EGL_OPENGL_BIT : - EGL_OPENGL_ES2_BIT); - - if (config->samples_per_pixel) - { - attributes[i++] = EGL_SAMPLE_BUFFERS; - attributes[i++] = 1; - attributes[i++] = EGL_SAMPLES; - attributes[i++] = config->samples_per_pixel; - } - - attributes[i++] = EGL_NONE; - - g_assert (i < MAX_EGL_CONFIG_ATTRIBS); -} - -EGLBoolean -_cogl_winsys_egl_make_current (CoglDisplay *display, - EGLSurface draw, - EGLSurface read, - EGLContext context) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = display->renderer->winsys; - EGLBoolean ret; - - if (egl_display->current_draw_surface == draw && - egl_display->current_read_surface == read && - egl_display->current_context == context) - return EGL_TRUE; - - ret = eglMakeCurrent (egl_renderer->edpy, - draw, - read, - context); - - egl_display->current_draw_surface = draw; - egl_display->current_read_surface = read; - egl_display->current_context = context; - - return ret; -} - -EGLBoolean -_cogl_winsys_egl_ensure_current (CoglDisplay *display) -{ - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = display->renderer->winsys; - - return eglMakeCurrent (egl_renderer->edpy, - egl_display->current_draw_surface, - egl_display->current_read_surface, - egl_display->current_context); -} - -static void -cleanup_context (CoglDisplay *display) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_display->egl_context != EGL_NO_CONTEXT) - { - _cogl_winsys_egl_make_current (display, - EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - eglDestroyContext (egl_renderer->edpy, egl_display->egl_context); - egl_display->egl_context = EGL_NO_CONTEXT; - } - - if (egl_renderer->platform_vtable->cleanup_context) - egl_renderer->platform_vtable->cleanup_context (display); -} - -static void -print_attribs (EGLDisplay egl_display, - EGLConfig egl_config) -{ - const EGLint names[] = - { - EGL_BUFFER_SIZE, - EGL_RED_SIZE, - EGL_GREEN_SIZE, - EGL_BLUE_SIZE, - EGL_ALPHA_SIZE, - }; - struct - { - EGLint buffer_size; - EGLint red_size; - EGLint green_size; - EGLint blue_size; - EGLint alpha_size; - } values; - int i; - - for (i = 0; i < G_N_ELEMENTS (names); i++) - { - if (!eglGetConfigAttrib (egl_display, - egl_config, - names[i], - (EGLint *) &values + i)) - ((EGLint *) &values)[i] = -1; - } - - COGL_NOTE (WINSYS, "EGL color depth is %d-bit (R:G:B:A = %d:%d:%d:%d)", - (int) values.buffer_size, - (int) values.red_size, - (int) values.green_size, - (int) values.blue_size, - (int) values.alpha_size); -} - -static gboolean -try_create_context (CoglDisplay *display, - GError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLDisplay edpy; - EGLConfig config; - EGLint attribs[11]; - EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS]; - GError *config_error = NULL; - const char *error_message; - int i = 0; - - g_return_val_if_fail (egl_display->egl_context == NULL, TRUE); - - cogl_renderer_bind_api (renderer); - - cogl_display_egl_determine_attributes (display, - &display->onscreen_template->config, - cfg_attribs); - - edpy = egl_renderer->edpy; - - if (!egl_renderer->platform_vtable->choose_config (display, - cfg_attribs, - &config, - &config_error)) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Couldn't choose config: %s", config_error->message); - g_error_free (config_error); - goto err; - } - - egl_display->egl_config = config; - - if (display->renderer->driver == COGL_DRIVER_GL3) - { - if (!(egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT)) - { - error_message = "Driver does not support GL 3 contexts"; - goto fail; - } - - /* Try to get a core profile 3.1 context with no deprecated features */ - attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR; - attribs[i++] = 3; - attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR; - attribs[i++] = 1; - attribs[i++] = EGL_CONTEXT_FLAGS_KHR; - attribs[i++] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; - attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; - attribs[i++] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - } - else if (display->renderer->driver == COGL_DRIVER_GLES2) - { - attribs[i++] = EGL_CONTEXT_CLIENT_VERSION; - attribs[i++] = 2; - } - - if (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) - { - attribs[i++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; - attribs[i++] = EGL_CONTEXT_PRIORITY_HIGH_IMG; - } - - attribs[i++] = EGL_NONE; - - egl_display->egl_context = eglCreateContext (edpy, - config, - EGL_NO_CONTEXT, - attribs); - - if (egl_display->egl_context == EGL_NO_CONTEXT) - { - error_message = "Unable to create a suitable EGL context"; - goto fail; - } - - if (egl_renderer->private_features & - COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY) - { - EGLint value = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; - - eglQueryContext (egl_renderer->edpy, - egl_display->egl_context, - EGL_CONTEXT_PRIORITY_LEVEL_IMG, - &value); - - if (value != EGL_CONTEXT_PRIORITY_HIGH_IMG) - g_message ("Failed to obtain high priority context"); - } - - if (egl_renderer->platform_vtable->context_created && - !egl_renderer->platform_vtable->context_created (display, error)) - return FALSE; - - print_attribs (egl_renderer->edpy, config); - - return TRUE; - -fail: - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - -err: - cleanup_context (display); - - return FALSE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglRendererEGL *egl_renderer = display->renderer->winsys; - CoglDisplayEGL *egl_display = display->winsys; - - g_return_if_fail (egl_display != NULL); - - cleanup_context (display); - - if (egl_renderer->platform_vtable->display_destroy) - egl_renderer->platform_vtable->display_destroy (display); - - g_free (display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglDisplayEGL *egl_display; - CoglRenderer *renderer = display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - egl_display = g_new0 (CoglDisplayEGL, 1); - display->winsys = egl_display; - - if (egl_renderer->platform_vtable->display_setup && - !egl_renderer->platform_vtable->display_setup (display, error)) - goto error; - - if (!try_create_context (display, error)) - goto error; - - egl_display->found_egl_config = TRUE; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -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); - - g_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->private_features & COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) && - _cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_OES_EGL_SYNC)) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE); - - if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_BUFFER_AGE, - TRUE); - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); - } - - if (egl_renderer->platform_vtable->context_init && - !egl_renderer->platform_vtable->context_init (context, error)) - return FALSE; - - return TRUE; -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - CoglRenderer *renderer = context->display->renderer; - CoglRendererEGL *egl_renderer = renderer->winsys; - - if (egl_renderer->platform_vtable->context_deinit) - egl_renderer->platform_vtable->context_deinit (context); - - g_free (context->winsys); -} - -#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) -static void * -_cogl_winsys_fence_add (CoglContext *context) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - void *ret; - - if (renderer->pf_eglCreateSync) - ret = renderer->pf_eglCreateSync (renderer->edpy, - EGL_SYNC_FENCE_KHR, - NULL); - else - ret = NULL; - - return ret; -} - -static gboolean -_cogl_winsys_fence_is_complete (CoglContext *context, void *fence) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - EGLint ret; - - ret = renderer->pf_eglClientWaitSync (renderer->edpy, - fence, - EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, - 0); - return (ret == EGL_CONDITION_SATISFIED_KHR); -} - -static void -_cogl_winsys_fence_destroy (CoglContext *context, void *fence) -{ - CoglRendererEGL *renderer = context->display->renderer->winsys; - - renderer->pf_eglDestroySync (renderer->edpy, fence); -} -#endif - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .constraints = COGL_RENDERER_CONSTRAINT_USES_EGL, - - /* This winsys is only used as a base for the EGL-platform - winsys's so it does not have an ID or a name */ - - .renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .renderer_bind_api = _cogl_winsys_renderer_bind_api, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - -#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync) - .fence_add = _cogl_winsys_fence_add, - .fence_is_complete = _cogl_winsys_fence_is_complete, - .fence_destroy = _cogl_winsys_fence_destroy, -#endif - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -const CoglWinsysVtable * -_cogl_winsys_egl_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} - -#ifdef EGL_KHR_image_base -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; - - g_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 -#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT - /* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used - * in conjunction with the EGL_WAYLAND_BUFFER_WL target */ - if (target == EGL_WAYLAND_BUFFER_WL) - 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); -} - -void -_cogl_egl_destroy_image (CoglContext *ctx, - EGLImageKHR image) -{ - CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - - g_return_if_fail (egl_renderer->pf_eglDestroyImage); - - egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image); -} -#endif - -#ifdef EGL_WL_bind_wayland_display -gboolean -_cogl_egl_query_wayland_buffer (CoglContext *ctx, - struct wl_resource *buffer, - int attribute, - int *value) -{ - CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; - - g_return_val_if_fail (egl_renderer->pf_eglQueryWaylandBuffer, FALSE); - - return egl_renderer->pf_eglQueryWaylandBuffer (egl_renderer->edpy, - buffer, - attribute, - value); -} -#endif - -EGLDisplay -cogl_egl_context_get_egl_display (CoglContext *context) -{ - CoglRendererEGL *egl_renderer = context->display->renderer->winsys; - - return egl_renderer->edpy; -} diff --git a/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h b/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h deleted file mode 100644 index 31e73dbc2..000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx-feature-functions.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -/* This can be included multiple times with different definitions for - * the COGL_WINSYS_FEATURE_* functions. - */ - -/* Macro prototypes: - * COGL_WINSYS_FEATURE_BEGIN (major_glx_version, minor_glx_version, - * name, namespaces, extension_names, - * implied_legacy_feature_flags, - * implied_winsys_feature) - * COGL_WINSYS_FEATURE_FUNCTION (return_type, function_name, - * (arguments)) - * ... - * COGL_WINSYS_FEATURE_END () - * - * Note: You can list multiple namespace and extension names if the - * corresponding _FEATURE_FUNCTIONS have the same semantics across - * the different extension variants. - * - * XXX: NB: Don't add a trailing semicolon when using these macros - */ - -/* Base functions that we assume are always available */ -COGL_WINSYS_FEATURE_BEGIN (0, 0, /* always available */ - base_glx_functions, - "\0", - "\0", - 0, /* no implied public feature */ - 0 /* no winsys feature */) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyContext, - (Display *dpy, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXSwapBuffers, - (Display *dpy, GLXDrawable drawable)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXIsDirect, - (Display *dpy, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetFBConfigAttrib, - (Display *dpy, GLXFBConfig config, - int attribute, int *value)) -COGL_WINSYS_FEATURE_FUNCTION (GLXWindow, glXCreateWindow, - (Display *dpy, GLXFBConfig config, - Window win, const int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyWindow, - (Display *dpy, GLXWindow window)) -COGL_WINSYS_FEATURE_FUNCTION (GLXPixmap, glXCreatePixmap, - (Display *dpy, GLXFBConfig config, - Pixmap pixmap, const int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXDestroyPixmap, - (Display *dpy, GLXPixmap pixmap)) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateNewContext, - (Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, - Bool direct)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXMakeContextCurrent, - (Display *dpy, GLXDrawable draw, - GLXDrawable read, GLXContext ctx)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXSelectEvent, - (Display *dpy, GLXDrawable drawable, - unsigned long mask)) -COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXGetFBConfigs, - (Display *dpy, int screen, int *nelements)) -COGL_WINSYS_FEATURE_FUNCTION (GLXFBConfig *, glXChooseFBConfig, - (Display *dpy, int screen, - const int *attrib_list, int *nelements)) -COGL_WINSYS_FEATURE_FUNCTION (XVisualInfo *, glXGetVisualFromFBConfig, - (Display *dpy, GLXFBConfig config)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - texture_from_pixmap, - "EXT\0", - "texture_from_pixmap\0", - 0, - COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) -COGL_WINSYS_FEATURE_FUNCTION (void, glXBindTexImage, - (Display *display, - GLXDrawable drawable, - int buffer, - int *attribList)) -COGL_WINSYS_FEATURE_FUNCTION (void, glXReleaseTexImage, - (Display *display, - GLXDrawable drawable, - int buffer)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - video_sync, - "SGI\0", - "video_sync\0", - 0, - COGL_WINSYS_FEATURE_VBLANK_COUNTER) -COGL_WINSYS_FEATURE_FUNCTION (int, glXGetVideoSync, - (unsigned int *count)) -COGL_WINSYS_FEATURE_FUNCTION (int, glXWaitVideoSync, - (int divisor, - int remainder, - unsigned int *count)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_control, - "SGI\0", - "swap_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (int, glXSwapInterval, - (int interval)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - sync_control, - "OML\0", - "sync_control\0", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXGetSyncValues, - (Display* dpy, - GLXDrawable drawable, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_FUNCTION (Bool, glXWaitForMsc, - (Display* dpy, - GLXDrawable drawable, - int64_t target_msc, - int64_t divisor, - int64_t remainder, - int64_t* ust, - int64_t* msc, - int64_t* sbc)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - copy_sub_buffer, - "MESA\0", - "copy_sub_buffer\0", - 0, -/* We initially assumed that copy_sub_buffer is synchronized on - * which is only the case for a subset of GPUs for example it is not - * synchronized on INTEL gen6 and gen7, so we remove this assumption - * for now - */ -#if 0 - COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED) -#endif - 0) -COGL_WINSYS_FEATURE_FUNCTION (void, glXCopySubBuffer, - (Display *dpy, - GLXDrawable drawable, - int x, int y, int width, int height)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - swap_event, - "INTEL\0", - "swap_event\0", - 0, - COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) - -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - create_context, - "ARB\0", - "create_context", - 0, - 0) -COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs, - (Display *dpy, - GLXFBConfig config, - GLXContext share_context, - Bool direct, - const int *attrib_list)) -COGL_WINSYS_FEATURE_END () - -COGL_WINSYS_FEATURE_BEGIN (255, 255, - buffer_age, - "EXT\0", - "buffer_age\0", - 0, - COGL_WINSYS_FEATURE_BUFFER_AGE) -COGL_WINSYS_FEATURE_END () diff --git a/cogl/cogl/winsys/cogl-winsys-glx-private.h b/cogl/cogl/winsys/cogl-winsys-glx-private.h deleted file mode 100644 index 7151a8efe..000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx-private.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2012 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_WINSYS_GLX_PRIVATE_H -#define __COGL_WINSYS_GLX_PRIVATE_H - -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void); - -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - const CoglFramebufferConfig *config, - GLXFBConfig *config_ret, - GError **error); - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable); - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context); - -#endif /* __COGL_WINSYS_GLX_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c deleted file mode 100644 index f3738e07c..000000000 --- a/cogl/cogl/winsys/cogl-winsys-glx.c +++ /dev/null @@ -1,1461 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - * Authors: - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cogl-config.h" - -#include "cogl-i18n-private.h" -#include "cogl-util.h" -#include "cogl-feature-private.h" -#include "cogl-context-private.h" -#include "cogl-framebuffer.h" -#include "cogl-swap-chain-private.h" -#include "cogl-renderer-private.h" -#include "cogl-glx-renderer-private.h" -#include "cogl-onscreen-template-private.h" -#include "cogl-glx-display-private.h" -#include "cogl-private.h" -#include "cogl-texture-2d-private.h" -#include "cogl-frame-info-private.h" -#include "cogl-framebuffer-private.h" -#include "cogl-onscreen-private.h" -#include "cogl-swap-chain-private.h" -#include "cogl-xlib-renderer.h" -#include "cogl-util.h" -#include "cogl-poll-private.h" -#include "cogl-version.h" -#include "cogl-glx.h" -#include "driver/gl/cogl-pipeline-opengl-private.h" -#include "winsys/cogl-onscreen-glx.h" -#include "winsys/cogl-winsys-private.h" -#include "winsys/cogl-winsys-glx-private.h" - -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <errno.h> -#include <fcntl.h> -#include <time.h> -#include <unistd.h> - -#include <GL/glx.h> -#include <X11/Xlib.h> - -#include <glib.h> - -/* This is a relatively new extension */ -#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV -#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 -#endif - -#define MAX_GLX_CONFIG_ATTRIBS 30 - -typedef struct _CoglOnscreenGlx CoglOnscreenGlx; - -typedef struct _CoglContextGLX -{ - GLXDrawable current_drawable; -} CoglContextGLX; - -typedef struct _CoglPixmapTextureEyeGLX -{ - CoglTexture *glx_tex; - gboolean bind_tex_image_queued; - gboolean pixmap_bound; -} CoglPixmapTextureEyeGLX; - -typedef struct _CoglTexturePixmapGLX -{ - GLXPixmap glx_pixmap; - gboolean has_mipmap_space; - gboolean can_mipmap; - - CoglPixmapTextureEyeGLX left; - CoglPixmapTextureEyeGLX right; -} CoglTexturePixmapGLX; - -/* Define a set of arrays containing the functions required from GL - for each winsys feature */ -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - static const CoglFeatureFunction \ - cogl_glx_feature_ ## name ## _funcs[] = { -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \ - { G_STRINGIFY (name), G_STRUCT_OFFSET (CoglGLXRenderer, name) }, -#define COGL_WINSYS_FEATURE_END() \ - { NULL, 0 }, \ - }; -#include "winsys/cogl-winsys-glx-feature-functions.h" - -/* Define an array of features */ -#undef COGL_WINSYS_FEATURE_BEGIN -#define COGL_WINSYS_FEATURE_BEGIN(major_version, minor_version, \ - name, namespaces, extension_names, \ - feature_flags, \ - winsys_feature) \ - { major_version, minor_version, \ - 0, namespaces, extension_names, \ - 0, \ - winsys_feature, \ - cogl_glx_feature_ ## name ## _funcs }, -#undef COGL_WINSYS_FEATURE_FUNCTION -#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) -#undef COGL_WINSYS_FEATURE_END -#define COGL_WINSYS_FEATURE_END() - -static const CoglFeatureData winsys_feature_data[] = - { -#include "winsys/cogl-winsys-glx-feature-functions.h" - }; - -static GCallback -_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer, - const char *name, - gboolean in_core) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - /* The GLX_ARB_get_proc_address extension documents that this should - * work for core functions too so we don't need to do anything - * special with in_core */ - - return glx_renderer->glXGetProcAddress ((const GLubyte *) name); -} - -static CoglOnscreen * -find_onscreen_for_xid (CoglContext *context, uint32_t xid) -{ - GList *l; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - CoglOnscreen *onscreen; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - onscreen = COGL_ONSCREEN (framebuffer); - if (cogl_onscreen_glx_is_for_window (onscreen, (Window) xid)) - return onscreen; - } - - return NULL; -} - -static void -notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event) -{ - CoglOnscreen *onscreen = find_onscreen_for_xid (context, (uint32_t)swap_event->drawable); - - if (!onscreen) - return; - - cogl_onscreen_glx_notify_swap_buffers (onscreen, swap_event); -} - -static void -notify_resize (CoglContext *context, - XConfigureEvent *configure_event) -{ - CoglOnscreen *onscreen; - - onscreen = find_onscreen_for_xid (context, configure_event->window); - if (!onscreen) - return; - - cogl_onscreen_glx_resize (onscreen, configure_event); -} - -static CoglFilterReturn -glx_event_filter_cb (XEvent *xevent, void *data) -{ - CoglContext *context = data; -#ifdef GLX_INTEL_swap_event - CoglGLXRenderer *glx_renderer; -#endif - - if (xevent->type == ConfigureNotify) - { - notify_resize (context, - &xevent->xconfigure); - - /* we let ConfigureNotify pass through */ - return COGL_FILTER_CONTINUE; - } - -#ifdef GLX_INTEL_swap_event - glx_renderer = context->display->renderer->winsys; - - if (xevent->type == (glx_renderer->glx_event_base + GLX_BufferSwapComplete)) - { - GLXBufferSwapComplete *swap_event = (GLXBufferSwapComplete *) xevent; - - notify_swap_buffers (context, swap_event); - - /* remove SwapComplete events from the queue */ - return COGL_FILTER_REMOVE; - } -#endif /* GLX_INTEL_swap_event */ - - if (xevent->type == Expose) - { - CoglOnscreen *onscreen = - find_onscreen_for_xid (context, xevent->xexpose.window); - - if (onscreen) - { - CoglOnscreenDirtyInfo info; - - info.x = xevent->xexpose.x; - info.y = xevent->xexpose.y; - info.width = xevent->xexpose.width; - info.height = xevent->xexpose.height; - - _cogl_onscreen_queue_dirty (onscreen, &info); - } - - return COGL_FILTER_CONTINUE; - } - - return COGL_FILTER_CONTINUE; -} - -static void -_cogl_winsys_renderer_disconnect (CoglRenderer *renderer) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - - _cogl_xlib_renderer_disconnect (renderer); - - if (glx_renderer->libgl_module) - g_module_close (glx_renderer->libgl_module); - - g_free (renderer->winsys); -} - -static gboolean -update_all_outputs (CoglRenderer *renderer) -{ - GList *l; - - _COGL_GET_CONTEXT (context, FALSE); - - if (context->display == NULL) /* during connection */ - return FALSE; - - if (context->display->renderer != renderer) - return FALSE; - - for (l = context->framebuffers; l; l = l->next) - { - CoglFramebuffer *framebuffer = l->data; - - if (!COGL_IS_ONSCREEN (framebuffer)) - continue; - - cogl_onscreen_glx_update_output (COGL_ONSCREEN (framebuffer)); - } - - return TRUE; -} - -static void -_cogl_winsys_renderer_outputs_changed (CoglRenderer *renderer) -{ - update_all_outputs (renderer); -} - -static void -_cogl_winsys_renderer_bind_api (CoglRenderer *renderer) -{ -} - -static gboolean -resolve_core_glx_functions (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - - glx_renderer = renderer->winsys; - - if (!g_module_symbol (glx_renderer->libgl_module, "glXQueryExtension", - (void **) &glx_renderer->glXQueryExtension) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryVersion", - (void **) &glx_renderer->glXQueryVersion) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryExtensionsString", - (void **) &glx_renderer->glXQueryExtensionsString) || - (!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress", - (void **) &glx_renderer->glXGetProcAddress) && - !g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddressARB", - (void **) &glx_renderer->glXGetProcAddress)) || - !g_module_symbol (glx_renderer->libgl_module, "glXQueryDrawable", - (void **) &glx_renderer->glXQueryDrawable)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to resolve required GLX symbol"); - return FALSE; - } - - return TRUE; -} - -static void -update_base_winsys_features (CoglRenderer *renderer) -{ - CoglGLXRenderer *glx_renderer = renderer->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (renderer); - const char *glx_extensions; - int default_screen; - char **split_extensions; - int i; - - default_screen = DefaultScreen (xlib_renderer->xdpy); - glx_extensions = - glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - default_screen); - - COGL_NOTE (WINSYS, " GLX Extensions: %s", glx_extensions); - - split_extensions = g_strsplit (glx_extensions, " ", 0 /* max_tokens */); - - for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++) - if (_cogl_feature_check (renderer, - "GLX", winsys_feature_data + i, - glx_renderer->glx_major, - glx_renderer->glx_minor, - COGL_DRIVER_GL, /* the driver isn't used */ - split_extensions, - glx_renderer)) - { - if (winsys_feature_data[i].winsys_feature) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - winsys_feature_data[i].winsys_feature, - TRUE); - } - - g_strfreev (split_extensions); - - /* The GLX_SGI_video_sync spec explicitly states this extension - * only works for direct contexts; we don't know per-renderer - * if the context is direct or not, so we turn off the feature - * flag; we still use the extension within this file looking - * instead at glx_display->have_vblank_counter. - */ - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_COUNTER, - FALSE); - - - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_MULTIPLE_ONSCREEN, - TRUE); - - /* Because of the direct-context dependency, the VBLANK_WAIT feature - * doesn't reflect the presence of GLX_SGI_video_sync. - */ - if (glx_renderer->glXWaitForMsc) - COGL_FLAGS_SET (glx_renderer->base_winsys_features, - COGL_WINSYS_FEATURE_VBLANK_WAIT, - TRUE); -} - -static gboolean -_cogl_winsys_renderer_connect (CoglRenderer *renderer, - GError **error) -{ - CoglGLXRenderer *glx_renderer; - CoglXlibRenderer *xlib_renderer; - - renderer->winsys = g_new0 (CoglGLXRenderer, 1); - - glx_renderer = renderer->winsys; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - - if (!_cogl_xlib_renderer_connect (renderer, error)) - goto error; - - if (renderer->driver != COGL_DRIVER_GL && - renderer->driver != COGL_DRIVER_GL3) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "GLX Backend can only be used in conjunction with OpenGL"); - goto error; - } - - glx_renderer->libgl_module = g_module_open (COGL_GL_LIBNAME, - G_MODULE_BIND_LAZY); - - if (glx_renderer->libgl_module == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "Failed to dynamically open the OpenGL library"); - goto error; - } - - if (!resolve_core_glx_functions (renderer, error)) - goto error; - - if (!glx_renderer->glXQueryExtension (xlib_renderer->xdpy, - &glx_renderer->glx_error_base, - &glx_renderer->glx_event_base)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX support"); - goto error; - } - - /* XXX: Note: For a long time Mesa exported a hybrid GLX, exporting - * extensions specified to require GLX 1.3, but still reporting 1.2 - * via glXQueryVersion. */ - if (!glx_renderer->glXQueryVersion (xlib_renderer->xdpy, - &glx_renderer->glx_major, - &glx_renderer->glx_minor) - || !(glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 2)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_INIT, - "XServer appears to lack required GLX 1.2 support"); - goto error; - } - - update_base_winsys_features (renderer); - - glx_renderer->dri_fd = -1; - - return TRUE; - -error: - _cogl_winsys_renderer_disconnect (renderer); - return FALSE; -} - -static gboolean -update_winsys_features (CoglContext *context, GError **error) -{ - CoglGLXDisplay *glx_display = context->display->winsys; - CoglGLXRenderer *glx_renderer = context->display->renderer->winsys; - - g_return_val_if_fail (glx_display->glx_context, FALSE); - - if (!_cogl_context_update_features (context, error)) - return FALSE; - - memcpy (context->winsys_features, - glx_renderer->base_winsys_features, - sizeof (context->winsys_features)); - - if (glx_renderer->glXCopySubBuffer || context->glBlitFramebuffer) - COGL_FLAGS_SET (context->winsys_features, COGL_WINSYS_FEATURE_SWAP_REGION, TRUE); - - /* Note: glXCopySubBuffer and glBlitFramebuffer won't be throttled - * by the SwapInterval so we have to throttle swap_region requests - * manually... */ - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION) && - (glx_display->have_vblank_counter || glx_display->can_vblank_wait)) - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE); - - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT)) - { - COGL_FLAGS_SET (context->winsys_features, - COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE); - } - - /* We'll manually handle queueing dirty events in response to - * Expose events from X */ - COGL_FLAGS_SET (context->private_features, - COGL_PRIVATE_FEATURE_DIRTY_EVENTS, - TRUE); - - if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE)) - COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_BUFFER_AGE, TRUE); - - return TRUE; -} - -static void -glx_attributes_from_framebuffer_config (CoglDisplay *display, - const CoglFramebufferConfig *config, - int *attributes) -{ - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - int i = 0; - - attributes[i++] = GLX_DRAWABLE_TYPE; - attributes[i++] = GLX_WINDOW_BIT; - - attributes[i++] = GLX_RENDER_TYPE; - attributes[i++] = GLX_RGBA_BIT; - - attributes[i++] = GLX_DOUBLEBUFFER; - attributes[i++] = GL_TRUE; - - attributes[i++] = GLX_RED_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_GREEN_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_BLUE_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_ALPHA_SIZE; - attributes[i++] = GLX_DONT_CARE; - attributes[i++] = GLX_DEPTH_SIZE; - attributes[i++] = 1; - attributes[i++] = GLX_STENCIL_SIZE; - attributes[i++] = config->need_stencil ? 2 : 0; - if (config->stereo_enabled) - { - attributes[i++] = GLX_STEREO; - attributes[i++] = TRUE; - } - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4 && - config->samples_per_pixel) - { - attributes[i++] = GLX_SAMPLE_BUFFERS; - attributes[i++] = 1; - attributes[i++] = GLX_SAMPLES; - attributes[i++] = config->samples_per_pixel; - } - - attributes[i++] = None; - - g_assert (i < MAX_GLX_CONFIG_ATTRIBS); -} - -/* It seems the GLX spec never defined an invalid GLXFBConfig that - * we could overload as an indication of error, so we have to return - * an explicit boolean status. */ -gboolean -cogl_display_glx_find_fbconfig (CoglDisplay *display, - const CoglFramebufferConfig *config, - GLXFBConfig *config_ret, - GError **error) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXFBConfig *configs = NULL; - int n_configs; - static int attributes[MAX_GLX_CONFIG_ATTRIBS]; - gboolean ret = TRUE; - int xscreen_num = DefaultScreen (xlib_renderer->xdpy); - - glx_attributes_from_framebuffer_config (display, config, attributes); - - configs = glx_renderer->glXChooseFBConfig (xlib_renderer->xdpy, - xscreen_num, - attributes, - &n_configs); - - if (!configs || n_configs == 0) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Failed to find any compatible fbconfigs"); - ret = FALSE; - goto done; - } - - COGL_NOTE (WINSYS, "Using the first available FBConfig"); - *config_ret = configs[0]; - -done: - XFree (configs); - return ret; -} - -static GLXContext -create_gl3_context (CoglDisplay *display, - GLXFBConfig fb_config) -{ - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - - /* We want a core profile 3.1 context with no deprecated features */ - static const int attrib_list[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - None - }; - /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context - and in part on ARB_robustness. Namely, it needs the notification - strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the - driver exposes the GetGraphicsResetStatusARB function. This means - we don't actually enable robust buffer access. */ - static const int attrib_list_reset_on_purge[] = - { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 1, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, - GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, - GL_TRUE, - GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_LOSE_CONTEXT_ON_RESET_ARB, - None - }; - - /* Make sure that the display supports the GLX_ARB_create_context - extension */ - if (glx_renderer->glXCreateContextAttribs == NULL) - return NULL; - - /* We can't check the presence of this extension with the usual - COGL_WINSYS_FEATURE machinery because that only gets initialized - later when the CoglContext is created. */ - if (display->renderer->xlib_want_reset_on_video_memory_purge && - strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, - DefaultScreen (xlib_renderer->xdpy)), - "GLX_NV_robustness_video_memory_purge")) - { - CoglXlibTrapState old_state; - GLXContext ctx; - - _cogl_xlib_renderer_trap_errors (display->renderer, &old_state); - ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list_reset_on_purge); - if (!_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) && ctx) - return ctx; - } - - return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, - fb_config, - NULL /* share_context */, - True, /* direct */ - attrib_list); -} - -static gboolean -create_context (CoglDisplay *display, GError **error) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - GLXFBConfig config; - GError *fbconfig_error = NULL; - XSetWindowAttributes attrs; - XVisualInfo *xvisinfo; - GLXDrawable dummy_drawable; - CoglXlibTrapState old_state; - - g_return_val_if_fail (glx_display->glx_context == NULL, TRUE); - - glx_display->found_fbconfig = - cogl_display_glx_find_fbconfig (display, - &display->onscreen_template->config, - &config, - &fbconfig_error); - if (!glx_display->found_fbconfig) - { - g_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to find suitable fbconfig for the GLX context: %s", - fbconfig_error->message); - g_error_free (fbconfig_error); - return FALSE; - } - - glx_display->fbconfig = config; - - COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", - xlib_renderer->xdpy); - - _cogl_xlib_renderer_trap_errors (display->renderer, &old_state); - - if (display->renderer->driver == COGL_DRIVER_GL3) - glx_display->glx_context = create_gl3_context (display, config); - else - glx_display->glx_context = - glx_renderer->glXCreateNewContext (xlib_renderer->xdpy, - config, - GLX_RGBA_TYPE, - NULL, - True); - - if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) || - glx_display->glx_context == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to create suitable GL context"); - return FALSE; - } - - glx_display->is_direct = - glx_renderer->glXIsDirect (xlib_renderer->xdpy, glx_display->glx_context); - glx_display->have_vblank_counter = glx_display->is_direct && glx_renderer->glXWaitVideoSync; - glx_display->can_vblank_wait = glx_renderer->glXWaitForMsc || glx_display->have_vblank_counter; - - COGL_NOTE (WINSYS, "Setting %s context", - glx_display->is_direct ? "direct" : "indirect"); - - /* XXX: GLX doesn't let us make a context current without a window - * so we create a dummy window that we can use while no CoglOnscreen - * framebuffer is in use. - */ - - xvisinfo = glx_renderer->glXGetVisualFromFBConfig (xlib_renderer->xdpy, - config); - if (xvisinfo == NULL) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to retrieve the X11 visual"); - return FALSE; - } - - _cogl_xlib_renderer_trap_errors (display->renderer, &old_state); - - attrs.override_redirect = True; - attrs.colormap = XCreateColormap (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - xvisinfo->visual, - AllocNone); - attrs.border_pixel = 0; - - glx_display->dummy_xwin = - XCreateWindow (xlib_renderer->xdpy, - DefaultRootWindow (xlib_renderer->xdpy), - -100, -100, 1, 1, - 0, - xvisinfo->depth, - CopyFromParent, - xvisinfo->visual, - CWOverrideRedirect | CWColormap | CWBorderPixel, - &attrs); - - /* Try and create a GLXWindow to use with extensions dependent on - * GLX versions >= 1.3 that don't accept regular X Windows as GLX - * drawables. */ - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 3) - { - glx_display->dummy_glxwin = - glx_renderer->glXCreateWindow (xlib_renderer->xdpy, - config, - glx_display->dummy_xwin, - NULL); - } - - if (glx_display->dummy_glxwin) - dummy_drawable = glx_display->dummy_glxwin; - else - dummy_drawable = glx_display->dummy_xwin; - - COGL_NOTE (WINSYS, "Selecting dummy 0x%x for the GLX context", - (unsigned int) dummy_drawable); - - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - dummy_drawable, - dummy_drawable, - glx_display->glx_context); - - xlib_renderer->xvisinfo = xvisinfo; - - if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state)) - { - g_set_error_literal (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "Unable to select the newly created GLX context"); - return FALSE; - } - - return TRUE; -} - -static void -_cogl_winsys_display_destroy (CoglDisplay *display) -{ - CoglGLXDisplay *glx_display = display->winsys; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (display->renderer); - CoglGLXRenderer *glx_renderer = display->renderer->winsys; - - g_return_if_fail (glx_display != NULL); - - if (glx_display->glx_context) - { - glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy, - None, None, NULL); - glx_renderer->glXDestroyContext (xlib_renderer->xdpy, - glx_display->glx_context); - glx_display->glx_context = NULL; - } - - if (glx_display->dummy_glxwin) - { - glx_renderer->glXDestroyWindow (xlib_renderer->xdpy, - glx_display->dummy_glxwin); - glx_display->dummy_glxwin = None; - } - - if (glx_display->dummy_xwin) - { - XDestroyWindow (xlib_renderer->xdpy, glx_display->dummy_xwin); - glx_display->dummy_xwin = None; - } - - g_free (display->winsys); - display->winsys = NULL; -} - -static gboolean -_cogl_winsys_display_setup (CoglDisplay *display, - GError **error) -{ - CoglGLXDisplay *glx_display; - int i; - - g_return_val_if_fail (display->winsys == NULL, FALSE); - - glx_display = g_new0 (CoglGLXDisplay, 1); - display->winsys = glx_display; - - if (!create_context (display, error)) - goto error; - - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - glx_display->glx_cached_configs[i].depth = -1; - - return TRUE; - -error: - _cogl_winsys_display_destroy (display); - return FALSE; -} - -static gboolean -_cogl_winsys_context_init (CoglContext *context, GError **error) -{ - context->winsys = g_new0 (CoglContextGLX, 1); - - cogl_xlib_renderer_add_filter (context->display->renderer, - glx_event_filter_cb, - context); - return update_winsys_features (context, error); -} - -static void -_cogl_winsys_context_deinit (CoglContext *context) -{ - cogl_xlib_renderer_remove_filter (context->display->renderer, - glx_event_filter_cb, - context); - g_free (context->winsys); -} - -static gboolean -get_fbconfig_for_depth (CoglContext *context, - unsigned int depth, - gboolean stereo, - GLXFBConfig *fbconfig_ret, - gboolean *can_mipmap_ret) -{ - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - CoglGLXDisplay *glx_display; - Display *dpy; - GLXFBConfig *fbconfigs; - int n_elements, i; - int db, stencil, alpha, mipmap, rgba, value; - int spare_cache_slot = 0; - gboolean found = FALSE; - - xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer); - glx_renderer = context->display->renderer->winsys; - glx_display = context->display->winsys; - - /* Check if we've already got a cached config for this depth and stereo */ - for (i = 0; i < COGL_GLX_N_CACHED_CONFIGS; i++) - if (glx_display->glx_cached_configs[i].depth == -1) - spare_cache_slot = i; - else if (glx_display->glx_cached_configs[i].depth == depth && - glx_display->glx_cached_configs[i].stereo == stereo) - { - *fbconfig_ret = glx_display->glx_cached_configs[i].fb_config; - *can_mipmap_ret = glx_display->glx_cached_configs[i].can_mipmap; - return glx_display->glx_cached_configs[i].found; - } - - dpy = xlib_renderer->xdpy; - - fbconfigs = glx_renderer->glXGetFBConfigs (dpy, DefaultScreen (dpy), - &n_elements); - - db = G_MAXSHORT; - stencil = G_MAXSHORT; - mipmap = 0; - rgba = 0; - - for (i = 0; i < n_elements; i++) - { - XVisualInfo *vi; - int visual_depth; - - vi = glx_renderer->glXGetVisualFromFBConfig (dpy, fbconfigs[i]); - if (vi == NULL) - continue; - - visual_depth = vi->depth; - - XFree (vi); - - if (visual_depth != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_ALPHA_SIZE, - &alpha); - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BUFFER_SIZE, - &value); - if (value != depth && (value - alpha) != depth) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STEREO, - &value); - if (!!value != !!stereo) - continue; - - if (glx_renderer->glx_major == 1 && glx_renderer->glx_minor >= 4) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_SAMPLES, - &value); - if (value > 1) - continue; - } - - value = 0; - if (depth == 32) - { - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGBA_EXT, - &value); - if (value) - rgba = 1; - } - - if (!value) - { - if (rgba) - continue; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_TEXTURE_RGB_EXT, - &value); - if (!value) - continue; - } - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_DOUBLEBUFFER, - &value); - if (value > db) - continue; - - db = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_STENCIL_SIZE, - &value); - if (value > stencil) - continue; - - stencil = value; - - glx_renderer->glXGetFBConfigAttrib (dpy, - fbconfigs[i], - GLX_BIND_TO_MIPMAP_TEXTURE_EXT, - &value); - - if (value < mipmap) - continue; - - mipmap = value; - - *fbconfig_ret = fbconfigs[i]; - *can_mipmap_ret = mipmap; - found = TRUE; - } - - if (n_elements) - XFree (fbconfigs); - - glx_display->glx_cached_configs[spare_cache_slot].depth = depth; - glx_display->glx_cached_configs[spare_cache_slot].found = found; - glx_display->glx_cached_configs[spare_cache_slot].fb_config = *fbconfig_ret; - glx_display->glx_cached_configs[spare_cache_slot].can_mipmap = mipmap; - - return found; -} - -static gboolean -try_create_glx_pixmap (CoglContext *context, - CoglTexturePixmapX11 *tex_pixmap, - gboolean mipmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - Display *dpy; - /* We have to initialize this *opaque* variable because gcc tries to - * be too smart for its own good and warns that the variable may be - * used uninitialized otherwise. */ - GLXFBConfig fb_config = (GLXFBConfig)0; - int attribs[7]; - int i = 0; - CoglXlibTrapState trap_state; - - unsigned int depth = tex_pixmap->depth; - Visual* visual = tex_pixmap->visual; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = renderer->winsys; - dpy = xlib_renderer->xdpy; - - if (!get_fbconfig_for_depth (context, depth, - tex_pixmap->stereo_mode != COGL_TEXTURE_PIXMAP_MONO, - &fb_config, - &glx_tex_pixmap->can_mipmap)) - { - COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i", - depth); - return FALSE; - } - - if (!glx_tex_pixmap->can_mipmap) - mipmap = FALSE; - - attribs[i++] = GLX_TEXTURE_FORMAT_EXT; - - /* Check whether an alpha channel is used by comparing the total - * number of 1-bits in color masks against the color depth requested - * by the client. - */ - if (_cogl_util_popcountl (visual->red_mask | - visual->green_mask | - visual->blue_mask) == depth) - attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; - else - attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; - - attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; - attribs[i++] = mipmap; - - attribs[i++] = GLX_TEXTURE_TARGET_EXT; - attribs[i++] = GLX_TEXTURE_2D_EXT; - - attribs[i++] = None; - - /* We need to trap errors from glXCreatePixmap because it can - * sometimes fail during normal usage. For example on NVidia it gets - * upset if you try to create two GLXPixmaps for the same drawable. - */ - - _cogl_xlib_renderer_trap_errors (renderer, &trap_state); - - glx_tex_pixmap->glx_pixmap = - glx_renderer->glXCreatePixmap (dpy, - fb_config, - tex_pixmap->pixmap, - attribs); - glx_tex_pixmap->has_mipmap_space = mipmap; - - XSync (dpy, False); - - if (_cogl_xlib_renderer_untrap_errors (renderer, &trap_state)) - { - COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); - _cogl_xlib_renderer_trap_errors (renderer, &trap_state); - glx_renderer->glXDestroyPixmap (dpy, glx_tex_pixmap->glx_pixmap); - XSync (dpy, False); - _cogl_xlib_renderer_untrap_errors (renderer, &trap_state); - - glx_tex_pixmap->glx_pixmap = None; - return FALSE; - } - - return TRUE; -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - CoglContext *ctx = COGL_TEXTURE (tex_pixmap)->context; - - if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP)) - { - tex_pixmap->winsys = NULL; - return FALSE; - } - - glx_tex_pixmap = g_new0 (CoglTexturePixmapGLX, 1); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->can_mipmap = FALSE; - glx_tex_pixmap->has_mipmap_space = FALSE; - - glx_tex_pixmap->left.glx_tex = NULL; - glx_tex_pixmap->right.glx_tex = NULL; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; - - tex_pixmap->winsys = glx_tex_pixmap; - - if (!try_create_glx_pixmap (ctx, tex_pixmap, FALSE)) - { - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); - return FALSE; - } - - return TRUE; -} - -static void -free_glx_pixmap (CoglContext *context, - CoglTexturePixmapGLX *glx_tex_pixmap) -{ - CoglXlibTrapState trap_state; - CoglRenderer *renderer; - CoglXlibRenderer *xlib_renderer; - CoglGLXRenderer *glx_renderer; - - renderer = context->display->renderer; - xlib_renderer = _cogl_xlib_renderer_get_data (renderer); - glx_renderer = renderer->winsys; - - if (glx_tex_pixmap->left.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_LEFT_EXT); - if (glx_tex_pixmap->right.pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - GLX_FRONT_RIGHT_EXT); - - /* FIXME - we need to trap errors and synchronize here because - * of ordering issues between the XPixmap destruction and the - * GLXPixmap destruction. - * - * If the X pixmap is destroyed, the GLX pixmap is destroyed as - * well immediately, and thus, when Cogl calls glXDestroyPixmap() - * it'll cause a BadDrawable error. - * - * this is technically a bug in the X server, which should not - * destroy either pixmaps until the call to glXDestroyPixmap(); so - * at some point we should revisit this code and remove the - * trap+sync after verifying that the destruction is indeed safe. - * - * for reference, see: - * http://bugzilla.clutter-project.org/show_bug.cgi?id=2324 - */ - _cogl_xlib_renderer_trap_errors (renderer, &trap_state); - glx_renderer->glXDestroyPixmap (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap); - XSync (xlib_renderer->xdpy, False); - _cogl_xlib_renderer_untrap_errors (renderer, &trap_state); - - glx_tex_pixmap->glx_pixmap = None; - glx_tex_pixmap->left.pixmap_bound = FALSE; - glx_tex_pixmap->right.pixmap_bound = FALSE; -} - -static void -_cogl_winsys_texture_pixmap_x11_free (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap; - - if (!tex_pixmap->winsys) - return; - - glx_tex_pixmap = tex_pixmap->winsys; - - free_glx_pixmap (COGL_TEXTURE (tex_pixmap)->context, glx_tex_pixmap); - - if (glx_tex_pixmap->left.glx_tex) - cogl_object_unref (glx_tex_pixmap->left.glx_tex); - - if (glx_tex_pixmap->right.glx_tex) - cogl_object_unref (glx_tex_pixmap->right.glx_tex); - - tex_pixmap->winsys = NULL; - g_free (glx_tex_pixmap); -} - -static gboolean -_cogl_winsys_texture_pixmap_x11_update (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap) -{ - CoglTexture *tex = COGL_TEXTURE (tex_pixmap); - CoglContext *ctx = COGL_TEXTURE (tex_pixmap)->context; - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - CoglPixmapTextureEyeGLX *texture_info; - int buffer; - CoglGLXRenderer *glx_renderer; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - { - texture_info = &glx_tex_pixmap->right; - buffer = GLX_FRONT_RIGHT_EXT; - } - else - { - texture_info = &glx_tex_pixmap->left; - buffer = GLX_FRONT_LEFT_EXT; - } - - /* If we don't have a GLX pixmap then fallback */ - if (glx_tex_pixmap->glx_pixmap == None) - return FALSE; - - glx_renderer = ctx->display->renderer->winsys; - - /* Lazily create a texture to hold the pixmap */ - if (texture_info->glx_tex == NULL) - { - CoglPixelFormat texture_format; - GError *error = NULL; - - texture_format = (tex_pixmap->depth >= 32 ? - COGL_PIXEL_FORMAT_RGBA_8888_PRE : - COGL_PIXEL_FORMAT_RGB_888); - - texture_info->glx_tex = COGL_TEXTURE ( - cogl_texture_2d_new_with_size (ctx, tex->width, tex->height)); - - _cogl_texture_set_internal_format (tex, texture_format); - - if (cogl_texture_allocate (texture_info->glx_tex, &error)) - COGL_NOTE (TEXTURE_PIXMAP, "Created a texture 2d for %p", tex_pixmap); - else - { - COGL_NOTE (TEXTURE_PIXMAP, "Falling back for %p because a " - "texture 2d could not be created: %s", - tex_pixmap, error->message); - g_error_free (error); - free_glx_pixmap (ctx, glx_tex_pixmap); - return FALSE; - } - } - - if (needs_mipmap) - { - /* If we can't support mipmapping then temporarily fallback */ - if (!glx_tex_pixmap->can_mipmap) - return FALSE; - - /* Recreate the GLXPixmap if it wasn't previously created with a - * mipmap tree */ - if (!glx_tex_pixmap->has_mipmap_space) - { - free_glx_pixmap (ctx, glx_tex_pixmap); - - COGL_NOTE (TEXTURE_PIXMAP, "Recreating GLXPixmap with mipmap " - "support for %p", tex_pixmap); - if (!try_create_glx_pixmap (ctx, tex_pixmap, TRUE)) - - { - /* If the pixmap failed then we'll permanently fallback - * to using XImage. This shouldn't happen. */ - COGL_NOTE (TEXTURE_PIXMAP, "Falling back to XGetImage " - "updates for %p because creating the GLXPixmap " - "with mipmap support failed", tex_pixmap); - - if (texture_info->glx_tex) - cogl_object_unref (texture_info->glx_tex); - return FALSE; - } - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; - } - } - - if (texture_info->bind_tex_image_queued) - { - GLuint gl_handle, gl_target; - CoglXlibRenderer *xlib_renderer = - _cogl_xlib_renderer_get_data (ctx->display->renderer); - - cogl_texture_get_gl_texture (texture_info->glx_tex, - &gl_handle, &gl_target); - - COGL_NOTE (TEXTURE_PIXMAP, "Rebinding GLXPixmap for %p", tex_pixmap); - - _cogl_bind_gl_texture_transient (gl_target, gl_handle); - - if (texture_info->pixmap_bound) - glx_renderer->glXReleaseTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer); - - glx_renderer->glXBindTexImage (xlib_renderer->xdpy, - glx_tex_pixmap->glx_pixmap, - buffer, - NULL); - - /* According to the recommended usage in the spec for - * GLX_EXT_texture_pixmap we should release the texture after - * we've finished drawing with it and it is undefined what - * happens if you render to a pixmap that is bound to a texture. - * However that would require the texture backend to know when - * Cogl has finished painting and it may be more expensive to - * keep unbinding the texture. Leaving it bound appears to work - * on Mesa and NVidia drivers and it is also what Compiz does so - * it is probably ok */ - - texture_info->bind_tex_image_queued = FALSE; - texture_info->pixmap_bound = TRUE; - - _cogl_texture_2d_externally_modified (texture_info->glx_tex); - } - - return TRUE; -} - -static void -_cogl_winsys_texture_pixmap_x11_damage_notify (CoglTexturePixmapX11 *tex_pixmap) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - glx_tex_pixmap->left.bind_tex_image_queued = TRUE; - glx_tex_pixmap->right.bind_tex_image_queued = TRUE; -} - -static CoglTexture * -_cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode) -{ - CoglTexturePixmapGLX *glx_tex_pixmap = tex_pixmap->winsys; - - if (stereo_mode == COGL_TEXTURE_PIXMAP_RIGHT) - return glx_tex_pixmap->right.glx_tex; - else - return glx_tex_pixmap->left.glx_tex; -} - -void -cogl_context_glx_set_current_drawable (CoglContext *context, - GLXDrawable drawable) -{ - CoglContextGLX *glx_context = context->winsys; - - glx_context->current_drawable = drawable; -} - -GLXDrawable -cogl_context_glx_get_current_drawable (CoglContext *context) -{ - CoglContextGLX *glx_context = context->winsys; - - return glx_context->current_drawable; -} - -static CoglWinsysVtable _cogl_winsys_vtable = - { - .id = COGL_WINSYS_ID_GLX, - .name = "GLX", - .constraints = (COGL_RENDERER_CONSTRAINT_USES_X11 | - COGL_RENDERER_CONSTRAINT_USES_XLIB), - - .renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address, - .renderer_connect = _cogl_winsys_renderer_connect, - .renderer_disconnect = _cogl_winsys_renderer_disconnect, - .renderer_outputs_changed = _cogl_winsys_renderer_outputs_changed, - .renderer_bind_api = _cogl_winsys_renderer_bind_api, - .display_setup = _cogl_winsys_display_setup, - .display_destroy = _cogl_winsys_display_destroy, - .context_init = _cogl_winsys_context_init, - .context_deinit = _cogl_winsys_context_deinit, - - /* X11 tfp support... */ - /* XXX: instead of having a rather monolithic winsys vtable we could - * perhaps look for a way to separate these... */ - .texture_pixmap_x11_create = - _cogl_winsys_texture_pixmap_x11_create, - .texture_pixmap_x11_free = - _cogl_winsys_texture_pixmap_x11_free, - .texture_pixmap_x11_update = - _cogl_winsys_texture_pixmap_x11_update, - .texture_pixmap_x11_damage_notify = - _cogl_winsys_texture_pixmap_x11_damage_notify, - .texture_pixmap_x11_get_texture = - _cogl_winsys_texture_pixmap_x11_get_texture, - }; - -/* XXX: we use a function because no doubt someone will complain - * about using c99 member initializers because they aren't portable - * to windows. We want to avoid having to rigidly follow the real - * order of members since some members are #ifdefd and we'd have - * to mirror the #ifdefing to add padding etc. For any winsys that - * can assume the platform has a sane compiler then we can just use - * c99 initializers for insane platforms they can initialize - * the members by name in a function. - */ -COGL_EXPORT const CoglWinsysVtable * -_cogl_winsys_glx_get_vtable (void) -{ - return &_cogl_winsys_vtable; -} diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h deleted file mode 100644 index b323a704d..000000000 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#ifndef __COGL_WINSYS_PRIVATE_H -#define __COGL_WINSYS_PRIVATE_H - -#include "cogl-renderer.h" -#include "cogl-scanout.h" - -#ifdef COGL_HAS_XLIB_SUPPORT -#include "cogl-texture-pixmap-x11-private.h" -#endif - -#ifdef COGL_HAS_XLIB_SUPPORT -#include <X11/Xutil.h> -#include "cogl-texture-pixmap-x11-private.h" -#endif - -#ifdef COGL_HAS_EGL_SUPPORT -#include "cogl-egl-private.h" -#endif - -#include "cogl-poll.h" - -COGL_EXPORT uint32_t -_cogl_winsys_error_quark (void); - -#define COGL_WINSYS_ERROR (_cogl_winsys_error_quark ()) - -typedef enum /*< prefix=COGL_WINSYS_ERROR >*/ -{ - COGL_WINSYS_ERROR_INIT, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - COGL_WINSYS_ERROR_CREATE_ONSCREEN, - COGL_WINSYS_ERROR_MAKE_CURRENT, -} CoglWinsysError; - -typedef struct _CoglWinsysVtable -{ - CoglWinsysID id; - CoglRendererConstraint constraints; - - const char *name; - - /* Required functions */ - - GCallback - (*renderer_get_proc_address) (CoglRenderer *renderer, - const char *name, - gboolean in_core); - - gboolean - (*renderer_connect) (CoglRenderer *renderer, GError **error); - - void - (*renderer_disconnect) (CoglRenderer *renderer); - - void - (*renderer_outputs_changed) (CoglRenderer *renderer); - - gboolean - (*display_setup) (CoglDisplay *display, GError **error); - - void - (*display_destroy) (CoglDisplay *display); - - CoglDmaBufHandle * - (*renderer_create_dma_buf) (CoglRenderer *renderer, - int width, - int height, - GError **error); - - void - (*renderer_bind_api) (CoglRenderer *renderer); - - gboolean - (*context_init) (CoglContext *context, GError **error); - - void - (*context_deinit) (CoglContext *context); - - /* Optional functions */ - -#ifdef COGL_HAS_XLIB_SUPPORT - gboolean - (*texture_pixmap_x11_create) (CoglTexturePixmapX11 *tex_pixmap); - void - (*texture_pixmap_x11_free) (CoglTexturePixmapX11 *tex_pixmap); - - gboolean - (*texture_pixmap_x11_update) (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode, - gboolean needs_mipmap); - - void - (*texture_pixmap_x11_damage_notify) (CoglTexturePixmapX11 *tex_pixmap); - - CoglTexture * - (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap, - CoglTexturePixmapStereoMode stereo_mode); -#endif - - void * - (*fence_add) (CoglContext *ctx); - - gboolean - (*fence_is_complete) (CoglContext *ctx, void *fence); - - void - (*fence_destroy) (CoglContext *ctx, void *fence); - -} CoglWinsysVtable; - -typedef const CoglWinsysVtable *(*CoglWinsysVtableGetter) (void); - -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature); - -#endif /* __COGL_WINSYS_PRIVATE_H */ diff --git a/cogl/cogl/winsys/cogl-winsys.c b/cogl/cogl/winsys/cogl-winsys.c deleted file mode 100644 index 9eacd81c0..000000000 --- a/cogl/cogl/winsys/cogl-winsys.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Cogl - * - * A Low Level GPU Graphics and Utilities API - * - * Copyright (C) 2007,2008,2009,2010 Intel Corporation. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * - */ - -#include "cogl-config.h" - -#include "cogl-context-private.h" - -#include <gmodule.h> - -uint32_t -_cogl_winsys_error_quark (void) -{ - return g_quark_from_static_string ("cogl-winsys-error-quark"); -} - -/* FIXME: we should distinguish renderer and context features */ -gboolean -_cogl_winsys_has_feature (CoglWinsysFeature feature) -{ - _COGL_GET_CONTEXT (ctx, FALSE); - - return COGL_FLAGS_GET (ctx->winsys_features, feature); -} |