|
|
21ac67 |
Only things missing here from upstream are translations and .gitignore changes
|
|
|
21ac67 |
|
|
|
21ac67 |
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
|
|
|
21ac67 |
index 33214ab..80d3b09 100644
|
|
|
21ac67 |
--- a/cogl/Makefile.am
|
|
|
21ac67 |
+++ b/cogl/Makefile.am
|
|
|
21ac67 |
@@ -349,6 +349,8 @@ cogl_sources_c = \
|
|
|
21ac67 |
$(srcdir)/cogl-pipeline-snippet.c \
|
|
|
21ac67 |
$(srcdir)/cogl-pipeline-cache.h \
|
|
|
21ac67 |
$(srcdir)/cogl-pipeline-cache.c \
|
|
|
21ac67 |
+ $(srcdir)/cogl-pipeline-hash-table.h \
|
|
|
21ac67 |
+ $(srcdir)/cogl-pipeline-hash-table.c \
|
|
|
21ac67 |
$(srcdir)/cogl-material-compat.c \
|
|
|
21ac67 |
$(srcdir)/cogl-program.c \
|
|
|
21ac67 |
$(srcdir)/cogl-program-private.h \
|
|
|
21ac67 |
@@ -552,7 +554,7 @@ include $(top_srcdir)/build/autotools/Makefile.am.enums
|
|
|
21ac67 |
|
|
|
21ac67 |
lib_LTLIBRARIES += libcogl.la
|
|
|
21ac67 |
|
|
|
21ac67 |
-libcogl_la_LIBADD = -lm $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
|
|
21ac67 |
+libcogl_la_LIBADD = $(LIBM) $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
|
|
21ac67 |
if !USE_GLIB
|
|
|
21ac67 |
libcogl_la_LIBADD += $(top_builddir)/deps/glib/libglib.la
|
|
|
21ac67 |
libcogl_la_LIBADD += $(top_builddir)/deps/gmodule/libgmodule.la
|
|
|
21ac67 |
diff --git a/cogl/cogl-bitmap-pixbuf.c b/cogl/cogl-bitmap-pixbuf.c
|
|
|
21ac67 |
index a02b253..ad34234 100644
|
|
|
21ac67 |
--- a/cogl/cogl-bitmap-pixbuf.c
|
|
|
21ac67 |
+++ b/cogl/cogl-bitmap-pixbuf.c
|
|
|
21ac67 |
@@ -125,11 +125,24 @@ _cogl_bitmap_from_file (CoglContext *ctx,
|
|
|
21ac67 |
/* allocate buffer big enough to hold pixel data */
|
|
|
21ac67 |
bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
|
|
|
21ac67 |
width, height,
|
|
|
21ac67 |
- COGL_PIXEL_FORMAT_ARGB_8888);
|
|
|
21ac67 |
+ COGL_PIXEL_FORMAT_ARGB_8888,
|
|
|
21ac67 |
+ error);
|
|
|
21ac67 |
+ if (bmp == NULL)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ CFRelease (image);
|
|
|
21ac67 |
+ return NULL;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
rowstride = cogl_bitmap_get_rowstride (bmp);
|
|
|
21ac67 |
out_data = _cogl_bitmap_map (bmp,
|
|
|
21ac67 |
COGL_BUFFER_ACCESS_WRITE,
|
|
|
21ac67 |
- COGL_BUFFER_MAP_HINT_DISCARD);
|
|
|
21ac67 |
+ COGL_BUFFER_MAP_HINT_DISCARD,
|
|
|
21ac67 |
+ error);
|
|
|
21ac67 |
+ if (out_data == NULL)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ cogl_object_unref (bmp);
|
|
|
21ac67 |
+ CFRelease (image);
|
|
|
21ac67 |
+ return NULL;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
|
|
|
21ac67 |
/* render to buffer */
|
|
|
21ac67 |
color_space = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
|
|
|
21ac67 |
diff --git a/cogl/cogl-matrix.h b/cogl/cogl-matrix.h
|
|
|
21ac67 |
index 90f3ea9..a136ea0 100644
|
|
|
21ac67 |
--- a/cogl/cogl-matrix.h
|
|
|
21ac67 |
+++ b/cogl/cogl-matrix.h
|
|
|
21ac67 |
@@ -27,6 +27,8 @@
|
|
|
21ac67 |
#ifndef __COGL_MATRIX_H
|
|
|
21ac67 |
#define __COGL_MATRIX_H
|
|
|
21ac67 |
|
|
|
21ac67 |
+#include <cogl/cogl-defines.h>
|
|
|
21ac67 |
+
|
|
|
21ac67 |
#ifdef COGL_HAS_GTYPE_SUPPORT
|
|
|
21ac67 |
#include <glib-object.h>
|
|
|
21ac67 |
#endif /* COGL_HAS_GTYPE_SUPPORT */
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline-cache.c b/cogl/cogl-pipeline-cache.c
|
|
|
21ac67 |
index fab3614..df4c433 100644
|
|
|
21ac67 |
--- a/cogl/cogl-pipeline-cache.c
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline-cache.c
|
|
|
21ac67 |
@@ -3,7 +3,7 @@
|
|
|
21ac67 |
*
|
|
|
21ac67 |
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
21ac67 |
*
|
|
|
21ac67 |
- * Copyright (C) 2011 Intel Corporation.
|
|
|
21ac67 |
+ * Copyright (C) 2011, 2013 Intel Corporation.
|
|
|
21ac67 |
*
|
|
|
21ac67 |
* This library is free software; you can redistribute it and/or
|
|
|
21ac67 |
* modify it under the terms of the GNU Lesser General Public
|
|
|
21ac67 |
@@ -32,133 +32,47 @@
|
|
|
21ac67 |
#include "cogl-context-private.h"
|
|
|
21ac67 |
#include "cogl-pipeline-private.h"
|
|
|
21ac67 |
#include "cogl-pipeline-cache.h"
|
|
|
21ac67 |
+#include "cogl-pipeline-hash-table.h"
|
|
|
21ac67 |
|
|
|
21ac67 |
struct _CoglPipelineCache
|
|
|
21ac67 |
{
|
|
|
21ac67 |
- GHashTable *fragment_hash;
|
|
|
21ac67 |
- GHashTable *vertex_hash;
|
|
|
21ac67 |
- GHashTable *combined_hash;
|
|
|
21ac67 |
+ CoglPipelineHashTable fragment_hash;
|
|
|
21ac67 |
+ CoglPipelineHashTable vertex_hash;
|
|
|
21ac67 |
+ CoglPipelineHashTable combined_hash;
|
|
|
21ac67 |
};
|
|
|
21ac67 |
|
|
|
21ac67 |
-static unsigned int
|
|
|
21ac67 |
-pipeline_fragment_hash (const void *data)
|
|
|
21ac67 |
-{
|
|
|
21ac67 |
- unsigned int fragment_state;
|
|
|
21ac67 |
- unsigned int layer_fragment_state;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- _COGL_GET_CONTEXT (ctx, 0);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- fragment_state =
|
|
|
21ac67 |
- _cogl_pipeline_get_state_for_fragment_codegen (ctx);
|
|
|
21ac67 |
- layer_fragment_state =
|
|
|
21ac67 |
- _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return _cogl_pipeline_hash ((CoglPipeline *)data,
|
|
|
21ac67 |
- fragment_state, layer_fragment_state,
|
|
|
21ac67 |
- 0);
|
|
|
21ac67 |
-}
|
|
|
21ac67 |
-
|
|
|
21ac67 |
-static CoglBool
|
|
|
21ac67 |
-pipeline_fragment_equal (const void *a, const void *b)
|
|
|
21ac67 |
+CoglPipelineCache *
|
|
|
21ac67 |
+_cogl_pipeline_cache_new (void)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
+ CoglPipelineCache *cache = g_new (CoglPipelineCache, 1);
|
|
|
21ac67 |
+ unsigned long vertex_state;
|
|
|
21ac67 |
+ unsigned long layer_vertex_state;
|
|
|
21ac67 |
unsigned int fragment_state;
|
|
|
21ac67 |
unsigned int layer_fragment_state;
|
|
|
21ac67 |
|
|
|
21ac67 |
_COGL_GET_CONTEXT (ctx, 0);
|
|
|
21ac67 |
|
|
|
21ac67 |
+ vertex_state =
|
|
|
21ac67 |
+ COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
+ layer_vertex_state =
|
|
|
21ac67 |
+ COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
fragment_state =
|
|
|
21ac67 |
_cogl_pipeline_get_state_for_fragment_codegen (ctx);
|
|
|
21ac67 |
layer_fragment_state =
|
|
|
21ac67 |
_cogl_pipeline_get_layer_state_for_fragment_codegen (ctx);
|
|
|
21ac67 |
|
|
|
21ac67 |
- return _cogl_pipeline_equal ((CoglPipeline *)a, (CoglPipeline *)b,
|
|
|
21ac67 |
- fragment_state, layer_fragment_state,
|
|
|
21ac67 |
- 0);
|
|
|
21ac67 |
-}
|
|
|
21ac67 |
-
|
|
|
21ac67 |
-static unsigned int
|
|
|
21ac67 |
-pipeline_vertex_hash (const void *data)
|
|
|
21ac67 |
-{
|
|
|
21ac67 |
- unsigned long vertex_state =
|
|
|
21ac67 |
- COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
- unsigned long layer_vertex_state =
|
|
|
21ac67 |
- COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return _cogl_pipeline_hash ((CoglPipeline *)data,
|
|
|
21ac67 |
- vertex_state, layer_vertex_state,
|
|
|
21ac67 |
- 0);
|
|
|
21ac67 |
-}
|
|
|
21ac67 |
-
|
|
|
21ac67 |
-static CoglBool
|
|
|
21ac67 |
-pipeline_vertex_equal (const void *a, const void *b)
|
|
|
21ac67 |
-{
|
|
|
21ac67 |
- unsigned long vertex_state =
|
|
|
21ac67 |
- COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
- unsigned long layer_vertex_state =
|
|
|
21ac67 |
- COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return _cogl_pipeline_equal ((CoglPipeline *)a, (CoglPipeline *)b,
|
|
|
21ac67 |
- vertex_state, layer_vertex_state,
|
|
|
21ac67 |
- 0);
|
|
|
21ac67 |
-}
|
|
|
21ac67 |
-
|
|
|
21ac67 |
-static unsigned int
|
|
|
21ac67 |
-pipeline_combined_hash (const void *data)
|
|
|
21ac67 |
-{
|
|
|
21ac67 |
- unsigned int combined_state;
|
|
|
21ac67 |
- unsigned int layer_combined_state;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- _COGL_GET_CONTEXT (ctx, 0);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- combined_state =
|
|
|
21ac67 |
- _cogl_pipeline_get_state_for_fragment_codegen (ctx) |
|
|
|
21ac67 |
- COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
- layer_combined_state =
|
|
|
21ac67 |
- _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) |
|
|
|
21ac67 |
- COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return _cogl_pipeline_hash ((CoglPipeline *)data,
|
|
|
21ac67 |
- combined_state, layer_combined_state,
|
|
|
21ac67 |
- 0);
|
|
|
21ac67 |
-}
|
|
|
21ac67 |
-
|
|
|
21ac67 |
-static CoglBool
|
|
|
21ac67 |
-pipeline_combined_equal (const void *a, const void *b)
|
|
|
21ac67 |
-{
|
|
|
21ac67 |
- unsigned int combined_state;
|
|
|
21ac67 |
- unsigned int layer_combined_state;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- _COGL_GET_CONTEXT (ctx, 0);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- combined_state =
|
|
|
21ac67 |
- _cogl_pipeline_get_state_for_fragment_codegen (ctx) |
|
|
|
21ac67 |
- COGL_PIPELINE_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
- layer_combined_state =
|
|
|
21ac67 |
- _cogl_pipeline_get_layer_state_for_fragment_codegen (ctx) |
|
|
|
21ac67 |
- COGL_PIPELINE_LAYER_STATE_AFFECTS_VERTEX_CODEGEN;
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return _cogl_pipeline_equal ((CoglPipeline *)a, (CoglPipeline *)b,
|
|
|
21ac67 |
- combined_state, layer_combined_state,
|
|
|
21ac67 |
- 0);
|
|
|
21ac67 |
-}
|
|
|
21ac67 |
-
|
|
|
21ac67 |
-CoglPipelineCache *
|
|
|
21ac67 |
-_cogl_pipeline_cache_new (void)
|
|
|
21ac67 |
-{
|
|
|
21ac67 |
- CoglPipelineCache *cache = g_new (CoglPipelineCache, 1);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- cache->fragment_hash = g_hash_table_new_full (pipeline_fragment_hash,
|
|
|
21ac67 |
- pipeline_fragment_equal,
|
|
|
21ac67 |
- cogl_object_unref,
|
|
|
21ac67 |
- cogl_object_unref);
|
|
|
21ac67 |
- cache->vertex_hash = g_hash_table_new_full (pipeline_vertex_hash,
|
|
|
21ac67 |
- pipeline_vertex_equal,
|
|
|
21ac67 |
- cogl_object_unref,
|
|
|
21ac67 |
- cogl_object_unref);
|
|
|
21ac67 |
- cache->combined_hash = g_hash_table_new_full (pipeline_combined_hash,
|
|
|
21ac67 |
- pipeline_combined_equal,
|
|
|
21ac67 |
- cogl_object_unref,
|
|
|
21ac67 |
- cogl_object_unref);
|
|
|
21ac67 |
+ _cogl_pipeline_hash_table_init (&cache->vertex_hash,
|
|
|
21ac67 |
+ vertex_state,
|
|
|
21ac67 |
+ layer_vertex_state,
|
|
|
21ac67 |
+ "vertex shaders");
|
|
|
21ac67 |
+ _cogl_pipeline_hash_table_init (&cache->fragment_hash,
|
|
|
21ac67 |
+ fragment_state,
|
|
|
21ac67 |
+ layer_fragment_state,
|
|
|
21ac67 |
+ "fragment shaders");
|
|
|
21ac67 |
+ _cogl_pipeline_hash_table_init (&cache->combined_hash,
|
|
|
21ac67 |
+ vertex_state | fragment_state,
|
|
|
21ac67 |
+ layer_vertex_state | layer_fragment_state,
|
|
|
21ac67 |
+ "programs");
|
|
|
21ac67 |
|
|
|
21ac67 |
return cache;
|
|
|
21ac67 |
}
|
|
|
21ac67 |
@@ -166,9 +80,9 @@ _cogl_pipeline_cache_new (void)
|
|
|
21ac67 |
void
|
|
|
21ac67 |
_cogl_pipeline_cache_free (CoglPipelineCache *cache)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
- g_hash_table_destroy (cache->fragment_hash);
|
|
|
21ac67 |
- g_hash_table_destroy (cache->vertex_hash);
|
|
|
21ac67 |
- g_hash_table_destroy (cache->combined_hash);
|
|
|
21ac67 |
+ _cogl_pipeline_hash_table_destroy (&cache->fragment_hash);
|
|
|
21ac67 |
+ _cogl_pipeline_hash_table_destroy (&cache->vertex_hash);
|
|
|
21ac67 |
+ _cogl_pipeline_hash_table_destroy (&cache->combined_hash);
|
|
|
21ac67 |
g_free (cache);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
@@ -176,107 +90,22 @@ CoglPipeline *
|
|
|
21ac67 |
_cogl_pipeline_cache_get_fragment_template (CoglPipelineCache *cache,
|
|
|
21ac67 |
CoglPipeline *key_pipeline)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
- CoglPipeline *template =
|
|
|
21ac67 |
- g_hash_table_lookup (cache->fragment_hash, key_pipeline);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- if (template == NULL)
|
|
|
21ac67 |
- {
|
|
|
21ac67 |
- /* XXX: I wish there was a way to insert into a GHashTable with
|
|
|
21ac67 |
- * a pre-calculated hash value since there is a cost to
|
|
|
21ac67 |
- * calculating the hash of a CoglPipeline and in this case we
|
|
|
21ac67 |
- * know we have already called _cogl_pipeline_hash during the
|
|
|
21ac67 |
- * lookup so we could pass the value through to here to avoid
|
|
|
21ac67 |
- * hashing it again.
|
|
|
21ac67 |
- */
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- /* XXX: Any keys referenced by the hash table need to remain
|
|
|
21ac67 |
- * valid all the while that there are corresponding values,
|
|
|
21ac67 |
- * so for now we simply make a copy of the current authority
|
|
|
21ac67 |
- * pipeline.
|
|
|
21ac67 |
- *
|
|
|
21ac67 |
- * FIXME: A problem with this is that our key into the cache may
|
|
|
21ac67 |
- * hold references to some arbitrary user textures which will
|
|
|
21ac67 |
- * now be kept alive indefinitly which is a shame. A better
|
|
|
21ac67 |
- * solution will be to derive a special "key pipeline" from the
|
|
|
21ac67 |
- * authority which derives from the base Cogl pipeline (to avoid
|
|
|
21ac67 |
- * affecting the lifetime of any other pipelines) and only takes
|
|
|
21ac67 |
- * a copy of the state that relates to the fragment shader and
|
|
|
21ac67 |
- * references small dummy textures instead of potentially large
|
|
|
21ac67 |
- * user textures. */
|
|
|
21ac67 |
- template = cogl_pipeline_copy (key_pipeline);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- g_hash_table_insert (cache->fragment_hash,
|
|
|
21ac67 |
- template,
|
|
|
21ac67 |
- cogl_object_ref (template));
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- if (G_UNLIKELY (g_hash_table_size (cache->fragment_hash) > 50))
|
|
|
21ac67 |
- {
|
|
|
21ac67 |
- static CoglBool seen = FALSE;
|
|
|
21ac67 |
- if (!seen)
|
|
|
21ac67 |
- g_warning ("Over 50 separate fragment shaders have been "
|
|
|
21ac67 |
- "generated which is very unusual, so something "
|
|
|
21ac67 |
- "is probably wrong!\n");
|
|
|
21ac67 |
- seen = TRUE;
|
|
|
21ac67 |
- }
|
|
|
21ac67 |
- }
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return template;
|
|
|
21ac67 |
+ return _cogl_pipeline_hash_table_get (&cache->fragment_hash,
|
|
|
21ac67 |
+ key_pipeline);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
CoglPipeline *
|
|
|
21ac67 |
_cogl_pipeline_cache_get_vertex_template (CoglPipelineCache *cache,
|
|
|
21ac67 |
CoglPipeline *key_pipeline)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
- CoglPipeline *template =
|
|
|
21ac67 |
- g_hash_table_lookup (cache->vertex_hash, key_pipeline);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- if (template == NULL)
|
|
|
21ac67 |
- {
|
|
|
21ac67 |
- template = cogl_pipeline_copy (key_pipeline);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- g_hash_table_insert (cache->vertex_hash,
|
|
|
21ac67 |
- template,
|
|
|
21ac67 |
- cogl_object_ref (template));
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- if (G_UNLIKELY (g_hash_table_size (cache->vertex_hash) > 50))
|
|
|
21ac67 |
- {
|
|
|
21ac67 |
- static CoglBool seen = FALSE;
|
|
|
21ac67 |
- if (!seen)
|
|
|
21ac67 |
- g_warning ("Over 50 separate vertex shaders have been "
|
|
|
21ac67 |
- "generated which is very unusual, so something "
|
|
|
21ac67 |
- "is probably wrong!\n");
|
|
|
21ac67 |
- seen = TRUE;
|
|
|
21ac67 |
- }
|
|
|
21ac67 |
- }
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return template;
|
|
|
21ac67 |
+ return _cogl_pipeline_hash_table_get (&cache->vertex_hash,
|
|
|
21ac67 |
+ key_pipeline);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
CoglPipeline *
|
|
|
21ac67 |
_cogl_pipeline_cache_get_combined_template (CoglPipelineCache *cache,
|
|
|
21ac67 |
CoglPipeline *key_pipeline)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
- CoglPipeline *template =
|
|
|
21ac67 |
- g_hash_table_lookup (cache->combined_hash, key_pipeline);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- if (template == NULL)
|
|
|
21ac67 |
- {
|
|
|
21ac67 |
- template = cogl_pipeline_copy (key_pipeline);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- g_hash_table_insert (cache->combined_hash,
|
|
|
21ac67 |
- template,
|
|
|
21ac67 |
- cogl_object_ref (template));
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- if (G_UNLIKELY (g_hash_table_size (cache->combined_hash) > 50))
|
|
|
21ac67 |
- {
|
|
|
21ac67 |
- static CoglBool seen = FALSE;
|
|
|
21ac67 |
- if (!seen)
|
|
|
21ac67 |
- g_warning ("Over 50 separate programs have been "
|
|
|
21ac67 |
- "generated which is very unusual, so something "
|
|
|
21ac67 |
- "is probably wrong!\n");
|
|
|
21ac67 |
- seen = TRUE;
|
|
|
21ac67 |
- }
|
|
|
21ac67 |
- }
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- return template;
|
|
|
21ac67 |
+ return _cogl_pipeline_hash_table_get (&cache->combined_hash,
|
|
|
21ac67 |
+ key_pipeline);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline-hash-table.c b/cogl/cogl-pipeline-hash-table.c
|
|
|
21ac67 |
new file mode 100644
|
|
|
21ac67 |
index 0000000..8921efc
|
|
|
21ac67 |
--- /dev/null
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline-hash-table.c
|
|
|
21ac67 |
@@ -0,0 +1,153 @@
|
|
|
21ac67 |
+/*
|
|
|
21ac67 |
+ * Cogl
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * Copyright (C) 2013 Intel Corporation.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * This library is free software; you can redistribute it and/or
|
|
|
21ac67 |
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
21ac67 |
+ * License as published by the Free Software Foundation; either
|
|
|
21ac67 |
+ * version 2 of the License, or (at your option) any later version.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
21ac67 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
21ac67 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
21ac67 |
+ * Lesser General Public License for more details.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
21ac67 |
+ * License along with this library. If not, see
|
|
|
21ac67 |
+ * <http://www.gnu.org/licenses/>.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * Authors:
|
|
|
21ac67 |
+ * Neil Roberts <neil@linux.intel.com>
|
|
|
21ac67 |
+ * Robert Bragg <robert@linux.intel.com>
|
|
|
21ac67 |
+ */
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#ifdef HAVE_CONFIG_H
|
|
|
21ac67 |
+#include "config.h"
|
|
|
21ac67 |
+#endif
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#include "cogl-context-private.h"
|
|
|
21ac67 |
+#include "cogl-pipeline-private.h"
|
|
|
21ac67 |
+#include "cogl-pipeline-hash-table.h"
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+typedef struct
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ /* The template pipeline */
|
|
|
21ac67 |
+ CoglPipeline *pipeline;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Calculating the hash is a little bit expensive for pipelines so
|
|
|
21ac67 |
+ * we don't want to do it repeatedly for entries that are already in
|
|
|
21ac67 |
+ * the hash table. Instead we cache the value here and calculate it
|
|
|
21ac67 |
+ * outside of the GHashTable. */
|
|
|
21ac67 |
+ unsigned int hash_value;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* GHashTable annoyingly doesn't let us pass a user data pointer to
|
|
|
21ac67 |
+ * the hash and equal functions so to work around it we have to
|
|
|
21ac67 |
+ * store the pointer in every hash table entry. We will use this
|
|
|
21ac67 |
+ * entry as both the key and the value */
|
|
|
21ac67 |
+ CoglPipelineHashTable *hash;
|
|
|
21ac67 |
+} CoglPipelineHashTableEntry;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+static void
|
|
|
21ac67 |
+value_destroy_cb (void *value)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ CoglPipelineHashTableEntry *entry = value;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ cogl_object_unref (entry->pipeline);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ g_slice_free (CoglPipelineHashTableEntry, entry);
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+static unsigned int
|
|
|
21ac67 |
+entry_hash (const void *data)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ const CoglPipelineHashTableEntry *entry = data;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return entry->hash_value;
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+static CoglBool
|
|
|
21ac67 |
+entry_equal (const void *a,
|
|
|
21ac67 |
+ const void *b)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ const CoglPipelineHashTableEntry *entry_a = a;
|
|
|
21ac67 |
+ const CoglPipelineHashTableEntry *entry_b = b;
|
|
|
21ac67 |
+ const CoglPipelineHashTable *hash = entry_a->hash;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return _cogl_pipeline_equal (entry_a->pipeline,
|
|
|
21ac67 |
+ entry_b->pipeline,
|
|
|
21ac67 |
+ hash->main_state,
|
|
|
21ac67 |
+ hash->layer_state,
|
|
|
21ac67 |
+ 0);
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+_cogl_pipeline_hash_table_init (CoglPipelineHashTable *hash,
|
|
|
21ac67 |
+ unsigned int main_state,
|
|
|
21ac67 |
+ unsigned int layer_state,
|
|
|
21ac67 |
+ const char *debug_string)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ hash->n_unique_pipelines = 0;
|
|
|
21ac67 |
+ hash->debug_string = debug_string;
|
|
|
21ac67 |
+ hash->main_state = main_state;
|
|
|
21ac67 |
+ hash->layer_state = layer_state;
|
|
|
21ac67 |
+ hash->table = g_hash_table_new_full (entry_hash,
|
|
|
21ac67 |
+ entry_equal,
|
|
|
21ac67 |
+ NULL, /* key destroy */
|
|
|
21ac67 |
+ value_destroy_cb);
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+_cogl_pipeline_hash_table_destroy (CoglPipelineHashTable *hash)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ g_hash_table_destroy (hash->table);
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+CoglPipeline *
|
|
|
21ac67 |
+_cogl_pipeline_hash_table_get (CoglPipelineHashTable *hash,
|
|
|
21ac67 |
+ CoglPipeline *key_pipeline)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ CoglPipelineHashTableEntry dummy_entry;
|
|
|
21ac67 |
+ CoglPipelineHashTableEntry *entry;
|
|
|
21ac67 |
+ unsigned int copy_state;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ dummy_entry.pipeline = key_pipeline;
|
|
|
21ac67 |
+ dummy_entry.hash = hash;
|
|
|
21ac67 |
+ dummy_entry.hash_value = _cogl_pipeline_hash (key_pipeline,
|
|
|
21ac67 |
+ hash->main_state,
|
|
|
21ac67 |
+ hash->layer_state,
|
|
|
21ac67 |
+ 0);
|
|
|
21ac67 |
+ entry = g_hash_table_lookup (hash->table, &dummy_entry);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (entry)
|
|
|
21ac67 |
+ return entry->pipeline;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (hash->n_unique_pipelines == 50)
|
|
|
21ac67 |
+ g_warning ("Over 50 separate %s have been generated which is very "
|
|
|
21ac67 |
+ "unusual, so something is probably wrong!\n",
|
|
|
21ac67 |
+ hash->debug_string);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ entry = g_slice_new (CoglPipelineHashTableEntry);
|
|
|
21ac67 |
+ entry->hash = hash;
|
|
|
21ac67 |
+ entry->hash_value = dummy_entry.hash_value;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ copy_state = hash->main_state;
|
|
|
21ac67 |
+ if (hash->layer_state)
|
|
|
21ac67 |
+ copy_state |= COGL_PIPELINE_STATE_LAYERS;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Create a new pipeline that is a child of the root pipeline
|
|
|
21ac67 |
+ * instead of a normal copy so that the template pipeline won't hold
|
|
|
21ac67 |
+ * a reference to the original pipeline */
|
|
|
21ac67 |
+ entry->pipeline = _cogl_pipeline_deep_copy (key_pipeline,
|
|
|
21ac67 |
+ copy_state,
|
|
|
21ac67 |
+ hash->layer_state);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ g_hash_table_insert (hash->table, entry, entry);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ hash->n_unique_pipelines++;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return entry->pipeline;
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline-hash-table.h b/cogl/cogl-pipeline-hash-table.h
|
|
|
21ac67 |
new file mode 100644
|
|
|
21ac67 |
index 0000000..1b0a0d9
|
|
|
21ac67 |
--- /dev/null
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline-hash-table.h
|
|
|
21ac67 |
@@ -0,0 +1,69 @@
|
|
|
21ac67 |
+/*
|
|
|
21ac67 |
+ * Cogl
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * Copyright (C) 2013 Intel Corporation.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * This library is free software; you can redistribute it and/or
|
|
|
21ac67 |
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
21ac67 |
+ * License as published by the Free Software Foundation; either
|
|
|
21ac67 |
+ * version 2 of the License, or (at your option) any later version.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
21ac67 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
21ac67 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
21ac67 |
+ * Lesser General Public License for more details.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
21ac67 |
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ *
|
|
|
21ac67 |
+ */
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#ifndef __COGL_PIPELINE_HASH_H__
|
|
|
21ac67 |
+#define __COGL_PIPELINE_HASH_H__
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#include "cogl-pipeline.h"
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+typedef struct
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ /* Total number of pipelines that were ever added to the hash. This
|
|
|
21ac67 |
+ * is not decremented when a pipeline is removed. It is only used to
|
|
|
21ac67 |
+ * generate a warning if an unusually high number of pipelines are
|
|
|
21ac67 |
+ * generated */
|
|
|
21ac67 |
+ int n_unique_pipelines;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* String that will be used to describe the usage of this hash table
|
|
|
21ac67 |
+ * in the debug warning when too many pipelines are generated. This
|
|
|
21ac67 |
+ * must be a static string because it won't be copied or freed */
|
|
|
21ac67 |
+ const char *debug_string;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ unsigned int main_state;
|
|
|
21ac67 |
+ unsigned int layer_state;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ GHashTable *table;
|
|
|
21ac67 |
+} CoglPipelineHashTable;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+_cogl_pipeline_hash_table_init (CoglPipelineHashTable *hash,
|
|
|
21ac67 |
+ unsigned int main_state,
|
|
|
21ac67 |
+ unsigned int layer_state,
|
|
|
21ac67 |
+ const char *debug_string);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+_cogl_pipeline_hash_table_destroy (CoglPipelineHashTable *hash);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+/*
|
|
|
21ac67 |
+ * Gets a pipeline from the hash that has the same state as
|
|
|
21ac67 |
+ * @key_pipeline according to the limited state bits passed to
|
|
|
21ac67 |
+ * _cogl_pipeline_hash_table_init(). If there is no matching pipelines
|
|
|
21ac67 |
+ * already then a copy of key_pipeline is stored in the hash so that
|
|
|
21ac67 |
+ * it will be used next time the function is called with a similar
|
|
|
21ac67 |
+ * pipeline. In that case the copy itself will be returned
|
|
|
21ac67 |
+ */
|
|
|
21ac67 |
+CoglPipeline *
|
|
|
21ac67 |
+_cogl_pipeline_hash_table_get (CoglPipelineHashTable *hash,
|
|
|
21ac67 |
+ CoglPipeline *key_pipeline);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#endif /* __COGL_PIPELINE_HASH_H__ */
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline-layer-private.h b/cogl/cogl-pipeline-layer-private.h
|
|
|
21ac67 |
index 125b967..7577559 100644
|
|
|
21ac67 |
--- a/cogl/cogl-pipeline-layer-private.h
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline-layer-private.h
|
|
|
21ac67 |
@@ -358,6 +358,11 @@ _cogl_pipeline_layer_get_wrap_mode_t (CoglPipelineLayer *layer);
|
|
|
21ac67 |
CoglPipelineWrapMode
|
|
|
21ac67 |
_cogl_pipeline_layer_get_wrap_mode_p (CoglPipelineLayer *layer);
|
|
|
21ac67 |
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+_cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest,
|
|
|
21ac67 |
+ CoglPipelineLayer *src,
|
|
|
21ac67 |
+ unsigned long differences);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
unsigned long
|
|
|
21ac67 |
_cogl_pipeline_layer_compare_differences (CoglPipelineLayer *layer0,
|
|
|
21ac67 |
CoglPipelineLayer *layer1);
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline-layer.c b/cogl/cogl-pipeline-layer.c
|
|
|
21ac67 |
index d9590c8..9bc26ef 100644
|
|
|
21ac67 |
--- a/cogl/cogl-pipeline-layer.c
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline-layer.c
|
|
|
21ac67 |
@@ -42,6 +42,8 @@
|
|
|
21ac67 |
#include "cogl-context-private.h"
|
|
|
21ac67 |
#include "cogl-texture-private.h"
|
|
|
21ac67 |
|
|
|
21ac67 |
+#include <string.h>
|
|
|
21ac67 |
+
|
|
|
21ac67 |
static void
|
|
|
21ac67 |
_cogl_pipeline_layer_free (CoglPipelineLayer *layer);
|
|
|
21ac67 |
|
|
|
21ac67 |
@@ -146,6 +148,107 @@ _cogl_get_n_args_for_combine_func (CoglPipelineCombineFunc func)
|
|
|
21ac67 |
return 0;
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+_cogl_pipeline_layer_copy_differences (CoglPipelineLayer *dest,
|
|
|
21ac67 |
+ CoglPipelineLayer *src,
|
|
|
21ac67 |
+ unsigned long differences)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ CoglPipelineLayerBigState *big_dest, *big_src;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if ((differences & COGL_PIPELINE_LAYER_STATE_NEEDS_BIG_STATE) &&
|
|
|
21ac67 |
+ !dest->has_big_state)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ dest->big_state = g_slice_new (CoglPipelineLayerBigState);
|
|
|
21ac67 |
+ dest->has_big_state = TRUE;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ big_dest = dest->big_state;
|
|
|
21ac67 |
+ big_src = src->big_state;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ dest->differences |= differences;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ while (differences)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ int index = _cogl_util_ffs (differences) - 1;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ differences &= ~(1 << index);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* This convoluted switch statement is just here so that we'll
|
|
|
21ac67 |
+ * get a warning if a new state is added without handling it
|
|
|
21ac67 |
+ * here */
|
|
|
21ac67 |
+ switch (index)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_COUNT:
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_UNIT_INDEX:
|
|
|
21ac67 |
+ g_warn_if_reached ();
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX:
|
|
|
21ac67 |
+ dest->texture_type = src->texture_type;
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX:
|
|
|
21ac67 |
+ dest->texture = src->texture;
|
|
|
21ac67 |
+ if (dest->texture)
|
|
|
21ac67 |
+ cogl_object_ref (dest->texture);
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_SAMPLER_INDEX:
|
|
|
21ac67 |
+ dest->sampler_cache_entry = src->sampler_cache_entry;
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_COMBINE_INDEX:
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ CoglPipelineCombineFunc func;
|
|
|
21ac67 |
+ int n_args, i;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ func = big_src->texture_combine_rgb_func;
|
|
|
21ac67 |
+ big_dest->texture_combine_rgb_func = func;
|
|
|
21ac67 |
+ n_args = _cogl_get_n_args_for_combine_func (func);
|
|
|
21ac67 |
+ for (i = 0; i < n_args; i++)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ big_dest->texture_combine_rgb_src[i] =
|
|
|
21ac67 |
+ big_src->texture_combine_rgb_src[i];
|
|
|
21ac67 |
+ big_dest->texture_combine_rgb_op[i] =
|
|
|
21ac67 |
+ big_src->texture_combine_rgb_op[i];
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ func = big_src->texture_combine_alpha_func;
|
|
|
21ac67 |
+ big_dest->texture_combine_alpha_func = func;
|
|
|
21ac67 |
+ n_args = _cogl_get_n_args_for_combine_func (func);
|
|
|
21ac67 |
+ for (i = 0; i < n_args; i++)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ big_dest->texture_combine_alpha_src[i] =
|
|
|
21ac67 |
+ big_src->texture_combine_alpha_src[i];
|
|
|
21ac67 |
+ big_dest->texture_combine_alpha_op[i] =
|
|
|
21ac67 |
+ big_src->texture_combine_alpha_op[i];
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_COMBINE_CONSTANT_INDEX:
|
|
|
21ac67 |
+ memcpy (big_dest->texture_combine_constant,
|
|
|
21ac67 |
+ big_src->texture_combine_constant,
|
|
|
21ac67 |
+ sizeof (big_dest->texture_combine_constant));
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS_INDEX:
|
|
|
21ac67 |
+ big_dest->point_sprite_coords = big_src->point_sprite_coords;
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_VERTEX_SNIPPETS_INDEX:
|
|
|
21ac67 |
+ _cogl_pipeline_snippet_list_copy (&big_dest->vertex_snippets,
|
|
|
21ac67 |
+ &big_src->vertex_snippets);
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ case COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS_INDEX:
|
|
|
21ac67 |
+ _cogl_pipeline_snippet_list_copy (&big_dest->fragment_snippets,
|
|
|
21ac67 |
+ &big_src->fragment_snippets);
|
|
|
21ac67 |
+ break;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
static void
|
|
|
21ac67 |
_cogl_pipeline_layer_init_multi_property_sparse_state (
|
|
|
21ac67 |
CoglPipelineLayer *layer,
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
|
|
|
21ac67 |
index 56700b5..acb5653 100644
|
|
|
21ac67 |
--- a/cogl/cogl-pipeline-private.h
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline-private.h
|
|
|
21ac67 |
@@ -845,6 +845,17 @@ _cogl_pipeline_hash (CoglPipeline *pipeline,
|
|
|
21ac67 |
unsigned long layer_differences,
|
|
|
21ac67 |
CoglPipelineEvalFlags flags);
|
|
|
21ac67 |
|
|
|
21ac67 |
+/* Makes a copy of the given pipeline that is a child of the root
|
|
|
21ac67 |
+ * pipeline rather than a child of the source pipeline. That way the
|
|
|
21ac67 |
+ * new pipeline won't hold a reference to the source pipeline. The
|
|
|
21ac67 |
+ * differences specified in @differences and @layer_differences are
|
|
|
21ac67 |
+ * copied across and all other state is left with the default
|
|
|
21ac67 |
+ * values. */
|
|
|
21ac67 |
+CoglPipeline *
|
|
|
21ac67 |
+_cogl_pipeline_deep_copy (CoglPipeline *pipeline,
|
|
|
21ac67 |
+ unsigned long differences,
|
|
|
21ac67 |
+ unsigned long layer_differences);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
CoglPipeline *
|
|
|
21ac67 |
_cogl_pipeline_journal_ref (CoglPipeline *pipeline);
|
|
|
21ac67 |
|
|
|
21ac67 |
diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
|
|
|
21ac67 |
index c029f45..a91ad25 100644
|
|
|
21ac67 |
--- a/cogl/cogl-pipeline.c
|
|
|
21ac67 |
+++ b/cogl/cogl-pipeline.c
|
|
|
21ac67 |
@@ -2771,6 +2771,97 @@ _cogl_pipeline_hash (CoglPipeline *pipeline,
|
|
|
21ac67 |
|
|
|
21ac67 |
typedef struct
|
|
|
21ac67 |
{
|
|
|
21ac67 |
+ CoglContext *context;
|
|
|
21ac67 |
+ CoglPipeline *src_pipeline;
|
|
|
21ac67 |
+ CoglPipeline *dst_pipeline;
|
|
|
21ac67 |
+ unsigned int layer_differences;
|
|
|
21ac67 |
+} DeepCopyData;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+static CoglBool
|
|
|
21ac67 |
+deep_copy_layer_cb (CoglPipelineLayer *src_layer,
|
|
|
21ac67 |
+ void *user_data)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ DeepCopyData *data = user_data;
|
|
|
21ac67 |
+ CoglPipelineLayer *dst_layer;
|
|
|
21ac67 |
+ unsigned int differences = data->layer_differences;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ dst_layer = _cogl_pipeline_get_layer (data->dst_pipeline, src_layer->index);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ while (src_layer != data->context->default_layer_n &&
|
|
|
21ac67 |
+ src_layer != data->context->default_layer_0 &&
|
|
|
21ac67 |
+ differences)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ unsigned long to_copy = differences & src_layer->differences;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (to_copy)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ _cogl_pipeline_layer_copy_differences (dst_layer, src_layer, to_copy);
|
|
|
21ac67 |
+ differences ^= to_copy;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ src_layer = COGL_PIPELINE_LAYER (COGL_NODE (src_layer)->parent);
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return TRUE;
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+CoglPipeline *
|
|
|
21ac67 |
+_cogl_pipeline_deep_copy (CoglPipeline *pipeline,
|
|
|
21ac67 |
+ unsigned long differences,
|
|
|
21ac67 |
+ unsigned long layer_differences)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ CoglPipeline *new, *authority;
|
|
|
21ac67 |
+ CoglBool copy_layer_state;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ _COGL_GET_CONTEXT (ctx, NULL);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if ((differences & COGL_PIPELINE_STATE_LAYERS))
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ copy_layer_state = TRUE;
|
|
|
21ac67 |
+ differences &= ~COGL_PIPELINE_STATE_LAYERS;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+ else
|
|
|
21ac67 |
+ copy_layer_state = FALSE;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ new = cogl_pipeline_new (ctx);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ for (authority = pipeline;
|
|
|
21ac67 |
+ authority != ctx->default_pipeline && differences;
|
|
|
21ac67 |
+ authority = COGL_PIPELINE (COGL_NODE (authority)->parent))
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ unsigned long to_copy = differences & authority->differences;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (to_copy)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ _cogl_pipeline_copy_differences (new, authority, to_copy);
|
|
|
21ac67 |
+ differences ^= to_copy;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (copy_layer_state)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ DeepCopyData data;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* The unit index doesn't need to be copied because it should
|
|
|
21ac67 |
+ * end up with the same values anyway because the new pipeline
|
|
|
21ac67 |
+ * will have the same indices as the source pipeline */
|
|
|
21ac67 |
+ layer_differences &= ~COGL_PIPELINE_LAYER_STATE_UNIT;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ data.context = ctx;
|
|
|
21ac67 |
+ data.src_pipeline = pipeline;
|
|
|
21ac67 |
+ data.dst_pipeline = new;
|
|
|
21ac67 |
+ data.layer_differences = layer_differences;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ _cogl_pipeline_foreach_layer_internal (pipeline,
|
|
|
21ac67 |
+ deep_copy_layer_cb,
|
|
|
21ac67 |
+ &data);
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return new;
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+typedef struct
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
int i;
|
|
|
21ac67 |
CoglPipelineLayer **layers;
|
|
|
21ac67 |
} AddLayersToArrayState;
|
|
|
21ac67 |
diff --git a/cogl/cogl-xlib-renderer.c b/cogl/cogl-xlib-renderer.c
|
|
|
21ac67 |
index 18c0fe6..eb1f51a 100644
|
|
|
21ac67 |
--- a/cogl/cogl-xlib-renderer.c
|
|
|
21ac67 |
+++ b/cogl/cogl-xlib-renderer.c
|
|
|
21ac67 |
@@ -238,7 +238,7 @@ update_outputs (CoglRenderer *renderer,
|
|
|
21ac67 |
|
|
|
21ac67 |
_cogl_xlib_renderer_trap_errors (renderer, &state);
|
|
|
21ac67 |
|
|
|
21ac67 |
- for (i = 0; i < resources->ncrtc && !error; i++)
|
|
|
21ac67 |
+ for (i = 0; resources && i < resources->ncrtc && !error; i++)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
XRRCrtcInfo *crtc_info = NULL;
|
|
|
21ac67 |
XRROutputInfo *output_info = NULL;
|
|
|
21ac67 |
diff --git a/cogl/cogl-xlib.h b/cogl/cogl-xlib.h
|
|
|
21ac67 |
index 7a6bc7e..5dab8ae 100644
|
|
|
21ac67 |
--- a/cogl/cogl-xlib.h
|
|
|
21ac67 |
+++ b/cogl/cogl-xlib.h
|
|
|
21ac67 |
@@ -79,6 +79,8 @@ cogl_xlib_set_display (Display *display);
|
|
|
21ac67 |
CoglFilterReturn
|
|
|
21ac67 |
cogl_xlib_handle_event (XEvent *xevent);
|
|
|
21ac67 |
|
|
|
21ac67 |
+COGL_END_DECLS
|
|
|
21ac67 |
+
|
|
|
21ac67 |
#undef __COGL_XLIB_H_INSIDE__
|
|
|
21ac67 |
|
|
|
21ac67 |
#endif /* __COGL_XLIB_H__ */
|
|
|
21ac67 |
diff --git a/configure.ac b/configure.ac
|
|
|
21ac67 |
index 43bf407..4ba85b8 100644
|
|
|
21ac67 |
--- a/configure.ac
|
|
|
21ac67 |
+++ b/configure.ac
|
|
|
21ac67 |
@@ -25,7 +25,7 @@ m4_define([cogl_version],
|
|
|
21ac67 |
dnl Since the core Cogl library has to also maintain support for the
|
|
|
21ac67 |
dnl Cogl 1.x API for Clutter then we track the 1.x version separately.
|
|
|
21ac67 |
m4_define([cogl_1_minor_version], [14])
|
|
|
21ac67 |
-m4_define([cogl_1_micro_version], [0])
|
|
|
21ac67 |
+m4_define([cogl_1_micro_version], [1])
|
|
|
21ac67 |
m4_define([cogl_1_version], [1.cogl_1_minor_version.cogl_1_micro_version])
|
|
|
21ac67 |
|
|
|
21ac67 |
dnl ================================================================
|
|
|
21ac67 |
@@ -70,7 +70,7 @@ dnl ================================================================
|
|
|
21ac67 |
# libtool version info we don't automatically derive this from the
|
|
|
21ac67 |
# pretty version number because we want to test the results of
|
|
|
21ac67 |
# updating the version number in advance of a release.
|
|
|
21ac67 |
-m4_define([cogl_release_status], [release])
|
|
|
21ac67 |
+m4_define([cogl_release_status], [git])
|
|
|
21ac67 |
|
|
|
21ac67 |
AC_INIT(cogl, [cogl_1_version])
|
|
|
21ac67 |
AC_CONFIG_SRCDIR(cogl/cogl.h)
|
|
|
21ac67 |
@@ -178,6 +178,12 @@ dnl internal glib configure (as-glibconfig.m4)
|
|
|
21ac67 |
m4_ifdef([LT_OUTPUT], [LT_OUTPUT])
|
|
|
21ac67 |
|
|
|
21ac67 |
dnl ================================================================
|
|
|
21ac67 |
+dnl Find an appropriate libm, for sin() etc.
|
|
|
21ac67 |
+dnl ================================================================
|
|
|
21ac67 |
+LT_LIB_M
|
|
|
21ac67 |
+AC_SUBST(LIBM)
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+dnl ================================================================
|
|
|
21ac67 |
dnl See what platform we are building for
|
|
|
21ac67 |
dnl ================================================================
|
|
|
21ac67 |
AC_CANONICAL_HOST
|
|
|
21ac67 |
@@ -474,6 +480,7 @@ AS_IF(
|
|
|
21ac67 |
EXPERIMENTAL_OPTIONS="$EXPERIMENTAL_OPTIONS Quartz Core Graphics,"
|
|
|
21ac67 |
AC_DEFINE([USE_QUARTZ], 1,
|
|
|
21ac67 |
[Use Core Graphics (Quartz) for loading image data])
|
|
|
21ac67 |
+ COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -framework ApplicationServices"
|
|
|
21ac67 |
COGL_IMAGE_BACKEND="quartz"
|
|
|
21ac67 |
],
|
|
|
21ac67 |
[
|
|
|
21ac67 |
@@ -1173,6 +1180,12 @@ AC_CHECK_FUNCS([ffs])
|
|
|
21ac67 |
dnl 'memmem' is a GNU extension but we have a simple fallback
|
|
|
21ac67 |
AC_CHECK_FUNCS([memmem])
|
|
|
21ac67 |
|
|
|
21ac67 |
+dnl This is used in the cogl-gles2-gears example but it is a GNU extension
|
|
|
21ac67 |
+save_libs="$LIBS"
|
|
|
21ac67 |
+LIBS="$LIBS $LIBM"
|
|
|
21ac67 |
+AC_CHECK_FUNCS([sincos])
|
|
|
21ac67 |
+LIBS="$save_libs"
|
|
|
21ac67 |
+
|
|
|
21ac67 |
dnl ================================================================
|
|
|
21ac67 |
dnl Platform values
|
|
|
21ac67 |
dnl ================================================================
|
|
|
21ac67 |
diff --git a/examples/Makefile.am b/examples/Makefile.am
|
|
|
21ac67 |
index 86801c6..ae3e5f7 100644
|
|
|
21ac67 |
--- a/examples/Makefile.am
|
|
|
21ac67 |
+++ b/examples/Makefile.am
|
|
|
21ac67 |
@@ -20,7 +20,8 @@ endif
|
|
|
21ac67 |
|
|
|
21ac67 |
common_ldadd = \
|
|
|
21ac67 |
$(COGL_DEP_LIBS) \
|
|
|
21ac67 |
- $(top_builddir)/cogl/libcogl.la
|
|
|
21ac67 |
+ $(top_builddir)/cogl/libcogl.la \
|
|
|
21ac67 |
+ $(LIBM)
|
|
|
21ac67 |
|
|
|
21ac67 |
if !USE_GLIB
|
|
|
21ac67 |
common_ldadd += $(top_builddir)/deps/glib/libglib.la
|
|
|
21ac67 |
diff --git a/examples/android/hello/jni/main.c b/examples/android/hello/jni/main.c
|
|
|
21ac67 |
index 2c5bd9b..c9a8401 100644
|
|
|
21ac67 |
--- a/examples/android/hello/jni/main.c
|
|
|
21ac67 |
+++ b/examples/android/hello/jni/main.c
|
|
|
21ac67 |
@@ -42,7 +42,7 @@ static int test_init (TestData* data)
|
|
|
21ac67 |
CoglOnscreen *onscreen;
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogl-gles2-context.c b/examples/cogl-gles2-context.c
|
|
|
21ac67 |
index 1cf375f..de66c21 100644
|
|
|
21ac67 |
--- a/examples/cogl-gles2-context.c
|
|
|
21ac67 |
+++ b/examples/cogl-gles2-context.c
|
|
|
21ac67 |
@@ -70,7 +70,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
CoglOnscreen *onscreen;
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogl-gles2-gears.c b/examples/cogl-gles2-gears.c
|
|
|
21ac67 |
index d7dd271..c7185b6 100644
|
|
|
21ac67 |
--- a/examples/cogl-gles2-gears.c
|
|
|
21ac67 |
+++ b/examples/cogl-gles2-gears.c
|
|
|
21ac67 |
@@ -35,6 +35,10 @@
|
|
|
21ac67 |
* Jul 13, 2010
|
|
|
21ac67 |
*/
|
|
|
21ac67 |
|
|
|
21ac67 |
+#ifdef HAVE_CONFIG_H
|
|
|
21ac67 |
+#include "config.h"
|
|
|
21ac67 |
+#endif
|
|
|
21ac67 |
+
|
|
|
21ac67 |
#define GL_GLEXT_PROTOTYPES
|
|
|
21ac67 |
|
|
|
21ac67 |
#include <math.h>
|
|
|
21ac67 |
@@ -110,6 +114,15 @@ static GLfloat ProjectionMatrix[16];
|
|
|
21ac67 |
/** The direction of the directional light for the scene */
|
|
|
21ac67 |
static const GLfloat LightSourcePosition[4] = { 5.0, 5.0, 10.0, 1.0};
|
|
|
21ac67 |
|
|
|
21ac67 |
+#ifndef HAVE_SINCOS
|
|
|
21ac67 |
+static void
|
|
|
21ac67 |
+sincos (double x, double *sinx, double *cosx)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ *sinx = sin (x);
|
|
|
21ac67 |
+ *cosx = cos (x);
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+#endif /* HAVE_SINCOS */
|
|
|
21ac67 |
+
|
|
|
21ac67 |
/**
|
|
|
21ac67 |
* Fills a gear vertex.
|
|
|
21ac67 |
*
|
|
|
21ac67 |
diff --git a/examples/cogl-hello.c b/examples/cogl-hello.c
|
|
|
21ac67 |
index 5bda9bf..3ba1e31 100644
|
|
|
21ac67 |
--- a/examples/cogl-hello.c
|
|
|
21ac67 |
+++ b/examples/cogl-hello.c
|
|
|
21ac67 |
@@ -39,7 +39,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
CoglOnscreen *onscreen;
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogl-msaa.c b/examples/cogl-msaa.c
|
|
|
21ac67 |
index 73f9c4e..4a388bc 100644
|
|
|
21ac67 |
--- a/examples/cogl-msaa.c
|
|
|
21ac67 |
+++ b/examples/cogl-msaa.c
|
|
|
21ac67 |
@@ -12,7 +12,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
CoglFramebuffer *fb;
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogl-sdl-hello.c b/examples/cogl-sdl-hello.c
|
|
|
21ac67 |
index 961137a..acb9125 100644
|
|
|
21ac67 |
--- a/examples/cogl-sdl-hello.c
|
|
|
21ac67 |
+++ b/examples/cogl-sdl-hello.c
|
|
|
21ac67 |
@@ -80,7 +80,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
CoglOnscreen *onscreen;
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogl-sdl2-hello.c b/examples/cogl-sdl2-hello.c
|
|
|
21ac67 |
index 405cb92..12e6ced 100644
|
|
|
21ac67 |
--- a/examples/cogl-sdl2-hello.c
|
|
|
21ac67 |
+++ b/examples/cogl-sdl2-hello.c
|
|
|
21ac67 |
@@ -89,7 +89,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
CoglOnscreen *onscreen;
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogl-x11-foreign.c b/examples/cogl-x11-foreign.c
|
|
|
21ac67 |
index ca9e3ed..a60397c 100644
|
|
|
21ac67 |
--- a/examples/cogl-x11-foreign.c
|
|
|
21ac67 |
+++ b/examples/cogl-x11-foreign.c
|
|
|
21ac67 |
@@ -61,7 +61,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
unsigned long mask;
|
|
|
21ac67 |
Window xwin;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
diff --git a/examples/cogland.c b/examples/cogland.c
|
|
|
21ac67 |
index c18850a..7a02719 100644
|
|
|
21ac67 |
--- a/examples/cogland.c
|
|
|
21ac67 |
+++ b/examples/cogland.c
|
|
|
21ac67 |
@@ -93,7 +93,6 @@ struct _CoglandCompositor
|
|
|
21ac67 |
struct wl_display *wayland_display;
|
|
|
21ac67 |
struct wl_event_loop *wayland_loop;
|
|
|
21ac67 |
|
|
|
21ac67 |
- CoglDisplay *cogl_display;
|
|
|
21ac67 |
CoglContext *cogl_context;
|
|
|
21ac67 |
|
|
|
21ac67 |
int virtual_width;
|
|
|
21ac67 |
@@ -336,15 +335,16 @@ cogland_queue_redraw (CoglandCompositor *compositor)
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
static void
|
|
|
21ac67 |
-shm_buffer_damaged (CoglandSurface *surface,
|
|
|
21ac67 |
- int32_t x,
|
|
|
21ac67 |
- int32_t y,
|
|
|
21ac67 |
- int32_t width,
|
|
|
21ac67 |
- int32_t height)
|
|
|
21ac67 |
+surface_damaged (CoglandSurface *surface,
|
|
|
21ac67 |
+ int32_t x,
|
|
|
21ac67 |
+ int32_t y,
|
|
|
21ac67 |
+ int32_t width,
|
|
|
21ac67 |
+ int32_t height)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
struct wl_buffer *wayland_buffer = surface->buffer;
|
|
|
21ac67 |
|
|
|
21ac67 |
- if (surface->texture)
|
|
|
21ac67 |
+ if (surface->texture &&
|
|
|
21ac67 |
+ wl_buffer_is_shm (surface->buffer))
|
|
|
21ac67 |
{
|
|
|
21ac67 |
CoglPixelFormat format;
|
|
|
21ac67 |
int stride = wl_shm_buffer_get_stride (wayland_buffer);
|
|
|
21ac67 |
@@ -381,6 +381,8 @@ shm_buffer_damaged (CoglandSurface *surface,
|
|
|
21ac67 |
stride,
|
|
|
21ac67 |
data);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ cogland_queue_redraw (surface->compositor);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
static void
|
|
|
21ac67 |
@@ -546,16 +548,18 @@ cogland_surface_commit (struct wl_client *client,
|
|
|
21ac67 |
|
|
|
21ac67 |
wl_signal_add (&surface->buffer->resource.destroy_signal,
|
|
|
21ac67 |
&surface->buffer_destroy_listener);
|
|
|
21ac67 |
- wl_list_remove (&surface->pending.buffer_destroy_listener.link);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
}
|
|
|
21ac67 |
- surface->pending.buffer = NULL;
|
|
|
21ac67 |
+ if (surface->pending.buffer)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ wl_list_remove (&surface->pending.buffer_destroy_listener.link);
|
|
|
21ac67 |
+ surface->pending.buffer = NULL;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
surface->pending.sx = 0;
|
|
|
21ac67 |
surface->pending.sy = 0;
|
|
|
21ac67 |
|
|
|
21ac67 |
/* wl_surface.damage */
|
|
|
21ac67 |
if (surface->buffer &&
|
|
|
21ac67 |
- wl_buffer_is_shm (surface->buffer) &&
|
|
|
21ac67 |
surface->texture &&
|
|
|
21ac67 |
!region_is_empty (&surface->pending.damage))
|
|
|
21ac67 |
{
|
|
|
21ac67 |
@@ -571,11 +575,11 @@ cogland_surface_commit (struct wl_client *client,
|
|
|
21ac67 |
if (region->y1 < 0)
|
|
|
21ac67 |
region->y1 = 0;
|
|
|
21ac67 |
|
|
|
21ac67 |
- shm_buffer_damaged (surface,
|
|
|
21ac67 |
- region->x1,
|
|
|
21ac67 |
- region->y1,
|
|
|
21ac67 |
- region->x2 - region->x1,
|
|
|
21ac67 |
- region->y2 - region->y1);
|
|
|
21ac67 |
+ surface_damaged (surface,
|
|
|
21ac67 |
+ region->x1,
|
|
|
21ac67 |
+ region->y1,
|
|
|
21ac67 |
+ region->x2 - region->x1,
|
|
|
21ac67 |
+ region->y2 - region->y1);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
region_init (&surface->pending.damage);
|
|
|
21ac67 |
|
|
|
21ac67 |
@@ -583,8 +587,6 @@ cogland_surface_commit (struct wl_client *client,
|
|
|
21ac67 |
wl_list_insert_list (&compositor->frame_callbacks,
|
|
|
21ac67 |
&surface->pending.frame_callback_list);
|
|
|
21ac67 |
wl_list_init (&surface->pending.frame_callback_list);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- cogland_queue_redraw (compositor);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
static void
|
|
|
21ac67 |
@@ -614,6 +616,9 @@ cogland_surface_free (CoglandSurface *surface)
|
|
|
21ac67 |
compositor->surfaces = g_list_remove (compositor->surfaces, surface);
|
|
|
21ac67 |
cogland_surface_detach_buffer_and_notify (surface);
|
|
|
21ac67 |
|
|
|
21ac67 |
+ if (surface->pending.buffer)
|
|
|
21ac67 |
+ wl_list_remove (&surface->pending.buffer_destroy_listener.link);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
wl_list_for_each_safe (cb, next,
|
|
|
21ac67 |
&surface->pending.frame_callback_list, link)
|
|
|
21ac67 |
wl_resource_destroy (&cb->resource);
|
|
|
21ac67 |
@@ -970,7 +975,7 @@ get_shell_surface (struct wl_client *client,
|
|
|
21ac67 |
struct wl_resource *surface_resource)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
CoglandSurface *surface = surface_resource->data;
|
|
|
21ac67 |
- CoglandShellSurface *shell_surface = g_new0 (CoglandShellSurface, 1);
|
|
|
21ac67 |
+ CoglandShellSurface *shell_surface;
|
|
|
21ac67 |
|
|
|
21ac67 |
if (surface->has_shell_surface)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
@@ -980,6 +985,7 @@ get_shell_surface (struct wl_client *client,
|
|
|
21ac67 |
return;
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
+ shell_surface = g_new0 (CoglandShellSurface, 1);
|
|
|
21ac67 |
shell_surface->resource.destroy = destroy_shell_surface;
|
|
|
21ac67 |
shell_surface->resource.object.id = id;
|
|
|
21ac67 |
shell_surface->resource.object.interface = &wl_shell_surface_interface;
|
|
|
21ac67 |
@@ -1012,6 +1018,36 @@ bind_shell (struct wl_client *client,
|
|
|
21ac67 |
&cogland_shell_interface, id, data);
|
|
|
21ac67 |
}
|
|
|
21ac67 |
|
|
|
21ac67 |
+static CoglContext *
|
|
|
21ac67 |
+create_cogl_context (CoglandCompositor *compositor,
|
|
|
21ac67 |
+ CoglBool use_egl_constraint,
|
|
|
21ac67 |
+ CoglError **error)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ CoglRenderer *renderer = renderer = cogl_renderer_new ();
|
|
|
21ac67 |
+ CoglDisplay *display;
|
|
|
21ac67 |
+ CoglContext *context;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (use_egl_constraint)
|
|
|
21ac67 |
+ cogl_renderer_add_constraint (renderer, COGL_RENDERER_CONSTRAINT_USES_EGL);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (!cogl_renderer_connect (renderer, error))
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ cogl_object_unref (renderer);
|
|
|
21ac67 |
+ return NULL;
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ display = cogl_display_new (renderer, NULL);
|
|
|
21ac67 |
+ cogl_wayland_display_set_compositor_display (display,
|
|
|
21ac67 |
+ compositor->wayland_display);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ context = cogl_context_new (display, error);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ cogl_object_unref (renderer);
|
|
|
21ac67 |
+ cogl_object_unref (display);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return context;
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
int
|
|
|
21ac67 |
main (int argc, char **argv)
|
|
|
21ac67 |
{
|
|
|
21ac67 |
@@ -1020,7 +1056,7 @@ main (int argc, char **argv)
|
|
|
21ac67 |
CoglError *error = NULL;
|
|
|
21ac67 |
GError *gerror = NULL;
|
|
|
21ac67 |
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
21ac67 |
- {0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
21ac67 |
+ {0, 0.7, 0xff, 0x00, 0x00, 0xff},
|
|
|
21ac67 |
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
21ac67 |
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
21ac67 |
};
|
|
|
21ac67 |
@@ -1055,13 +1091,30 @@ main (int argc, char **argv)
|
|
|
21ac67 |
wayland_event_source_new (compositor.wayland_display);
|
|
|
21ac67 |
g_source_attach (compositor.wayland_event_source, NULL);
|
|
|
21ac67 |
|
|
|
21ac67 |
- compositor.cogl_display = cogl_display_new (NULL, NULL);
|
|
|
21ac67 |
- cogl_wayland_display_set_compositor_display (compositor.cogl_display,
|
|
|
21ac67 |
- compositor.wayland_display);
|
|
|
21ac67 |
-
|
|
|
21ac67 |
- compositor.cogl_context = cogl_context_new (compositor.cogl_display, &error);
|
|
|
21ac67 |
- if (!compositor.cogl_context)
|
|
|
21ac67 |
- g_error ("Failed to create a Cogl context: %s\n", error->message);
|
|
|
21ac67 |
+ /* We want Cogl to use an EGL renderer because otherwise it won't
|
|
|
21ac67 |
+ * set up the wl_drm object and only SHM buffers will work. */
|
|
|
21ac67 |
+ compositor.cogl_context =
|
|
|
21ac67 |
+ create_cogl_context (&compositor,
|
|
|
21ac67 |
+ TRUE /* use EGL constraint */,
|
|
|
21ac67 |
+ &error);
|
|
|
21ac67 |
+ if (compositor.cogl_context == NULL)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ /* If we couldn't get an EGL context then try any type of
|
|
|
21ac67 |
+ * context */
|
|
|
21ac67 |
+ cogl_error_free (error);
|
|
|
21ac67 |
+ error = NULL;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ compositor.cogl_context =
|
|
|
21ac67 |
+ create_cogl_context (&compositor,
|
|
|
21ac67 |
+ FALSE, /* don't set EGL constraint */
|
|
|
21ac67 |
+ &error);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (compositor.cogl_context)
|
|
|
21ac67 |
+ g_warning ("Failed to create context with EGL constraint, "
|
|
|
21ac67 |
+ "falling back");
|
|
|
21ac67 |
+ else
|
|
|
21ac67 |
+ g_error ("Failed to create a Cogl context: %s\n", error->message);
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
|
|
|
21ac67 |
compositor.virtual_width = 800;
|
|
|
21ac67 |
compositor.virtual_height = 600;
|
|
|
21ac67 |
diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am
|
|
|
21ac67 |
index 69a460d..9782755 100644
|
|
|
21ac67 |
--- a/tests/conform/Makefile.am
|
|
|
21ac67 |
+++ b/tests/conform/Makefile.am
|
|
|
21ac67 |
@@ -65,6 +65,7 @@ test_sources = \
|
|
|
21ac67 |
test-framebuffer-get-bits.c \
|
|
|
21ac67 |
test-primitive-and-journal.c \
|
|
|
21ac67 |
test-copy-replace-texture.c \
|
|
|
21ac67 |
+ test-pipeline-cache-unrefs-texture.c \
|
|
|
21ac67 |
$(NULL)
|
|
|
21ac67 |
|
|
|
21ac67 |
test_conformance_SOURCES = $(common_sources) $(test_sources)
|
|
|
21ac67 |
@@ -131,7 +132,10 @@ AM_CPPFLAGS += \
|
|
|
21ac67 |
-DCOGL_COMPILATION
|
|
|
21ac67 |
|
|
|
21ac67 |
test_conformance_CFLAGS = -g3 -O0 $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS)
|
|
|
21ac67 |
-test_conformance_LDADD = $(COGL_DEP_LIBS) $(top_builddir)/cogl/libcogl.la
|
|
|
21ac67 |
+test_conformance_LDADD = \
|
|
|
21ac67 |
+ $(COGL_DEP_LIBS) \
|
|
|
21ac67 |
+ $(top_builddir)/cogl/libcogl.la \
|
|
|
21ac67 |
+ $(LIBM)
|
|
|
21ac67 |
if !USE_GLIB
|
|
|
21ac67 |
test_conformance_LDADD += $(top_builddir)/deps/glib/libglib.la
|
|
|
21ac67 |
endif
|
|
|
21ac67 |
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
|
|
|
21ac67 |
index 0b55db6..1d1447e 100644
|
|
|
21ac67 |
--- a/tests/conform/test-conform-main.c
|
|
|
21ac67 |
+++ b/tests/conform/test-conform-main.c
|
|
|
21ac67 |
@@ -120,6 +120,8 @@ main (int argc, char **argv)
|
|
|
21ac67 |
|
|
|
21ac67 |
ADD_TEST (test_copy_replace_texture, 0, 0);
|
|
|
21ac67 |
|
|
|
21ac67 |
+ ADD_TEST (test_pipeline_cache_unrefs_texture, 0, 0);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
UNPORTED_TEST (test_viewport);
|
|
|
21ac67 |
|
|
|
21ac67 |
ADD_TEST (test_gles2_context, TEST_REQUIREMENT_GLES2_CONTEXT, 0);
|
|
|
21ac67 |
diff --git a/tests/conform/test-pipeline-cache-unrefs-texture.c b/tests/conform/test-pipeline-cache-unrefs-texture.c
|
|
|
21ac67 |
new file mode 100644
|
|
|
21ac67 |
index 0000000..ccd02e7
|
|
|
21ac67 |
--- /dev/null
|
|
|
21ac67 |
+++ b/tests/conform/test-pipeline-cache-unrefs-texture.c
|
|
|
21ac67 |
@@ -0,0 +1,92 @@
|
|
|
21ac67 |
+#include <cogl/cogl.h>
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#include "test-utils.h"
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+/* Keep track of the number of textures that we've created and are
|
|
|
21ac67 |
+ * still alive */
|
|
|
21ac67 |
+static int destroyed_texture_count = 0;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+#define N_TEXTURES 3
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+static void
|
|
|
21ac67 |
+free_texture_cb (void *user_data)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ destroyed_texture_count++;
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+static CoglTexture *
|
|
|
21ac67 |
+create_texture (void)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ static const guint8 data[] =
|
|
|
21ac67 |
+ { 0xff, 0xff, 0xff, 0xff };
|
|
|
21ac67 |
+ static CoglUserDataKey texture_data_key;
|
|
|
21ac67 |
+ CoglTexture2D *tex_2d;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ tex_2d = cogl_texture_2d_new_from_data (test_ctx,
|
|
|
21ac67 |
+ 1, 1, /* width / height */
|
|
|
21ac67 |
+ COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
|
|
21ac67 |
+ COGL_PIXEL_FORMAT_ANY,
|
|
|
21ac67 |
+ 4, /* rowstride */
|
|
|
21ac67 |
+ data,
|
|
|
21ac67 |
+ NULL);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Set some user data on the texture so we can track when it has
|
|
|
21ac67 |
+ * been destroyed */
|
|
|
21ac67 |
+ cogl_object_set_user_data (COGL_OBJECT (tex_2d),
|
|
|
21ac67 |
+ &texture_data_key,
|
|
|
21ac67 |
+ GINT_TO_POINTER (1),
|
|
|
21ac67 |
+ free_texture_cb);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ return COGL_TEXTURE (tex_2d);
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+void
|
|
|
21ac67 |
+test_pipeline_cache_unrefs_texture (void)
|
|
|
21ac67 |
+{
|
|
|
21ac67 |
+ CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
|
|
|
21ac67 |
+ CoglPipeline *simple_pipeline;
|
|
|
21ac67 |
+ int i;
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Create a pipeline with three texture layers. That way we can be
|
|
|
21ac67 |
+ * pretty sure the pipeline will cause a unique shader to be
|
|
|
21ac67 |
+ * generated in the cache */
|
|
|
21ac67 |
+ for (i = 0; i < N_TEXTURES; i++)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ CoglTexture *tex = create_texture ();
|
|
|
21ac67 |
+ cogl_pipeline_set_layer_texture (pipeline, i, tex);
|
|
|
21ac67 |
+ cogl_object_unref (tex);
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Draw something with the pipeline to ensure it gets into the
|
|
|
21ac67 |
+ * pipeline cache */
|
|
|
21ac67 |
+ cogl_framebuffer_draw_rectangle (test_fb,
|
|
|
21ac67 |
+ pipeline,
|
|
|
21ac67 |
+ 0, 0, 10, 10);
|
|
|
21ac67 |
+ cogl_framebuffer_finish (test_fb);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Draw something else so that it is no longer the current flushed
|
|
|
21ac67 |
+ * pipeline, and the units have a different texture bound */
|
|
|
21ac67 |
+ simple_pipeline = cogl_pipeline_new (test_ctx);
|
|
|
21ac67 |
+ for (i = 0; i < N_TEXTURES; i++)
|
|
|
21ac67 |
+ {
|
|
|
21ac67 |
+ CoglColor combine_constant;
|
|
|
21ac67 |
+ cogl_color_init_from_4ub (&combine_constant, i, 0, 0, 255);
|
|
|
21ac67 |
+ cogl_pipeline_set_layer_combine_constant (simple_pipeline,
|
|
|
21ac67 |
+ i,
|
|
|
21ac67 |
+ &combine_constant);
|
|
|
21ac67 |
+ }
|
|
|
21ac67 |
+ cogl_framebuffer_draw_rectangle (test_fb, simple_pipeline, 0, 0, 10, 10);
|
|
|
21ac67 |
+ cogl_framebuffer_finish (test_fb);
|
|
|
21ac67 |
+ cogl_object_unref (simple_pipeline);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ g_assert_cmpint (destroyed_texture_count, ==, 0);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ /* Destroy the pipeline. This should immediately cause the textures
|
|
|
21ac67 |
+ * to be freed */
|
|
|
21ac67 |
+ cogl_object_unref (pipeline);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ g_assert_cmpint (destroyed_texture_count, ==, N_TEXTURES);
|
|
|
21ac67 |
+
|
|
|
21ac67 |
+ if (cogl_test_verbose ())
|
|
|
21ac67 |
+ g_print ("OK\n");
|
|
|
21ac67 |
+}
|
|
|
21ac67 |
diff --git a/tests/micro-perf/Makefile.am b/tests/micro-perf/Makefile.am
|
|
|
21ac67 |
index c221dd6..5c5f69d 100644
|
|
|
21ac67 |
--- a/tests/micro-perf/Makefile.am
|
|
|
21ac67 |
+++ b/tests/micro-perf/Makefile.am
|
|
|
21ac67 |
@@ -19,5 +19,10 @@ endif
|
|
|
21ac67 |
|
|
|
21ac67 |
AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS)
|
|
|
21ac67 |
|
|
|
21ac67 |
+common_ldadd = \
|
|
|
21ac67 |
+ $(COGL_DEP_LIBS) \
|
|
|
21ac67 |
+ $(top_builddir)/cogl/libcogl.la \
|
|
|
21ac67 |
+ $(LIBM)
|
|
|
21ac67 |
+
|
|
|
21ac67 |
test_journal_SOURCES = test-journal.c
|
|
|
21ac67 |
-test_journal_LDADD = $(COGL_DEP_LIBS) $(top_builddir)/cogl/libcogl.la
|
|
|
21ac67 |
+test_journal_LDADD = $(common_ldadd)
|