[cogl/wip/cogl-gst] gst: Cache the shader snippets
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/cogl-gst] gst: Cache the shader snippets
- Date: Tue, 5 Mar 2013 15:16:12 +0000 (UTC)
commit 47c40bab8cf262e8c216d5965fffd88359df9e29
Author: Neil Roberts <neil linux intel com>
Date: Tue Mar 5 15:12:56 2013 +0000
gst: Cache the shader snippets
Previously every time the renderer is initialised it will create a new
snippet. This will cause Cogl to compile a new GLSL program. Cogl
currently never destroys GLSL programs because they are always retained
in the pipeline cache so if the application ends up playing a lot of
videos it could end up with a lot of identical GLSL programs floating
around.
If we make it reuse the same snippets instead then it should be able to
take advantage of the pipeline cache and avoid creating a new program
object. The snippets are always created with a small set of static
strings and snippets can be constructed without a context so this patch
makes it just store the snippet in a static variable in renderer init
functions.
cogl-gst/cogl-gst-video-sink.c | 78 ++++++++++++++++++++++++++++------------
1 files changed, 55 insertions(+), 23 deletions(-)
---
diff --git a/cogl-gst/cogl-gst-video-sink.c b/cogl-gst/cogl-gst-video-sink.c
index fae22c5..1e49b9a 100644
--- a/cogl-gst/cogl-gst-video-sink.c
+++ b/cogl-gst/cogl-gst-video-sink.c
@@ -198,9 +198,20 @@ cogl_gst_video_sink_set_priority (CoglGstVideoSink *sink,
g_source_set_priority ((GSource*) sink->priv->source, priority);
}
+/* We want to cache the snippets instead of recreating a new one every
+ * time we initialise a pipeline so that if we end up recreating the
+ * same pipeline again then Cogl will be able to use the pipeline
+ * cache to avoid linking a redundant identical shader program */
+typedef struct
+{
+ CoglSnippet *vertex_snippet;
+ CoglSnippet *fragment_snippet;
+} SnippetCache;
+
static void
create_template_pipeline (CoglGstVideoSink *sink,
const char *decl,
+ SnippetCache *snippet_cache,
int n_layers)
{
CoglGstVideoSinkPrivate *priv = sink->priv;
@@ -212,34 +223,41 @@ create_template_pipeline (CoglGstVideoSink *sink,
if (decl)
{
- CoglSnippet *snippet;
+ static CoglSnippet *default_sample_snippet = NULL;
/* The global sampling function gets added to both the fragment
* and vertex stages. The hope is that the GLSL compiler will
* easily remove the dead code if it's not actually used */
- snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
- decl,
- NULL /* post */);
- cogl_pipeline_add_snippet (priv->pipeline, snippet);
- cogl_object_unref (snippet);
-
- snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
- decl,
- NULL /* post */);
- cogl_pipeline_add_snippet (priv->pipeline, snippet);
- cogl_object_unref (snippet);
+ if (snippet_cache->vertex_snippet == NULL)
+ snippet_cache->vertex_snippet =
+ cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
+ decl,
+ NULL /* post */);
+ cogl_pipeline_add_snippet (priv->pipeline,
+ snippet_cache->vertex_snippet);
+
+ if (snippet_cache->fragment_snippet == NULL)
+ snippet_cache->fragment_snippet =
+ cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
+ decl,
+ NULL /* post */);
+ cogl_pipeline_add_snippet (priv->pipeline,
+ snippet_cache->fragment_snippet);
/* Set the replace string for the last layer so that no
* redundant code for the previous layers will be generated. The
* application can also replace this default sampling by adding
* another layer */
- snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
- NULL,
- NULL);
- cogl_snippet_set_replace (snippet,
- _cogl_gst_shader_default_sample);
- cogl_pipeline_add_layer_snippet (priv->pipeline, n_layers - 1, snippet);
- cogl_object_unref (snippet);
+ if (default_sample_snippet == NULL)
+ {
+ default_sample_snippet =
+ cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, NULL, NULL);
+ cogl_snippet_set_replace (default_sample_snippet,
+ _cogl_gst_shader_default_sample);
+ }
+ cogl_pipeline_add_layer_snippet (priv->pipeline,
+ n_layers - 1,
+ default_sample_snippet);
}
g_signal_emit (sink, video_sink_signals[PIPELINE_READY_SIGNAL], 0, NULL);
@@ -285,11 +303,16 @@ cogl_gst_rgb_init (CoglGstVideoSink *sink)
CoglGstVideoSinkPrivate *priv = sink->priv;
if (cogl_has_feature (priv->ctx, COGL_FEATURE_ID_GLSL))
- create_template_pipeline (sink,
- _cogl_gst_shader_rgba_to_rgba_decl,
- 1);
+ {
+ static SnippetCache snippet_cache;
+
+ create_template_pipeline (sink,
+ _cogl_gst_shader_rgba_to_rgba_decl,
+ &snippet_cache,
+ 1);
+ }
else
- create_template_pipeline (sink, NULL, 1);
+ create_template_pipeline (sink, NULL, NULL, 1);
}
static CoglBool
@@ -434,8 +457,11 @@ map_fail:
static void
cogl_gst_yv12_glsl_init (CoglGstVideoSink *sink)
{
+ static SnippetCache snippet_cache;
+
create_template_pipeline (sink,
_cogl_gst_shader_yv12_to_rgba_decl,
+ &snippet_cache,
3);
}
@@ -453,8 +479,11 @@ static CoglGstRenderer yv12_glsl_renderer =
static void
cogl_gst_i420_glsl_init (CoglGstVideoSink *sink)
{
+ static SnippetCache snippet_cache;
+
create_template_pipeline (sink,
_cogl_gst_shader_yv12_to_rgba_decl,
+ &snippet_cache,
3);
}
@@ -472,8 +501,11 @@ static CoglGstRenderer i420_glsl_renderer =
static void
cogl_gst_ayuv_glsl_init (CoglGstVideoSink *sink)
{
+ static SnippetCache snippet_cache;
+
create_template_pipeline (sink,
_cogl_gst_shader_ayuv_to_rgba_decl,
+ &snippet_cache,
1);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]