summaryrefslogtreecommitdiff
path: root/cogl/cogl/driver/gl
diff options
context:
space:
mode:
Diffstat (limited to 'cogl/cogl/driver/gl')
-rw-r--r--cogl/cogl/driver/gl/cogl-attribute-gl-private.h50
-rw-r--r--cogl/cogl/driver/gl/cogl-attribute-gl.c304
-rw-r--r--cogl/cogl/driver/gl/cogl-bitmap-gl-private.h52
-rw-r--r--cogl/cogl/driver/gl/cogl-bitmap-gl.c122
-rw-r--r--cogl/cogl/driver/gl/cogl-buffer-gl-private.h74
-rw-r--r--cogl/cogl/driver/gl/cogl-buffer-gl.c432
-rw-r--r--cogl/cogl/driver/gl/cogl-clip-stack-gl-private.h45
-rw-r--r--cogl/cogl/driver/gl/cogl-clip-stack-gl.c546
-rw-r--r--cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h66
-rw-r--r--cogl/cogl/driver/gl/cogl-framebuffer-gl.c681
-rw-r--r--cogl/cogl/driver/gl/cogl-gl-framebuffer-back.c303
-rw-r--r--cogl/cogl/driver/gl/cogl-gl-framebuffer-back.h41
-rw-r--r--cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.c659
-rw-r--r--cogl/cogl/driver/gl/cogl-gl-framebuffer-fbo.h41
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl-private.h45
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-fragend-glsl.c1120
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-opengl-private.h172
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-opengl.c1285
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-progend-glsl-private.h47
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c1145
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl-private.h45
-rw-r--r--cogl/cogl/driver/gl/cogl-pipeline-vertend-glsl.c794
-rw-r--r--cogl/cogl/driver/gl/cogl-texture-2d-gl-private.h121
-rw-r--r--cogl/cogl/driver/gl/cogl-texture-2d-gl.c632
-rw-r--r--cogl/cogl/driver/gl/cogl-texture-gl-private.h65
-rw-r--r--cogl/cogl/driver/gl/cogl-texture-gl.c154
-rw-r--r--cogl/cogl/driver/gl/cogl-util-gl-private.h253
-rw-r--r--cogl/cogl/driver/gl/cogl-util-gl.c562
-rw-r--r--cogl/cogl/driver/gl/gl/cogl-driver-gl.c604
-rw-r--r--cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c482
-rw-r--r--cogl/cogl/driver/gl/gles/cogl-driver-gles.c492
-rw-r--r--cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c537
32 files changed, 0 insertions, 11971 deletions
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
- };