summaryrefslogtreecommitdiff
path: root/gsk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-08-20 22:50:41 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-08-20 22:58:30 -0400
commite9e373913ee5e5d1380fcd8634afb1b6237ae391 (patch)
tree84d3a46634d950220662a554ba2fe93e4f5d1a3f /gsk
parentf1f197e3b94a55d5cbfaae2498f991a0ae733b32 (diff)
downloadgtk+-e9e373913ee5e5d1380fcd8634afb1b6237ae391.tar.gz
gsk: Drop the gl renderer
ngl supports all the same platforms as gl now, and has seen more improvements in the last cycle.
Diffstat (limited to 'gsk')
-rw-r--r--gsk/gl/glutilsprivate.h317
-rw-r--r--gsk/gl/gskgldriver.c849
-rw-r--r--gsk/gl/gskgldriverprivate.h86
-rw-r--r--gsk/gl/gskglglyphcache.c397
-rw-r--r--gsk/gl/gskglglyphcacheprivate.h92
-rw-r--r--gsk/gl/gskgliconcache.c275
-rw-r--r--gsk/gl/gskgliconcacheprivate.h44
-rw-r--r--gsk/gl/gskglimage.c64
-rw-r--r--gsk/gl/gskglimageprivate.h41
-rw-r--r--gsk/gl/gskglnodesample.c51
-rw-r--r--gsk/gl/gskglnodesampleprivate.h28
-rw-r--r--gsk/gl/gskglrenderer.c4559
-rw-r--r--gsk/gl/gskglrenderer.h52
-rw-r--r--gsk/gl/gskglrendererprivate.h14
-rw-r--r--gsk/gl/gskglrenderops.c976
-rw-r--r--gsk/gl/gskglrenderopsprivate.h353
-rw-r--r--gsk/gl/gskglshaderbuilder.c271
-rw-r--r--gsk/gl/gskglshaderbuilderprivate.h42
-rw-r--r--gsk/gl/gskglshadowcache.c141
-rw-r--r--gsk/gl/gskglshadowcacheprivate.h31
-rw-r--r--gsk/gl/gskgltextureatlas.c309
-rw-r--r--gsk/gl/gskgltextureatlasprivate.h72
-rw-r--r--gsk/gl/opbuffer.c137
-rw-r--r--gsk/gl/opbuffer.h306
-rw-r--r--gsk/gl/resources/blend.glsl310
-rw-r--r--gsk/gl/resources/blit.glsl13
-rw-r--r--gsk/gl/resources/blur.glsl55
-rw-r--r--gsk/gl/resources/border.glsl40
-rw-r--r--gsk/gl/resources/color.glsl18
-rw-r--r--gsk/gl/resources/color_matrix.glsl25
-rw-r--r--gsk/gl/resources/coloring.glsl22
-rw-r--r--gsk/gl/resources/conic_gradient.glsl73
-rw-r--r--gsk/gl/resources/cross_fade.glsl20
-rw-r--r--gsk/gl/resources/custom.glsl21
-rw-r--r--gsk/gl/resources/inset_shadow.glsl41
-rw-r--r--gsk/gl/resources/linear_gradient.glsl95
-rw-r--r--gsk/gl/resources/outset_shadow.glsl33
-rw-r--r--gsk/gl/resources/preamble.fs.glsl139
-rw-r--r--gsk/gl/resources/preamble.glsl57
-rw-r--r--gsk/gl/resources/preamble.vs.glsl69
-rw-r--r--gsk/gl/resources/radial_gradient.glsl74
-rw-r--r--gsk/gl/resources/repeat.glsl41
-rw-r--r--gsk/gl/resources/unblurred_outset_shadow.glsl42
-rw-r--r--gsk/gskglshader.c5
-rw-r--r--gsk/gskrenderer.c8
-rw-r--r--gsk/meson.build37
-rw-r--r--gsk/ngl/gskglprofiler.c (renamed from gsk/gl/gskglprofiler.c)0
-rw-r--r--gsk/ngl/gskglprofilerprivate.h (renamed from gsk/gl/gskglprofilerprivate.h)0
-rw-r--r--gsk/ngl/gsknglcommandqueueprivate.h2
-rw-r--r--gsk/ngl/gskngltexturelibraryprivate.h2
-rw-r--r--gsk/ngl/stb_rect_pack.c (renamed from gsk/gl/stb_rect_pack.c)0
-rw-r--r--gsk/ngl/stb_rect_pack.h (renamed from gsk/gl/stb_rect_pack.h)0
52 files changed, 7 insertions, 10742 deletions
diff --git a/gsk/gl/glutilsprivate.h b/gsk/gl/glutilsprivate.h
deleted file mode 100644
index f035bda26e..0000000000
--- a/gsk/gl/glutilsprivate.h
+++ /dev/null
@@ -1,317 +0,0 @@
-
-#pragma once
-
-#define SANITY_CHECKS 0
-
-
-
-#define rounded_rect_top_left(r) (GRAPHENE_RECT_INIT(r->bounds.origin.x, \
- r->bounds.origin.y, \
- r->corner[0].width, r->corner[0].height))
-
-#define rounded_rect_top_right(r) (GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[1].width, \
- r->bounds.origin.y, \
- r->corner[1].width, r->corner[1].height))
-
-#define rounded_rect_bottom_right(r) (GRAPHENE_RECT_INIT(r->bounds.origin.x + r->bounds.size.width - r->corner[2].width, \
- r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
- r->corner[2].width, r->corner[2].height))
-
-#define rounded_rect_bottom_left(r) (GRAPHENE_RECT_INIT(r->bounds.origin.x, \
- r->bounds.origin.y + r->bounds.size.height - r->corner[2].height, \
- r->corner[3].width, r->corner[3].height))
-
-
-#define rounded_rect_corner0(r) rounded_rect_top_left(r)
-#define rounded_rect_corner1(r) rounded_rect_top_right(r)
-#define rounded_rect_corner2(r) rounded_rect_bottom_right(r)
-#define rounded_rect_corner3(r) rounded_rect_bottom_left(r)
-
-#define rounded_rect_corner(r, i) (rounded_rect_corner ##i(r))
-#define graphene_size_non_zero(s) (s->width > 0 && s->height > 0)
-#define rounded_rect_has_corner(r, i) (r->corner[i].width > 0 && r->corner[i].height > 0)
-
-#define rect_contains_point(r, _x, _y) (_x >= (r)->origin.x && _x <= (r)->origin.x + (r)->size.width && \
- _y >= (r)->origin.y && _y <= (r)->origin.y + (r)->size.height)
-
-enum {
- NINE_SLICE_TOP_LEFT = 0,
- NINE_SLICE_TOP_CENTER = 1,
- NINE_SLICE_TOP_RIGHT = 2,
- NINE_SLICE_LEFT_CENTER = 3,
- NINE_SLICE_CENTER = 4,
- NINE_SLICE_RIGHT_CENTER = 5,
- NINE_SLICE_BOTTOM_LEFT = 6,
- NINE_SLICE_BOTTOM_CENTER = 7,
- NINE_SLICE_BOTTOM_RIGHT = 8,
-};
-#define NINE_SLICE_SIZE 9 /* Hah. */
-
-typedef struct
-{
- int texture_id;
- float x;
- float y;
- float x2;
- float y2;
-} TextureRegion;
-
-static inline bool G_GNUC_PURE
-slice_is_visible (const cairo_rectangle_int_t *r)
-{
- return (r->width > 0 && r->height > 0);
-}
-
-static inline void
-nine_slice_rounded_rect (const GskRoundedRect *rect,
- cairo_rectangle_int_t *out_rects)
-{
- const graphene_point_t *origin = &rect->bounds.origin;
- const graphene_size_t *size = &rect->bounds.size;
- const int top_height = ceilf (MAX (rect->corner[GSK_CORNER_TOP_LEFT].height,
- rect->corner[GSK_CORNER_TOP_RIGHT].height));
- const int bottom_height = ceilf (MAX (rect->corner[GSK_CORNER_BOTTOM_LEFT].height,
- rect->corner[GSK_CORNER_BOTTOM_RIGHT].height));
- const int right_width = ceilf (MAX (rect->corner[GSK_CORNER_TOP_RIGHT].width,
- rect->corner[GSK_CORNER_BOTTOM_RIGHT].width));
- const int left_width = ceilf (MAX (rect->corner[GSK_CORNER_TOP_LEFT].width,
- rect->corner[GSK_CORNER_BOTTOM_LEFT].width));
-
- /* Top left */
- out_rects[0] = (cairo_rectangle_int_t) {
- origin->x, origin->y,
- left_width, top_height,
- };
-
- /* Top center */
- out_rects[1] = (cairo_rectangle_int_t) {
- origin->x + size->width / 2.0 - 0.5, origin->y,
- 1, top_height,
- };
-
- /* Top right */
- out_rects[2] = (cairo_rectangle_int_t) {
- origin->x + size->width - right_width, origin->y,
- right_width, top_height
- };
-
- /* Left center */
- out_rects[3] = (cairo_rectangle_int_t) {
- origin->x, origin->y + size->height / 2,
- left_width, 1,
- };
-
- /* center */
- out_rects[4] = (cairo_rectangle_int_t) {
- origin->x + size->width / 2.0 - 0.5,
- origin->y + size->height / 2.0 - 0.5,
- 1, 1
- };
-
- /* Right center */
- out_rects[5] = (cairo_rectangle_int_t) {
- origin->x + size->width - right_width,
- origin->y + (size->height / 2.0) - 0.5,
- right_width,
- 1,
- };
-
- /* Bottom Left */
- out_rects[6] = (cairo_rectangle_int_t) {
- origin->x, origin->y + size->height - bottom_height,
- left_width, bottom_height,
- };
-
- /* Bottom center */
- out_rects[7] = (cairo_rectangle_int_t) {
- origin->x + (size->width / 2.0) - 0.5,
- origin->y + size->height - bottom_height,
- 1, bottom_height,
- };
-
- /* Bottom right */
- out_rects[8] = (cairo_rectangle_int_t) {
- origin->x + size->width - right_width,
- origin->y + size->height - bottom_height,
- right_width, bottom_height,
- };
-
-#if SANITY_CHECKS
- g_assert_cmpfloat (size->width, >=, left_width + right_width);
- g_assert_cmpfloat (size->height, >=, top_height + bottom_height);
-#endif
-}
-
-static inline void
-nine_slice_grow (cairo_rectangle_int_t *slices,
- const int amount)
-{
- /* top left */
- slices[0].x -= amount;
- slices[0].y -= amount;
- if (amount > slices[0].width)
- slices[0].width += amount * 2;
- else
- slices[0].width += amount;
-
- if (amount > slices[0].height)
- slices[0].height += amount * 2;
- else
- slices[0].height += amount;
-
-
- /* Top center */
- slices[1].y -= amount;
- if (amount > slices[1].height)
- slices[1].height += amount * 2;
- else
- slices[1].height += amount;
-
- /* top right */
- slices[2].y -= amount;
- if (amount > slices[2].width)
- {
- slices[2].x -= amount;
- slices[2].width += amount * 2;
- }
- else
- {
- slices[2].width += amount;
- }
-
- if (amount > slices[2].height)
- slices[2].height += amount * 2;
- else
- slices[2].height += amount;
-
-
-
- slices[3].x -= amount;
- if (amount > slices[3].width)
- slices[3].width += amount * 2;
- else
- slices[3].width += amount;
-
- /* Leave Britney^Wcenter alone */
-
- if (amount > slices[5].width)
- {
- slices[5].x -= amount;
- slices[5].width += amount * 2;
- }
- else
- {
- slices[5].width += amount;
- }
-
-
- /* Bottom left */
- slices[6].x -= amount;
- if (amount > slices[6].width)
- {
- slices[6].width += amount * 2;
- }
- else
- {
- slices[6].width += amount;
- }
-
- if (amount > slices[6].height)
- {
- slices[6].y -= amount;
- slices[6].height += amount * 2;
- }
- else
- {
- slices[6].height += amount;
- }
-
-
- /* Bottom center */
- if (amount > slices[7].height)
- {
- slices[7].y -= amount;
- slices[7].height += amount * 2;
- }
- else
- {
- slices[7].height += amount;
- }
-
- if (amount > slices[8].width)
- {
- slices[8].x -= amount;
- slices[8].width += amount * 2;
- }
- else
- {
- slices[8].width += amount;
- }
-
- if (amount > slices[8].height)
- {
- slices[8].y -= amount;
- slices[8].height += amount * 2;
- }
- else
- {
- slices[8].height += amount;
- }
-
-#if SANITY_CHECKS
- {
- for (int i = 0; i < 9; i ++)
- {
- g_assert_cmpint (slices[i].x, >=, 0);
- g_assert_cmpint (slices[i].y, >=, 0);
- g_assert_cmpint (slices[i].width, >=, 0);
- g_assert_cmpint (slices[i].height, >=, 0);
- }
-
- /* Rows don't overlap */
- for (int i = 0; i < 3; i++)
- {
- g_assert_cmpint (slices[i * 3 + 0].x + slices[i * 3 + 0].width, <, slices[i * 3 + 1].x);
- }
- }
-#endif
-
-}
-
-static inline void
-nine_slice_to_texture_coords (const cairo_rectangle_int_t *slices,
- const int texture_width,
- const int texture_height,
- TextureRegion *out_regions)
-{
- const float fw = (float)texture_width;
- const float fh = (float)texture_height;
- int i;
-
- for (i = 0; i < 9; i++)
- {
- out_regions[i] = (TextureRegion) {
- 0, /* Texture id */
- slices[i].x / fw,
- 1.0 - ((slices[i].y + slices[i].height) / fh),
- (slices[i].x + slices[i].width) / fw,
- 1.0 - (slices[i].y / fh),
- };
- }
-
-#if SANITY_CHECKS
- {
- for (i = 0; i < 9; i++)
- {
- const TextureRegion *r = &out_regions[i];
- g_assert_cmpfloat (r->x, >=, 0);
- g_assert_cmpfloat (r->x, <=, 1);
- g_assert_cmpfloat (r->y, >=, 0);
- g_assert_cmpfloat (r->y, <=, 1);
-
- g_assert_cmpfloat (r->x, <, r->x2);
- g_assert_cmpfloat (r->y, <, r->y2);
- }
- }
-#endif
-}
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
deleted file mode 100644
index 8fe726b315..0000000000
--- a/gsk/gl/gskgldriver.c
+++ /dev/null
@@ -1,849 +0,0 @@
-#include "config.h"
-
-#include "gskgldriverprivate.h"
-
-#include "gskdebugprivate.h"
-#include "gskprofilerprivate.h"
-#include "gdk/gdkglcontextprivate.h"
-#include "gdk/gdktextureprivate.h"
-#include "gdk/gdkgltextureprivate.h"
-#include "gdkmemorytextureprivate.h"
-
-#include <gdk/gdk.h>
-#include <epoxy/gl.h>
-
- typedef struct {
- GLuint fbo_id;
- GLuint depth_stencil_id;
-} Fbo;
-
-typedef struct {
- GLuint texture_id;
- int width;
- int height;
- GLuint min_filter;
- GLuint mag_filter;
- Fbo fbo;
- GdkTexture *user;
- guint in_use : 1;
- guint permanent : 1;
-
- /* TODO: Make this optional and not for every texture... */
- TextureSlice *slices;
- guint n_slices;
-} Texture;
-
-struct _GskGLDriver
-{
- GObject parent_instance;
-
- GdkGLContext *gl_context;
- GskProfiler *profiler;
- struct {
- GQuark created_textures;
- GQuark reused_textures;
- GQuark surface_uploads;
- } counters;
-
- Fbo default_fbo;
-
- GHashTable *textures; /* texture_id -> Texture */
- GHashTable *pointer_textures; /* pointer -> texture_id */
-
- const Texture *bound_source_texture;
-
- int max_texture_size;
-
- gboolean in_frame : 1;
-};
-
-G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
-
-static void
-upload_gdk_texture (GdkTexture *source_texture,
- int target,
- int x_offset,
- int y_offset,
- int width,
- int height)
-{
- cairo_surface_t *surface = NULL;
- GdkMemoryFormat data_format;
- const guchar *data;
- gsize data_stride;
- gsize bpp;
-
- g_return_if_fail (source_texture != NULL);
- g_return_if_fail (x_offset + width <= gdk_texture_get_width (source_texture));
- g_return_if_fail (y_offset + height <= gdk_texture_get_height (source_texture));
-
- /* Note: GdkGLTextures are already handled before we reach this and reused as-is */
-
- if (GDK_IS_MEMORY_TEXTURE (source_texture))
- {
- GdkMemoryTexture *memory_texture = GDK_MEMORY_TEXTURE (source_texture);
- data = gdk_memory_texture_get_data (memory_texture);
- data_format = gdk_memory_texture_get_format (memory_texture);
- data_stride = gdk_memory_texture_get_stride (memory_texture);
- }
- else
- {
- /* Fall back to downloading to a surface */
- surface = gdk_texture_download_surface (source_texture);
- cairo_surface_flush (surface);
- data = cairo_image_surface_get_data (surface);
- data_format = GDK_MEMORY_DEFAULT;
- data_stride = cairo_image_surface_get_stride (surface);
- }
-
- bpp = gdk_memory_format_bytes_per_pixel (data_format);
-
- gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
- data + x_offset * bpp + y_offset * data_stride,
- width, height, data_stride,
- data_format, target);
-
- if (surface)
- cairo_surface_destroy (surface);
-}
-
-static Texture *
-texture_new (void)
-{
- return g_slice_new0 (Texture);
-}
-
-static inline void
-fbo_clear (const Fbo *f)
-{
- if (f->depth_stencil_id != 0)
- glDeleteRenderbuffers (1, &f->depth_stencil_id);
-
- glDeleteFramebuffers (1, &f->fbo_id);
-}
-
-static void
-texture_free (gpointer data)
-{
- Texture *t = data;
- guint i;
-
- if (t->user)
- gdk_texture_clear_render_data (t->user);
-
- if (t->fbo.fbo_id != 0)
- fbo_clear (&t->fbo);
-
- if (t->texture_id != 0)
- {
- glDeleteTextures (1, &t->texture_id);
- }
- else
- {
- g_assert_cmpint (t->n_slices, >, 0);
-
- for (i = 0; i < t->n_slices; i ++)
- glDeleteTextures (1, &t->slices[i].texture_id);
- }
-
- g_slice_free (Texture, t);
-}
-
-static void
-gsk_gl_driver_set_texture_parameters (GskGLDriver *self,
- int min_filter,
- int mag_filter)
-{
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
-static void
-gsk_gl_driver_finalize (GObject *gobject)
-{
- GskGLDriver *self = GSK_GL_DRIVER (gobject);
-
- gdk_gl_context_make_current (self->gl_context);
-
- g_clear_pointer (&self->textures, g_hash_table_unref);
- g_clear_pointer (&self->pointer_textures, g_hash_table_unref);
- g_clear_object (&self->profiler);
-
- if (self->gl_context == gdk_gl_context_get_current ())
- gdk_gl_context_clear_current ();
-
- G_OBJECT_CLASS (gsk_gl_driver_parent_class)->finalize (gobject);
-}
-
-static void
-gsk_gl_driver_class_init (GskGLDriverClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->finalize = gsk_gl_driver_finalize;
-}
-
-static void
-gsk_gl_driver_init (GskGLDriver *self)
-{
- self->textures = g_hash_table_new_full (NULL, NULL, NULL, texture_free);
-
- self->max_texture_size = -1;
-
-#ifdef G_ENABLE_DEBUG
- self->profiler = gsk_profiler_new ();
- self->counters.created_textures = gsk_profiler_add_counter (self->profiler,
- "created_textures",
- "Textures created this frame",
- TRUE);
- self->counters.reused_textures = gsk_profiler_add_counter (self->profiler,
- "reused_textures",
- "Textures reused this frame",
- TRUE);
- self->counters.surface_uploads = gsk_profiler_add_counter (self->profiler,
- "surface_uploads",
- "Texture uploads from surfaces this frame",
- TRUE);
-#endif
-}
-
-GskGLDriver *
-gsk_gl_driver_new (GdkGLContext *context)
-{
- GskGLDriver *self;
- g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), NULL);
-
- self = (GskGLDriver *) g_object_new (GSK_TYPE_GL_DRIVER, NULL);
- self->gl_context = context;
-
- return self;
-}
-
-void
-gsk_gl_driver_begin_frame (GskGLDriver *self)
-{
- g_return_if_fail (GSK_IS_GL_DRIVER (self));
- g_return_if_fail (!self->in_frame);
-
- self->in_frame = TRUE;
-
- if (self->max_texture_size < 0)
- {
- glGetIntegerv (GL_MAX_TEXTURE_SIZE, (GLint *) &self->max_texture_size);
- GSK_NOTE (OPENGL, g_message ("GL max texture size: %d", self->max_texture_size));
- }
-
- glBindFramebuffer (GL_FRAMEBUFFER, 0);
-
- glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_2D, 0);
-
- glActiveTexture (GL_TEXTURE0 + 1);
- glBindTexture (GL_TEXTURE_2D, 0);
-
- glBindVertexArray (0);
- glUseProgram (0);
-
- glActiveTexture (GL_TEXTURE0);
-
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_reset (self->profiler);
-#endif
-}
-
-gboolean
-gsk_gl_driver_in_frame (GskGLDriver *self)
-{
- return self->in_frame;
-}
-
-void
-gsk_gl_driver_end_frame (GskGLDriver *self)
-{
- g_return_if_fail (GSK_IS_GL_DRIVER (self));
- g_return_if_fail (self->in_frame);
-
- self->bound_source_texture = NULL;
-
- self->default_fbo.fbo_id = 0;
-
-#ifdef G_ENABLE_DEBUG
- GSK_NOTE (OPENGL,
- g_message ("Textures created: %" G_GINT64_FORMAT "\n"
- " Textures reused: %" G_GINT64_FORMAT "\n"
- " Surface uploads: %" G_GINT64_FORMAT,
- gsk_profiler_counter_get (self->profiler, self->counters.created_textures),
- gsk_profiler_counter_get (self->profiler, self->counters.reused_textures),
- gsk_profiler_counter_get (self->profiler, self->counters.surface_uploads)));
-#endif
-
- GSK_NOTE (OPENGL,
- g_message ("*** Frame end: textures=%d",
- g_hash_table_size (self->textures)));
-
- self->in_frame = FALSE;
-}
-
-int
-gsk_gl_driver_collect_textures (GskGLDriver *self)
-{
- GHashTableIter iter;
- gpointer value_p = NULL;
- int old_size;
-
- g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
- g_return_val_if_fail (!self->in_frame, 0);
-
- old_size = g_hash_table_size (self->textures);
-
- g_hash_table_iter_init (&iter, self->textures);
- while (g_hash_table_iter_next (&iter, NULL, &value_p))
- {
- Texture *t = value_p;
-
- if (t->user || t->permanent)
- continue;
-
- if (t->in_use)
- {
- t->in_use = FALSE;
-
- if (t->fbo.fbo_id != 0)
- {
- fbo_clear (&t->fbo);
- t->fbo.fbo_id = 0;
- }
- }
- else
- {
- /* Remove from self->pointer_textures. */
- /* TODO: Is there a better way for this? */
- if (self->pointer_textures)
- {
- GHashTableIter pointer_iter;
- gpointer value;
- gpointer p;
-
- g_hash_table_iter_init (&pointer_iter, self->pointer_textures);
- while (g_hash_table_iter_next (&pointer_iter, &p, &value))
- {
- if (GPOINTER_TO_INT (value) == t->texture_id)
- {
- g_hash_table_iter_remove (&pointer_iter);
- break;
- }
- }
- }
-
- g_hash_table_iter_remove (&iter);
- }
- }
-
- return old_size - g_hash_table_size (self->textures);
-}
-
-
-GdkGLContext *
-gsk_gl_driver_get_gl_context (GskGLDriver *self)
-{
- return self->gl_context;
-}
-
-int
-gsk_gl_driver_get_max_texture_size (GskGLDriver *self)
-{
- if (self->max_texture_size < 0)
- {
- if (gdk_gl_context_get_use_es (self->gl_context))
- return 2048;
-
- return 1024;
- }
-
- return self->max_texture_size;
-}
-
-static Texture *
-gsk_gl_driver_get_texture (GskGLDriver *self,
- int texture_id)
-{
- Texture *t;
-
- if (g_hash_table_lookup_extended (self->textures, GINT_TO_POINTER (texture_id), NULL, (gpointer *) &t))
- return t;
-
- return NULL;
-}
-
-static Texture *
-create_texture (GskGLDriver *self,
- float fwidth,
- float fheight)
-{
- guint texture_id;
- Texture *t;
- int width = ceilf (fwidth);
- int height = ceilf (fheight);
-
- g_assert (width > 0);
- g_assert (height > 0);
-
- if (width > self->max_texture_size ||
- height > self->max_texture_size)
- {
- g_critical ("Texture %d x %d is bigger than supported texture limit of %d; clipping...",
- width, height,
- self->max_texture_size);
-
- width = MIN (width, self->max_texture_size);
- height = MIN (height, self->max_texture_size);
- }
-
- glGenTextures (1, &texture_id);
- t = texture_new ();
- t->texture_id = texture_id;
- t->width = width;
- t->height = height;
- t->min_filter = GL_NEAREST;
- t->mag_filter = GL_NEAREST;
- t->in_use = TRUE;
- g_hash_table_insert (self->textures, GINT_TO_POINTER (texture_id), t);
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_counter_inc (self->profiler, self->counters.created_textures);
-#endif
-
- return t;
-}
-
-static void
-gsk_gl_driver_release_texture (gpointer data)
-{
- Texture *t = data;
-
- t->user = NULL;
-}
-
-void
-gsk_gl_driver_slice_texture (GskGLDriver *self,
- GdkTexture *texture,
- TextureSlice **out_slices,
- guint *out_n_slices)
-{
- const int max_texture_size = gsk_gl_driver_get_max_texture_size (self) / 4; // XXX Too much?
- const int cols = (texture->width / max_texture_size) + 1;
- const int rows = (texture->height / max_texture_size) + 1;
- int col, row;
- int x = 0, y = 0; /* Position in the texture */
- TextureSlice *slices;
- Texture *tex;
-
- g_assert (texture->width > max_texture_size || texture->height > max_texture_size);
-
-
- tex = gdk_texture_get_render_data (texture, self);
-
- if (tex != NULL)
- {
- g_assert (tex->n_slices > 0);
- *out_slices = tex->slices;
- *out_n_slices = tex->n_slices;
- return;
- }
-
- slices = g_new0 (TextureSlice, cols * rows);
-
- for (col = 0; col < cols; col ++)
- {
- const int slice_width = MIN (max_texture_size, texture->width - x);
-
- for (row = 0; row < rows; row ++)
- {
- const int slice_height = MIN (max_texture_size, texture->height - y);
- const int slice_index = (col * rows) + row;
- guint texture_id;
-
- glGenTextures (1, &texture_id);
-
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_counter_inc (self->profiler, self->counters.created_textures);
-#endif
- glBindTexture (GL_TEXTURE_2D, texture_id);
- gsk_gl_driver_set_texture_parameters (self, GL_NEAREST, GL_NEAREST);
- upload_gdk_texture (texture, GL_TEXTURE_2D, x, y, slice_width, slice_height);
-
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
-#endif
-
- slices[slice_index].rect = (GdkRectangle){x, y, slice_width, slice_height};
- slices[slice_index].texture_id = texture_id;
-
- y += slice_height;
- }
-
- y = 0;
- x += slice_width;
- }
-
- /* Allocate one Texture for the entire thing. */
- tex = texture_new ();
- tex->width = texture->width;
- tex->height = texture->height;
- tex->min_filter = GL_NEAREST;
- tex->mag_filter = GL_NEAREST;
- tex->in_use = TRUE;
- tex->slices = slices;
- tex->n_slices = cols * rows;
-
- /* Use texture_free as destroy notify here since we are not inserting this Texture
- * into self->textures! */
- gdk_texture_set_render_data (texture, self, tex, texture_free);
-
- *out_slices = slices;
- *out_n_slices = cols * rows;
-}
-
-int
-gsk_gl_driver_get_texture_for_texture (GskGLDriver *self,
- GdkTexture *texture,
- int min_filter,
- int mag_filter)
-{
- Texture *t;
- GdkTexture *downloaded_texture = NULL;
- GdkTexture *source_texture;
-
- if (GDK_IS_GL_TEXTURE (texture))
- {
- GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
- GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
-
- if (gdk_gl_context_is_shared (self->gl_context, texture_context))
- {
- /* A GL texture from the same GL context is a simple task... */
- return gdk_gl_texture_get_id (gl_texture);
- }
- else
- {
- cairo_surface_t *surface;
-
- /* In this case, we have to temporarily make the texture's context the current one,
- * download its data into our context and then create a texture from it. */
- if (texture_context)
- gdk_gl_context_make_current (texture_context);
-
- surface = gdk_texture_download_surface (texture);
- downloaded_texture = gdk_texture_new_for_surface (surface);
- cairo_surface_destroy (surface);
-
- gdk_gl_context_make_current (self->gl_context);
-
- source_texture = downloaded_texture;
- }
- }
- else
- {
- t = gdk_texture_get_render_data (texture, self);
-
- if (t)
- {
- if (t->min_filter == min_filter && t->mag_filter == mag_filter)
- return t->texture_id;
- }
-
- source_texture = texture;
- }
-
- t = create_texture (self, gdk_texture_get_width (texture), gdk_texture_get_height (texture));
-
- if (gdk_texture_set_render_data (texture, self, t, gsk_gl_driver_release_texture))
- t->user = texture;
-
- gsk_gl_driver_bind_source_texture (self, t->texture_id);
- gsk_gl_driver_init_texture (self,
- t->texture_id,
- source_texture,
- min_filter,
- mag_filter);
- gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, t->texture_id,
- "GdkTexture<%p> %d", texture, t->texture_id);
-
- if (downloaded_texture)
- g_object_unref (downloaded_texture);
-
- return t->texture_id;
-}
-
-static guint
-texture_key_hash (gconstpointer v)
-{
- const GskTextureKey *k = (GskTextureKey *)v;
-
- return GPOINTER_TO_UINT (k->pointer)
- + (guint)(k->scale_x * 100)
- + (guint)(k->scale_y * 100)
- + (guint)k->filter * 2 +
- + (guint)k->pointer_is_child;
-}
-
-static gboolean
-texture_key_equal (gconstpointer v1, gconstpointer v2)
-{
- const GskTextureKey *k1 = (GskTextureKey *)v1;
- const GskTextureKey *k2 = (GskTextureKey *)v2;
-
- return k1->pointer == k2->pointer &&
- k1->scale_x == k2->scale_x &&
- k1->scale_y == k2->scale_y &&
- k1->filter == k2->filter &&
- k1->pointer_is_child == k2->pointer_is_child &&
- (!k1->pointer_is_child || graphene_rect_equal (&k1->parent_rect, &k2->parent_rect));
-}
-
-int
-gsk_gl_driver_get_texture_for_key (GskGLDriver *self,
- GskTextureKey *key)
-{
- int id = 0;
-
- if (G_UNLIKELY (self->pointer_textures == NULL))
- self->pointer_textures = g_hash_table_new_full (texture_key_hash, texture_key_equal, g_free, NULL);
-
- id = GPOINTER_TO_INT (g_hash_table_lookup (self->pointer_textures, key));
-
- if (id != 0)
- {
- Texture *t;
-
- t = g_hash_table_lookup (self->textures, GINT_TO_POINTER (id));
-
- if (t != NULL)
- t->in_use = TRUE;
- }
-
- return id;
-}
-
-void
-gsk_gl_driver_set_texture_for_key (GskGLDriver *self,
- GskTextureKey *key,
- int texture_id)
-{
- GskTextureKey *k;
-
- if (G_UNLIKELY (self->pointer_textures == NULL))
- self->pointer_textures = g_hash_table_new_full (texture_key_hash, texture_key_equal, g_free, NULL);
-
- k = g_new (GskTextureKey, 1);
- *k = *key;
-
- g_hash_table_insert (self->pointer_textures, k, GINT_TO_POINTER (texture_id));
-}
-
-int
-gsk_gl_driver_create_texture (GskGLDriver *self,
- float width,
- float height)
-{
- Texture *t;
-
- g_return_val_if_fail (GSK_IS_GL_DRIVER (self), -1);
-
- t = create_texture (self, width, height);
-
- return t->texture_id;
-}
-
-void
-gsk_gl_driver_create_render_target (GskGLDriver *self,
- int width,
- int height,
- int min_filter,
- int mag_filter,
- int *out_texture_id,
- int *out_render_target_id)
-{
- GLuint fbo_id;
- Texture *texture;
-
- g_return_if_fail (self->in_frame);
-
- texture = create_texture (self, width, height);
- gsk_gl_driver_bind_source_texture (self, texture->texture_id);
- gsk_gl_driver_init_texture_empty (self, texture->texture_id, min_filter, mag_filter);
-
- glGenFramebuffers (1, &fbo_id);
- glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
- glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture_id, 0);
-
-#if 0
- if (add_depth_buffer || add_stencil_buffer)
- {
- glGenRenderbuffersEXT (1, &depth_stencil_buffer_id);
- gdk_gl_context_label_object_printf (self->gl_context, GL_RENDERBUFFER, depth_stencil_buffer_id,
- "%s buffer for %d", add_depth_buffer ? "Depth" : "Stencil", texture_id);
- }
- else
- depth_stencil_buffer_id = 0;
-
- glBindRenderbuffer (GL_RENDERBUFFER, depth_stencil_buffer_id);
-
- if (add_depth_buffer || add_stencil_buffer)
- {
- if (add_stencil_buffer)
- glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, t->width, t->height);
- else
- glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, t->width, t->height);
-
- if (add_depth_buffer)
- glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, depth_stencil_buffer_id);
-
- if (add_stencil_buffer)
- glFramebufferRenderbufferEXT (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, depth_stencil_buffer_id);
- texture->fbo.depth_stencil_id = depth_stencil_buffer_id;
- }
-#endif
-
- texture->fbo.fbo_id = fbo_id;
-
- g_assert_cmphex (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
-
- glBindFramebuffer (GL_FRAMEBUFFER, self->default_fbo.fbo_id);
-
- *out_texture_id = texture->texture_id;
- *out_render_target_id = fbo_id;
-}
-
-/* Mark the texture permanent, meaning it won'e be reused by the GLDriver.
- * E.g. to store it in some other cache. */
-void
-gsk_gl_driver_mark_texture_permanent (GskGLDriver *self,
- int texture_id)
-{
- Texture *t = gsk_gl_driver_get_texture (self, texture_id);
-
- g_assert (t != NULL);
-
- t->permanent = TRUE;
-}
-
-void
-gsk_gl_driver_bind_source_texture (GskGLDriver *self,
- int texture_id)
-{
- Texture *t;
-
- g_return_if_fail (GSK_IS_GL_DRIVER (self));
- g_return_if_fail (self->in_frame);
-
- t = gsk_gl_driver_get_texture (self, texture_id);
- if (t == NULL)
- {
- g_critical ("No texture %d found.", texture_id);
- return;
- }
-
- if (self->bound_source_texture != t)
- {
- glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_2D, t->texture_id);
-
- self->bound_source_texture = t;
- }
-}
-
-void
-gsk_gl_driver_destroy_texture (GskGLDriver *self,
- int texture_id)
-{
- g_return_if_fail (GSK_IS_GL_DRIVER (self));
-
- g_hash_table_remove (self->textures, GINT_TO_POINTER (texture_id));
-}
-
-
-void
-gsk_gl_driver_init_texture_empty (GskGLDriver *self,
- int texture_id,
- int min_filter,
- int mag_filter)
-{
- Texture *t;
-
- g_return_if_fail (GSK_IS_GL_DRIVER (self));
-
- t = gsk_gl_driver_get_texture (self, texture_id);
- if (t == NULL)
- {
- g_critical ("No texture %d found.", texture_id);
- return;
- }
-
- if (self->bound_source_texture != t)
- {
- g_critical ("You must bind the texture before initializing it.");
- return;
- }
-
- t->min_filter = min_filter;
- t->mag_filter = mag_filter;
-
- gsk_gl_driver_set_texture_parameters (self, t->min_filter, t->mag_filter);
-
- if (gdk_gl_context_get_use_es (self->gl_context))
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, t->width, t->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- else
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, t->width, t->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture (GL_TEXTURE_2D, 0);
-}
-
-static gboolean
-filter_uses_mipmaps (int filter)
-{
- return filter != GL_NEAREST && filter != GL_LINEAR;
-}
-
-void
-gsk_gl_driver_init_texture (GskGLDriver *self,
- int texture_id,
- GdkTexture *texture,
- int min_filter,
- int mag_filter)
-{
- Texture *t;
-
- g_return_if_fail (GSK_IS_GL_DRIVER (self));
-
- t = gsk_gl_driver_get_texture (self, texture_id);
- if (t == NULL)
- {
- g_critical ("No texture %d found.", texture_id);
- return;
- }
-
- if (self->bound_source_texture != t)
- {
- g_critical ("You must bind the texture before initializing it.");
- return;
- }
-
- gsk_gl_driver_set_texture_parameters (self, min_filter, mag_filter);
-
- upload_gdk_texture (texture, GL_TEXTURE_2D, 0, 0, t->width, t->height);
-
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_counter_inc (self->profiler, self->counters.surface_uploads);
-#endif
-
- t->min_filter = min_filter;
- t->mag_filter = mag_filter;
-
- if (filter_uses_mipmaps (t->min_filter))
- glGenerateMipmap (GL_TEXTURE_2D);
-}
diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h
deleted file mode 100644
index 86c5dd93d1..0000000000
--- a/gsk/gl/gskgldriverprivate.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __GSK_GL_DRIVER_PRIVATE_H__
-#define __GSK_GL_DRIVER_PRIVATE_H__
-
-#include <cairo.h>
-#include <gdk/gdk.h>
-#include <graphene.h>
-
-G_BEGIN_DECLS
-
-#define GSK_TYPE_GL_DRIVER (gsk_gl_driver_get_type ())
-
-G_DECLARE_FINAL_TYPE (GskGLDriver, gsk_gl_driver, GSK, GL_DRIVER, GObject)
-
-typedef struct {
- float position[2];
- float uv[2];
-} GskQuadVertex;
-
-typedef struct {
- cairo_rectangle_int_t rect;
- guint texture_id;
-} TextureSlice;
-
-typedef struct {
- gpointer pointer;
- float scale_x;
- float scale_y;
- int filter;
- int pointer_is_child;
- graphene_rect_t parent_rect; /* Only set if pointer_is_child */
-} GskTextureKey;
-
-GskGLDriver * gsk_gl_driver_new (GdkGLContext *context);
-GdkGLContext *gsk_gl_driver_get_gl_context (GskGLDriver *driver);
-
-int gsk_gl_driver_get_max_texture_size (GskGLDriver *driver);
-
-void gsk_gl_driver_begin_frame (GskGLDriver *driver);
-void gsk_gl_driver_end_frame (GskGLDriver *driver);
-gboolean gsk_gl_driver_in_frame (GskGLDriver *driver);
-int gsk_gl_driver_get_texture_for_texture (GskGLDriver *driver,
- GdkTexture *texture,
- int min_filter,
- int mag_filter);
-int gsk_gl_driver_get_texture_for_key (GskGLDriver *driver,
- GskTextureKey *key);
-void gsk_gl_driver_set_texture_for_key (GskGLDriver *driver,
- GskTextureKey *key,
- int texture_id);
-int gsk_gl_driver_create_texture (GskGLDriver *driver,
- float width,
- float height);
-void gsk_gl_driver_create_render_target (GskGLDriver *driver,
- int width,
- int height,
- int min_filter,
- int mag_filter,
- int *out_texture_id,
- int *out_render_target_id);
-void gsk_gl_driver_mark_texture_permanent (GskGLDriver *self,
- int texture_id);
-void gsk_gl_driver_bind_source_texture (GskGLDriver *driver,
- int texture_id);
-
-void gsk_gl_driver_init_texture_empty (GskGLDriver *driver,
- int texture_id,
- int min_filter,
- int max_filter);
-void gsk_gl_driver_init_texture (GskGLDriver *driver,
- int texture_id,
- GdkTexture *texture,
- int min_filter,
- int mag_filter);
-
-void gsk_gl_driver_destroy_texture (GskGLDriver *driver,
- int texture_id);
-
-int gsk_gl_driver_collect_textures (GskGLDriver *driver);
-void gsk_gl_driver_slice_texture (GskGLDriver *self,
- GdkTexture *texture,
- TextureSlice **out_slices,
- guint *out_n_slices);
-
-G_END_DECLS
-
-#endif /* __GSK_GL_DRIVER_PRIVATE_H__ */
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
deleted file mode 100644
index 864c741709..0000000000
--- a/gsk/gl/gskglglyphcache.c
+++ /dev/null
@@ -1,397 +0,0 @@
-#include "config.h"
-
-#include "gskglglyphcacheprivate.h"
-#include "gskgldriverprivate.h"
-#include "gskdebugprivate.h"
-#include "gskprivate.h"
-#include "gskgltextureatlasprivate.h"
-
-#include "gdk/gdkglcontextprivate.h"
-#include "gdk/gdkmemorytextureprivate.h"
-
-#include <graphene.h>
-#include <cairo.h>
-#include <epoxy/gl.h>
-#include <string.h>
-
-/* Cache eviction strategy
- *
- * We mark glyphs as accessed every time we use them.
- * Every few frames, we mark glyphs that haven't been
- * accessed since the last check as old.
- *
- * We keep count of the pixels of each atlas that are
- * taken up by old data. When the fraction of old pixels
- * gets too high, we drop the atlas and all the items it
- * contained.
- *
- * Big glyphs are not stored in the atlas, they get their
- * own texture, but they are still cached.
- */
-
-#define MAX_FRAME_AGE (60)
-#define MAX_GLYPH_SIZE 128 /* Will get its own texture if bigger */
-
-static guint glyph_cache_hash (gconstpointer v);
-static gboolean glyph_cache_equal (gconstpointer v1,
- gconstpointer v2);
-static void glyph_cache_key_free (gpointer v);
-static void glyph_cache_value_free (gpointer v);
-
-GskGLGlyphCache *
-gsk_gl_glyph_cache_new (GdkDisplay *display,
- GskGLTextureAtlases *atlases)
-{
- GskGLGlyphCache *glyph_cache;
-
- glyph_cache = g_new0 (GskGLGlyphCache, 1);
-
- glyph_cache->display = display;
- glyph_cache->hash_table = g_hash_table_new_full (glyph_cache_hash, glyph_cache_equal,
- glyph_cache_key_free, glyph_cache_value_free);
-
- glyph_cache->atlases = gsk_gl_texture_atlases_ref (atlases);
-
- glyph_cache->ref_count = 1;
-
- return glyph_cache;
-}
-
-GskGLGlyphCache *
-gsk_gl_glyph_cache_ref (GskGLGlyphCache *self)
-{
- self->ref_count++;
-
- return self;
-}
-
-void
-gsk_gl_glyph_cache_unref (GskGLGlyphCache *self)
-{
- g_assert (self->ref_count > 0);
-
- if (self->ref_count == 1)
- {
- gsk_gl_texture_atlases_unref (self->atlases);
- g_hash_table_unref (self->hash_table);
- g_free (self);
- return;
- }
-
- self->ref_count--;
-}
-
-static gboolean
-glyph_cache_equal (gconstpointer v1, gconstpointer v2)
-{
- return memcmp (v1, v2, sizeof (CacheKeyData)) == 0;
-}
-
-static guint
-glyph_cache_hash (gconstpointer v)
-{
- const GlyphCacheKey *key = v;
-
- return key->hash;
-}
-
-static void
-glyph_cache_key_free (gpointer v)
-{
- GlyphCacheKey *f = v;
-
- g_object_unref (f->data.font);
- g_free (f);
-}
-
-static void
-glyph_cache_value_free (gpointer v)
-{
- g_free (v);
-}
-
-static gboolean
-render_glyph (GlyphCacheKey *key,
- GskGLCachedGlyph *value,
- GskImageRegion *region)
-{
- cairo_surface_t *surface;
- cairo_t *cr;
- cairo_scaled_font_t *scaled_font;
- PangoGlyphString glyph_string;
- PangoGlyphInfo glyph_info;
- int surface_width, surface_height;
- int stride;
- unsigned char *data;
-
- scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)key->data.font);
- if (G_UNLIKELY (!scaled_font || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))
- {
- g_warning ("Failed to get a font");
- return FALSE;
- }
-
- surface_width = value->draw_width * key->data.scale / 1024;
- surface_height = value->draw_height * key->data.scale / 1024;
-
- stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, surface_width);
- data = g_malloc0 (stride * surface_height);
- surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
- surface_width, surface_height,
- stride);
- cairo_surface_set_device_scale (surface, key->data.scale / 1024.0, key->data.scale / 1024.0);
-
- cr = cairo_create (surface);
-
- cairo_set_scaled_font (cr, scaled_font);
- cairo_set_source_rgba (cr, 1, 1, 1, 1);
-
- glyph_info.glyph = key->data.glyph;
- glyph_info.geometry.width = value->draw_width * 1024;
- if (glyph_info.glyph & PANGO_GLYPH_UNKNOWN_FLAG)
- glyph_info.geometry.x_offset = 256 * key->data.xshift;
- else
- glyph_info.geometry.x_offset = 256 * key->data.xshift - value->draw_x * 1024;
- glyph_info.geometry.y_offset = 256 * key->data.yshift - value->draw_y * 1024;
-
- glyph_string.num_glyphs = 1;
- glyph_string.glyphs = &glyph_info;
-
- pango_cairo_show_glyph_string (cr, key->data.font, &glyph_string);
- cairo_destroy (cr);
-
- cairo_surface_flush (surface);
-
- region->width = cairo_image_surface_get_width (surface);
- region->height = cairo_image_surface_get_height (surface);
- region->stride = cairo_image_surface_get_stride (surface);
- region->data = data;
- if (value->atlas)
- {
- region->x = (gsize)(value->tx * value->atlas->width);
- region->y = (gsize)(value->ty * value->atlas->height);
- }
- else
- {
- region->x = 0;
- region->y = 0;
- }
-
- cairo_surface_destroy (surface);
-
- return TRUE;
-}
-
-static void
-upload_glyph (GlyphCacheKey *key,
- GskGLCachedGlyph *value)
-{
- GskImageRegion r;
- guchar *pixel_data;
- guchar *free_data = NULL;
- guint gl_format;
- guint gl_type;
-
- gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
- "Uploading glyph %d",
- key->data.glyph);
-
- if (render_glyph (key, value, &r))
- {
- glPixelStorei (GL_UNPACK_ROW_LENGTH, r.stride / 4);
- glBindTexture (GL_TEXTURE_2D, value->texture_id);
-
- if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
- {
- pixel_data = free_data = g_malloc (r.width * r.height * 4);
- gdk_memory_convert (pixel_data, r.width * 4,
- GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
- r.data, r.width * 4,
- GDK_MEMORY_DEFAULT, r.width, r.height);
- gl_format = GL_RGBA;
- gl_type = GL_UNSIGNED_BYTE;
- }
- else
- {
- pixel_data = r.data;
- gl_format = GL_BGRA;
- gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
- }
-
- glTexSubImage2D (GL_TEXTURE_2D, 0, r.x, r.y, r.width, r.height,
- gl_format, gl_type, pixel_data);
- glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
- g_free (r.data);
- g_free (free_data);
- }
-
- gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
-}
-
-static void
-add_to_cache (GskGLGlyphCache *self,
- GlyphCacheKey *key,
- GskGLDriver *driver,
- GskGLCachedGlyph *value)
-{
- const int width = value->draw_width * key->data.scale / 1024;
- const int height = value->draw_height * key->data.scale / 1024;
-
- if (width < MAX_GLYPH_SIZE && height < MAX_GLYPH_SIZE)
- {
- GskGLTextureAtlas *atlas = NULL;
- int packed_x = 0;
- int packed_y = 0;
-
- gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
-
- value->tx = (float)(packed_x + 1) / atlas->width;
- value->ty = (float)(packed_y + 1) / atlas->height;
- value->tw = (float)width / atlas->width;
- value->th = (float)height / atlas->height;
- value->used = TRUE;
-
- value->atlas = atlas;
- value->texture_id = atlas->texture_id;
- }
- else
- {
- value->atlas = NULL;
- value->texture_id = gsk_gl_driver_create_texture (driver, width, height);
- gsk_gl_driver_mark_texture_permanent (driver, value->texture_id);
-
- gsk_gl_driver_bind_source_texture (driver, value->texture_id);
- gsk_gl_driver_init_texture_empty (driver, value->texture_id, GL_LINEAR, GL_LINEAR);
-
- value->tx = 0.0f;
- value->ty = 0.0f;
- value->tw = 1.0f;
- value->th = 1.0f;
- }
-
- upload_glyph (key, value);
-}
-
-void
-gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *cache,
- GlyphCacheKey *lookup,
- GskGLDriver *driver,
- const GskGLCachedGlyph **cached_glyph_out)
-{
- GskGLCachedGlyph *value;
-
- value = g_hash_table_lookup (cache->hash_table, lookup);
-
- if (value)
- {
- if (value->atlas && !value->used)
- {
- gsk_gl_texture_atlas_mark_used (value->atlas, value->draw_width, value->draw_height);
- value->used = TRUE;
- }
- value->accessed = TRUE;
-
- *cached_glyph_out = value;
- return;
- }
-
- {
- GlyphCacheKey *key;
- PangoRectangle ink_rect;
-
- pango_font_get_glyph_extents (lookup->data.font, lookup->data.glyph, &ink_rect, NULL);
- pango_extents_to_pixels (&ink_rect, NULL);
- if (lookup->data.xshift != 0)
- ink_rect.width += 1;
- if (lookup->data.yshift != 0)
- ink_rect.height += 1;
-
- value = g_new0 (GskGLCachedGlyph, 1);
-
- value->draw_x = ink_rect.x;
- value->draw_y = ink_rect.y;
- value->draw_width = ink_rect.width;
- value->draw_height = ink_rect.height;
- value->accessed = TRUE;
- value->atlas = NULL; /* For now */
-
- key = g_new0 (GlyphCacheKey, 1);
-
- key->data.font = g_object_ref (lookup->data.font);
- key->data.glyph = lookup->data.glyph;
- key->data.xshift = lookup->data.xshift;
- key->data.yshift = lookup->data.yshift;
- key->data.scale = lookup->data.scale;
- key->hash = lookup->hash;
-
- if (key->data.scale > 0 &&
- value->draw_width * key->data.scale / 1024 > 0 &&
- value->draw_height * key->data.scale / 1024 > 0)
- add_to_cache (cache, key, driver, value);
-
- *cached_glyph_out = value;
- g_hash_table_insert (cache->hash_table, key, value);
- }
-}
-
-void
-gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
- GskGLDriver *driver,
- GPtrArray *removed_atlases)
-{
- GHashTableIter iter;
- GlyphCacheKey *key;
- GskGLCachedGlyph *value;
- guint dropped = 0;
-
- self->timestamp++;
-
- if (removed_atlases->len > 0)
- {
- g_hash_table_iter_init (&iter, self->hash_table);
- while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
- {
- if (g_ptr_array_find (removed_atlases, value->atlas, NULL))
- {
- g_hash_table_iter_remove (&iter);
- dropped++;
- }
- }
- }
-
- if (self->timestamp % MAX_FRAME_AGE == 30)
- {
- g_hash_table_iter_init (&iter, self->hash_table);
- while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
- {
- if (!value->accessed)
- {
- if (value->atlas)
- {
- if (value->used)
- {
- gsk_gl_texture_atlas_mark_unused (value->atlas, value->draw_width, value->draw_height);
- value->used = FALSE;
- }
- }
- else
- {
- gsk_gl_driver_destroy_texture (driver, value->texture_id);
- g_hash_table_iter_remove (&iter);
-
- /* Sadly, if we drop an atlas-less cached glyph, we
- * have to treat it like a dropped atlas and purge
- * text node render data.
- */
- dropped++;
- }
- }
- else
- value->accessed = FALSE;
- }
-
- GSK_NOTE(GLYPH_CACHE, g_message ("%d glyphs cached", g_hash_table_size (self->hash_table)));
- }
-
- GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d glyphs", dropped));
-}
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
deleted file mode 100644
index d66b251a44..0000000000
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef __GSK_GL_GLYPH_CACHE_PRIVATE_H__
-#define __GSK_GL_GLYPH_CACHE_PRIVATE_H__
-
-#include "gskgldriverprivate.h"
-#include "gskglimageprivate.h"
-#include "gskgltextureatlasprivate.h"
-#include <pango/pango.h>
-#include <gdk/gdk.h>
-
-typedef struct
-{
- int ref_count;
-
- GdkDisplay *display;
- GHashTable *hash_table;
- GskGLTextureAtlases *atlases;
-
- int timestamp;
-} GskGLGlyphCache;
-
-struct _CacheKeyData
-{
- PangoFont *font;
- PangoGlyph glyph;
- guint xshift : 3;
- guint yshift : 3;
- guint scale : 26; /* times 1024 */
-};
-
-typedef struct _CacheKeyData CacheKeyData;
-
-struct _GlyphCacheKey
-{
- CacheKeyData data;
- guint hash;
-};
-
-typedef struct _GlyphCacheKey GlyphCacheKey;
-
-#define PHASE(x) ((int)(floor (4 * (x + 0.125)) - 4 * floor (x + 0.125)))
-
-static inline void
-glyph_cache_key_set_glyph_and_shift (GlyphCacheKey *key,
- PangoGlyph glyph,
- float x,
- float y)
-{
- key->data.glyph = glyph;
- key->data.xshift = PHASE (x);
- key->data.yshift = PHASE (y);
- key->hash = GPOINTER_TO_UINT (key->data.font) ^
- key->data.glyph ^
- (key->data.xshift << 24) ^
- (key->data.yshift << 26) ^
- key->data.scale;
-}
-
-typedef struct _GskGLCachedGlyph GskGLCachedGlyph;
-
-struct _GskGLCachedGlyph
-{
- GskGLTextureAtlas *atlas;
- guint texture_id;
-
- float tx;
- float ty;
- float tw;
- float th;
-
- int draw_x;
- int draw_y;
- int draw_width;
- int draw_height;
-
- guint accessed : 1; /* accessed since last check */
- guint used : 1; /* accounted as used in the atlas */
-};
-
-
-GskGLGlyphCache * gsk_gl_glyph_cache_new (GdkDisplay *display,
- GskGLTextureAtlases *atlases);
-GskGLGlyphCache * gsk_gl_glyph_cache_ref (GskGLGlyphCache *self);
-void gsk_gl_glyph_cache_unref (GskGLGlyphCache *self);
-void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache *self,
- GskGLDriver *driver,
- GPtrArray *removed_atlases);
-void gsk_gl_glyph_cache_lookup_or_add (GskGLGlyphCache *self,
- GlyphCacheKey *lookup,
- GskGLDriver *driver,
- const GskGLCachedGlyph **cached_glyph_out);
-
-#endif
diff --git a/gsk/gl/gskgliconcache.c b/gsk/gl/gskgliconcache.c
deleted file mode 100644
index 4bbbdbb4da..0000000000
--- a/gsk/gl/gskgliconcache.c
+++ /dev/null
@@ -1,275 +0,0 @@
-#include "gskgliconcacheprivate.h"
-#include "gskgltextureatlasprivate.h"
-#include "gdk/gdktextureprivate.h"
-#include "gdk/gdkmemorytextureprivate.h"
-#include "gdk/gdkglcontextprivate.h"
-
-#include <epoxy/gl.h>
-
-#define MAX_FRAME_AGE 60
-
-static void
-icon_data_free (gpointer p)
-{
- g_object_unref (((IconData *)p)->source_texture);
- g_free (p);
-}
-
-GskGLIconCache *
-gsk_gl_icon_cache_new (GdkDisplay *display,
- GskGLTextureAtlases *atlases)
-{
- GskGLIconCache *self;
-
- self = g_new0 (GskGLIconCache, 1);
-
- self->display = display;
- self->icons = g_hash_table_new_full (NULL, NULL, NULL, icon_data_free);
- self->atlases = gsk_gl_texture_atlases_ref (atlases);
- self->ref_count = 1;
-
- return self;
-}
-
-GskGLIconCache *
-gsk_gl_icon_cache_ref (GskGLIconCache *self)
-{
- self->ref_count++;
-
- return self;
-}
-
-void
-gsk_gl_icon_cache_unref (GskGLIconCache *self)
-{
- g_assert (self->ref_count > 0);
-
- if (self->ref_count == 1)
- {
- gsk_gl_texture_atlases_unref (self->atlases);
- g_hash_table_unref (self->icons);
- g_free (self);
- return;
- }
-
- self->ref_count--;
-}
-
-void
-gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
- GPtrArray *removed_atlases)
-{
- GHashTableIter iter;
- GdkTexture *texture;
- IconData *icon_data;
-
- self->timestamp++;
-
- /* Drop icons on removed atlases */
- if (removed_atlases->len > 0)
- {
- guint dropped = 0;
-
- g_hash_table_iter_init (&iter, self->icons);
- while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
- {
- if (g_ptr_array_find (removed_atlases, icon_data->atlas, NULL))
- {
- g_hash_table_iter_remove (&iter);
- dropped++;
- }
- }
-
- GSK_NOTE(GLYPH_CACHE, if (dropped > 0) g_message ("Dropped %d icons", dropped));
- }
-
- if (self->timestamp % MAX_FRAME_AGE == 0)
- {
- g_hash_table_iter_init (&iter, self->icons);
- while (g_hash_table_iter_next (&iter, (gpointer *)&texture, (gpointer *)&icon_data))
- {
- if (!icon_data->accessed)
- {
- if (icon_data->used)
- {
- const int width = icon_data->source_texture->width;
- const int height = icon_data->source_texture->height;
- gsk_gl_texture_atlas_mark_unused (icon_data->atlas, width + 2, height + 2);
- icon_data->used = FALSE;
- }
- }
-
- icon_data->accessed = FALSE;
- }
-
- GSK_NOTE(GLYPH_CACHE, g_message ("%d icons cached", g_hash_table_size (self->icons)));
- }
-}
-
-void
-gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
- GdkTexture *texture,
- const IconData **out_icon_data)
-{
- IconData *icon_data = g_hash_table_lookup (self->icons, texture);
-
- if (icon_data)
- {
- if (!icon_data->used)
- {
- gsk_gl_texture_atlas_mark_used (icon_data->atlas, texture->width + 2, texture->height + 2);
- icon_data->used = TRUE;
- }
- icon_data->accessed = TRUE;
-
- *out_icon_data = icon_data;
- return;
- }
-
- /* texture not on any atlas yet. Find a suitable one. */
- {
- const int width = texture->width;
- const int height = texture->height;
- GskGLTextureAtlas *atlas = NULL;
- int packed_x = 0;
- int packed_y = 0;
- cairo_surface_t *surface;
- unsigned char *surface_data;
- unsigned char *pixel_data;
- guchar *free_data = NULL;
- guint gl_format;
- guint gl_type;
-
- gsk_gl_texture_atlases_pack (self->atlases, width + 2, height + 2, &atlas, &packed_x, &packed_y);
-
- icon_data = g_new0 (IconData, 1);
- icon_data->atlas = atlas;
- icon_data->accessed = TRUE;
- icon_data->used = TRUE;
- icon_data->texture_id = atlas->texture_id;
- icon_data->source_texture = g_object_ref (texture);
- icon_data->x = (float)(packed_x + 1) / atlas->width;
- icon_data->y = (float)(packed_y + 1) / atlas->width;
- icon_data->x2 = icon_data->x + (float)width / atlas->width;
- icon_data->y2 = icon_data->y + (float)height / atlas->height;
-
- g_hash_table_insert (self->icons, texture, icon_data);
-
- /* actually upload the texture */
- surface = gdk_texture_download_surface (texture);
- surface_data = cairo_image_surface_get_data (surface);
- gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
- "Uploading texture");
-
- if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
- {
- pixel_data = free_data = g_malloc (width * height * 4);
- gdk_memory_convert (pixel_data, width * 4,
- GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
- surface_data, cairo_image_surface_get_stride (surface),
- GDK_MEMORY_DEFAULT, width, height);
- gl_format = GL_RGBA;
- gl_type = GL_UNSIGNED_BYTE;
- }
- else
- {
- pixel_data = surface_data;
- gl_format = GL_BGRA;
- gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
- }
-
- glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
-
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x + 1, packed_y + 1,
- width, height,
- gl_format, gl_type,
- pixel_data);
- /* Padding top */
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x + 1, packed_y,
- width, 1,
- gl_format, gl_type,
- pixel_data);
- /* Padding left */
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x, packed_y + 1,
- 1, height,
- gl_format, gl_type,
- pixel_data);
- /* Padding top left */
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x, packed_y,
- 1, 1,
- gl_format, gl_type,
- pixel_data);
-
- /* Padding right */
- glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
- glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x + width + 1, packed_y + 1,
- 1, height,
- gl_format, gl_type,
- pixel_data);
- /* Padding top right */
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x + width + 1, packed_y,
- 1, 1,
- gl_format, gl_type,
- pixel_data);
- /* Padding bottom */
- glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei (GL_UNPACK_SKIP_ROWS, height - 1);
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x + 1, packed_y + 1 + height,
- width, 1,
- gl_format, gl_type,
- pixel_data);
- /* Padding bottom left */
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x, packed_y + 1 + height,
- 1, 1,
- gl_format, gl_type,
- pixel_data);
- /* Padding bottom right */
- glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
- glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
- glTexSubImage2D (GL_TEXTURE_2D, 0,
- packed_x + 1 + width, packed_y + 1 + height,
- 1, 1,
- gl_format, gl_type,
- pixel_data);
- /* Reset this */
- glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
-
- gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
-
- *out_icon_data = icon_data;
-
- cairo_surface_destroy (surface);
- g_free (free_data);
-
-#if 0
- {
- static int k;
- const int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, atlas->width);
- guchar *data = g_malloc (atlas->height * stride);
- cairo_surface_t *s;
- char *filename = g_strdup_printf ("atlas_%u_%d.png", atlas->texture_id, k++);
-
- glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
- glGetTexImage (GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
- s = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, atlas->width, atlas->height, stride);
- cairo_surface_write_to_png (s, filename);
-
- cairo_surface_destroy (s);
- g_free (data);
- g_free (filename);
- }
-#endif
- }
-}
diff --git a/gsk/gl/gskgliconcacheprivate.h b/gsk/gl/gskgliconcacheprivate.h
deleted file mode 100644
index e076278a4e..0000000000
--- a/gsk/gl/gskgliconcacheprivate.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __GSK_GL_ICON_CACHE_PRIVATE_H__
-#define __GSK_GL_ICON_CACHE_PRIVATE_H__
-
-#include "gskgldriverprivate.h"
-#include "gskglimageprivate.h"
-#include "gskrendererprivate.h"
-#include "gskgltextureatlasprivate.h"
-#include <pango/pango.h>
-#include <gdk/gdk.h>
-
-typedef struct
-{
- int ref_count;
-
- GdkDisplay *display;
- GskGLDriver *gl_driver;
-
- GskGLTextureAtlases *atlases;
- GHashTable *icons; /* GdkTexture -> IconData */
-
- int timestamp;
-} GskGLIconCache;
-
-typedef struct
-{
- float x, y, x2, y2;
- GskGLTextureAtlas *atlas;
- guint used : 1;
- guint accessed : 1;
- int texture_id;
- GdkTexture *source_texture;
-} IconData;
-
-GskGLIconCache * gsk_gl_icon_cache_new (GdkDisplay *display,
- GskGLTextureAtlases *atlases);
-GskGLIconCache * gsk_gl_icon_cache_ref (GskGLIconCache *self);
-void gsk_gl_icon_cache_unref (GskGLIconCache *self);
-void gsk_gl_icon_cache_begin_frame (GskGLIconCache *self,
- GPtrArray *removed_atlases);
-void gsk_gl_icon_cache_lookup_or_add (GskGLIconCache *self,
- GdkTexture *texture,
- const IconData **out_icon_data);
-
-#endif
diff --git a/gsk/gl/gskglimage.c b/gsk/gl/gskglimage.c
deleted file mode 100644
index 71d7bce2a3..0000000000
--- a/gsk/gl/gskglimage.c
+++ /dev/null
@@ -1,64 +0,0 @@
-
-#include "gskglimageprivate.h"
-#include <epoxy/gl.h>
-
-void
-gsk_gl_image_create (GskGLImage *self,
- GskGLDriver *gl_driver,
- int width,
- int height,
- int min_filter,
- int mag_filter)
-{
- self->texture_id = gsk_gl_driver_create_texture (gl_driver, width, height);
- self->width = width;
- self->height = height;
-
- gsk_gl_driver_bind_source_texture (gl_driver, self->texture_id);
- gsk_gl_driver_init_texture_empty (gl_driver, self->texture_id, min_filter, mag_filter);
- gsk_gl_driver_mark_texture_permanent (gl_driver, self->texture_id);
-}
-
-void
-gsk_gl_image_destroy (GskGLImage *self,
- GskGLDriver *gl_driver)
-{
- gsk_gl_driver_destroy_texture (gl_driver, self->texture_id);
- self->texture_id = 0;
-}
-
-void
-gsk_gl_image_write_to_png (const GskGLImage *self,
- GskGLDriver *gl_driver,
- const char *filename)
-{
- int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, self->width);
- guchar *data = g_malloc (self->height * stride);
- cairo_surface_t *s;
-
- gsk_gl_driver_bind_source_texture (gl_driver, self->texture_id);
- glGetTexImage (GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
- s = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, self->width, self->height, stride);
- cairo_surface_write_to_png (s, filename);
-
- cairo_surface_destroy (s);
- g_free (data);
-}
-
-void
-gsk_gl_image_upload_region (GskGLImage *self,
- GskGLDriver *gl_driver,
- const GskImageRegion *region)
-{
- gsk_gl_driver_bind_source_texture (gl_driver, self->texture_id);
- glBindTexture (GL_TEXTURE_2D, self->texture_id);
-
- glTexSubImage2D (GL_TEXTURE_2D, 0, region->x, region->y, region->width, region->height,
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, region->data);
-
-#ifdef G_ENABLE_DEBUG
- /*gsk_gl_driver_bind_source_texture (gl_driver, self->texture_id);*/
- /*gsk_gl_image_dump (self, gl_driver, "/home/baedert/atlases/test_dump.png");*/
-#endif
-}
-
diff --git a/gsk/gl/gskglimageprivate.h b/gsk/gl/gskglimageprivate.h
deleted file mode 100644
index 3d706723b8..0000000000
--- a/gsk/gl/gskglimageprivate.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __GSK_GL_IMAGE_H__
-#define __GSK_GL_IMAGE_H__
-
-#include "gskgldriverprivate.h"
-#include <cairo.h>
-
-typedef struct
-{
- guint texture_id;
- int width;
- int height;
-} GskGLImage;
-
-typedef struct
-{
- guchar *data;
- gsize width;
- gsize height;
- gsize stride;
- gsize x;
- gsize y;
-} GskImageRegion;
-
-void gsk_gl_image_create (GskGLImage *self,
- GskGLDriver *gl_driver,
- int width,
- int height,
- int min_filter,
- int mag_filter);
-void gsk_gl_image_destroy (GskGLImage *self,
- GskGLDriver *gl_driver);
-void gsk_gl_image_write_to_png (const GskGLImage *self,
- GskGLDriver *gl_driver,
- const char *filename);
-void gsk_gl_image_upload_region (GskGLImage *self,
- GskGLDriver *gl_driver,
- const GskImageRegion *region);
-
-
-#endif
-
diff --git a/gsk/gl/gskglnodesample.c b/gsk/gl/gskglnodesample.c
deleted file mode 100644
index cf1afa5a68..0000000000
--- a/gsk/gl/gskglnodesample.c
+++ /dev/null
@@ -1,51 +0,0 @@
-
-#include <glib/gprintf.h>
-#include "gskglnodesampleprivate.h"
-#include "gskrendernodeprivate.h"
-
-void
-node_sample_init (NodeSample *self)
-{
- memset (self->nodes, 0, sizeof (self->nodes));
- self->count = 0;
-}
-
-void
-node_sample_reset (NodeSample *self)
-{
- node_sample_init (self);
-}
-
-void
-node_sample_add (NodeSample *self,
- GskRenderNode *node)
-{
- const guint node_type = gsk_render_node_get_node_type (node);
-
- g_assert (node_type <= N_NODE_TYPES);
-
- if (self->nodes[node_type].class_name == NULL)
- self->nodes[node_type].class_name = g_type_name_from_instance ((GTypeInstance *) node);
-
- self->nodes[node_type].count ++;
- self->count ++;
-}
-
-void
-node_sample_print (const NodeSample *self,
- const char *prefix)
-{
- guint i;
-
- g_printf ("%s:\n", prefix);
-
- for (i = 0; i < N_NODE_TYPES; i ++)
- {
- if (self->nodes[i].count > 0)
- {
- double p = (double)self->nodes[i].count / (double)self->count;
-
- g_printf ("%s: %u (%.2f%%)\n", self->nodes[i].class_name, self->nodes[i].count, p * 100.0);
- }
- }
-}
diff --git a/gsk/gl/gskglnodesampleprivate.h b/gsk/gl/gskglnodesampleprivate.h
deleted file mode 100644
index a1d09a098f..0000000000
--- a/gsk/gl/gskglnodesampleprivate.h
+++ /dev/null
@@ -1,28 +0,0 @@
-
-#ifndef __GSK_GL_NODE_SAMPLE_PRIVATE_H__
-#define __GSK_GL_NODE_SAMPLE_PRIVATE_H__
-
-#include <glib.h>
-#include "gskenums.h"
-#include "gskrendernode.h"
-
-/* TODO: We have no other way for this...? */
-#define N_NODE_TYPES (GSK_DEBUG_NODE + 1)
-
-typedef struct
-{
- struct {
- const char *class_name;
- guint count;
- } nodes[N_NODE_TYPES];
- guint count;
-} NodeSample;
-
-void node_sample_init (NodeSample *self);
-void node_sample_reset (NodeSample *self);
-void node_sample_add (NodeSample *self,
- GskRenderNode *node);
-void node_sample_print (const NodeSample *self,
- const char *prefix);
-
-#endif
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
deleted file mode 100644
index a801f55ab3..0000000000
--- a/gsk/gl/gskglrenderer.c
+++ /dev/null
@@ -1,4559 +0,0 @@
-#include "config.h"
-
-#include "gskglrendererprivate.h"
-
-#include "gskdebugprivate.h"
-#include "gskenums.h"
-#include "gskgldriverprivate.h"
-#include "gskglprofilerprivate.h"
-#include "gskprofilerprivate.h"
-#include "gskrendererprivate.h"
-#include "gskrendernodeprivate.h"
-#include "gsktransformprivate.h"
-#include "gskglshaderbuilderprivate.h"
-#include "gskglglyphcacheprivate.h"
-#include "gskgliconcacheprivate.h"
-#include "gskglrenderopsprivate.h"
-#include "gskcairoblurprivate.h"
-#include "gskglshadowcacheprivate.h"
-#include "gskglnodesampleprivate.h"
-#include "gsktransform.h"
-#include "glutilsprivate.h"
-#include "gskglshaderprivate.h"
-
-#include "gskprivate.h"
-
-#include "gdk/gdkgltextureprivate.h"
-#include "gdk/gdkglcontextprivate.h"
-#include "gdk/gdkprofilerprivate.h"
-#include "gdk/gdkrgbaprivate.h"
-
-#include <epoxy/gl.h>
-
-#define SHADER_VERSION_GLES 100
-#define SHADER_VERSION_GL2_LEGACY 110
-#define SHADER_VERSION_GL3_LEGACY 130
-#define SHADER_VERSION_GL3 150
-
-#define ORTHO_NEAR_PLANE -10000
-#define ORTHO_FAR_PLANE 10000
-
-#define DEBUG_OPS 0
-
-#define SHADOW_EXTRA_SIZE 4
-
-#if DEBUG_OPS
-#define OP_PRINT(format, ...) g_print(format, ## __VA_ARGS__)
-#else
-#define OP_PRINT(format, ...)
-#endif
-
-#define INIT_PROGRAM_UNIFORM_LOCATION(program_name, uniform_basename) \
- G_STMT_START{\
- programs->program_name ## _program.program_name.uniform_basename ## _location = \
- glGetUniformLocation(programs->program_name ## _program.id, "u_" #uniform_basename);\
- if (programs->program_name ## _program.program_name.uniform_basename ## _location == -1) \
- { \
- g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED, \
- "Failed to find variable \"u_%s\" in shader program \"%s\"", #uniform_basename, #program_name); \
- g_clear_pointer (&programs, gsk_gl_renderer_programs_unref); \
- goto out; \
- } \
- }G_STMT_END
-
-#define INIT_COMMON_UNIFORM_LOCATION(program_ptr, uniform_basename) \
- G_STMT_START{\
- program_ptr->uniform_basename ## _location = \
- glGetUniformLocation(program_ptr->id, "u_" #uniform_basename);\
- }G_STMT_END
-
-static Program *gsk_gl_renderer_lookup_custom_program (GskGLRenderer *self,
- GskGLShader *shader);
-static Program *gsk_gl_renderer_create_custom_program (GskGLRenderer *self,
- GskGLShader *shader);
-
-typedef enum
-{
- FORCE_OFFSCREEN = 1 << 0,
- RESET_CLIP = 1 << 1,
- DUMP_FRAMEBUFFER = 1 << 3,
- NO_CACHE_PLZ = 1 << 5,
- LINEAR_FILTER = 1 << 6,
-} OffscreenFlags;
-
-static inline void
-init_full_texture_region (TextureRegion *r,
- int texture_id)
-{
- r->texture_id = texture_id;
- r->x = 0;
- r->y = 0;
- r->x2 = 1;
- r->y2 = 1;
-}
-
-static void G_GNUC_UNUSED
-print_render_node_tree (GskRenderNode *root, int level)
-{
-#define INDENT 4
- const guint type = gsk_render_node_get_node_type (root);
- guint i;
-
- switch (type)
- {
- case GSK_CONTAINER_NODE:
- g_print ("%*s Container\n", level * INDENT, " ");
- for (i = 0; i < gsk_container_node_get_n_children (root); i++)
- print_render_node_tree (gsk_container_node_get_child (root, i), level + 1);
- break;
-
- case GSK_TRANSFORM_NODE:
- g_print ("%*s Transform\n", level * INDENT, " ");
- print_render_node_tree (gsk_transform_node_get_child (root), level + 1);
- break;
-
- case GSK_COLOR_MATRIX_NODE:
- g_print ("%*s Color Matrix\n", level * INDENT, " ");
- print_render_node_tree (gsk_color_matrix_node_get_child (root), level + 1);
- break;
-
- case GSK_CROSS_FADE_NODE:
- g_print ("%*s Crossfade(%.2f)\n", level * INDENT, " ",
- gsk_cross_fade_node_get_progress (root));
- print_render_node_tree (gsk_cross_fade_node_get_start_child (root), level + 1);
- print_render_node_tree (gsk_cross_fade_node_get_end_child (root), level + 1);
- break;
-
- case GSK_TEXT_NODE:
- g_print ("%*s Text\n", level * INDENT, " ");
- break;
-
- case GSK_COLOR_NODE:
- g_print ("%*s Color %s\n", level * INDENT, " ", gdk_rgba_to_string (gsk_color_node_get_color (root)));
- break;
-
- case GSK_SHADOW_NODE:
- g_print ("%*s Shadow\n", level * INDENT, " ");
- print_render_node_tree (gsk_shadow_node_get_child (root), level + 1);
- break;
-
- case GSK_GL_SHADER_NODE:
- g_print ("%*s GL Shader\n", level * INDENT, " ");
- for (i = 0; i < gsk_gl_shader_node_get_n_children (root); i++)
- print_render_node_tree (gsk_gl_shader_node_get_child (root, i), level + 1);
- break;
-
- case GSK_TEXTURE_NODE:
- g_print ("%*s Texture %p\n", level * INDENT, " ", gsk_texture_node_get_texture (root));
- break;
-
- case GSK_DEBUG_NODE:
- g_print ("%*s Debug: %s\n", level * INDENT, " ", gsk_debug_node_get_message (root));
- print_render_node_tree (gsk_debug_node_get_child (root), level + 1);
- break;
-
- case GSK_CLIP_NODE:
- g_print ("%*s Clip (%f, %f, %f, %f):\n", level * INDENT, " ",
- root->bounds.origin.x, root->bounds.origin.y, root->bounds.size.width, root->bounds.size.height);
- print_render_node_tree (gsk_clip_node_get_child (root), level + 1);
- break;
-
- default:
- g_print ("%*s %s\n", level * INDENT, " ", g_type_name_from_instance ((GTypeInstance *) root));
- }
-
-#undef INDENT
-}
-
-
-static void G_GNUC_UNUSED
-dump_framebuffer (const char *filename, int w, int h)
-{
- int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, w);
- guchar *data = g_malloc (h * stride);
- cairo_surface_t *s;
-
- glReadPixels (0, 0, w, h, GL_BGRA, GL_UNSIGNED_BYTE, data);
- s = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, w, h, stride);
- cairo_surface_write_to_png (s, filename);
-
- cairo_surface_destroy (s);
- g_free (data);
-}
-
-static void G_GNUC_UNUSED
-dump_node (GskRenderNode *node,
- const char *filename)
-{
- const int surface_width = ceilf (node->bounds.size.width);
- const int surface_height = ceilf (node->bounds.size.height);
- cairo_surface_t *surface;
- cairo_t *cr;
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- surface_width,
- surface_height);
-
- cr = cairo_create (surface);
- cairo_save (cr);
- cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
- gsk_render_node_draw (node, cr);
- cairo_restore (cr);
- cairo_destroy (cr);
-
- cairo_surface_write_to_png (surface, filename);
- cairo_surface_destroy (surface);
-}
-
-static inline bool G_GNUC_PURE
-node_is_invisible (const GskRenderNode *node)
-{
- return node->bounds.size.width == 0.0f ||
- node->bounds.size.height == 0.0f ||
- isnan (node->bounds.size.width) ||
- isnan (node->bounds.size.height);
-}
-
-static inline bool G_GNUC_PURE
-graphene_rect_intersects (const graphene_rect_t *r1,
- const graphene_rect_t *r2)
-{
- /* Assume both rects are already normalized, as they usually are */
- if (r1->origin.x > (r2->origin.x + r2->size.width) ||
- (r1->origin.x + r1->size.width) < r2->origin.x)
- return false;
-
- if (r1->origin.y > (r2->origin.y + r2->size.height) ||
- (r1->origin.y + r1->size.height) < r2->origin.y)
- return false;
-
- return true;
-}
-
-static inline bool G_GNUC_PURE
-_graphene_rect_contains_rect (const graphene_rect_t *r1,
- const graphene_rect_t *r2)
-{
- if (r2->origin.x >= r1->origin.x &&
- (r2->origin.x + r2->size.width) <= (r1->origin.x + r1->size.width) &&
- r2->origin.y >= r1->origin.y &&
- (r2->origin.y + r2->size.height) <= (r1->origin.y + r1->size.height))
- return true;
-
- return false;
-}
-
-static inline bool G_GNUC_PURE
-equal_texture_nodes (GskRenderNode *node1,
- GskRenderNode *node2)
-{
- if (gsk_render_node_get_node_type (node1) != GSK_TEXTURE_NODE ||
- gsk_render_node_get_node_type (node2) != GSK_TEXTURE_NODE)
- return false;
-
- if (gsk_texture_node_get_texture (node1) !=
- gsk_texture_node_get_texture (node2))
- return false;
-
- return graphene_rect_equal (&node1->bounds, &node2->bounds);
-}
-
-static inline void
-sort_border_sides (const GdkRGBA *colors,
- int *indices)
-{
- gboolean done[4] = {0, 0, 0, 0};
- int i, k;
- int cur = 0;
-
- for (i = 0; i < 3; i ++)
- {
- if (done[i])
- continue;
-
- indices[cur] = i;
- done[i] = TRUE;
- cur ++;
-
- for (k = i + 1; k < 4; k ++)
- {
- if (gdk_rgba_equal (&colors[k], &colors[i]))
- {
- indices[cur] = k;
- done[k] = TRUE;
- cur ++;
- }
- }
-
- if (cur >= 4)
- break;
- }
-}
-
-static inline void
-init_projection_matrix (graphene_matrix_t *out_proj,
- const graphene_rect_t *viewport)
-{
- graphene_matrix_init_ortho (out_proj,
- viewport->origin.x,
- viewport->origin.x + viewport->size.width,
- viewport->origin.y,
- viewport->origin.y + viewport->size.height,
- ORTHO_NEAR_PLANE,
- ORTHO_FAR_PLANE);
- graphene_matrix_scale (out_proj, 1, -1, 1);
-}
-
-static inline gboolean G_GNUC_PURE
-color_matrix_modifies_alpha (GskRenderNode *node)
-{
- const graphene_matrix_t *matrix = gsk_color_matrix_node_get_color_matrix (node);
- const graphene_vec4_t *offset = gsk_color_matrix_node_get_color_offset (node);
- graphene_vec4_t row3;
-
- if (graphene_vec4_get_w (offset) != 0.0f)
- return TRUE;
-
- graphene_matrix_get_row (matrix, 3, &row3);
-
- return !graphene_vec4_equal (graphene_vec4_w_axis (), &row3);
-}
-
-static inline void
-gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
-{
- self->bounds.size.width = MAX (self->corner[0].width + self->corner[1].width,
- self->corner[3].width + self->corner[2].width);
- self->bounds.size.height = MAX (self->corner[0].height + self->corner[3].height,
- self->corner[1].height + self->corner[2].height);
-}
-
-static inline gboolean G_GNUC_PURE
-node_supports_transform (GskRenderNode *node)
-{
- /* Some nodes can't handle non-trivial transforms without being
- * rendered to a texture (e.g. rotated clips, etc.). Some however
- * work just fine, mostly because they already draw their child
- * to a texture and just render the texture manipulated in some
- * way, think opacity or color matrix. */
- const guint node_type = gsk_render_node_get_node_type (node);
-
- switch (node_type)
- {
- case GSK_COLOR_NODE:
- case GSK_OPACITY_NODE:
- case GSK_COLOR_MATRIX_NODE:
- case GSK_TEXTURE_NODE:
- case GSK_CROSS_FADE_NODE:
- case GSK_LINEAR_GRADIENT_NODE:
- case GSK_DEBUG_NODE:
- case GSK_TEXT_NODE:
- return TRUE;
-
- case GSK_TRANSFORM_NODE:
- return node_supports_transform (gsk_transform_node_get_child (node));
-
- default:
- return FALSE;
- }
- return FALSE;
-}
-
-static inline void
-load_vertex_data_with_region (GskQuadVertex vertex_data[GL_N_VERTICES],
- const graphene_rect_t *bounds,
- RenderOpBuilder *builder,
- const TextureRegion *r,
- gboolean flip_y)
-{
- const float min_x = builder->dx + bounds->origin.x;
- const float min_y = builder->dy + bounds->origin.y;
- const float max_x = min_x + bounds->size.width;
- const float max_y = min_y + bounds->size.height;
- const float y1 = flip_y ? r->y2 : r->y;
- const float y2 = flip_y ? r->y : r->y2;
-
- vertex_data[0].position[0] = min_x;
- vertex_data[0].position[1] = min_y;
- vertex_data[0].uv[0] = r->x;
- vertex_data[0].uv[1] = y1;
-
- vertex_data[1].position[0] = min_x;
- vertex_data[1].position[1] = max_y;
- vertex_data[1].uv[0] = r->x;
- vertex_data[1].uv[1] = y2;
-
- vertex_data[2].position[0] = max_x;
- vertex_data[2].position[1] = min_y;
- vertex_data[2].uv[0] = r->x2;
- vertex_data[2].uv[1] = y1;
-
- vertex_data[3].position[0] = max_x;
- vertex_data[3].position[1] = max_y;
- vertex_data[3].uv[0] = r->x2;
- vertex_data[3].uv[1] = y2;
-
- vertex_data[4].position[0] = min_x;
- vertex_data[4].position[1] = max_y;
- vertex_data[4].uv[0] = r->x;
- vertex_data[4].uv[1] = y2;
-
- vertex_data[5].position[0] = max_x;
- vertex_data[5].position[1] = min_y;
- vertex_data[5].uv[0] = r->x2;
- vertex_data[5].uv[1] = y1;
-}
-
-static inline void
-load_float_vertex_data (GskQuadVertex vertex_data[GL_N_VERTICES],
- RenderOpBuilder *builder,
- float x,
- float y,
- float width,
- float height)
-{
- const float min_x = builder->dx + x;
- const float min_y = builder->dy + y;
- const float max_x = min_x + width;
- const float max_y = min_y + height;
-
- vertex_data[0].position[0] = min_x;
- vertex_data[0].position[1] = min_y;
- vertex_data[0].uv[0] = 0;
- vertex_data[0].uv[1] = 0;
-
- vertex_data[1].position[0] = min_x;
- vertex_data[1].position[1] = max_y;
- vertex_data[1].uv[0] = 0;
- vertex_data[1].uv[1] = 1;
-
- vertex_data[2].position[0] = max_x;
- vertex_data[2].position[1] = min_y;
- vertex_data[2].uv[0] = 1;
- vertex_data[2].uv[1] = 0;
-
- vertex_data[3].position[0] = max_x;
- vertex_data[3].position[1] = max_y;
- vertex_data[3].uv[0] = 1;
- vertex_data[3].uv[1] = 1;
-
- vertex_data[4].position[0] = min_x;
- vertex_data[4].position[1] = max_y;
- vertex_data[4].uv[0] = 0;
- vertex_data[4].uv[1] = 1;
-
- vertex_data[5].position[0] = max_x;
- vertex_data[5].position[1] = min_y;
- vertex_data[5].uv[0] = 1;
- vertex_data[5].uv[1] = 0;
-}
-
-static void
-load_vertex_data (GskQuadVertex vertex_data[GL_N_VERTICES],
- const graphene_rect_t *bounds,
- RenderOpBuilder *builder)
-{
- load_float_vertex_data (vertex_data, builder,
- bounds->origin.x, bounds->origin.y,
- bounds->size.width, bounds->size.height);
-}
-
-static void
-fill_vertex_data (GskQuadVertex vertex_data[GL_N_VERTICES],
- const float min_x,
- const float min_y,
- const float max_x,
- const float max_y)
-{
- vertex_data[0].position[0] = min_x;
- vertex_data[0].position[1] = min_y;
- vertex_data[0].uv[0] = 0;
- vertex_data[0].uv[1] = 1;
-
- vertex_data[1].position[0] = min_x;
- vertex_data[1].position[1] = max_y;
- vertex_data[1].uv[0] = 0;
- vertex_data[1].uv[1] = 0;
-
- vertex_data[2].position[0] = max_x;
- vertex_data[2].position[1] = min_y;
- vertex_data[2].uv[0] = 1;
- vertex_data[2].uv[1] = 1;
-
- vertex_data[3].position[0] = max_x;
- vertex_data[3].position[1] = max_y;
- vertex_data[3].uv[0] = 1;
- vertex_data[3].uv[1] = 0;
-
- vertex_data[4].position[0] = min_x;
- vertex_data[4].position[1] = max_y;
- vertex_data[4].uv[0] = 0;
- vertex_data[4].uv[1] = 0;
-
- vertex_data[5].position[0] = max_x;
- vertex_data[5].position[1] = min_y;
- vertex_data[5].uv[0] = 1;
- vertex_data[5].uv[1] = 1;
-}
-
-static void
-load_offscreen_vertex_data (GskQuadVertex vertex_data[GL_N_VERTICES],
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float min_x = builder->dx + node->bounds.origin.x;
- const float min_y = builder->dy + node->bounds.origin.y;
- const float max_x = min_x + node->bounds.size.width;
- const float max_y = min_y + node->bounds.size.height;
-
- fill_vertex_data (vertex_data,
- min_x, min_y,
- max_x, max_y);
-}
-
-
-static void gsk_gl_renderer_setup_render_mode (GskGLRenderer *self);
-static gboolean add_offscreen_ops (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const graphene_rect_t *bounds,
- GskRenderNode *child_node,
- TextureRegion *region_out,
- gboolean *is_offscreen,
- guint flags) G_GNUC_WARN_UNUSED_RESULT;
-static void gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder);
-
-struct _GskGLRenderer
-{
- GskRenderer parent_instance;
-
- int scale_factor;
-
- GdkGLContext *gl_context;
- GskGLDriver *gl_driver;
- GskGLProfiler *gl_profiler;
-
- GskGLRendererPrograms *programs;
-
- RenderOpBuilder op_builder;
-
- GskGLTextureAtlases *atlases;
- GskGLGlyphCache *glyph_cache;
- GskGLIconCache *icon_cache;
- GskGLShadowCache shadow_cache;
-
-#ifdef G_ENABLE_DEBUG
- struct {
- GQuark frames;
- } profile_counters;
- struct {
- GQuark cpu_time;
- GQuark gpu_time;
- } profile_timers;
-#endif
-
- cairo_region_t *render_region;
-};
-
-struct _GskGLRendererClass
-{
- GskRendererClass parent_class;
-};
-
-G_DEFINE_TYPE (GskGLRenderer, gsk_gl_renderer, GSK_TYPE_RENDERER)
-
-static void
-init_shader_builder (GskGLRenderer *self,
- GskGLShaderBuilder *shader_builder)
-{
-#ifdef G_ENABLE_DEBUG
- if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
- shader_builder->debugging = TRUE;
-#endif
-
- if (gdk_gl_context_get_use_es (self->gl_context))
- {
- gsk_gl_shader_builder_set_glsl_version (shader_builder, SHADER_VERSION_GLES);
- shader_builder->gles = TRUE;
- }
- else if (gdk_gl_context_is_legacy (self->gl_context))
- {
- int maj, min;
-
- gdk_gl_context_get_version (self->gl_context, &maj, &min);
-
- if (maj == 3)
- gsk_gl_shader_builder_set_glsl_version (shader_builder, SHADER_VERSION_GL3_LEGACY);
- else
- gsk_gl_shader_builder_set_glsl_version (shader_builder, SHADER_VERSION_GL2_LEGACY);
-
- shader_builder->legacy = TRUE;
- }
- else
- {
- gsk_gl_shader_builder_set_glsl_version (shader_builder, SHADER_VERSION_GL3);
- shader_builder->gl3 = TRUE;
- }
-}
-
-static GdkRGBA BLACK = {0, 0, 0, 1};
-static void G_GNUC_UNUSED
-add_rect_outline_ops (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const graphene_rect_t *rect)
-{
- ops_set_program (builder, &self->programs->color_program);
- ops_set_color (builder, &BLACK);
-
- load_vertex_data (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (rect->origin.x, rect->origin.y, 1, rect->size.height),
- builder);
- load_vertex_data (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (rect->origin.x, rect->origin.y, rect->size.width, 1),
- builder);
- load_vertex_data (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (rect->origin.x + rect->size.width - 1,rect->origin.y,
- 1, rect->size.height),
- builder);
- load_vertex_data (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (rect->origin.x, rect->origin.y + rect->size.height - 1,
- rect->size.width, 1),
- builder);
-}
-
-static inline GskRoundedRect
-transform_rect (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const GskRoundedRect *rect)
-{
- GskRoundedRect r;
-
- r.bounds.origin.x = builder->dx + rect->bounds.origin.x;
- r.bounds.origin.y = builder->dy + rect->bounds.origin.y;
- r.bounds.size = rect->bounds.size;
-
- r.corner[0] = rect->corner[0];
- r.corner[1] = rect->corner[1];
- r.corner[2] = rect->corner[2];
- r.corner[3] = rect->corner[3];
-
- return r;
-}
-
-static inline void
-render_fallback_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float scale_x = builder->scale_x;
- const float scale_y = builder->scale_y;
- const int surface_width = ceilf (node->bounds.size.width * scale_x);
- const int surface_height = ceilf (node->bounds.size.height * scale_y);
- GdkTexture *texture;
- cairo_surface_t *surface;
- cairo_surface_t *rendered_surface;
- cairo_t *cr;
- int cached_id;
- int texture_id;
- GskTextureKey key;
-
- if (surface_width <= 0 ||
- surface_height <= 0)
- return;
-
- key.pointer = node;
- key.pointer_is_child = FALSE;
- key.scale_x = scale_x;
- key.scale_y = scale_y;
- key.filter = GL_NEAREST;
-
- cached_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
-
- if (cached_id != 0)
- {
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, cached_id);
- load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
- return;
- }
-
-
- /* We first draw the recording surface on an image surface,
- * just because the scaleY(-1) later otherwise screws up the
- * rendering... */
- {
- rendered_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- surface_width,
- surface_height);
-
- cairo_surface_set_device_scale (rendered_surface, scale_x, scale_y);
- cr = cairo_create (rendered_surface);
-
- cairo_save (cr);
- cairo_translate (cr, - floorf (node->bounds.origin.x), - floorf (node->bounds.origin.y));
- gsk_render_node_draw (node, cr);
- cairo_restore (cr);
- cairo_destroy (cr);
- }
-
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- surface_width,
- surface_height);
- cairo_surface_set_device_scale (surface, scale_x, scale_y);
- cr = cairo_create (surface);
-
- /* We draw upside down here, so it matches what GL does. */
- cairo_save (cr);
- cairo_scale (cr, 1, -1);
- cairo_translate (cr, 0, - surface_height / scale_y);
- cairo_set_source_surface (cr, rendered_surface, 0, 0);
- cairo_rectangle (cr, 0, 0, surface_width / scale_x, surface_height / scale_y);
- cairo_fill (cr);
- cairo_restore (cr);
-
-#ifdef G_ENABLE_DEBUG
- if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
- {
- cairo_move_to (cr, 0, 0);
- cairo_rectangle (cr, 0, 0, node->bounds.size.width, node->bounds.size.height);
- if (gsk_render_node_get_node_type (node) == GSK_CAIRO_NODE)
- cairo_set_source_rgba (cr, 0.3, 0, 1, 0.25);
- else
- cairo_set_source_rgba (cr, 1, 0, 0, 0.25);
- cairo_fill_preserve (cr);
- if (gsk_render_node_get_node_type (node) == GSK_CAIRO_NODE)
- cairo_set_source_rgba (cr, 0.3, 0, 1, 1);
- else
- cairo_set_source_rgba (cr, 1, 0, 0, 1);
- cairo_stroke (cr);
- }
-#endif
- cairo_destroy (cr);
-
-
- /* Upload the Cairo surface to a GL texture */
- texture_id = gsk_gl_driver_create_texture (self->gl_driver,
- surface_width,
- surface_height);
- gsk_gl_driver_bind_source_texture (self->gl_driver, texture_id);
-
- texture = gdk_texture_new_for_surface (surface);
- gsk_gl_driver_init_texture (self->gl_driver,
- texture_id,
- texture,
- GL_NEAREST, GL_NEAREST);
-
- if (gdk_gl_context_has_debug (self->gl_context))
- gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
- "Fallback %s %d",
- g_type_name_from_instance ((GTypeInstance *) node),
- texture_id);
-
- g_object_unref (texture);
- cairo_surface_destroy (surface);
- cairo_surface_destroy (rendered_surface);
-
- gsk_gl_driver_set_texture_for_key (self->gl_driver, &key, texture_id);
-
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, texture_id);
- load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
-}
-
-static inline void
-render_text_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder,
- const GdkRGBA *color,
- gboolean force_color)
-{
- const PangoFont *font = gsk_text_node_get_font (node);
- const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
- const float text_scale = MAX (builder->scale_x, builder->scale_y); /* TODO: Fix for uneven scales? */
- const graphene_point_t *offset = gsk_text_node_get_offset (node);
- const guint num_glyphs = gsk_text_node_get_num_glyphs (node);
- const float x = offset->x + builder->dx;
- const float y = offset->y + builder->dy;
- int i;
- int x_position = 0;
- GlyphCacheKey lookup;
-
- /* If the font has color glyphs, we don't need to recolor anything */
- if (!force_color && gsk_text_node_has_color_glyphs (node))
- {
- ops_set_program (builder, &self->programs->blit_program);
- }
- else
- {
- ops_set_program (builder, &self->programs->coloring_program);
- ops_set_color (builder, color);
- }
-
- memset (&lookup, 0, sizeof (CacheKeyData));
- lookup.data.font = (PangoFont *)font;
- lookup.data.scale = (guint) (text_scale * 1024);
-
- /* We use one quad per character */
- for (i = 0; i < num_glyphs; i++)
- {
- const PangoGlyphInfo *gi = &glyphs[i];
- const GskGLCachedGlyph *glyph;
- float glyph_x, glyph_y, glyph_x2, glyph_y2;
- float tx, ty, tx2, ty2;
- float cx;
- float cy;
-
- if (gi->glyph == PANGO_GLYPH_EMPTY)
- continue;
-
- cx = (float)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
- cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
-
- glyph_cache_key_set_glyph_and_shift (&lookup, gi->glyph, x + cx, y + cy);
-
- gsk_gl_glyph_cache_lookup_or_add (self->glyph_cache,
- &lookup,
- self->gl_driver,
- &glyph);
-
- if (glyph->texture_id == 0)
- goto next;
-
- ops_set_texture (builder, glyph->texture_id);
-
- tx = glyph->tx;
- ty = glyph->ty;
- tx2 = tx + glyph->tw;
- ty2 = ty + glyph->th;
-
- glyph_x = floor (x + cx + 0.125) + glyph->draw_x;
- glyph_y = floor (y + cy + 0.125) + glyph->draw_y;
- glyph_x2 = glyph_x + glyph->draw_width;
- glyph_y2 = glyph_y + glyph->draw_height;
-
- ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
- { { glyph_x, glyph_y }, { tx, ty }, },
- { { glyph_x, glyph_y2 }, { tx, ty2 }, },
- { { glyph_x2, glyph_y }, { tx2, ty }, },
-
- { { glyph_x2, glyph_y2 }, { tx2, ty2 }, },
- { { glyph_x, glyph_y2 }, { tx, ty2 }, },
- { { glyph_x2, glyph_y }, { tx2, ty }, },
- });
-
-next:
- x_position += gi->geometry.width;
- }
-}
-
-static inline void
-render_border_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const GdkRGBA *colors = gsk_border_node_get_colors (node);
- const GskRoundedRect *rounded_outline = gsk_border_node_get_outline (node);
- const float *widths = gsk_border_node_get_widths (node);
- int i;
- struct {
- float w;
- float h;
- } sizes[4];
-
- if (gsk_border_node_get_uniform (node))
- {
- ops_set_program (builder, &self->programs->inset_shadow_program);
- ops_set_inset_shadow (builder, transform_rect (self, builder, rounded_outline),
- widths[0], &colors[0], 0, 0);
-
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
- return;
- }
-
- /* Top left */
- if (widths[3] > 0)
- sizes[0].w = MAX (widths[3], rounded_outline->corner[0].width);
- else
- sizes[0].w = 0;
-
- if (widths[0] > 0)
- sizes[0].h = MAX (widths[0], rounded_outline->corner[0].height);
- else
- sizes[0].h = 0;
-
- /* Top right */
- if (widths[1] > 0)
- sizes[1].w = MAX (widths[1], rounded_outline->corner[1].width);
- else
- sizes[1].w = 0;
-
- if (widths[0] > 0)
- sizes[1].h = MAX (widths[0], rounded_outline->corner[1].height);
- else
- sizes[1].h = 0;
-
- /* Bottom right */
- if (widths[1] > 0)
- sizes[2].w = MAX (widths[1], rounded_outline->corner[2].width);
- else
- sizes[2].w = 0;
-
- if (widths[2] > 0)
- sizes[2].h = MAX (widths[2], rounded_outline->corner[2].height);
- else
- sizes[2].h = 0;
-
-
- /* Bottom left */
- if (widths[3] > 0)
- sizes[3].w = MAX (widths[3], rounded_outline->corner[3].width);
- else
- sizes[3].w = 0;
-
- if (widths[2] > 0)
- sizes[3].h = MAX (widths[2], rounded_outline->corner[3].height);
- else
- sizes[3].h = 0;
-
- {
- const float min_x = builder->dx + node->bounds.origin.x;
- const float min_y = builder->dy + node->bounds.origin.y;
- const float max_x = min_x + node->bounds.size.width;
- const float max_y = min_y + node->bounds.size.height;
- const GskQuadVertex side_data[4][6] = {
- /* Top */
- {
- { { min_x, min_y }, { 0, 1 }, }, /* Upper left */
- { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, }, /* Lower left */
- { { max_x, min_y }, { 1, 1 }, }, /* Upper right */
-
- { { max_x - sizes[1].w, min_y + sizes[1].h }, { 1, 0 }, }, /* Lower right */
- { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, }, /* Lower left */
- { { max_x, min_y }, { 1, 1 }, }, /* Upper right */
- },
- /* Right */
- {
- { { max_x - sizes[1].w, min_y + sizes[1].h }, { 0, 1 }, }, /* Upper left */
- { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, }, /* Lower left */
- { { max_x, min_y }, { 1, 1 }, }, /* Upper right */
-
- { { max_x, max_y }, { 1, 0 }, }, /* Lower right */
- { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, }, /* Lower left */
- { { max_x, min_y }, { 1, 1 }, }, /* Upper right */
- },
- /* Bottom */
- {
- { { min_x + sizes[3].w, max_y - sizes[3].h }, { 0, 1 }, }, /* Upper left */
- { { min_x, max_y }, { 0, 0 }, }, /* Lower left */
- { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, }, /* Upper right */
-
- { { max_x, max_y }, { 1, 0 }, }, /* Lower right */
- { { min_x , max_y }, { 0, 0 }, }, /* Lower left */
- { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, }, /* Upper right */
- },
- /* Left */
- {
- { { min_x, min_y }, { 0, 1 }, }, /* Upper left */
- { { min_x, max_y }, { 0, 0 }, }, /* Lower left */
- { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, }, /* Upper right */
-
- { { min_x + sizes[3].w, max_y - sizes[3].h }, { 1, 0 }, }, /* Lower right */
- { { min_x, max_y }, { 0, 0 }, }, /* Lower left */
- { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, }, /* Upper right */
- }
- };
- int indices[4] = { 0, 1, 2, 3 };
- GskRoundedRect outline;
-
- /* We sort them by color */
- sort_border_sides (colors, indices);
-
- /* Prepare outline */
- outline = transform_rect (self, builder, rounded_outline);
-
- ops_set_program (builder, &self->programs->border_program);
- ops_set_border_width (builder, widths);
- ops_set_border (builder, &outline);
-
- for (i = 0; i < 4; i ++)
- {
- if (widths[indices[i]] > 0)
- {
- ops_set_border_color (builder, &colors[indices[i]]);
- ops_draw (builder, side_data[indices[i]]);
- }
- }
- }
-}
-
-static inline void
-render_color_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- ops_set_program (builder, &self->programs->color_program);
- ops_set_color (builder, gsk_color_node_get_color (node));
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
-}
-
-static inline void
-upload_texture (GskGLRenderer *self,
- GdkTexture *texture,
- TextureRegion *out_region)
-{
- if (texture->width <= 128 &&
- texture->height <= 128 &&
- !GDK_IS_GL_TEXTURE (texture))
- {
- const IconData *icon_data;
-
- gsk_gl_icon_cache_lookup_or_add (self->icon_cache,
- texture,
- &icon_data);
-
- out_region->texture_id = icon_data->texture_id;
- out_region->x = icon_data->x;
- out_region->y = icon_data->y;
- out_region->x2 = icon_data->x2;
- out_region->y2 = icon_data->y2;
- }
- else
- {
-
- out_region->texture_id =
- gsk_gl_driver_get_texture_for_texture (self->gl_driver,
- texture,
- GL_LINEAR,
- GL_LINEAR);
-
- out_region->x = 0;
- out_region->y = 0;
- out_region->x2 = 1;
- out_region->y2 = 1;
- }
-}
-
-static inline void
-render_texture_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GdkTexture *texture = gsk_texture_node_get_texture (node);
- const int max_texture_size = gsk_gl_driver_get_max_texture_size (self->gl_driver);
-
- if (texture->width > max_texture_size || texture->height > max_texture_size)
- {
- const float min_x = builder->dx + node->bounds.origin.x;
- const float min_y = builder->dy + node->bounds.origin.y;
- const float max_x = min_x + node->bounds.size.width;
- const float max_y = min_y + node->bounds.size.height;
- const float scale_x = (max_x - min_x) / texture->width;
- const float scale_y = (max_y - min_y) / texture->height;
- TextureSlice *slices;
- guint n_slices;
- guint i;
-
- gsk_gl_driver_slice_texture (self->gl_driver, texture, &slices, &n_slices);
-
- ops_set_program (builder, &self->programs->blit_program);
- for (i = 0; i < n_slices; i ++)
- {
- const TextureSlice *slice = &slices[i];
- float x1, x2, y1, y2;
-
- x1 = min_x + (scale_x * slice->rect.x);
- x2 = x1 + (slice->rect.width * scale_x);
- y1 = min_y + (scale_y * slice->rect.y);
- y2 = y1 + (slice->rect.height * scale_y);
-
- ops_set_texture (builder, slice->texture_id);
- ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
- { { x1, y1 }, { 0, 0 }, },
- { { x1, y2 }, { 0, 1 }, },
- { { x2, y1 }, { 1, 0 }, },
-
- { { x2, y2 }, { 1, 1 }, },
- { { x1, y2 }, { 0, 1 }, },
- { { x2, y1 }, { 1, 0 }, },
- });
- }
- }
- else
- {
- TextureRegion r;
-
- upload_texture (self, texture, &r);
-
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, r.texture_id);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &node->bounds, builder,
- &r,
- FALSE);
- }
-}
-
-static Program *
-compile_glshader (GskGLRenderer *self,
- GskGLShader *shader,
- GError **error)
-{
- GskGLShaderBuilder shader_builder;
- const char *shader_source;
- gsize shader_source_len;
- int n_uniforms;
- const GskGLUniform *uniforms;
- GBytes *bytes;
- int n_required_textures = gsk_gl_shader_get_n_textures (shader);
- int program_id;
- Program *program;
-
- bytes = gsk_gl_shader_get_source (shader);
- shader_source = g_bytes_get_data (bytes, &shader_source_len);
- uniforms = gsk_gl_shader_get_uniforms (shader, &n_uniforms);
-
- if (n_uniforms > G_N_ELEMENTS (program->glshader.args_locations))
- {
- g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- "GLShaderNode supports max %d custom uniforms", (int)G_N_ELEMENTS (program->glshader.args_locations));
- return NULL;
- }
-
- if (n_required_textures > G_N_ELEMENTS (program->glshader.texture_locations))
- {
- g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_UNSUPPORTED_FORMAT,
- "GLShaderNode supports max %d texture sources", (int)(G_N_ELEMENTS (program->glshader.texture_locations)));
- return NULL;
- }
-
- gsk_gl_shader_builder_init (&shader_builder,
- "/org/gtk/libgsk/gl/preamble.glsl",
- "/org/gtk/libgsk/gl/preamble.vs.glsl",
- "/org/gtk/libgsk/gl/preamble.fs.glsl");
-
- init_shader_builder (self, &shader_builder);
- program_id = gsk_gl_shader_builder_create_program (&shader_builder,
- "/org/gtk/libgsk/gl/custom.glsl",
- shader_source, shader_source_len,
- error);
- gsk_gl_shader_builder_finish (&shader_builder);
-
- if (program_id < 0)
- return NULL;
-
- program = gsk_gl_renderer_create_custom_program (self, shader);
-
- program->id = program_id;
- INIT_COMMON_UNIFORM_LOCATION (program, alpha);
- INIT_COMMON_UNIFORM_LOCATION (program, clip_rect);
- INIT_COMMON_UNIFORM_LOCATION (program, viewport);
- INIT_COMMON_UNIFORM_LOCATION (program, projection);
- INIT_COMMON_UNIFORM_LOCATION (program, modelview);
- program->glshader.size_location = glGetUniformLocation(program->id, "u_size");
- program->glshader.texture_locations[0] = glGetUniformLocation(program->id, "u_texture1");
- program->glshader.texture_locations[1] = glGetUniformLocation(program->id, "u_texture2");
- program->glshader.texture_locations[2] = glGetUniformLocation(program->id, "u_texture3");
- program->glshader.texture_locations[3] = glGetUniformLocation(program->id, "u_texture4");
-
- /* We use u_texture1 for the texture 0 in the glshaders, so alias it here so we can use the regular setters */
- program->source_location = program->glshader.texture_locations[0];
-
- for (int i = 0; i < G_N_ELEMENTS (program->glshader.args_locations); i++)
- {
- if (i < n_uniforms)
- {
- program->glshader.args_locations[i] = glGetUniformLocation(program->id, uniforms[i].name);
- /* This isn't necessary a hard error, you might declare uniforms that are not actually
- always used, for instance if you have an "API" in uniforms for multiple shaders. */
- if (program->glshader.args_locations[i] == -1)
- g_debug ("Declared uniform `%s` not found in GskGLShader", uniforms[i].name);
- }
- else
- program->glshader.args_locations[i] = -1;
- }
-
- return program;
-}
-
-gboolean
-gsk_gl_renderer_try_compile_gl_shader (GskGLRenderer *self,
- GskGLShader *shader,
- GError **error)
-{
- Program *program;
-
- gdk_gl_context_make_current (self->gl_context);
-
- /* Maybe we tried to compile it already? */
- program = gsk_gl_renderer_lookup_custom_program (self, shader);
- if (program != NULL)
- {
- if (program->id > 0)
- return TRUE;
- else
- {
- g_propagate_error (error, g_error_copy (program->glshader.compile_error));
- return FALSE;
- }
- }
-
- program = compile_glshader (self, shader, error);
- return program != NULL;
-}
-
-static inline void
-render_gl_shader_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskGLShader *shader = gsk_gl_shader_node_get_shader (node);
- Program *program = gsk_gl_renderer_lookup_custom_program (self, shader);
- int n_children = gsk_gl_shader_node_get_n_children (node);
-
- if (program == NULL)
- {
- GError *error = NULL;
-
- program = compile_glshader (self, shader, &error);
- if (program == NULL)
- {
- /* We create the program anyway (in a failed state), so that any compiler warnings or other are only reported once */
- program = gsk_gl_renderer_create_custom_program (self, shader);
- program->id = -1;
- program->glshader.compile_error = error;
-
- g_warning ("Failed to compile gl shader: %s", error->message);
- }
- }
-
- if (program->id >= 0 && n_children <= G_N_ELEMENTS (program->glshader.texture_locations))
- {
- GBytes *args;
- TextureRegion regions[4];
- gboolean is_offscreen[4];
- for (guint i = 0; i < n_children; i++)
- {
- GskRenderNode *child = gsk_gl_shader_node_get_child (node, i);
- if (!add_offscreen_ops (self, builder,
- &node->bounds,
- child,
- &regions[i], &is_offscreen[i],
- FORCE_OFFSCREEN | RESET_CLIP))
- return;
- }
-
- args = gsk_gl_shader_node_get_args (node);
- ops_set_program (builder, program);
-
- ops_set_gl_shader_args (builder, shader, node->bounds.size.width, node->bounds.size.height, g_bytes_get_data (args, NULL));
- for (guint i = 0; i < n_children; i++)
- {
- if (i == 0)
- ops_set_texture (builder, regions[i].texture_id);
- else
- ops_set_extra_texture (builder, regions[i].texture_id, i);
- }
-
- load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
- }
- else
- {
- static GdkRGBA pink = { 255 / 255., 105 / 255., 180 / 255., 1.0 };
- ops_set_program (builder, &self->programs->color_program);
- ops_set_color (builder, &pink);
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
- }
-}
-
-/* Returns TRUE if applying @transform to @bounds
- * yields an axis-aligned rectangle
- */
-static gboolean
-result_is_axis_aligned (GskTransform *transform,
- const graphene_rect_t *bounds)
-{
- graphene_matrix_t m;
- graphene_quad_t q;
- graphene_rect_t b;
- graphene_point_t b1, b2;
- const graphene_point_t *p;
- int i;
-
- gsk_transform_to_matrix (transform, &m);
- gsk_matrix_transform_rect (&m, bounds, &q);
- graphene_quad_bounds (&q, &b);
- graphene_rect_get_top_left (&b, &b1);
- graphene_rect_get_bottom_right (&b, &b2);
-
- for (i = 0; i < 4; i++)
- {
- p = graphene_quad_get_point (&q, i);
- if (fabs (p->x - b1.x) > FLT_EPSILON && fabs (p->x - b2.x) > FLT_EPSILON)
- return FALSE;
- if (fabs (p->y - b1.y) > FLT_EPSILON && fabs (p->y - b2.y) > FLT_EPSILON)
- return FALSE;
- }
-
- return TRUE;
-}
-
-static inline void
-render_transform_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskTransform *node_transform = gsk_transform_node_get_transform (node);
- const GskTransformCategory category = gsk_transform_get_category (node_transform);
- GskRenderNode *child = gsk_transform_node_get_child (node);
-
- switch (category)
- {
- case GSK_TRANSFORM_CATEGORY_IDENTITY:
- gsk_gl_renderer_add_render_ops (self, child, builder);
- break;
-
- case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
- {
- float dx, dy;
-
- gsk_transform_to_translate (node_transform, &dx, &dy);
-
- ops_offset (builder, dx, dy);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_offset (builder, -dx, -dy);
- }
- break;
-
- case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
- {
- ops_push_modelview (builder, node_transform);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_modelview (builder);
- }
- break;
-
- case GSK_TRANSFORM_CATEGORY_2D:
- case GSK_TRANSFORM_CATEGORY_3D:
- case GSK_TRANSFORM_CATEGORY_ANY:
- case GSK_TRANSFORM_CATEGORY_UNKNOWN:
- {
- TextureRegion region;
- gboolean is_offscreen;
-
- if (node_supports_transform (child))
- {
- ops_push_modelview (builder, node_transform);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_modelview (builder);
- }
- else
- {
- int filter_flag = 0;
-
- if (!result_is_axis_aligned (node_transform, &child->bounds))
- filter_flag = LINEAR_FILTER;
-
- if (add_offscreen_ops (self, builder,
- &child->bounds,
- child,
- &region, &is_offscreen,
- RESET_CLIP | filter_flag))
- {
- /* For non-trivial transforms, we draw everything on a texture and then
- * draw the texture transformed. */
- /* TODO: We should compute a modelview containing only the "non-trivial"
- * part (e.g. the rotation) and use that. We want to keep the scale
- * for the texture.
- */
- ops_push_modelview (builder, node_transform);
- ops_set_texture (builder, region.texture_id);
- ops_set_program (builder, &self->programs->blit_program);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &child->bounds, builder,
- &region,
- is_offscreen);
- ops_pop_modelview (builder);
- }
- }
- }
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-}
-
-static inline void
-render_opacity_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskRenderNode *child = gsk_opacity_node_get_child (node);
- const float opacity = gsk_opacity_node_get_opacity (node);
- float prev_opacity;
-
- if (gsk_render_node_get_node_type (child) == GSK_CONTAINER_NODE)
- {
- gboolean is_offscreen;
- TextureRegion region;
-
- /* The semantics of an opacity node mandate that when, e.g., two color nodes overlap,
- * there may not be any blending between them */
- if (!add_offscreen_ops (self, builder, &child->bounds,
- child,
- &region, &is_offscreen,
- FORCE_OFFSCREEN | RESET_CLIP))
- return;
-
- prev_opacity = ops_set_opacity (builder,
- builder->current_opacity * opacity);
-
- if (builder->current_opacity >= ((float) 0x00ff / (float) 0xffff))
- {
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, region.texture_id);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &node->bounds, builder,
- &region,
- is_offscreen);
- }
- }
- else
- {
- prev_opacity = ops_set_opacity (builder,
- builder->current_opacity * opacity);
-
- if (builder->current_opacity >= ((float) 0x00ff / (float) 0xffff))
- gsk_gl_renderer_add_render_ops (self, child, builder);
- }
-
- ops_set_opacity (builder, prev_opacity);
-}
-
-static inline void
-render_linear_gradient_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const int n_color_stops = gsk_linear_gradient_node_get_n_color_stops (node);
-
- if (n_color_stops < GL_MAX_GRADIENT_STOPS)
- {
- const GskColorStop *stops = gsk_linear_gradient_node_get_color_stops (node, NULL);
- const graphene_point_t *start = gsk_linear_gradient_node_get_start (node);
- const graphene_point_t *end = gsk_linear_gradient_node_get_end (node);
-
- ops_set_program (builder, &self->programs->linear_gradient_program);
- ops_set_linear_gradient (builder,
- n_color_stops,
- stops,
- gsk_render_node_get_node_type (node) == GSK_REPEATING_LINEAR_GRADIENT_NODE,
- builder->dx + start->x,
- builder->dy + start->y,
- builder->dx + end->x,
- builder->dy + end->y);
-
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
- }
- else
- {
- render_fallback_node (self, node, builder);
- }
-}
-
-static inline void
-render_radial_gradient_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const int n_color_stops = gsk_radial_gradient_node_get_n_color_stops (node);
-
- if (n_color_stops < GL_MAX_GRADIENT_STOPS)
- {
- const GskColorStop *stops = gsk_radial_gradient_node_get_color_stops (node, NULL);
- const graphene_point_t *center = gsk_radial_gradient_node_get_center (node);
- const float start = gsk_radial_gradient_node_get_start (node);
- const float end = gsk_radial_gradient_node_get_end (node);
- const float hradius = gsk_radial_gradient_node_get_hradius (node);
- const float vradius = gsk_radial_gradient_node_get_vradius (node);
-
- ops_set_program (builder, &self->programs->radial_gradient_program);
- ops_set_radial_gradient (builder,
- n_color_stops,
- stops,
- gsk_render_node_get_node_type (node) == GSK_REPEATING_RADIAL_GRADIENT_NODE,
- builder->dx + center->x,
- builder->dy + center->y,
- start, end,
- hradius * builder->scale_x,
- vradius * builder->scale_y);
-
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
- }
- else
- {
- render_fallback_node (self, node, builder);
- }
-}
-
-static inline void
-render_conic_gradient_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const int n_color_stops = gsk_conic_gradient_node_get_n_color_stops (node);
-
- if (n_color_stops < GL_MAX_GRADIENT_STOPS)
- {
- const GskColorStop *stops = gsk_conic_gradient_node_get_color_stops (node, NULL);
- const graphene_point_t *center = gsk_conic_gradient_node_get_center (node);
- const float angle = gsk_conic_gradient_node_get_angle (node);
-
- ops_set_program (builder, &self->programs->conic_gradient_program);
- ops_set_conic_gradient (builder,
- n_color_stops,
- stops,
- builder->dx + center->x,
- builder->dy + center->y,
- angle);
-
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
- }
- else
- {
- render_fallback_node (self, node, builder);
- }
-}
-
-static inline gboolean
-rounded_inner_rect_contains_rect (const GskRoundedRect *rounded,
- const graphene_rect_t *rect)
-{
- const graphene_rect_t *rounded_bounds = &rounded->bounds;
- graphene_rect_t inner;
- float offset_x, offset_y;
-
- /* TODO: This is pretty conservative and we could to further, more
- * fine-grained checks to avoid offscreen drawing. */
-
- offset_x = MAX (rounded->corner[GSK_CORNER_TOP_LEFT].width,
- rounded->corner[GSK_CORNER_BOTTOM_LEFT].width);
- offset_y = MAX (rounded->corner[GSK_CORNER_TOP_LEFT].height,
- rounded->corner[GSK_CORNER_TOP_RIGHT].height);
-
-
- inner.origin.x = rounded_bounds->origin.x + offset_x;
- inner.origin.y = rounded_bounds->origin.y + offset_y;
- inner.size.width = rounded_bounds->size.width - offset_x -
- MAX (rounded->corner[GSK_CORNER_TOP_RIGHT].width,
- rounded->corner[GSK_CORNER_BOTTOM_RIGHT].width);
- inner.size.height = rounded_bounds->size.height - offset_y -
- MAX (rounded->corner[GSK_CORNER_BOTTOM_LEFT].height,
- rounded->corner[GSK_CORNER_BOTTOM_RIGHT].height);
-
- return _graphene_rect_contains_rect (&inner, rect);
-}
-
-/* Current clip is NOT rounded but new one is definitely! */
-static inline bool
-intersect_rounded_rectilinear (const graphene_rect_t *non_rounded,
- const GskRoundedRect *rounded,
- GskRoundedRect *result)
-{
- bool corners[4];
-
- /* Intersects with top left corner? */
- corners[0] = rounded_rect_has_corner (rounded, 0) &&
- graphene_rect_intersects (non_rounded,
- &rounded_rect_corner (rounded, 0));
- /* top right? */
- corners[1] = rounded_rect_has_corner (rounded, 1) &&
- graphene_rect_intersects (non_rounded,
- &rounded_rect_corner (rounded, 1));
- /* bottom right? */
- corners[2] = rounded_rect_has_corner (rounded, 2) &&
- graphene_rect_intersects (non_rounded,
- &rounded_rect_corner (rounded, 2));
- /* bottom left */
- corners[3] = rounded_rect_has_corner (rounded, 3) &&
- graphene_rect_intersects (non_rounded,
- &rounded_rect_corner (rounded, 3));
-
- if (corners[0] && !_graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 0)))
- return false;
- if (corners[1] && !_graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 1)))
- return false;
- if (corners[2] && !_graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 2)))
- return false;
- if (corners[3] && !_graphene_rect_contains_rect (non_rounded, &rounded_rect_corner (rounded, 3)))
- return false;
-
- /* We do intersect with at least one of the corners, but in such a way that the
- * intersection between the two clips can still be represented by a single rounded
- * rect in a trivial way. do that. */
- graphene_rect_intersection (non_rounded, &rounded->bounds, &result->bounds);
-
- for (int i = 0; i < 4; i++)
- {
- if (corners[i])
- result->corner[i] = rounded->corner[i];
- else
- result->corner[i].width = result->corner[i].height = 0;
- }
-
- return true;
-}
-
-/* This code intersects the current (maybe rounded) clip with the new
- * non-rounded clip */
-static inline void
-render_clipped_child (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const graphene_rect_t *clip,
- GskRenderNode *child)
-{
- graphene_rect_t transformed_clip;
- GskRoundedRect intersection;
-
- ops_transform_bounds_modelview (builder, clip, &transformed_clip);
-
- if (builder->clip_is_rectilinear)
- {
- memset (&intersection, 0, sizeof (GskRoundedRect));
- graphene_rect_intersection (&transformed_clip,
- &builder->current_clip->bounds,
- &intersection.bounds);
-
- ops_push_clip (builder, &intersection);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_clip (builder);
- }
- else if (intersect_rounded_rectilinear (&transformed_clip,
- builder->current_clip,
- &intersection))
- {
- ops_push_clip (builder, &intersection);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_clip (builder);
- }
- else
- {
- /* well fuck */
- const float scale_x = builder->scale_x;
- const float scale_y = builder->scale_y;
- const GskRoundedRect scaled_clip = GSK_ROUNDED_RECT_INIT ((builder->dx + clip->origin.x) * scale_x,
- (builder->dy + clip->origin.y) * scale_y,
- clip->size.width * scale_x,
- clip->size.height * scale_y);
- gboolean is_offscreen;
- TextureRegion region;
-
- ops_push_clip (builder, &scaled_clip);
- if (!add_offscreen_ops (self, builder, &child->bounds,
- child,
- &region, &is_offscreen,
- FORCE_OFFSCREEN))
- g_assert_not_reached ();
- ops_pop_clip (builder);
-
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, region.texture_id);
-
- load_offscreen_vertex_data (ops_draw (builder, NULL), child, builder);
- }
-}
-
-static inline void
-render_clip_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const graphene_rect_t *clip = gsk_clip_node_get_clip (node);
- GskRenderNode *child = gsk_clip_node_get_child (node);
-
- render_clipped_child (self, builder, clip, child);
-}
-
-static inline void
-render_rounded_clip_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float scale_x = builder->scale_x;
- const float scale_y = builder->scale_y;
- const GskRoundedRect *clip = gsk_rounded_clip_node_get_clip (node);
- GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
- GskRoundedRect transformed_clip;
- gboolean need_offscreen;
- int i;
-
- if (node_is_invisible (child))
- return;
-
- ops_transform_bounds_modelview (builder, &clip->bounds, &transformed_clip.bounds);
- for (i = 0; i < 4; i ++)
- {
- transformed_clip.corner[i].width = clip->corner[i].width * scale_x;
- transformed_clip.corner[i].height = clip->corner[i].height * scale_y;
- }
-
- if (builder->clip_is_rectilinear)
- {
- GskRoundedRect intersected_clip;
-
- if (intersect_rounded_rectilinear (&builder->current_clip->bounds,
- &transformed_clip,
- &intersected_clip))
- {
- ops_push_clip (builder, &intersected_clip);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_clip (builder);
- return;
- }
- }
-
- /* After this point we are really working with a new and a current clip
- * which both have rounded corners. */
-
- if (!ops_has_clip (builder))
- need_offscreen = FALSE;
- else if (rounded_inner_rect_contains_rect (builder->current_clip,
- &transformed_clip.bounds))
- need_offscreen = FALSE;
- else
- need_offscreen = TRUE;
-
- if (!need_offscreen)
- {
- /* If they don't intersect at all, we can simply set
- * the new clip and add the render ops */
-
- /* If the new clip entirely contains the current clip, the intersection is simply
- * the current clip, so we can ignore the new one */
- if (rounded_inner_rect_contains_rect (&transformed_clip, &builder->current_clip->bounds))
- {
- gsk_gl_renderer_add_render_ops (self, child, builder);
- return;
- }
-
- ops_push_clip (builder, &transformed_clip);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_clip (builder);
- }
- else
- {
- gboolean is_offscreen;
- TextureRegion region;
-
- ops_push_clip (builder, &transformed_clip);
- if (!add_offscreen_ops (self, builder, &node->bounds,
- child,
- &region, &is_offscreen,
- FORCE_OFFSCREEN))
- g_assert_not_reached ();
- ops_pop_clip (builder);
-
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, region.texture_id);
-
- load_vertex_data_with_region (ops_draw (builder, NULL), &node->bounds, builder,
- &region, is_offscreen);
- }
-}
-
-static inline void
-render_color_matrix_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskRenderNode *child = gsk_color_matrix_node_get_child (node);
- TextureRegion region;
- gboolean is_offscreen;
-
- if (node_is_invisible (child))
- return;
-
- if (!add_offscreen_ops (self, builder,
- &node->bounds,
- child,
- &region, &is_offscreen,
- RESET_CLIP))
- g_assert_not_reached ();
-
- ops_set_program (builder, &self->programs->color_matrix_program);
- ops_set_color_matrix (builder,
- gsk_color_matrix_node_get_color_matrix (node),
- gsk_color_matrix_node_get_color_offset (node));
-
- ops_set_texture (builder, region.texture_id);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &node->bounds, builder,
- &region,
- is_offscreen);
-}
-
-static inline int
-blur_texture (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const TextureRegion *region,
- const int texture_to_blur_width,
- const int texture_to_blur_height,
- float blur_radius_x,
- float blur_radius_y)
-{
- const GskRoundedRect new_clip = GSK_ROUNDED_RECT_INIT (0, 0, texture_to_blur_width, texture_to_blur_height);
- int pass1_texture_id, pass1_render_target;
- int pass2_texture_id, pass2_render_target;
- int prev_render_target;
- graphene_matrix_t prev_projection;
- graphene_rect_t prev_viewport;
- graphene_matrix_t item_proj;
- OpBlur *op;
-
- g_assert (blur_radius_x > 0);
- g_assert (blur_radius_y > 0);
-
- gsk_gl_driver_create_render_target (self->gl_driver,
- MAX (texture_to_blur_width, 1), MAX (texture_to_blur_height, 1),
- GL_NEAREST, GL_NEAREST,
- &pass1_texture_id, &pass1_render_target);
-
- if (texture_to_blur_width <= 0 || texture_to_blur_height <= 0)
- {
- return pass1_texture_id;
- }
-
- gsk_gl_driver_create_render_target (self->gl_driver,
- texture_to_blur_width, texture_to_blur_height,
- GL_NEAREST, GL_NEAREST,
- &pass2_texture_id, &pass2_render_target);
-
- init_projection_matrix (&item_proj, &new_clip.bounds);
-
- ops_set_program (builder, &self->programs->blur_program);
- prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, NULL);
- prev_viewport = ops_set_viewport (builder, &new_clip.bounds);
- ops_push_clip (builder, &new_clip);
-
- prev_render_target = ops_set_render_target (builder, pass1_render_target);
- ops_begin (builder, OP_CLEAR);
-
- op = ops_begin (builder, OP_CHANGE_BLUR);
- op->size.width = texture_to_blur_width;
- op->size.height = texture_to_blur_height;
- op->radius = blur_radius_x;
- op->dir[0] = 1;
- op->dir[1] = 0;
- ops_set_texture (builder, region->texture_id);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &new_clip.bounds,
- builder, region,
- FALSE);
-#if 0
- {
- static int k;
- ops_dump_framebuffer (builder,
- g_strdup_printf ("pass1_%d.png", k++),
- texture_to_blur_width,
- texture_to_blur_height);
- }
-#endif
- op = ops_begin (builder, OP_CHANGE_BLUR);
- op->size.width = texture_to_blur_width;
- op->size.height = texture_to_blur_height;
- op->radius = blur_radius_y;
- op->dir[0] = 0;
- op->dir[1] = 1;
- ops_set_texture (builder, pass1_texture_id);
- ops_set_render_target (builder, pass2_render_target);
- ops_begin (builder, OP_CLEAR);
- load_vertex_data_with_region (ops_draw (builder, NULL), /* render pass 2 */
- &new_clip.bounds,
- builder, region,
- FALSE);
-
-#if 0
- {
- static int k;
- ops_dump_framebuffer (builder,
- g_strdup_printf ("blurred%d.png", k++),
- texture_to_blur_width,
- texture_to_blur_height);
- }
-#endif
-
- ops_set_render_target (builder, prev_render_target);
- ops_set_viewport (builder, &prev_viewport);
- ops_set_projection (builder, &prev_projection);
- ops_pop_modelview (builder);
- ops_pop_clip (builder);
-
- return pass2_texture_id;
-}
-
-static inline void
-blur_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder,
- float blur_radius,
- guint extra_flags,
- TextureRegion *out_region,
- float *out_vertex_data[4]) /* min, max, min, max */
-{
- const float scale_x = builder->scale_x;
- const float scale_y = builder->scale_y;
- const float blur_extra = blur_radius * 2.0; /* 2.0 = shader radius_multiplier */
- float texture_width, texture_height;
- gboolean is_offscreen;
- TextureRegion region;
- int blurred_texture_id;
-
- g_assert (blur_radius > 0);
-
- /* Increase texture size for the given blur radius and scale it */
- texture_width = ceilf ((node->bounds.size.width + blur_extra));
- texture_height = ceilf ((node->bounds.size.height + blur_extra));
-
- /* Only blur this if the out region has no texture id yet */
- if (out_region->texture_id == 0)
- {
- if (!add_offscreen_ops (self, builder,
- &GRAPHENE_RECT_INIT (node->bounds.origin.x - (blur_extra / 2.0),
- node->bounds.origin.y - (blur_extra / 2.0),
- texture_width, texture_height),
- node,
- &region, &is_offscreen,
- RESET_CLIP | FORCE_OFFSCREEN | extra_flags))
- g_assert_not_reached ();
-
- blurred_texture_id = blur_texture (self, builder,
- &region,
- texture_width * scale_x, texture_height * scale_y,
- blur_radius * scale_x,
- blur_radius * scale_y);
- init_full_texture_region (out_region, blurred_texture_id);
- }
-
- if (out_vertex_data)
- {
- *out_vertex_data[0] = builder->dx + node->bounds.origin.x - (blur_extra / 2.0);
- *out_vertex_data[1] = builder->dx + node->bounds.origin.x + node->bounds.size.width + (blur_extra / 2.0);
- *out_vertex_data[2] = builder->dy + node->bounds.origin.y - (blur_extra / 2.0);
- *out_vertex_data[3] = builder->dy + node->bounds.origin.y + node->bounds.size.height + (blur_extra / 2.0);
- }
-}
-
-static inline void
-render_blur_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float blur_radius = gsk_blur_node_get_radius (node);
- GskRenderNode *child = gsk_blur_node_get_child (node);
- TextureRegion blurred_region;
- GskTextureKey key;
- float min_x, max_x, min_y, max_y;
-
- if (node_is_invisible (child))
- return;
-
- if (blur_radius <= 0)
- {
- gsk_gl_renderer_add_render_ops (self, child, builder);
- return;
- }
-
- key.pointer = node;
- key.pointer_is_child = FALSE;
- key.scale_x = builder->scale_x;
- key.scale_y = builder->scale_y;
- key.filter = GL_NEAREST;
- blurred_region.texture_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
- blur_node (self, child, builder, blur_radius, 0, &blurred_region,
- (float*[4]){&min_x, &max_x, &min_y, &max_y});
-
- g_assert (blurred_region.texture_id != 0);
-
- /* Draw the result */
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, blurred_region.texture_id);
- fill_vertex_data (ops_draw (builder, NULL), min_x, min_y, max_x, max_y);
-
-
- /* Add to cache for the blur node */
- gsk_gl_driver_set_texture_for_key (self->gl_driver, &key, blurred_region.texture_id);
-}
-
-static inline void
-render_unblurred_inset_shadow_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float dx = gsk_inset_shadow_node_get_dx (node);
- const float dy = gsk_inset_shadow_node_get_dy (node);
- const float spread = gsk_inset_shadow_node_get_spread (node);
-
- g_assert (gsk_inset_shadow_node_get_blur_radius (node) == 0);
-
- ops_set_program (builder, &self->programs->inset_shadow_program);
- ops_set_inset_shadow (builder, transform_rect (self, builder, gsk_inset_shadow_node_get_outline (node)),
- spread,
- gsk_inset_shadow_node_get_color (node),
- dx, dy);
-
- load_vertex_data (ops_draw (builder, NULL), &node->bounds, builder);
-}
-
-static inline void
-render_inset_shadow_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float scale_x = builder->scale_x;
- const float scale_y = builder->scale_y;
- const float blur_radius = gsk_inset_shadow_node_get_blur_radius (node);
- const float blur_extra = blur_radius * 2.0; /* 2.0 = shader radius_multiplier */
- const float dx = gsk_inset_shadow_node_get_dx (node);
- const float dy = gsk_inset_shadow_node_get_dy (node);
- const GskRoundedRect *node_outline = gsk_inset_shadow_node_get_outline (node);
- float texture_width;
- float texture_height;
- int blurred_texture_id;
- GskTextureKey key;
-
- g_assert (blur_radius > 0);
-
- texture_width = ceilf ((node_outline->bounds.size.width + blur_extra) * scale_x);
- texture_height = ceilf ((node_outline->bounds.size.height + blur_extra) * scale_y);
-
- key.pointer = node;
- key.pointer_is_child = FALSE;
- key.scale_x = scale_x;
- key.scale_y = scale_y;
- key.filter = GL_NEAREST;
- blurred_texture_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
- if (blurred_texture_id == 0)
- {
- const float spread = gsk_inset_shadow_node_get_spread (node) + (blur_extra / 2.0);
- GskRoundedRect outline_to_blur;
- int render_target, texture_id;
- int prev_render_target;
- graphene_matrix_t prev_projection;
- graphene_rect_t prev_viewport;
- graphene_matrix_t item_proj;
- int i;
-
- /* TODO: In the following code, we have to be careful about where we apply the scale.
- * We're manually scaling stuff (e.g. the outline) so we can later use texture_width
- * and texture_height (which are already scaled) as the geometry and keep the modelview
- * at a scale of 1. That's kinda complicated though... */
-
- /* Outline of what we actually want to blur later.
- * Spread grows inside, so we don't need to account for that. But the blur will need
- * to read outside of the inset shadow, so we need to draw some color in there. */
- outline_to_blur = *node_outline;
- gsk_rounded_rect_shrink (&outline_to_blur,
- - blur_extra / 2.0, - blur_extra / 2.0,
- - blur_extra / 2.0, - blur_extra / 2.0);
-
- /* Fit to our texture */
- outline_to_blur.bounds.origin.x = 0;
- outline_to_blur.bounds.origin.y = 0;
- outline_to_blur.bounds.size.width *= scale_x;
- outline_to_blur.bounds.size.height *= scale_y;
-
- for (i = 0; i < 4; i ++)
- {
- outline_to_blur.corner[i].width *= scale_x;
- outline_to_blur.corner[i].height *= scale_y;
- }
-
- gsk_gl_driver_create_render_target (self->gl_driver,
- texture_width, texture_height,
- GL_NEAREST, GL_NEAREST,
- &texture_id, &render_target);
-
- init_projection_matrix (&item_proj,
- &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
-
- prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, NULL);
- prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
- ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT (0, 0, texture_width, texture_height));
-
- prev_render_target = ops_set_render_target (builder, render_target);
- ops_begin (builder, OP_CLEAR);
-
- /* Actual inset shadow outline drawing */
- ops_set_program (builder, &self->programs->inset_shadow_program);
- ops_set_inset_shadow (builder, transform_rect (self, builder, &outline_to_blur),
- spread * MAX (scale_x, scale_y),
- gsk_inset_shadow_node_get_color (node),
- dx * scale_x, dy * scale_y);
-
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- 0, 0, texture_width, texture_height);
-
- ops_set_render_target (builder, prev_render_target);
- ops_set_viewport (builder, &prev_viewport);
- ops_set_projection (builder, &prev_projection);
- ops_pop_modelview (builder);
- ops_pop_clip (builder);
-
- blurred_texture_id = blur_texture (self, builder,
- &(TextureRegion) { texture_id, 0, 0, 1, 1 },
- texture_width,
- texture_height,
- blur_radius * scale_x,
- blur_radius * scale_y);
- }
-
- g_assert (blurred_texture_id != 0);
-
- /* Blur the rendered unblurred inset shadow */
- /* Use a clip to cut away the unwanted parts outside of the original outline */
- {
- const gboolean needs_clip = !gsk_rounded_rect_is_rectilinear (node_outline);
- const float tx1 = blur_extra / 2.0 * scale_x / texture_width;
- const float tx2 = 1.0 - tx1;
- const float ty1 = blur_extra / 2.0 * scale_y / texture_height;
- const float ty2 = 1.0 - ty1;
-
- gsk_gl_driver_set_texture_for_key (self->gl_driver, &key, blurred_texture_id);
-
- if (needs_clip)
- {
- GskRoundedRect node_clip;
-
- ops_transform_bounds_modelview (builder, &node_outline->bounds, &node_clip.bounds);
- for (int i = 0; i < 4; i ++)
- {
- node_clip.corner[i].width = node_outline->corner[i].width * scale_x;
- node_clip.corner[i].height = node_outline->corner[i].height * scale_y;
- }
-
- ops_push_clip (builder, &node_clip);
- }
-
- ops_set_program (builder, &self->programs->blit_program);
- ops_set_texture (builder, blurred_texture_id);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &node->bounds, builder,
- &(TextureRegion) { 0, tx1, ty1, tx2, ty2 },
- TRUE);
-
- if (needs_clip)
- ops_pop_clip (builder);
- }
-
-}
-
-/* Spread *grows* the outline. The offset moves the shadow and leaves the
- * inner rect where it was */
-static inline void
-render_unblurred_outset_shadow_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const GskRoundedRect *outline = gsk_outset_shadow_node_get_outline (node);
- const float x = node->bounds.origin.x;
- const float y = node->bounds.origin.y;
- const float w = node->bounds.size.width;
- const float h = node->bounds.size.height;
- const float spread = gsk_outset_shadow_node_get_spread (node);
- const float dx = gsk_outset_shadow_node_get_dx (node);
- const float dy = gsk_outset_shadow_node_get_dy (node);
- const float edge_sizes[] = { // Top, right, bottom, left
- spread - dy, spread + dx, spread + dy, spread - dx
- };
- const float corner_sizes[][2] = { // top left, top right, bottom right, bottom left
- { outline->corner[0].width + spread - dx, outline->corner[0].height + spread - dy },
- { outline->corner[1].width + spread + dx, outline->corner[1].height + spread - dy },
- { outline->corner[2].width + spread + dx, outline->corner[2].height + spread + dy },
- { outline->corner[3].width + spread - dx, outline->corner[3].height + spread + dy },
- };
-
- ops_set_program (builder, &self->programs->unblurred_outset_shadow_program);
- ops_set_unblurred_outset_shadow (builder, transform_rect (self, builder, outline),
- spread,
- gsk_outset_shadow_node_get_color (node),
- dx, dy);
-
- /* Corners... */
- if (corner_sizes[0][0] > 0 && corner_sizes[0][1] > 0) /* Top left */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x, y,
- corner_sizes[0][0], corner_sizes[0][1]);
- if (corner_sizes[1][0] > 0 && corner_sizes[1][1] > 0) /* Top right */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x + w - corner_sizes[1][0], y,
- corner_sizes[1][0], corner_sizes[1][1]);
- if (corner_sizes[2][0] > 0 && corner_sizes[2][1] > 0) /* Bottom right */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x + w - corner_sizes[2][0], y + h - corner_sizes[2][1],
- corner_sizes[2][0], corner_sizes[2][1]);
- if (corner_sizes[3][0] > 0 && corner_sizes[3][1] > 0) /* Bottom left */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x, y + h - corner_sizes[3][1],
- corner_sizes[3][0], corner_sizes[3][1]);
- /* Edges... */;
- if (edge_sizes[0] > 0) /* Top */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x + corner_sizes[0][0], y,
- w - corner_sizes[0][0] - corner_sizes[1][0], edge_sizes[0]);
- if (edge_sizes[1] > 0) /* Right */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x + w - edge_sizes[1], y + corner_sizes[1][1],
- edge_sizes[1], h - corner_sizes[1][1] - corner_sizes[2][1]);
- if (edge_sizes[2] > 0) /* Bottom */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x + corner_sizes[3][0], y + h - edge_sizes[2],
- w - corner_sizes[3][0] - corner_sizes[2][0], edge_sizes[2]);
- if (edge_sizes[3] > 0) /* Left */
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- x, y + corner_sizes[0][1],
- edge_sizes[3], h - corner_sizes[0][1] - corner_sizes[3][1]);
-}
-
-
-static GdkRGBA COLOR_WHITE = { 1, 1, 1, 1 };
-static inline void
-render_outset_shadow_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const float scale_x = builder->scale_x;
- const float scale_y = builder->scale_y;
- const GskRoundedRect *outline = gsk_outset_shadow_node_get_outline (node);
- const GdkRGBA *color = gsk_outset_shadow_node_get_color (node);
- const float blur_radius = gsk_outset_shadow_node_get_blur_radius (node);
- const float blur_extra = blur_radius * 2.0f; /* 2.0 = shader radius_multiplier */
- const int extra_blur_pixels = (int) ceilf(blur_extra / 2.0 * MAX (scale_x, scale_y)); /* TODO: No need to MAX() her actually */
- const float spread = gsk_outset_shadow_node_get_spread (node);
- const float dx = gsk_outset_shadow_node_get_dx (node);
- const float dy = gsk_outset_shadow_node_get_dy (node);
- GskRoundedRect scaled_outline;
- int texture_width, texture_height;
- OpOutsetShadow *shadow;
- int blurred_texture_id;
- int cached_tid;
- bool do_slicing;
-
- /* scaled_outline is the minimal outline we need to draw the given drop shadow,
- * enlarged by the spread and offset by the blur radius. */
- scaled_outline = *outline;
-
- if (outline->bounds.size.width < blur_extra ||
- outline->bounds.size.height < blur_extra)
- {
- do_slicing = false;
- gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
- }
- else
- {
- /* Shrink our outline to the minimum size that can still hold all the border radii */
- gsk_rounded_rect_shrink_to_minimum (&scaled_outline);
- /* Increase by the spread */
- gsk_rounded_rect_shrink (&scaled_outline, -spread, -spread, -spread, -spread);
- /* Grow bounds but don't grow corners */
- graphene_rect_inset (&scaled_outline.bounds, - blur_extra / 2.0, - blur_extra / 2.0);
- /* For the center part, we add a few pixels */
- scaled_outline.bounds.size.width += SHADOW_EXTRA_SIZE;
- scaled_outline.bounds.size.height += SHADOW_EXTRA_SIZE;
-
- do_slicing = true;
- }
-
- texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
- texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
-
- scaled_outline.bounds.origin.x = extra_blur_pixels;
- scaled_outline.bounds.origin.y = extra_blur_pixels;
- scaled_outline.bounds.size.width = texture_width - (extra_blur_pixels * 2);
- scaled_outline.bounds.size.height = texture_height - (extra_blur_pixels * 2);
-
- for (int i = 0; i < 4; i ++)
- {
- scaled_outline.corner[i].width *= scale_x;
- scaled_outline.corner[i].height *= scale_y;
- }
-
- cached_tid = gsk_gl_shadow_cache_get_texture_id (&self->shadow_cache,
- self->gl_driver,
- &scaled_outline,
- blur_radius);
-
- if (cached_tid == 0)
- {
- int texture_id, render_target;
- int prev_render_target;
- graphene_matrix_t prev_projection;
- graphene_rect_t prev_viewport;
- graphene_matrix_t item_proj;
-
- gsk_gl_driver_create_render_target (self->gl_driver,
- texture_width, texture_height,
- GL_NEAREST, GL_NEAREST,
- &texture_id, &render_target);
- if (gdk_gl_context_has_debug (self->gl_context))
- {
- gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
- "Outset Shadow Temp %d", texture_id);
- gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
- "Outset Shadow FB Temp %d", render_target);
- }
-
- ops_set_program (builder, &self->programs->color_program);
- init_projection_matrix (&item_proj,
- &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
-
- prev_render_target = ops_set_render_target (builder, render_target);
- ops_begin (builder, OP_CLEAR);
- prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, NULL);
- prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
-
- /* Draw outline */
- ops_push_clip (builder, &scaled_outline);
- ops_set_color (builder, &COLOR_WHITE);
- load_float_vertex_data (ops_draw (builder, NULL), builder,
- 0, 0, texture_width, texture_height);
-
- ops_pop_clip (builder);
- ops_set_viewport (builder, &prev_viewport);
- ops_pop_modelview (builder);
- ops_set_projection (builder, &prev_projection);
- ops_set_render_target (builder, prev_render_target);
-
- /* Now blur the outline */
- blurred_texture_id = blur_texture (self, builder,
- &(TextureRegion) { texture_id, 0, 0, 1, 1 },
- texture_width,
- texture_height,
- blur_radius * scale_x,
- blur_radius * scale_y);
-
- gsk_gl_driver_mark_texture_permanent (self->gl_driver, blurred_texture_id);
- gsk_gl_shadow_cache_commit (&self->shadow_cache,
- &scaled_outline,
- blur_radius,
- blurred_texture_id);
- }
- else
- {
- blurred_texture_id = cached_tid;
- }
-
-
- if (!do_slicing)
- {
- const float min_x = floorf (outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx);
- const float min_y = floorf (outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy);
-
- ops_set_program (builder, &self->programs->outset_shadow_program);
- ops_set_color (builder, color);
- ops_set_texture (builder, blurred_texture_id);
-
- shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
- shadow->outline.value = transform_rect (self, builder, outline);
- shadow->outline.send = TRUE;
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x, min_y,
- texture_width / scale_x, texture_height / scale_y
- ), builder,
- &(TextureRegion) { 0, 0, 0, 1, 1 },
- FALSE);
- return;
- }
-
-
- ops_set_program (builder, &self->programs->outset_shadow_program);
- ops_set_color (builder, color);
- ops_set_texture (builder, blurred_texture_id);
-
- shadow = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
- shadow->outline.value = transform_rect (self, builder, outline);
- shadow->outline.send = TRUE;
-
- {
- const float min_x = floorf (outline->bounds.origin.x - spread - (blur_extra / 2.0) + dx);
- const float min_y = floorf (outline->bounds.origin.y - spread - (blur_extra / 2.0) + dy);
- const float max_x = ceilf (outline->bounds.origin.x + outline->bounds.size.width +
- (blur_extra / 2.0) + dx + spread);
- const float max_y = ceilf (outline->bounds.origin.y + outline->bounds.size.height +
- (blur_extra / 2.0) + dy + spread);
- cairo_rectangle_int_t slices[9];
- TextureRegion tregs[9];
-
- /* TODO: The slicing never changes and could just go into the cache */
- nine_slice_rounded_rect (&scaled_outline, slices);
- nine_slice_grow (slices, extra_blur_pixels);
- nine_slice_to_texture_coords (slices, texture_width, texture_height, tregs);
-
- /* Our texture coordinates MUST be scaled, while the actual vertex coords
- * MUST NOT be scaled. */
-
- /* Top left */
- if (slice_is_visible (&slices[NINE_SLICE_TOP_LEFT]))
- {
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x, min_y,
- slices[NINE_SLICE_TOP_LEFT].width / scale_x,
- slices[NINE_SLICE_TOP_LEFT].height / scale_y
- ),
- builder,
- &tregs[NINE_SLICE_TOP_LEFT], TRUE);
- }
-
- /* Top center */
- if (slice_is_visible (&slices[NINE_SLICE_TOP_CENTER]))
- {
- const float width = (max_x - min_x) - (slices[NINE_SLICE_TOP_LEFT].width / scale_x +
- slices[NINE_SLICE_TOP_RIGHT].width / scale_x);
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x + (slices[NINE_SLICE_TOP_LEFT].width / scale_x),
- min_y,
- width,
- slices[NINE_SLICE_TOP_CENTER].height / scale_y
- ),
- builder,
- &tregs[NINE_SLICE_TOP_CENTER], TRUE);
- }
- /* Top right */
- if (slice_is_visible (&slices[NINE_SLICE_TOP_RIGHT]))
- {
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- max_x - (slices[NINE_SLICE_TOP_RIGHT].width / scale_x),
- min_y,
- slices[NINE_SLICE_TOP_RIGHT].width / scale_x,
- slices[NINE_SLICE_TOP_RIGHT].height / scale_y
- ),
- builder,
- &tregs[NINE_SLICE_TOP_RIGHT], TRUE);
- }
-
- /* Bottom right */
- if (slice_is_visible (&slices[NINE_SLICE_BOTTOM_RIGHT]))
- {
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- max_x - (slices[NINE_SLICE_BOTTOM_RIGHT].width / scale_x),
- max_y - (slices[NINE_SLICE_BOTTOM_RIGHT].height / scale_y),
- slices[NINE_SLICE_BOTTOM_RIGHT].width / scale_x,
- slices[NINE_SLICE_BOTTOM_RIGHT].height / scale_y
- ),
- builder,
- &tregs[NINE_SLICE_BOTTOM_RIGHT], TRUE);
- }
-
- /* Bottom left */
- if (slice_is_visible (&slices[NINE_SLICE_BOTTOM_LEFT]))
- {
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x,
- max_y - (slices[NINE_SLICE_BOTTOM_LEFT].height / scale_y),
- slices[NINE_SLICE_BOTTOM_LEFT].width / scale_x,
- slices[NINE_SLICE_BOTTOM_LEFT].height / scale_y
- ),
- builder,
- &tregs[NINE_SLICE_BOTTOM_LEFT], TRUE);
- }
-
- /* Left side */
- if (slice_is_visible (&slices[NINE_SLICE_LEFT_CENTER]))
- {
- const float height = (max_y - min_y) - (slices[NINE_SLICE_TOP_LEFT].height / scale_y +
- slices[NINE_SLICE_BOTTOM_LEFT].height / scale_y);
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x,
- min_y + (slices[NINE_SLICE_TOP_LEFT].height / scale_y),
- slices[NINE_SLICE_LEFT_CENTER].width / scale_x,
- height
- ),
- builder,
- &tregs[NINE_SLICE_LEFT_CENTER], TRUE);
- }
-
- /* Right side */
- if (slice_is_visible (&slices[NINE_SLICE_RIGHT_CENTER]))
- {
- const float height = (max_y - min_y) - (slices[NINE_SLICE_TOP_RIGHT].height / scale_y +
- slices[NINE_SLICE_BOTTOM_RIGHT].height / scale_y);
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- max_x - (slices[NINE_SLICE_RIGHT_CENTER].width / scale_x),
- min_y + (slices[NINE_SLICE_TOP_LEFT].height / scale_y),
- slices[NINE_SLICE_RIGHT_CENTER].width / scale_x,
- height
- ),
- builder,
- &tregs[NINE_SLICE_RIGHT_CENTER], TRUE);
- }
-
- /* Bottom side */
- if (slice_is_visible (&slices[NINE_SLICE_BOTTOM_CENTER]))
- {
- const float width = (max_x - min_x) - (slices[NINE_SLICE_BOTTOM_LEFT].width / scale_x +
- slices[NINE_SLICE_BOTTOM_RIGHT].width / scale_x);
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x + (slices[NINE_SLICE_BOTTOM_LEFT].width / scale_x),
- max_y - (slices[NINE_SLICE_BOTTOM_CENTER].height / scale_y),
- width,
- slices[NINE_SLICE_BOTTOM_CENTER].height / scale_y
- ),
- builder,
- &tregs[NINE_SLICE_BOTTOM_CENTER], TRUE);
- }
-
- /* Middle */
- if (slice_is_visible (&slices[NINE_SLICE_CENTER]))
- {
- const float width = (max_x - min_x) - (slices[NINE_SLICE_LEFT_CENTER].width / scale_x +
- slices[NINE_SLICE_RIGHT_CENTER].width / scale_x);
- const float height = (max_y - min_y) - (slices[NINE_SLICE_TOP_CENTER].height / scale_y +
- slices[NINE_SLICE_BOTTOM_CENTER].height / scale_y);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &GRAPHENE_RECT_INIT (
- min_x + (slices[NINE_SLICE_LEFT_CENTER].width / scale_x),
- min_y + (slices[NINE_SLICE_TOP_CENTER].height / scale_y),
- width, height
- ),
- builder,
- &tregs[NINE_SLICE_CENTER], TRUE);
- }
- }
-}
-
-static inline void
-render_shadow_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- const gsize n_shadows = gsk_shadow_node_get_n_shadows (node);
- GskRenderNode *original_child = gsk_shadow_node_get_child (node);
- GskRenderNode *shadow_child = original_child;
- guint i;
-
- /* Shadow nodes recolor every pixel of the source texture, but leave the alpha in tact.
- * If the child is a color matrix node that doesn't touch the alpha, we can throw that away. */
- if (gsk_render_node_get_node_type (shadow_child) == GSK_COLOR_MATRIX_NODE &&
- !color_matrix_modifies_alpha (shadow_child))
- {
- shadow_child = gsk_color_matrix_node_get_child (shadow_child);
- }
-
- for (i = 0; i < n_shadows; i ++)
- {
- const GskShadow *shadow = gsk_shadow_node_get_shadow (node, i);
- const float dx = shadow->dx;
- const float dy = shadow->dy;
- TextureRegion region;
- gboolean is_offscreen;
- graphene_rect_t bounds;
-
- if (shadow->radius == 0 &&
- gsk_render_node_get_node_type (shadow_child) == GSK_TEXT_NODE)
- {
- ops_offset (builder, dx, dy);
- render_text_node (self, shadow_child, builder, &shadow->color, TRUE);
- ops_offset (builder, - dx, - dy);
- continue;
- }
-
- if (gdk_rgba_is_clear (&shadow->color))
- continue;
-
- if (node_is_invisible (shadow_child))
- continue;
-
- if (shadow->radius > 0)
- {
- float min_x;
- float min_y;
- float max_x;
- float max_y;
-
- region.texture_id = 0;
- blur_node (self, shadow_child, builder, shadow->radius, NO_CACHE_PLZ, &region,
- (float*[4]){&min_x, &max_x, &min_y, &max_y});
- bounds.origin.x = min_x - builder->dx;
- bounds.origin.y = min_y - builder->dy;
- bounds.size.width = max_x - min_x;
- bounds.size.height = max_y - min_y;
- is_offscreen = TRUE;
- }
- else if (dx == 0 && dy == 0)
- {
- continue; /* Invisible anyway */
- }
- else
- {
- if (!add_offscreen_ops (self, builder,
- &shadow_child->bounds,
- shadow_child, &region, &is_offscreen,
- RESET_CLIP | NO_CACHE_PLZ))
- g_assert_not_reached ();
-
- bounds = shadow_child->bounds;
- }
-
- ops_set_program (builder, &self->programs->coloring_program);
- ops_set_color (builder, &shadow->color);
- ops_set_texture (builder, region.texture_id);
-
- ops_offset (builder, dx, dy);
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &bounds, builder,
- &region,
- is_offscreen);
- ops_offset (builder, -dx, -dy);
- }
-
- /* Now draw the child normally */
- gsk_gl_renderer_add_render_ops (self, original_child, builder);
-}
-
-static inline void
-render_cross_fade_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
- GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
- const float progress = gsk_cross_fade_node_get_progress (node);
- TextureRegion start_region;
- TextureRegion end_region;
- gboolean is_offscreen1, is_offscreen2;
- OpCrossFade *op;
-
- if (progress <= 0)
- {
- gsk_gl_renderer_add_render_ops (self, start_node, builder);
- return;
- }
- else if (progress >= 1)
- {
- gsk_gl_renderer_add_render_ops (self, end_node, builder);
- return;
- }
-
- if (equal_texture_nodes (start_node, end_node))
- {
- gsk_gl_renderer_add_render_ops (self, end_node, builder);
- return;
- }
-
- /* TODO: We create 2 textures here as big as the cross-fade node, but both the
- * start and the end node might be a lot smaller than that. */
-
- if (!add_offscreen_ops (self, builder,
- &node->bounds,
- start_node,
- &start_region, &is_offscreen1,
- FORCE_OFFSCREEN | RESET_CLIP))
- {
- gsk_gl_renderer_add_render_ops (self, end_node, builder);
- return;
- }
-
- if (!add_offscreen_ops (self, builder,
- &node->bounds,
- end_node,
- &end_region, &is_offscreen2,
- FORCE_OFFSCREEN | RESET_CLIP))
- {
- const float prev_opacity = ops_set_opacity (builder, builder->current_opacity * progress);
- gsk_gl_renderer_add_render_ops (self, start_node, builder);
- ops_set_opacity (builder, prev_opacity);
-
- return;
- }
-
- ops_set_program (builder, &self->programs->cross_fade_program);
-
- op = ops_begin (builder, OP_CHANGE_CROSS_FADE);
- op->progress = progress;
- op->source2 = end_region.texture_id;
-
- ops_set_texture (builder, start_region.texture_id);
-
- load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
-}
-
-static inline void
-render_blend_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskRenderNode *top_child = gsk_blend_node_get_top_child (node);
- GskRenderNode *bottom_child = gsk_blend_node_get_bottom_child (node);
- TextureRegion top_region;
- TextureRegion bottom_region;
- gboolean is_offscreen1, is_offscreen2;
- OpBlend *op;
-
- /* TODO: We create 2 textures here as big as the blend node, but both the
- * start and the end node might be a lot smaller than that. */
- if (!add_offscreen_ops (self, builder,
- &node->bounds,
- bottom_child,
- &bottom_region, &is_offscreen1,
- FORCE_OFFSCREEN | RESET_CLIP))
- {
- gsk_gl_renderer_add_render_ops (self, top_child, builder);
- return;
- }
-
- if (!add_offscreen_ops (self, builder,
- &node->bounds,
- top_child,
- &top_region, &is_offscreen2,
- FORCE_OFFSCREEN | RESET_CLIP))
- {
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &node->bounds,
- builder,
- &bottom_region,
- TRUE);
- return;
- }
-
- ops_set_program (builder, &self->programs->blend_program);
- ops_set_texture (builder, bottom_region.texture_id);
-
- op = ops_begin (builder, OP_CHANGE_BLEND);
- op->source2 = top_region.texture_id;
- op->mode = gsk_blend_node_get_blend_mode (node);
-
- load_offscreen_vertex_data (ops_draw (builder, NULL), node, builder);
-}
-
-static inline void
-render_repeat_node (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- GskRenderNode *child = gsk_repeat_node_get_child (node);
- const graphene_rect_t *child_bounds = gsk_repeat_node_get_child_bounds (node);
- TextureRegion region;
- gboolean is_offscreen;
- OpRepeat *op;
-
- if (node_is_invisible (child))
- return;
-
- if (!graphene_rect_equal (child_bounds, &child->bounds))
- {
- /* TODO: Implement these repeat nodes. */
- render_fallback_node (self, node, builder);
- return;
- }
-
- /* If the size of the repeat node is smaller than the size of the
- * child node, we don't repeat at all and can just draw that part
- * of the child texture... */
- if (graphene_rect_contains_rect (child_bounds, &node->bounds))
- {
- render_clipped_child (self, builder, &node->bounds, child);
- return;
- }
-
- /* Draw the entire child on a texture */
- if (!add_offscreen_ops (self, builder,
- &child->bounds,
- child,
- &region, &is_offscreen,
- RESET_CLIP))
- g_assert_not_reached ();
-
- ops_set_program (builder, &self->programs->repeat_program);
- ops_set_texture (builder, region.texture_id);
-
- op = ops_begin (builder, OP_CHANGE_REPEAT);
- op->child_bounds[0] = (node->bounds.origin.x - child_bounds->origin.x) / child_bounds->size.width;
- op->child_bounds[1] = (node->bounds.origin.y - child_bounds->origin.y) / child_bounds->size.height;
- op->child_bounds[2] = node->bounds.size.width / child_bounds->size.width;
- op->child_bounds[3] = node->bounds.size.height / child_bounds->size.height;
-
- op->texture_rect[0] = region.x;
- op->texture_rect[2] = region.x2;
-
- if (is_offscreen)
- {
- op->texture_rect[1] = region.y2;
- op->texture_rect[3] = region.y;
- }
- else
- {
- op->texture_rect[1] = region.y;
- op->texture_rect[3] = region.y2;
- }
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &node->bounds, builder,
- &region,
- is_offscreen);
-}
-
-static inline void
-apply_viewport_op (const Program *program,
- const OpViewport *op)
-{
- OP_PRINT (" -> New Viewport: %f, %f, %f, %f",
- op->viewport.origin.x, op->viewport.origin.y,
- op->viewport.size.width, op->viewport.size.height);
- glUniform4f (program->viewport_location,
- op->viewport.origin.x, op->viewport.origin.y,
- op->viewport.size.width, op->viewport.size.height);
- glViewport (0, 0, op->viewport.size.width, op->viewport.size.height);
-}
-
-static inline void
-apply_modelview_op (const Program *program,
- const OpMatrix *op)
-{
- float mat[16];
-
- graphene_matrix_to_float (&op->matrix, mat);
- OP_PRINT (" -> Modelview { { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }",
- mat[0], mat[1], mat[2], mat[3],
- mat[4], mat[5], mat[6], mat[7],
- mat[8], mat[9], mat[10], mat[11],
- mat[12], mat[13], mat[14], mat[15]);
- glUniformMatrix4fv (program->modelview_location, 1, GL_FALSE, mat);
-}
-
-static inline void
-apply_projection_op (const Program *program,
- const OpMatrix *op)
-{
- float mat[16];
-
- graphene_matrix_to_float (&op->matrix, mat);
- OP_PRINT (" -> Projection { { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }",
- mat[0], mat[1], mat[2], mat[3],
- mat[4], mat[5], mat[6], mat[7],
- mat[8], mat[9], mat[10], mat[11],
- mat[12], mat[13], mat[14], mat[15]);
- glUniformMatrix4fv (program->projection_location, 1, GL_FALSE, mat);
-}
-
-static inline void
-apply_program_op (const Program *program,
- const OpProgram *op)
-{
- OP_PRINT (" -> Program: %d", op->program->index);
- glUseProgram (op->program->id);
-}
-
-static inline void
-apply_render_target_op (GskGLRenderer *self,
- const OpRenderTarget *op)
-{
- OP_PRINT (" -> Render Target: %d", op->render_target_id);
-
- glBindFramebuffer (GL_FRAMEBUFFER, op->render_target_id);
-
- if (op->render_target_id != 0)
- glDisable (GL_SCISSOR_TEST);
- else
- gsk_gl_renderer_setup_render_mode (self); /* Reset glScissor etc. */
-}
-
-static inline void
-apply_color_op (const Program *program,
- const OpColor *op)
-{
- OP_PRINT (" -> Color: (%f, %f, %f, %f)",
- op->rgba->red, op->rgba->green, op->rgba->blue, op->rgba->alpha);
- glUniform4fv (program->color.color_location, 1, (float *)op->rgba);
-}
-
-static inline void
-apply_opacity_op (const Program *program,
- const OpOpacity *op)
-{
- OP_PRINT (" -> Opacity %f", op->opacity);
- glUniform1f (program->alpha_location, op->opacity);
-}
-
-static inline void
-apply_source_texture_op (const Program *program,
- const OpTexture *op)
-{
- g_assert(op->texture_id != 0);
- OP_PRINT (" -> New texture: %d", op->texture_id);
- /* Use texture unit 0 for the source */
- glUniform1i (program->source_location, 0);
- glActiveTexture (GL_TEXTURE0);
- glBindTexture (GL_TEXTURE_2D, op->texture_id);
-}
-
-static inline void
-apply_source_extra_texture_op (const Program *program,
- const OpExtraTexture *op)
-{
- g_assert(op->texture_id != 0);
- OP_PRINT (" -> New extra texture %d: %d", op->idx, op->texture_id);
- glUniform1i (program->glshader.texture_locations[op->idx], op->idx);
- glActiveTexture (GL_TEXTURE0 + op->idx);
- glBindTexture (GL_TEXTURE_2D, op->texture_id);
-}
-
-static inline void
-apply_color_matrix_op (const Program *program,
- const OpColorMatrix *op)
-{
- OP_PRINT (" -> Color matrix. Send matrix: %d. Send offset: %d.",
- op->matrix.send, op->offset.send);
-
- if (op->matrix.send)
- {
- float mat[16];
- graphene_matrix_to_float (op->matrix.value, mat);
- glUniformMatrix4fv (program->color_matrix.color_matrix_location, 1, GL_FALSE, mat);
- }
-
- if (op->offset.send)
- {
- float vec[4];
- graphene_vec4_to_float (op->offset.value, vec);
- glUniform4fv (program->color_matrix.color_offset_location, 1, vec);
- }
-}
-
-static inline void
-apply_clip_op (const Program *program,
- const OpClip *op)
-{
- int count;
-
- if (op->send_corners)
- {
- OP_PRINT (" -> Clip: %s", gsk_rounded_rect_to_string (&op->clip));
- count = 3;
- }
- else
- {
- OP_PRINT (" -> clip: %f, %f, %f, %f",
- op->clip.bounds.origin.x, op->clip.bounds.origin.y,
- op->clip.bounds.size.width, op->clip.bounds.size.height);
- count = 1;
- }
-
- glUniform4fv (program->clip_rect_location, count, (float *)&op->clip.bounds);
-}
-
-static inline void
-apply_inset_shadow_op (const Program *program,
- const OpShadow *op)
-{
- OP_PRINT (" -> inset shadow. Color: %s, Offset: (%f, %f), Spread: %f, Outline: %s",
- op->color.send ? gdk_rgba_to_string (op->color.value) : "don't send",
- op->offset.send ? op->offset.value[0] : -1337.0,
- op->offset.send ? op->offset.value[1] : -1337.0,
- op->spread.send ? op->spread.value : -1337.0,
- op->outline.send ? gsk_rounded_rect_to_string (&op->outline.value) : "don't send");
- if (op->outline.send)
- {
- if (op->outline.send_corners)
- glUniform4fv (program->inset_shadow.outline_rect_location, 3, (float *)&op->outline.value);
- else
- glUniform4fv (program->inset_shadow.outline_rect_location, 1, (float *)&op->outline.value);
- }
-
- if (op->color.send)
- glUniform4fv (program->inset_shadow.color_location, 1, (float *)op->color.value);
-
- if (op->spread.send)
- glUniform1f (program->inset_shadow.spread_location, op->spread.value);
-
- if (op->offset.send)
- glUniform2fv (program->inset_shadow.offset_location, 1, op->offset.value);
-}
-
-static inline void
-apply_unblurred_outset_shadow_op (const Program *program,
- const OpShadow *op)
-{
- OP_PRINT (" -> unblurred outset shadow");
-
- if (op->outline.send)
- {
- if (op->outline.send_corners)
- glUniform4fv (program->unblurred_outset_shadow.outline_rect_location, 3, (float *)&op->outline.value);
- else
- glUniform4fv (program->unblurred_outset_shadow.outline_rect_location, 1, (float *)&op->outline.value);
- }
-
- if (op->color.send)
- glUniform4fv (program->unblurred_outset_shadow.color_location, 1, (float *)op->color.value);
-
- if (op->spread.send)
- glUniform1f (program->unblurred_outset_shadow.spread_location, op->spread.value);
-
- if (op->offset.send)
- glUniform2fv (program->unblurred_outset_shadow.offset_location, 1, op->offset.value);
-}
-
-static inline void
-apply_outset_shadow_op (const Program *program,
- const OpOutsetShadow *op)
-{
- OP_PRINT (" -> outset shadow");
- glUniform4fv (program->outset_shadow.outline_rect_location, 3, (float *)&op->outline.value.bounds);
-}
-
-static inline void
-apply_linear_gradient_op (const Program *program,
- const OpLinearGradient *op)
-{
- OP_PRINT (" -> Linear gradient");
- if (op->n_color_stops.send)
- glUniform1i (program->linear_gradient.num_color_stops_location, op->n_color_stops.value);
-
- if (op->color_stops.send)
- glUniform1fv (program->linear_gradient.color_stops_location,
- op->n_color_stops.value * 5,
- (float *)op->color_stops.value);
-
- glUniform4f (program->linear_gradient.points_location,
- op->start_point[0], op->start_point[1],
- op->end_point[0] - op->start_point[0], op->end_point[1] - op->start_point[1]);
- glUniform1i (program->linear_gradient.repeat_location, op->repeat);
-}
-
-static inline void
-apply_radial_gradient_op (const Program *program,
- const OpRadialGradient *op)
-{
- float scale;
- float bias;
-
- OP_PRINT (" -> Radial gradient");
- if (op->n_color_stops.send)
- glUniform1i (program->radial_gradient.num_color_stops_location, op->n_color_stops.value);
-
- if (op->color_stops.send)
- glUniform1fv (program->radial_gradient.color_stops_location,
- op->n_color_stops.value * 5,
- (float *)op->color_stops.value);
-
- scale = 1.0f / (op->end - op->start);
- bias = -op->start * scale;
-
- glUniform1i (program->radial_gradient.repeat_location, op->repeat);
- glUniform2f (program->radial_gradient.range_location, scale, bias);
- glUniform4f (program->radial_gradient.geometry_location,
- op->center[0], op->center[1],
- 1.0f / op->radius[0], 1.0f / op->radius[1]);
-}
-
-static inline void
-apply_conic_gradient_op (const Program *program,
- const OpConicGradient *op)
-{
- float bias;
- float scale;
-
- OP_PRINT (" -> Conic gradient");
- if (op->n_color_stops.send)
- glUniform1i (program->conic_gradient.num_color_stops_location, op->n_color_stops.value);
-
- if (op->color_stops.send)
- glUniform1fv (program->conic_gradient.color_stops_location,
- op->n_color_stops.value * 5,
- (float *)op->color_stops.value);
-
- scale = 0.5f * M_1_PI;
- bias = op->angle * scale + 2.0f;
- glUniform4f (program->conic_gradient.geometry_location, op->center[0], op->center[1], scale, bias);
-}
-
-static inline void
-apply_border_op (const Program *program,
- const OpBorder *op)
-{
- OP_PRINT (" -> Border Outline");
-
- glUniform4fv (program->border.outline_rect_location, 3, (float *)&op->outline.bounds);
-}
-
-static inline void
-apply_gl_shader_args_op (const Program *program,
- const OpGLShader *op)
-{
- int n_uniforms, i;
- const GskGLUniform *uniforms;
-
- OP_PRINT (" -> GL Shader Args");
-
- glUniform2fv (program->glshader.size_location, 1, op->size);
-
- uniforms = gsk_gl_shader_get_uniforms (op->shader, &n_uniforms);
- for (i = 0; i < n_uniforms; i++)
- {
- const GskGLUniform *u = &uniforms[i];
- const guchar *data = op->uniform_data + u->offset;
-
- switch (u->type)
- {
- default:
- case GSK_GL_UNIFORM_TYPE_NONE:
- break;
- case GSK_GL_UNIFORM_TYPE_FLOAT:
- glUniform1fv (program->glshader.args_locations[i], 1, (const float *)data);
- break;
- case GSK_GL_UNIFORM_TYPE_INT:
- glUniform1iv (program->glshader.args_locations[i], 1, (const gint32 *)data);
- break;
- case GSK_GL_UNIFORM_TYPE_UINT:
- case GSK_GL_UNIFORM_TYPE_BOOL:
- glUniform1uiv (program->glshader.args_locations[i], 1, (const guint32 *) data);
- break;
- case GSK_GL_UNIFORM_TYPE_VEC2:
- glUniform2fv (program->glshader.args_locations[i], 1, (const float *)data);
- break;
- case GSK_GL_UNIFORM_TYPE_VEC3:
- glUniform3fv (program->glshader.args_locations[i], 1, (const float *)data);
- break;
- case GSK_GL_UNIFORM_TYPE_VEC4:
- glUniform4fv (program->glshader.args_locations[i], 1, (const float *)data);
- break;
- }
- }
-}
-
-static inline void
-apply_border_width_op (const Program *program,
- const OpBorder *op)
-{
- OP_PRINT (" -> Border width (%f, %f, %f, %f)",
- op->widths[0], op->widths[1], op->widths[2], op->widths[3]);
-
- glUniform4fv (program->border.widths_location, 1, op->widths);
-}
-
-static inline void
-apply_border_color_op (const Program *program,
- const OpBorder *op)
-{
- OP_PRINT (" -> Border color: %s", gdk_rgba_to_string (op->color));
- glUniform4fv (program->border.color_location, 1, (float *)op->color);
-}
-
-static inline void
-apply_blur_op (const Program *program,
- const OpBlur *op)
-{
- OP_PRINT (" -> Blur");
- glUniform1f (program->blur.blur_radius_location, op->radius);
- glUniform2f (program->blur.blur_size_location, op->size.width, op->size.height);
- glUniform2f (program->blur.blur_dir_location, op->dir[0], op->dir[1]);
-}
-
-static inline void
-apply_cross_fade_op (const Program *program,
- const OpCrossFade *op)
-{
- OP_PRINT (" -> Cross fade");
- /* End texture id */
- glUniform1i (program->cross_fade.source2_location, 1);
- glActiveTexture (GL_TEXTURE0 + 1);
- glBindTexture (GL_TEXTURE_2D, op->source2);
- /* progress */
- glUniform1f (program->cross_fade.progress_location, op->progress);
-}
-
-static inline void
-apply_blend_op (const Program *program,
- const OpBlend *op)
-{
- /* End texture id */
- glUniform1i (program->blend.source2_location, 1);
- glActiveTexture (GL_TEXTURE0 + 1);
- glBindTexture (GL_TEXTURE_2D, op->source2);
- /* progress */
- glUniform1i (program->blend.mode_location, op->mode);
-}
-
-static inline void
-apply_repeat_op (const Program *program,
- const OpRepeat *op)
-{
- OP_PRINT (" -> Repeat");
- glUniform4fv (program->repeat.child_bounds_location, 1, op->child_bounds);
- glUniform4fv (program->repeat.texture_rect_location, 1, op->texture_rect);
-}
-
-static void
-gsk_gl_renderer_dispose (GObject *gobject)
-{
- GskGLRenderer *self = GSK_GL_RENDERER (gobject);
-
- ops_free (&self->op_builder);
-
- G_OBJECT_CLASS (gsk_gl_renderer_parent_class)->dispose (gobject);
-}
-
-static void
-program_init (Program *program)
-{
- program->index = -1;
- program->state.opacity = 1.0f;
-}
-
-static void
-program_finalize (Program *program)
-{
- if (program->id > 0)
- glDeleteProgram (program->id);
- if (program->index == -1 &&
- program->glshader.compile_error != NULL)
- g_error_free (program->glshader.compile_error);
-
- gsk_transform_unref (program->state.modelview);
-}
-
-static void
-program_free (Program *program)
-{
- program_finalize (program);
- g_free (program);
-}
-
-static GskGLRendererPrograms *
-gsk_gl_renderer_programs_new (void)
-{
- GskGLRendererPrograms *programs;
- int i;
-
- programs = g_new0 (GskGLRendererPrograms, 1);
- programs->ref_count = 1;
- for (i = 0; i < GL_N_PROGRAMS; i ++)
- program_init (&programs->programs[i]);
-
- /* We use direct hash for performance, not string hash on the source, because we assume each caller
- * reuses a single GskGLShader for all uses and different callers will use different source content. */
- programs->custom_programs = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify)g_object_unref, (GDestroyNotify)program_free);
-
- return programs;
-}
-
-static GskGLRendererPrograms *
-gsk_gl_renderer_programs_ref (GskGLRendererPrograms *programs)
-{
- programs->ref_count++;
- return programs;
-}
-
-/* Must be called with the context current */
-static void
-gsk_gl_renderer_programs_unref (GskGLRendererPrograms *programs)
-{
- int i;
- programs->ref_count--;
- if (programs->ref_count == 0)
- {
- for (i = 0; i < GL_N_PROGRAMS; i ++)
- program_finalize (&programs->programs[i]);
-
- g_hash_table_destroy (programs->custom_programs);
- g_free (programs);
- }
-}
-
-static Program *
-gsk_gl_renderer_lookup_custom_program (GskGLRenderer *self,
- GskGLShader *shader)
-{
- return g_hash_table_lookup (self->programs->custom_programs, shader);
-}
-
-static Program *
-gsk_gl_renderer_create_custom_program (GskGLRenderer *self,
- GskGLShader *shader)
-{
- Program *program = g_new0 (Program, 1);
-
- program_init (program);
-
- g_hash_table_insert (self->programs->custom_programs, g_object_ref (shader), program);
-
- return program;
-}
-
-static GskGLRendererPrograms *
-gsk_gl_renderer_create_programs (GskGLRenderer *self,
- GError **error)
-{
- GskGLShaderBuilder shader_builder;
- GskGLRendererPrograms *programs = NULL;
- int i;
- static const struct {
- const char *resource_path;
- const char *name;
- } program_definitions[] = {
- { "/org/gtk/libgsk/gl/blend.glsl", "blend" },
- { "/org/gtk/libgsk/gl/blit.glsl", "blit" },
- { "/org/gtk/libgsk/gl/blur.glsl", "blur" },
- { "/org/gtk/libgsk/gl/border.glsl", "border" },
- { "/org/gtk/libgsk/gl/color_matrix.glsl", "color matrix" },
- { "/org/gtk/libgsk/gl/color.glsl", "color" },
- { "/org/gtk/libgsk/gl/coloring.glsl", "coloring" },
- { "/org/gtk/libgsk/gl/cross_fade.glsl", "cross fade" },
- { "/org/gtk/libgsk/gl/inset_shadow.glsl", "inset shadow" },
- { "/org/gtk/libgsk/gl/linear_gradient.glsl", "linear gradient" },
- { "/org/gtk/libgsk/gl/radial_gradient.glsl", "radial gradient" },
- { "/org/gtk/libgsk/gl/conic_gradient.glsl", "conic gradient" },
- { "/org/gtk/libgsk/gl/outset_shadow.glsl", "outset shadow" },
- { "/org/gtk/libgsk/gl/repeat.glsl", "repeat" },
- { "/org/gtk/libgsk/gl/unblurred_outset_shadow.glsl", "unblurred_outset shadow" },
- };
-
- gsk_gl_shader_builder_init (&shader_builder,
- "/org/gtk/libgsk/gl/preamble.glsl",
- "/org/gtk/libgsk/gl/preamble.vs.glsl",
- "/org/gtk/libgsk/gl/preamble.fs.glsl");
-
- g_assert (G_N_ELEMENTS (program_definitions) == GL_N_PROGRAMS);
-
- init_shader_builder (self, &shader_builder);
-
- programs = gsk_gl_renderer_programs_new ();
-
- for (i = 0; i < GL_N_PROGRAMS; i ++)
- {
- Program *prog = &programs->programs[i];
-
- prog->name = program_definitions[i].name;
- prog->index = i;
- prog->id = gsk_gl_shader_builder_create_program (&shader_builder,
- program_definitions[i].resource_path,
- NULL, 0, error);
- if (prog->id < 0)
- {
- g_clear_pointer (&programs, gsk_gl_renderer_programs_unref);
- goto out;
- }
-
- INIT_COMMON_UNIFORM_LOCATION (prog, alpha);
- INIT_COMMON_UNIFORM_LOCATION (prog, source);
- INIT_COMMON_UNIFORM_LOCATION (prog, clip_rect);
- INIT_COMMON_UNIFORM_LOCATION (prog, viewport);
- INIT_COMMON_UNIFORM_LOCATION (prog, projection);
- INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
- }
- /* color */
- INIT_PROGRAM_UNIFORM_LOCATION (color, color);
-
- /* coloring */
- INIT_PROGRAM_UNIFORM_LOCATION (coloring, color);
-
- /* color matrix */
- INIT_PROGRAM_UNIFORM_LOCATION (color_matrix, color_matrix);
- INIT_PROGRAM_UNIFORM_LOCATION (color_matrix, color_offset);
-
- /* linear gradient */
- INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, color_stops);
- INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, num_color_stops);
- INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, repeat);
- INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient, points);
-
- /* radial gradient */
- INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, color_stops);
- INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, num_color_stops);
- INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, repeat);
- INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, geometry);
- INIT_PROGRAM_UNIFORM_LOCATION (radial_gradient, range);
-
- /* conic gradient */
- INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, color_stops);
- INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, num_color_stops);
- INIT_PROGRAM_UNIFORM_LOCATION (conic_gradient, geometry);
-
- /* blur */
- INIT_PROGRAM_UNIFORM_LOCATION (blur, blur_radius);
- INIT_PROGRAM_UNIFORM_LOCATION (blur, blur_size);
- INIT_PROGRAM_UNIFORM_LOCATION (blur, blur_dir);
-
- /* inset shadow */
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, color);
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, spread);
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, offset);
- INIT_PROGRAM_UNIFORM_LOCATION (inset_shadow, outline_rect);
-
- /* outset shadow */
- INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, color);
- INIT_PROGRAM_UNIFORM_LOCATION (outset_shadow, outline_rect);
-
- /* unblurred outset shadow */
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, color);
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, spread);
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, offset);
- INIT_PROGRAM_UNIFORM_LOCATION (unblurred_outset_shadow, outline_rect);
-
- /* border */
- INIT_PROGRAM_UNIFORM_LOCATION (border, color);
- INIT_PROGRAM_UNIFORM_LOCATION (border, widths);
- INIT_PROGRAM_UNIFORM_LOCATION (border, outline_rect);
-
- /* cross fade */
- INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
- INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, source2);
-
- /* blend */
- INIT_PROGRAM_UNIFORM_LOCATION (blend, source2);
- INIT_PROGRAM_UNIFORM_LOCATION (blend, mode);
-
- /* repeat */
- INIT_PROGRAM_UNIFORM_LOCATION (repeat, child_bounds);
- INIT_PROGRAM_UNIFORM_LOCATION (repeat, texture_rect);
-
-
- /* We initialize the alpha uniform here, since the default value is important.
- * We can't do it in the shader like a reasonable person would because that doesn't
- * work in gles. */
- for (i = 0; i < GL_N_PROGRAMS; i++)
- {
- glUseProgram(programs->programs[i].id);
- glUniform1f (programs->programs[i].alpha_location, 1.0);
- }
-
-out:
- gsk_gl_shader_builder_finish (&shader_builder);
-
- /* Check we indeed emitted an error if there was one */
- g_assert (programs || !error || *error);
-
- return programs;
-}
-
-static GskGLRendererPrograms *
-get_programs_for_display (GskGLRenderer *self,
- GdkDisplay *display,
- GError **error)
-{
- GskGLRendererPrograms *programs;
-
- if (g_getenv ("GSK_NO_SHARED_PROGRAMS"))
- return gsk_gl_renderer_create_programs (self, error);
-
- programs = (GskGLRendererPrograms *)g_object_get_data (G_OBJECT (display), "gsk-gl-programs");
- if (programs == NULL)
- {
- programs = gsk_gl_renderer_create_programs (self, error);
- if (programs)
- g_object_set_data_full (G_OBJECT (display), "gsk-gl-programs",
- programs,
- (GDestroyNotify) gsk_gl_renderer_programs_unref);
- }
-
- if (programs)
- return gsk_gl_renderer_programs_ref (programs);
- return NULL;
-}
-
-
-static GskGLTextureAtlases *
-get_texture_atlases_for_display (GdkDisplay *display)
-{
- GskGLTextureAtlases *atlases;
-
- if (g_getenv ("GSK_NO_SHARED_CACHES"))
- return gsk_gl_texture_atlases_new ();
-
- atlases = (GskGLTextureAtlases*)g_object_get_data (G_OBJECT (display), "gsk-gl-texture-atlases");
- if (atlases == NULL)
- {
- atlases = gsk_gl_texture_atlases_new ();
- g_object_set_data_full (G_OBJECT (display), "gsk-gl-texture-atlases",
- atlases,
- (GDestroyNotify) gsk_gl_texture_atlases_unref);
- }
-
- return gsk_gl_texture_atlases_ref (atlases);
-}
-
-static GskGLGlyphCache *
-get_glyph_cache_for_display (GdkDisplay *display,
- GskGLTextureAtlases *atlases)
-{
- GskGLGlyphCache *glyph_cache;
-
- if (g_getenv ("GSK_NO_SHARED_CACHES"))
- return gsk_gl_glyph_cache_new (display, atlases);
-
- glyph_cache = (GskGLGlyphCache*)g_object_get_data (G_OBJECT (display), "gsk-gl-glyph-cache");
- if (glyph_cache == NULL)
- {
- glyph_cache = gsk_gl_glyph_cache_new (display, atlases);
- g_object_set_data_full (G_OBJECT (display), "gsk-gl-glyph-cache",
- glyph_cache,
- (GDestroyNotify) gsk_gl_glyph_cache_unref);
- }
-
- return gsk_gl_glyph_cache_ref (glyph_cache);
-}
-
-static GskGLIconCache *
-get_icon_cache_for_display (GdkDisplay *display,
- GskGLTextureAtlases *atlases)
-{
- GskGLIconCache *icon_cache;
-
- if (g_getenv ("GSK_NO_SHARED_CACHES"))
- return gsk_gl_icon_cache_new (display, atlases);
-
- icon_cache = (GskGLIconCache*)g_object_get_data (G_OBJECT (display), "gsk-gl-icon-cache");
- if (icon_cache == NULL)
- {
- icon_cache = gsk_gl_icon_cache_new (display, atlases);
- g_object_set_data_full (G_OBJECT (display), "gsk-gl-icon-cache",
- icon_cache,
- (GDestroyNotify) gsk_gl_icon_cache_unref);
- }
-
- return gsk_gl_icon_cache_ref (icon_cache);
-}
-
-static gboolean
-gsk_gl_renderer_realize (GskRenderer *renderer,
- GdkSurface *surface,
- GError **error)
-{
- GskGLRenderer *self = GSK_GL_RENDERER (renderer);
- gint64 before G_GNUC_UNUSED;
-
- before = GDK_PROFILER_CURRENT_TIME;
- /* If we didn't get a GdkGLContext before realization, try creating
- * one now, for our exclusive use.
- */
- if (self->gl_context == NULL)
- {
- self->gl_context = gdk_surface_create_gl_context (surface, error);
- if (self->gl_context == NULL)
- return FALSE;
- }
-
- if (!gdk_gl_context_realize (self->gl_context, error))
- return FALSE;
-
- gdk_gl_context_make_current (self->gl_context);
-
- g_assert (self->gl_driver == NULL);
- self->gl_profiler = gsk_gl_profiler_new (self->gl_context);
- self->gl_driver = gsk_gl_driver_new (self->gl_context);
-
- GSK_RENDERER_NOTE (renderer, OPENGL, g_message ("Creating buffers and programs"));
- self->programs = get_programs_for_display (self, gdk_surface_get_display (surface), error);
- if (self->programs == NULL)
- return FALSE;
- self->op_builder.programs = self->programs;
-
- self->atlases = get_texture_atlases_for_display (gdk_surface_get_display (surface));
- self->glyph_cache = get_glyph_cache_for_display (gdk_surface_get_display (surface), self->atlases);
- self->icon_cache = get_icon_cache_for_display (gdk_surface_get_display (surface), self->atlases);
- gsk_gl_shadow_cache_init (&self->shadow_cache);
-
- gdk_profiler_end_mark (before, "gl renderer realize", NULL);
-
- return TRUE;
-}
-
-static void
-gsk_gl_renderer_unrealize (GskRenderer *renderer)
-{
- GskGLRenderer *self = GSK_GL_RENDERER (renderer);
-
- if (self->gl_context == NULL)
- return;
-
- gdk_gl_context_make_current (self->gl_context);
-
- /* We don't need to iterate to destroy the associated GL resources,
- * as they will be dropped when we finalize the GskGLDriver
- */
- ops_reset (&self->op_builder);
- self->op_builder.programs = NULL;
-
- g_clear_pointer (&self->programs, gsk_gl_renderer_programs_unref);
- g_clear_pointer (&self->glyph_cache, gsk_gl_glyph_cache_unref);
- g_clear_pointer (&self->icon_cache, gsk_gl_icon_cache_unref);
- g_clear_pointer (&self->atlases, gsk_gl_texture_atlases_unref);
- gsk_gl_shadow_cache_free (&self->shadow_cache, self->gl_driver);
-
- g_clear_object (&self->gl_profiler);
- g_clear_object (&self->gl_driver);
-
- if (self->gl_context == gdk_gl_context_get_current ())
- gdk_gl_context_clear_current ();
-
- g_clear_object (&self->gl_context);
-}
-
-static void
-gsk_gl_renderer_clear_tree (GskGLRenderer *self)
-{
- if (self->gl_context == NULL)
- return;
-
- gdk_gl_context_make_current (self->gl_context);
-
- ops_reset (&self->op_builder);
-
-#ifdef G_ENABLE_DEBUG
- int removed_textures = gsk_gl_driver_collect_textures (self->gl_driver);
- GSK_RENDERER_NOTE (GSK_RENDERER (self), OPENGL, g_message ("Collected: %d textures", removed_textures));
-#else
- gsk_gl_driver_collect_textures (self->gl_driver);
-#endif
-}
-
-static void
-gsk_gl_renderer_clear (GskGLRenderer *self)
-{
- GSK_RENDERER_NOTE (GSK_RENDERER (self), OPENGL, g_message ("Clearing viewport"));
- glClearColor (0, 0, 0, 0);
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-}
-
-static void
-gsk_gl_renderer_setup_render_mode (GskGLRenderer *self)
-{
- if (self->render_region == NULL)
- {
- glDisable (GL_SCISSOR_TEST);
- }
- else
- {
- GdkSurface *surface = gsk_renderer_get_surface (GSK_RENDERER (self));
- cairo_rectangle_int_t extents;
- int surface_height;
-
- g_assert (cairo_region_num_rectangles (self->render_region) == 1);
-
- surface_height = gdk_surface_get_height (surface) * self->scale_factor;
- cairo_region_get_rectangle (self->render_region, 0, &extents);
-
- glEnable (GL_SCISSOR_TEST);
- glScissor (extents.x * self->scale_factor,
- surface_height - (extents.height * self->scale_factor) - (extents.y * self->scale_factor),
- extents.width * self->scale_factor,
- extents.height * self->scale_factor);
- }
-}
-
-static void
-gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
- GskRenderNode *node,
- RenderOpBuilder *builder)
-{
- /* This can still happen, even if the render nodes are created using
- * GtkSnapshot, so let's just be safe. */
- if (node_is_invisible (node))
- return;
-
- /* Check whether the render node is entirely out of the current
- * already transformed clip region */
- {
- graphene_rect_t transformed_node_bounds;
-
- ops_transform_bounds_modelview (builder,
- &node->bounds,
- &transformed_node_bounds);
-
- if (!graphene_rect_intersects (&builder->current_clip->bounds,
- &transformed_node_bounds))
- return;
- }
-
- switch (gsk_render_node_get_node_type (node))
- {
- case GSK_NOT_A_RENDER_NODE:
- g_assert_not_reached ();
-
- case GSK_CONTAINER_NODE:
- {
- guint i, p;
-
- for (i = 0, p = gsk_container_node_get_n_children (node); i < p; i ++)
- {
- GskRenderNode *child = gsk_container_node_get_child (node, i);
-
- gsk_gl_renderer_add_render_ops (self, child, builder);
- }
- }
- break;
-
- case GSK_DEBUG_NODE:
- {
- const char *message = gsk_debug_node_get_message (node);
- if (message)
- ops_push_debug_group (builder, message);
- gsk_gl_renderer_add_render_ops (self,
- gsk_debug_node_get_child (node),
- builder);
- if (message)
- ops_pop_debug_group (builder);
- }
- break;
-
- case GSK_COLOR_NODE:
- render_color_node (self, node, builder);
- break;
-
- case GSK_TEXTURE_NODE:
- render_texture_node (self, node, builder);
- break;
-
- case GSK_TRANSFORM_NODE:
- render_transform_node (self, node, builder);
- break;
-
- case GSK_OPACITY_NODE:
- render_opacity_node (self, node, builder);
- break;
-
- case GSK_LINEAR_GRADIENT_NODE:
- case GSK_REPEATING_LINEAR_GRADIENT_NODE:
- render_linear_gradient_node (self, node, builder);
- break;
-
- case GSK_RADIAL_GRADIENT_NODE:
- case GSK_REPEATING_RADIAL_GRADIENT_NODE:
- render_radial_gradient_node (self, node, builder);
- break;
-
- case GSK_CONIC_GRADIENT_NODE:
- render_conic_gradient_node (self, node, builder);
- break;
-
- case GSK_CLIP_NODE:
- render_clip_node (self, node, builder);
- break;
-
- case GSK_ROUNDED_CLIP_NODE:
- render_rounded_clip_node (self, node, builder);
- break;
-
- case GSK_TEXT_NODE:
- render_text_node (self, node, builder,
- gsk_text_node_get_color (node), FALSE);
- break;
-
- case GSK_COLOR_MATRIX_NODE:
- render_color_matrix_node (self, node, builder);
- break;
-
- case GSK_BLUR_NODE:
- render_blur_node (self, node, builder);
- break;
-
- case GSK_INSET_SHADOW_NODE:
- if (gsk_inset_shadow_node_get_blur_radius (node) > 0)
- render_inset_shadow_node (self, node, builder);
- else
- render_unblurred_inset_shadow_node (self, node, builder);
- break;
-
- case GSK_OUTSET_SHADOW_NODE:
- if (gsk_outset_shadow_node_get_blur_radius (node) > 0)
- render_outset_shadow_node (self, node, builder);
- else
- render_unblurred_outset_shadow_node (self, node, builder);
- break;
-
- case GSK_SHADOW_NODE:
- render_shadow_node (self, node, builder);
- break;
-
- case GSK_BORDER_NODE:
- render_border_node (self, node, builder);
- break;
-
- case GSK_CROSS_FADE_NODE:
- render_cross_fade_node (self, node, builder);
- break;
-
- case GSK_BLEND_NODE:
- render_blend_node (self, node, builder);
- break;
-
- case GSK_REPEAT_NODE:
- render_repeat_node (self, node, builder);
- break;
-
- case GSK_GL_SHADER_NODE:
- render_gl_shader_node (self, node, builder);
- break;
-
- case GSK_CAIRO_NODE:
- default:
- {
- render_fallback_node (self, node, builder);
- }
- }
-}
-
-static gboolean
-add_offscreen_ops (GskGLRenderer *self,
- RenderOpBuilder *builder,
- const graphene_rect_t *bounds,
- GskRenderNode *child_node,
- TextureRegion *texture_region_out,
- gboolean *is_offscreen,
- guint flags)
-{
- const float dx = builder->dx;
- const float dy = builder->dy;
- float scaled_width, scaled_height;
- float scale_x;
- float scale_y;
- int render_target;
- int prev_render_target;
- graphene_matrix_t prev_projection;
- graphene_rect_t prev_viewport;
- graphene_matrix_t item_proj;
- float prev_opacity = 1.0;
- int texture_id = 0;
- int filter;
- GskTextureKey key;
- int cached_id;
- graphene_rect_t viewport;
-
- if (node_is_invisible (child_node))
- {
- /* Just to be safe */
- *is_offscreen = FALSE;
- init_full_texture_region (texture_region_out, 0);
- return FALSE;
- }
-
- /* We need the child node as a texture. If it already is one, we don't need to draw
- * it on a framebuffer of course. */
- if (gsk_render_node_get_node_type (child_node) == GSK_TEXTURE_NODE &&
- (flags & FORCE_OFFSCREEN) == 0)
- {
- GdkTexture *texture = gsk_texture_node_get_texture (child_node);
- upload_texture (self, texture, texture_region_out);
- *is_offscreen = FALSE;
- return TRUE;
- }
-
- if (flags & LINEAR_FILTER)
- filter = GL_LINEAR;
- else
- filter = GL_NEAREST;
-
- /* Check if we've already cached the drawn texture. */
- key.pointer = child_node;
- key.pointer_is_child = TRUE; /* Don't conflict with the child using the cache too */
- key.parent_rect = *bounds;
- key.scale_x = builder->scale_x;
- key.scale_y = builder->scale_y;
- key.filter = filter;
- cached_id = gsk_gl_driver_get_texture_for_key (self->gl_driver, &key);
-
- if (cached_id != 0)
- {
- init_full_texture_region (texture_region_out, cached_id);
- /* We didn't render it offscreen, but hand out an offscreen texture id */
- *is_offscreen = TRUE;
- return TRUE;
- }
-
- scale_x = builder->scale_x;
- scale_y = builder->scale_y;
-
- /* Tweak the scale factor so that the required texture doesn't
- * exceed the max texture limit. This will render with a lower
- * resolution, but this is better than clipping.
- */
- {
- const int max_texture_size = gsk_gl_driver_get_max_texture_size (self->gl_driver);
-
- scaled_width = ceilf (bounds->size.width * scale_x);
- if (scaled_width > max_texture_size)
- {
- scale_x *= (float)max_texture_size / scaled_width;
- scaled_width = max_texture_size;
- }
-
- scaled_height = ceilf (bounds->size.height * scale_y);
- if (scaled_height > max_texture_size)
- {
- scale_y *= (float)max_texture_size / scaled_height;
- scaled_height = max_texture_size;
- }
- }
-
- gsk_gl_driver_create_render_target (self->gl_driver,
- scaled_width, scaled_height,
- filter, filter,
- &texture_id, &render_target);
- if (gdk_gl_context_has_debug (self->gl_context))
- {
- gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
- "Offscreen<%s> %d",
- g_type_name_from_instance ((GTypeInstance *) child_node),
- texture_id);
- gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, render_target,
- "Offscreen<%s> FB %d",
- g_type_name_from_instance ((GTypeInstance *) child_node),
- render_target);
- }
-
- ops_transform_bounds_modelview (builder, bounds, &viewport);
- /* Code above will scale the size with the scale we use in the render ops,
- * but for the viewport size, we need our own size limited by the texture size */
- viewport.size.width = scaled_width;
- viewport.size.height = scaled_height;
-
- init_projection_matrix (&item_proj, &viewport);
- prev_render_target = ops_set_render_target (builder, render_target);
- /* Clear since we use this rendertarget for the first time */
- ops_begin (builder, OP_CLEAR);
- prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, gsk_transform_scale (NULL, scale_x, scale_y));
- prev_viewport = ops_set_viewport (builder, &viewport);
- if (flags & RESET_CLIP)
- ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
-
- builder->dx = dx;
- builder->dy = dy;
-
- prev_opacity = ops_set_opacity (builder, 1.0);
-
- gsk_gl_renderer_add_render_ops (self, child_node, builder);
-
-#ifdef G_ENABLE_DEBUG
- if (G_UNLIKELY (flags & DUMP_FRAMEBUFFER))
- {
- static int k;
- ops_dump_framebuffer (builder,
- g_strdup_printf ("%s_%p_%d.png",
- g_type_name_from_instance ((GTypeInstance *) child_node),
- child_node,
- k ++),
- scaled_width, scaled_height);
- }
-#endif
-
- ops_set_opacity (builder, prev_opacity);
-
- builder->dx = dx;
- builder->dy = dy;
-
- if (flags & RESET_CLIP)
- ops_pop_clip (builder);
-
- ops_set_viewport (builder, &prev_viewport);
- ops_pop_modelview (builder);
- ops_set_projection (builder, &prev_projection);
- ops_set_render_target (builder, prev_render_target);
-
- *is_offscreen = TRUE;
- init_full_texture_region (texture_region_out, texture_id);
-
- if ((flags & NO_CACHE_PLZ) == 0)
- gsk_gl_driver_set_texture_for_key (self->gl_driver, &key, texture_id);
-
- return TRUE;
-}
-
-static void
-gsk_gl_renderer_render_ops (GskGLRenderer *self)
-{
- const Program *program = NULL;
- const gsize vertex_data_size = self->op_builder.vertices->len * sizeof (GskQuadVertex);
- const float *vertex_data = (float *)self->op_builder.vertices->data;
- OpBufferIter iter;
- OpKind kind;
- gpointer ptr;
- GLuint buffer_id, vao_id;
-
-#if DEBUG_OPS
- g_print ("============================================\n");
-#endif
-
- glGenVertexArrays (1, &vao_id);
- glBindVertexArray (vao_id);
-
- glGenBuffers (1, &buffer_id);
- glBindBuffer (GL_ARRAY_BUFFER, buffer_id);
-
- glBufferData (GL_ARRAY_BUFFER, vertex_data_size, vertex_data, GL_STATIC_DRAW);
-
- /* 0 = position location */
- glEnableVertexAttribArray (0);
- glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE,
- sizeof (GskQuadVertex),
- (void *) G_STRUCT_OFFSET (GskQuadVertex, position));
- /* 1 = texture coord location */
- glEnableVertexAttribArray (1);
- glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE,
- sizeof (GskQuadVertex),
- (void *) G_STRUCT_OFFSET (GskQuadVertex, uv));
-
- op_buffer_iter_init (&iter, ops_get_buffer (&self->op_builder));
- while ((ptr = op_buffer_iter_next (&iter, &kind)))
- {
- if (kind == OP_NONE)
- continue;
-
- if (program == NULL &&
- kind != OP_PUSH_DEBUG_GROUP &&
- kind != OP_POP_DEBUG_GROUP &&
- kind != OP_CHANGE_PROGRAM &&
- kind != OP_CHANGE_RENDER_TARGET &&
- kind != OP_CLEAR)
- continue;
-
- OP_PRINT ("Op %u: %u", iter.pos - 2, kind);
-
- switch (kind)
- {
- case OP_CHANGE_PROJECTION:
- apply_projection_op (program, ptr);
- break;
-
- case OP_CHANGE_MODELVIEW:
- apply_modelview_op (program, ptr);
- break;
-
- case OP_CHANGE_PROGRAM:
- {
- const OpProgram *op = ptr;
- apply_program_op (program, op);
- program = op->program;
- break;
- }
-
- case OP_CHANGE_RENDER_TARGET:
- apply_render_target_op (self, ptr);
- break;
-
- case OP_CLEAR:
- OP_PRINT ("-> CLEAR");
- glClearColor (0, 0, 0, 0);
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- break;
-
- case OP_CHANGE_VIEWPORT:
- apply_viewport_op (program, ptr);
- break;
-
- case OP_CHANGE_OPACITY:
- apply_opacity_op (program, ptr);
- break;
-
- case OP_CHANGE_COLOR_MATRIX:
- apply_color_matrix_op (program, ptr);
- break;
-
- case OP_CHANGE_COLOR:
- /*g_assert (program == &self->color_program || program == &self->coloring_program ||*/
- /*program == &self->shadow_program);*/
- apply_color_op (program, ptr);
- break;
-
- case OP_CHANGE_BORDER_COLOR:
- apply_border_color_op (program, ptr);
- break;
-
- case OP_CHANGE_CLIP:
- apply_clip_op (program, ptr);
- break;
-
- case OP_CHANGE_SOURCE_TEXTURE:
- apply_source_texture_op (program, ptr);
- break;
-
- case OP_CHANGE_EXTRA_SOURCE_TEXTURE:
- apply_source_extra_texture_op (program, ptr);
- break;
-
- case OP_CHANGE_CROSS_FADE:
- g_assert (program == &self->programs->cross_fade_program);
- apply_cross_fade_op (program, ptr);
- break;
-
- case OP_CHANGE_BLEND:
- g_assert (program == &self->programs->blend_program);
- apply_blend_op (program, ptr);
- break;
-
- case OP_CHANGE_LINEAR_GRADIENT:
- apply_linear_gradient_op (program, ptr);
- break;
-
- case OP_CHANGE_RADIAL_GRADIENT:
- apply_radial_gradient_op (program, ptr);
- break;
-
- case OP_CHANGE_CONIC_GRADIENT:
- apply_conic_gradient_op (program, ptr);
- break;
-
- case OP_CHANGE_BLUR:
- apply_blur_op (program, ptr);
- break;
-
- case OP_CHANGE_INSET_SHADOW:
- apply_inset_shadow_op (program, ptr);
- break;
-
- case OP_CHANGE_OUTSET_SHADOW:
- apply_outset_shadow_op (program, ptr);
- break;
-
- case OP_CHANGE_BORDER:
- apply_border_op (program, ptr);
- break;
-
- case OP_CHANGE_BORDER_WIDTH:
- apply_border_width_op (program, ptr);
- break;
-
- case OP_CHANGE_UNBLURRED_OUTSET_SHADOW:
- apply_unblurred_outset_shadow_op (program, ptr);
- break;
-
- case OP_CHANGE_REPEAT:
- apply_repeat_op (program, ptr);
- break;
-
- case OP_CHANGE_GL_SHADER_ARGS:
- apply_gl_shader_args_op (program, ptr);
- break;
-
- case OP_DRAW:
- {
- const OpDraw *op = ptr;
-
- OP_PRINT (" -> draw %ld, size %ld and program %d: %s",
- op->vao_offset, op->vao_size, program->index,
- program->name ?: "");
- glDrawArrays (GL_TRIANGLES, op->vao_offset, op->vao_size);
- break;
- }
-
- case OP_DUMP_FRAMEBUFFER:
- {
- const OpDumpFrameBuffer *op = ptr;
-
- dump_framebuffer (op->filename, op->width, op->height);
- break;
- }
-
- case OP_PUSH_DEBUG_GROUP:
- {
- const OpDebugGroup *op = ptr;
- gdk_gl_context_push_debug_group (self->gl_context, op->text);
- OP_PRINT (" Debug: %s", op->text);
- break;
- }
-
- case OP_POP_DEBUG_GROUP:
- gdk_gl_context_pop_debug_group (self->gl_context);
- break;
-
- case OP_NONE:
- case OP_LAST:
- default:
- g_warn_if_reached ();
- }
-
- OP_PRINT ("\n");
- }
-
- glDeleteVertexArrays (1, &vao_id);
- glDeleteBuffers (1, &buffer_id);
-}
-
-static void
-gsk_gl_renderer_do_render (GskRenderer *renderer,
- GskRenderNode *root,
- const graphene_rect_t *viewport,
- int fbo_id,
- int scale_factor)
-{
- GskGLRenderer *self = GSK_GL_RENDERER (renderer);
- graphene_matrix_t projection;
-#ifdef G_ENABLE_DEBUG
- GskProfiler *profiler;
- gint64 gpu_time, cpu_time;
- gint64 start_time G_GNUC_UNUSED;
-#endif
- GPtrArray *removed;
-
-#ifdef G_ENABLE_DEBUG
- profiler = gsk_renderer_get_profiler (renderer);
-#endif
-
- if (self->gl_context == NULL)
- {
- GSK_RENDERER_NOTE (renderer, OPENGL, g_message ("No valid GL context associated to the renderer"));
- return;
- }
-
- g_assert (gsk_gl_driver_in_frame (self->gl_driver));
-
- removed = g_ptr_array_new ();
- gsk_gl_texture_atlases_begin_frame (self->atlases, removed);
- gsk_gl_glyph_cache_begin_frame (self->glyph_cache, self->gl_driver, removed);
- gsk_gl_icon_cache_begin_frame (self->icon_cache, removed);
- gsk_gl_shadow_cache_begin_frame (&self->shadow_cache, self->gl_driver);
- g_ptr_array_unref (removed);
-
- /* Set up the modelview and projection matrices to fit our viewport */
- init_projection_matrix (&projection, viewport);
- ops_set_projection (&self->op_builder, &projection);
- ops_set_viewport (&self->op_builder, viewport);
- ops_set_modelview (&self->op_builder, gsk_transform_scale (NULL, scale_factor, scale_factor));
-
- /* Initial clip is self->render_region! */
- if (self->render_region != NULL)
- {
- graphene_rect_t transformed_render_region;
- cairo_rectangle_int_t render_extents;
-
- cairo_region_get_extents (self->render_region, &render_extents);
-
- ops_transform_bounds_modelview (&self->op_builder,
- &GRAPHENE_RECT_INIT (render_extents.x,
- render_extents.y,
- render_extents.width,
- render_extents.height),
- &transformed_render_region);
- ops_push_clip (&self->op_builder,
- &GSK_ROUNDED_RECT_INIT (transformed_render_region.origin.x,
- transformed_render_region.origin.y,
- transformed_render_region.size.width,
- transformed_render_region.size.height));
- }
- else
- {
- ops_push_clip (&self->op_builder,
- &GSK_ROUNDED_RECT_INIT (viewport->origin.x,
- viewport->origin.y,
- viewport->size.width,
- viewport->size.height));
- }
-
- if (fbo_id != 0)
- ops_set_render_target (&self->op_builder, fbo_id);
-
- gdk_gl_context_push_debug_group (self->gl_context, "Adding render ops");
- gsk_gl_renderer_add_render_ops (self, root, &self->op_builder);
- gdk_gl_context_pop_debug_group (self->gl_context);
-
- /* We correctly reset the state everywhere */
- g_assert_cmpint (self->op_builder.current_render_target, ==, fbo_id);
- ops_pop_modelview (&self->op_builder);
- ops_pop_clip (&self->op_builder);
- ops_finish (&self->op_builder);
-
- /*g_message ("Ops: %u", self->render_ops->len);*/
-
- /* Now actually draw things... */
-#ifdef G_ENABLE_DEBUG
- gsk_gl_profiler_begin_gpu_region (self->gl_profiler);
- gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
-#endif
-
- /* Actually do the rendering */
- if (fbo_id != 0)
- glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
-
- glViewport (0, 0, ceilf (viewport->size.width), ceilf (viewport->size.height));
- gsk_gl_renderer_setup_render_mode (self);
- gsk_gl_renderer_clear (self);
-
- glEnable (GL_DEPTH_TEST);
- glDepthFunc (GL_LEQUAL);
-
- /* Pre-multiplied alpha! */
- glEnable (GL_BLEND);
- glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glBlendEquation (GL_FUNC_ADD);
-
- gdk_gl_context_push_debug_group (self->gl_context, "Rendering ops");
- gsk_gl_renderer_render_ops (self);
- gdk_gl_context_pop_debug_group (self->gl_context);
-
-#ifdef G_ENABLE_DEBUG
- gsk_profiler_counter_inc (profiler, self->profile_counters.frames);
-
- start_time = gsk_profiler_timer_get_start (profiler, self->profile_timers.cpu_time);
- cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
- gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
-
- gpu_time = gsk_gl_profiler_end_gpu_region (self->gl_profiler);
- gsk_profiler_timer_set (profiler, self->profile_timers.gpu_time, gpu_time);
-
- gsk_profiler_push_samples (profiler);
-
- gdk_profiler_add_mark (start_time * 1000, cpu_time * 1000, "GL render", "");
-#endif
-}
-
-static GdkTexture *
-gsk_gl_renderer_render_texture (GskRenderer *renderer,
- GskRenderNode *root,
- const graphene_rect_t *viewport)
-{
- GskGLRenderer *self = GSK_GL_RENDERER (renderer);
- GdkTexture *texture;
- int width, height;
- guint texture_id;
- guint fbo_id;
-
- g_return_val_if_fail (self->gl_context != NULL, NULL);
-
- gdk_gl_context_make_current (self->gl_context);
- gdk_gl_context_push_debug_group_printf (self->gl_context,
- "Render %s<%p> to texture",
- g_type_name_from_instance ((GTypeInstance *) root),
- root);
-
- width = ceilf (viewport->size.width);
- height = ceilf (viewport->size.height);
-
- self->scale_factor = gdk_surface_get_scale_factor (gsk_renderer_get_surface (renderer));
-
- /* Prepare our framebuffer */
- gsk_gl_driver_begin_frame (self->gl_driver);
- glGenTextures (1, &texture_id);
- glBindTexture (GL_TEXTURE_2D, texture_id);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
- if (gdk_gl_context_has_debug (self->gl_context))
- gdk_gl_context_label_object_printf (self->gl_context, GL_TEXTURE, texture_id,
- "Texture %s<%p> %d",
- g_type_name_from_instance ((GTypeInstance *) root),
- root,
- texture_id);
-
- if (gdk_gl_context_get_use_es (self->gl_context))
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- else
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
-
- glGenFramebuffers (1, &fbo_id);
- glBindFramebuffer (GL_FRAMEBUFFER, fbo_id);
-
- if (gdk_gl_context_has_debug (self->gl_context))
- gdk_gl_context_label_object_printf (self->gl_context, GL_FRAMEBUFFER, fbo_id,
- "FB %s<%p> %d",
- g_type_name_from_instance ((GTypeInstance *) root),
- root,
- fbo_id);
- glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
-
- /* Render the actual scene */
- gsk_gl_renderer_do_render (renderer, root, viewport, fbo_id, 1);
-
- glDeleteFramebuffers (1, &fbo_id);
-
-
- /* Render the now drawn framebuffer y-flipped so it's as GdkGLTexture expects it to be */
- {
- guint final_texture_id, final_fbo_id;
- graphene_matrix_t m;
-
- ops_reset (&self->op_builder);
-
- glGenFramebuffers (1, &final_fbo_id);
- glBindFramebuffer (GL_FRAMEBUFFER, final_fbo_id);
- glGenTextures (1, &final_texture_id);
- glBindTexture (GL_TEXTURE_2D, final_texture_id);
-
- if (gdk_gl_context_get_use_es (self->gl_context))
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- else
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
- glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, final_texture_id, 0);
- g_assert_cmphex (glCheckFramebufferStatus (GL_FRAMEBUFFER), ==, GL_FRAMEBUFFER_COMPLETE);
-
- ops_set_render_target (&self->op_builder, final_fbo_id);
- ops_push_clip (&self->op_builder, &GSK_ROUNDED_RECT_INIT (0, 0, width, height));
- ops_set_program (&self->op_builder, &self->programs->blit_program);
-
- ops_begin (&self->op_builder, OP_CLEAR);
- ops_set_texture (&self->op_builder, texture_id);
- ops_set_modelview (&self->op_builder, NULL);
- ops_set_viewport (&self->op_builder, &GRAPHENE_RECT_INIT (0, 0, width, height));
- init_projection_matrix (&m, &GRAPHENE_RECT_INIT (0, 0, width, height));
- graphene_matrix_scale (&m, 1, -1, 1); /* Undo the scale init_projection_matrix() does again */
- ops_set_projection (&self->op_builder, &m);
-
- fill_vertex_data (ops_draw (&self->op_builder, NULL),
- 0, 0, width, height);
- ops_pop_clip (&self->op_builder);
- gsk_gl_renderer_render_ops (self);
-
- ops_finish (&self->op_builder);
-
- glDeleteTextures (1, &texture_id);
-
- texture_id = final_texture_id;
- }
-
- texture = gdk_gl_texture_new (self->gl_context,
- texture_id,
- width, height,
- NULL, NULL);
-
- gsk_gl_driver_end_frame (self->gl_driver);
-
- gdk_gl_context_pop_debug_group (self->gl_context);
-
- gsk_gl_renderer_clear_tree (self);
- return texture;
-}
-
-static void
-gsk_gl_renderer_render (GskRenderer *renderer,
- GskRenderNode *root,
- const cairo_region_t *update_area)
-{
- GskGLRenderer *self = GSK_GL_RENDERER (renderer);
- graphene_rect_t viewport;
- const cairo_region_t *damage;
- GdkRectangle whole_surface;
- GdkSurface *surface;
-
- if (self->gl_context == NULL)
- return;
-
- surface = gsk_renderer_get_surface (renderer);
- self->scale_factor = gdk_surface_get_scale_factor (surface);
-
- gdk_gl_context_make_current (self->gl_context);
- gdk_gl_context_push_debug_group_printf (self->gl_context,
- "Render root node %p", root);
-
- whole_surface = (GdkRectangle) {
- 0, 0,
- gdk_surface_get_width (surface) * self->scale_factor,
- gdk_surface_get_height (surface) * self->scale_factor
- };
-
- gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->gl_context),
- update_area);
-
- damage = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->gl_context));
-
- if (cairo_region_contains_rectangle (damage, &whole_surface) == CAIRO_REGION_OVERLAP_IN)
- {
- self->render_region = NULL;
- }
- else
- {
- GdkRectangle extents;
-
- cairo_region_get_extents (damage, &extents);
-
- if (gdk_rectangle_equal (&extents, &whole_surface))
- self->render_region = NULL;
- else
- self->render_region = cairo_region_create_rectangle (&extents);
- }
-
- gdk_gl_context_make_current (self->gl_context);
-
- viewport.origin.x = 0;
- viewport.origin.y = 0;
- viewport.size.width = whole_surface.width;
- viewport.size.height = whole_surface.height;
-
- gsk_gl_driver_begin_frame (self->gl_driver);
- gsk_gl_renderer_do_render (renderer, root, &viewport, 0, self->scale_factor);
- gsk_gl_driver_end_frame (self->gl_driver);
-
- gsk_gl_renderer_clear_tree (self);
-
- gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->gl_context));
- gdk_gl_context_make_current (self->gl_context);
-
- gdk_gl_context_pop_debug_group (self->gl_context);
-
- g_clear_pointer (&self->render_region, cairo_region_destroy);
-}
-
-static void
-gsk_gl_renderer_class_init (GskGLRendererClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass);
-
- gobject_class->dispose = gsk_gl_renderer_dispose;
-
- renderer_class->realize = gsk_gl_renderer_realize;
- renderer_class->unrealize = gsk_gl_renderer_unrealize;
- renderer_class->render = gsk_gl_renderer_render;
- renderer_class->render_texture = gsk_gl_renderer_render_texture;
-}
-
-static void
-gsk_gl_renderer_init (GskGLRenderer *self)
-{
- gsk_ensure_resources ();
-
- ops_init (&self->op_builder);
- self->op_builder.renderer = self;
-
-#ifdef G_ENABLE_DEBUG
- {
- GskProfiler *profiler = gsk_renderer_get_profiler (GSK_RENDERER (self));
-
- self->profile_counters.frames = gsk_profiler_add_counter (profiler, "frames", "Frames", FALSE);
-
- self->profile_timers.cpu_time = gsk_profiler_add_timer (profiler, "cpu-time", "CPU time", FALSE, TRUE);
- self->profile_timers.gpu_time = gsk_profiler_add_timer (profiler, "gpu-time", "GPU time", FALSE, TRUE);
- }
-#endif
-}
-
-/**
- * gsk_gl_renderer_new:
- *
- * Creates a new `GskRenderer` using OpenGL.
- *
- * Returns: a new GL renderer
- */
-GskRenderer *
-gsk_gl_renderer_new (void)
-{
- return g_object_new (GSK_TYPE_GL_RENDERER, NULL);
-}
diff --git a/gsk/gl/gskglrenderer.h b/gsk/gl/gskglrenderer.h
deleted file mode 100644
index 13466fc56d..0000000000
--- a/gsk/gl/gskglrenderer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright © 2016 Endless
- * 2018 Timm Bäder <mail@baedert.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors: Timm Bäder <mail@baedert.org>
- */
-
-#ifndef __GSK_GL_RENDERER_H__
-#define __GSK_GL_RENDERER_H__
-
-#include <gsk/gskrenderer.h>
-
-G_BEGIN_DECLS
-
-#define GSK_TYPE_GL_RENDERER (gsk_gl_renderer_get_type ())
-
-#define GSK_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_GL_RENDERER, GskGLRenderer))
-#define GSK_IS_GL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_GL_RENDERER))
-#define GSK_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
-#define GSK_IS_GL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_GL_RENDERER))
-#define GSK_GL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_GL_RENDERER, GskGLRendererClass))
-
-/**
- * GskGLRenderer:
- *
- * A GSK renderer that is using OpenGL.
- */
-typedef struct _GskGLRenderer GskGLRenderer;
-typedef struct _GskGLRendererClass GskGLRendererClass;
-
-GDK_AVAILABLE_IN_ALL
-GType gsk_gl_renderer_get_type (void) G_GNUC_CONST;
-
-GDK_AVAILABLE_IN_ALL
-GskRenderer * gsk_gl_renderer_new (void);
-
-G_END_DECLS
-
-#endif /* __GSK_GL_RENDERER_H__ */
diff --git a/gsk/gl/gskglrendererprivate.h b/gsk/gl/gskglrendererprivate.h
deleted file mode 100644
index 924ee18ca3..0000000000
--- a/gsk/gl/gskglrendererprivate.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __GSK_GL_RENDERER_PRIVATE_H__
-#define __GSK_GL_RENDERER_PRIVATE_H__
-
-#include "gskglrenderer.h"
-
-G_BEGIN_DECLS
-
-gboolean gsk_gl_renderer_try_compile_gl_shader (GskGLRenderer *self,
- GskGLShader *shader,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GSK_GL_RENDERER_PRIVATE_H__ */
diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c
deleted file mode 100644
index 36f7e37e35..0000000000
--- a/gsk/gl/gskglrenderops.c
+++ /dev/null
@@ -1,976 +0,0 @@
-#include "gskglrenderopsprivate.h"
-#include "gsktransform.h"
-
-typedef struct
-{
- GskRoundedRect rect;
- bool is_rectilinear;
-} ClipStackEntry;
-
-static inline gboolean
-rect_equal (const graphene_rect_t *a,
- const graphene_rect_t *b)
-{
- return memcmp (a, b, sizeof (graphene_rect_t)) == 0;
-}
-
-static inline bool G_GNUC_PURE
-rounded_rect_equal (const GskRoundedRect *r1,
- const GskRoundedRect *r2)
-{
- if (r1 == r2)
- return true;
-
- if (!r1)
- return false;
-
- if (r1->bounds.origin.x != r2->bounds.origin.x ||
- r1->bounds.origin.y != r2->bounds.origin.y ||
- r1->bounds.size.width != r2->bounds.size.width ||
- r1->bounds.size.height != r2->bounds.size.height)
- return false;
-
- for (int i = 0; i < 4; i ++)
- if (r1->corner[i].width != r2->corner[i].width ||
- r1->corner[i].height != r2->corner[i].height)
- return false;
-
- return true;
-}
-
-static inline gboolean G_GNUC_PURE
-rounded_rect_corners_equal (const GskRoundedRect *r1,
- const GskRoundedRect *r2)
-{
- int i;
-
- if (!r1)
- return FALSE;
-
- for (i = 0; i < 4; i ++)
- if (r1->corner[i].width != r2->corner[i].width ||
- r1->corner[i].height != r2->corner[i].height)
- return FALSE;
-
- return TRUE;
-}
-
-static inline ProgramState *
-get_current_program_state (RenderOpBuilder *builder)
-{
- if (!builder->current_program)
- return NULL;
-
- return &builder->current_program->state;
-}
-
-void
-ops_finish (RenderOpBuilder *builder)
-{
- if (builder->mv_stack)
- g_array_free (builder->mv_stack, TRUE);
- builder->mv_stack = NULL;
-
- if (builder->clip_stack)
- g_array_free (builder->clip_stack, TRUE);
- builder->clip_stack = NULL;
-
- builder->dx = 0;
- builder->dy = 0;
- builder->scale_x = 1;
- builder->scale_y = 1;
- builder->current_modelview = NULL;
- builder->current_clip = NULL;
- builder->clip_is_rectilinear = TRUE;
- builder->current_render_target = 0;
- builder->current_texture = 0;
- builder->current_program = NULL;
- graphene_matrix_init_identity (&builder->current_projection);
- builder->current_viewport = GRAPHENE_RECT_INIT (0, 0, 0, 0);
-}
-
-/* Debugging only! */
-void
-ops_dump_framebuffer (RenderOpBuilder *builder,
- const char *filename,
- int width,
- int height)
-{
- OpDumpFrameBuffer *op;
-
- op = ops_begin (builder, OP_DUMP_FRAMEBUFFER);
- op->filename = g_strdup (filename);
- op->width = width;
- op->height = height;
-}
-
-void
-ops_push_debug_group (RenderOpBuilder *builder,
- const char *text)
-{
- OpDebugGroup *op;
-
- op = ops_begin (builder, OP_PUSH_DEBUG_GROUP);
- strncpy (op->text, text, sizeof(op->text) - 1);
- op->text[sizeof(op->text) - 1] = 0; /* Ensure zero terminated */
-}
-
-void
-ops_pop_debug_group (RenderOpBuilder *builder)
-{
- ops_begin (builder, OP_POP_DEBUG_GROUP);
-}
-
-static void
-extract_matrix_metadata (GskTransform *transform,
- OpsMatrixMetadata *md)
-{
- float dummy;
-
- switch (gsk_transform_get_category (transform))
- {
- case GSK_TRANSFORM_CATEGORY_IDENTITY:
- case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
- md->scale_x = 1;
- md->scale_y = 1;
- break;
-
- case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
- gsk_transform_to_affine (transform,
- &md->scale_x, &md->scale_y,
- &dummy, &dummy);
- break;
-
- case GSK_TRANSFORM_CATEGORY_UNKNOWN:
- case GSK_TRANSFORM_CATEGORY_ANY:
- case GSK_TRANSFORM_CATEGORY_3D:
- case GSK_TRANSFORM_CATEGORY_2D:
- {
- graphene_vec3_t col1;
- graphene_vec3_t col2;
- graphene_matrix_t m;
-
- gsk_transform_to_matrix (transform, &m);
-
- /* TODO: 90% sure this is incorrect. But we should never hit this code
- * path anyway. */
- graphene_vec3_init (&col1,
- graphene_matrix_get_value (&m, 0, 0),
- graphene_matrix_get_value (&m, 1, 0),
- graphene_matrix_get_value (&m, 2, 0));
-
- graphene_vec3_init (&col2,
- graphene_matrix_get_value (&m, 0, 1),
- graphene_matrix_get_value (&m, 1, 1),
- graphene_matrix_get_value (&m, 2, 1));
-
- md->scale_x = graphene_vec3_length (&col1);
- md->scale_y = graphene_vec3_length (&col2);
- }
- break;
- default:
- {}
- }
-}
-
-void
-ops_transform_bounds_modelview (const RenderOpBuilder *builder,
- const graphene_rect_t *src,
- graphene_rect_t *dst)
-{
- graphene_rect_t r = *src;
-
- g_assert (builder->mv_stack != NULL);
- g_assert (builder->mv_stack->len >= 1);
-
- r.origin.x += builder->dx;
- r.origin.y += builder->dy;
-
- gsk_transform_transform_bounds (builder->current_modelview, &r, dst);
-}
-
-void
-ops_init (RenderOpBuilder *builder)
-{
- memset (builder, 0, sizeof (*builder));
-
- builder->current_opacity = 1.0f;
-
- op_buffer_init (&builder->render_ops);
- builder->vertices = g_array_new (FALSE, TRUE, sizeof (GskQuadVertex));
-}
-
-void
-ops_free (RenderOpBuilder *builder)
-{
- g_array_unref (builder->vertices);
- op_buffer_destroy (&builder->render_ops);
-}
-
-void
-ops_set_program (RenderOpBuilder *builder,
- Program *program)
-{
- OpProgram *op;
-
- if (builder->current_program == program)
- return;
-
- op = ops_begin (builder, OP_CHANGE_PROGRAM);
- op->program = program;
-
- builder->current_program = program;
-}
-
-void
-ops_push_clip (RenderOpBuilder *self,
- const GskRoundedRect *clip)
-{
- ClipStackEntry entry;
-
- if (G_UNLIKELY (self->clip_stack == NULL))
- self->clip_stack = g_array_new (FALSE, TRUE, sizeof (ClipStackEntry));
-
- g_assert (self->clip_stack != NULL);
-
- entry.rect = *clip;
- entry.is_rectilinear = gsk_rounded_rect_is_rectilinear (clip);
- g_array_append_val (self->clip_stack, entry);
- self->current_clip = &g_array_index (self->clip_stack, ClipStackEntry, self->clip_stack->len - 1).rect;
- self->clip_is_rectilinear = entry.is_rectilinear;
-}
-
-void
-ops_pop_clip (RenderOpBuilder *self)
-{
- const ClipStackEntry *head;
-
- g_assert (self->clip_stack);
- g_assert (self->clip_stack->len >= 1);
-
- self->clip_stack->len --;
- head = &g_array_index (self->clip_stack, ClipStackEntry, self->clip_stack->len - 1);
-
- if (self->clip_stack->len >= 1)
- {
- self->current_clip = &head->rect;
- self->clip_is_rectilinear = head->is_rectilinear;
- }
- else
- {
- self->current_clip = NULL;
- self->clip_is_rectilinear = TRUE;
- }
-}
-
-gboolean
-ops_has_clip (RenderOpBuilder *self)
-{
- return self->clip_stack != NULL &&
- self->clip_stack->len > 1;
-}
-
-/**
- * ops_set_modelview:
- * @builder
- * @transform: (transfer full): The new modelview transform
- *
- * This sets the modelview to the given one without looking at the
- * one that's currently set */
-void
-ops_set_modelview (RenderOpBuilder *builder,
- GskTransform *transform)
-{
- MatrixStackEntry *entry;
-
- if (G_UNLIKELY (builder->mv_stack == NULL))
- builder->mv_stack = g_array_new (FALSE, TRUE, sizeof (MatrixStackEntry));
-
- g_assert (builder->mv_stack != NULL);
-
- g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
- entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
-
- entry->transform = transform;
-
- entry->metadata.dx_before = builder->dx;
- entry->metadata.dy_before = builder->dy;
- extract_matrix_metadata (entry->transform, &entry->metadata);
-
- builder->dx = 0;
- builder->dy = 0;
- builder->current_modelview = entry->transform;
- builder->scale_x = entry->metadata.scale_x;
- builder->scale_y = entry->metadata.scale_y;
-}
-
-/* This sets the given modelview to the one we get when multiplying
- * the given modelview with the current one. */
-void
-ops_push_modelview (RenderOpBuilder *builder,
- GskTransform *transform)
-{
- MatrixStackEntry *entry;
-
- if (G_UNLIKELY (builder->mv_stack == NULL))
- builder->mv_stack = g_array_new (FALSE, TRUE, sizeof (MatrixStackEntry));
-
- g_assert (builder->mv_stack != NULL);
-
- g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
- entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
-
- if (G_LIKELY (builder->mv_stack->len >= 2))
- {
- const MatrixStackEntry *cur;
- GskTransform *t = NULL;
-
- cur = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 2);
- /* Multiply given matrix with current modelview */
-
- t = gsk_transform_translate (gsk_transform_ref (cur->transform),
- &(graphene_point_t) { builder->dx, builder->dy});
- t = gsk_transform_transform (t, transform);
- entry->transform = t;
- }
- else
- {
- entry->transform = gsk_transform_ref (transform);
- }
-
- entry->metadata.dx_before = builder->dx;
- entry->metadata.dy_before = builder->dy;
- extract_matrix_metadata (entry->transform, &entry->metadata);
-
- builder->dx = 0;
- builder->dy = 0;
- builder->scale_x = entry->metadata.scale_x;
- builder->scale_y = entry->metadata.scale_y;
- builder->current_modelview = entry->transform;
-}
-
-void
-ops_pop_modelview (RenderOpBuilder *builder)
-{
- const MatrixStackEntry *head;
-
- g_assert (builder->mv_stack);
- g_assert (builder->mv_stack->len >= 1);
-
- head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
- builder->dx = head->metadata.dx_before;
- builder->dy = head->metadata.dy_before;
- gsk_transform_unref (head->transform);
-
- builder->mv_stack->len --;
- head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
-
- if (builder->mv_stack->len >= 1)
- {
- builder->scale_x = head->metadata.scale_x;
- builder->scale_y = head->metadata.scale_y;
- builder->current_modelview = head->transform;
- }
- else
- {
- builder->current_modelview = NULL;
- }
-}
-
-graphene_matrix_t
-ops_set_projection (RenderOpBuilder *builder,
- const graphene_matrix_t *projection)
-{
- graphene_matrix_t prev_mv;
-
- prev_mv = builder->current_projection;
- builder->current_projection = *projection;
-
- return prev_mv;
-}
-
-graphene_rect_t
-ops_set_viewport (RenderOpBuilder *builder,
- const graphene_rect_t *viewport)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- OpViewport *op;
- graphene_rect_t prev_viewport;
-
- if (rect_equal (&builder->current_viewport, viewport))
- return *viewport;
-
- op = ops_begin (builder, OP_CHANGE_VIEWPORT);
- op->viewport = *viewport;
-
- if (current_program_state != NULL)
- current_program_state->viewport = *viewport;
-
- prev_viewport = builder->current_viewport;
- builder->current_viewport = *viewport;
-
- return prev_viewport;
-}
-
-void
-ops_set_texture (RenderOpBuilder *builder,
- int texture_id)
-{
- OpTexture *op;
-
- if (builder->current_texture == texture_id)
- return;
-
- op = ops_begin (builder, OP_CHANGE_SOURCE_TEXTURE);
- op->texture_id = texture_id;
- builder->current_texture = texture_id;
-}
-
-void
-ops_set_extra_texture (RenderOpBuilder *builder,
- int texture_id,
- int idx)
-{
- OpExtraTexture *op;
-
- op = ops_begin (builder, OP_CHANGE_EXTRA_SOURCE_TEXTURE);
- op->texture_id = texture_id;
- op->idx = idx;
-}
-
-int
-ops_set_render_target (RenderOpBuilder *builder,
- int render_target_id)
-{
- OpRenderTarget *op;
- int prev_render_target;
-
- if (builder->current_render_target == render_target_id)
- return render_target_id;
-
- prev_render_target = builder->current_render_target;
-
- if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_RENDER_TARGET)))
- op = op_buffer_add (&builder->render_ops, OP_CHANGE_RENDER_TARGET);
-
- op->render_target_id = render_target_id;
-
- builder->current_render_target = render_target_id;
-
- return prev_render_target;
-}
-
-float
-ops_set_opacity (RenderOpBuilder *builder,
- float opacity)
-{
- float prev_opacity;
-
- if (builder->current_opacity == opacity)
- return opacity;
-
- prev_opacity = builder->current_opacity;
- builder->current_opacity = opacity;
-
- return prev_opacity;
-}
-
-void
-ops_set_color (RenderOpBuilder *builder,
- const GdkRGBA *color)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- OpColor *op;
-
- if (gdk_rgba_equal (color, &current_program_state->color))
- return;
-
- current_program_state->color = *color;
-
- op = ops_begin (builder, OP_CHANGE_COLOR);
- op->rgba = color;
-}
-
-void
-ops_set_gl_shader_args (RenderOpBuilder *builder,
- GskGLShader *shader,
- float width,
- float height,
- const guchar *uniform_data)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- OpGLShader *op;
- gsize args_size = gsk_gl_shader_get_args_size (shader);
-
- if (current_program_state)
- {
- if (current_program_state->gl_shader.width == width &&
- current_program_state->gl_shader.height == height &&
- current_program_state->gl_shader.uniform_data_len == args_size &&
- memcmp (current_program_state->gl_shader.uniform_data, uniform_data, args_size) == 0)
- return;
-
- current_program_state->gl_shader.width = width;
- current_program_state->gl_shader.height = height;
- if (args_size > sizeof (current_program_state->gl_shader.uniform_data))
- current_program_state->gl_shader.uniform_data_len = 0;
- else
- {
- current_program_state->gl_shader.uniform_data_len = args_size;
- memcpy (current_program_state->gl_shader.uniform_data, uniform_data, args_size);
- }
- }
-
- op = ops_begin (builder, OP_CHANGE_GL_SHADER_ARGS);
- op->shader = shader;
- op->size[0] = width;
- op->size[1] = height;
- op->uniform_data = uniform_data;
-}
-
-void
-ops_set_color_matrix (RenderOpBuilder *builder,
- const graphene_matrix_t *matrix,
- const graphene_vec4_t *offset)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- const bool offset_equal = graphene_vec4_equal (offset, &current_program_state->color_matrix.offset);
- const bool matrix_equal = graphene_matrix_equal_fast (matrix,
- &current_program_state->color_matrix.matrix);
- OpColorMatrix *op;
-
- if (offset_equal && matrix_equal)
- return;
-
- op = ops_begin (builder, OP_CHANGE_COLOR_MATRIX);
-
- if (!matrix_equal)
- {
- current_program_state->color_matrix.matrix = *matrix;
- op->matrix.value = matrix;
- op->matrix.send = TRUE;
- }
- else
- op->matrix.send = FALSE;
-
- if (!offset_equal)
- {
- current_program_state->color_matrix.offset = *offset;
- op->offset.value = offset;
- op->offset.send = TRUE;
- }
- else
- op->offset.send = FALSE;
-}
-
-void
-ops_set_border (RenderOpBuilder *builder,
- const GskRoundedRect *outline)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- OpBorder *op;
-
- if (memcmp (&current_program_state->border.outline,
- outline, sizeof (GskRoundedRect)) == 0)
- return;
-
- current_program_state->border.outline = *outline;
-
- op = ops_begin (builder, OP_CHANGE_BORDER);
- op->outline = *outline;
-}
-
-void
-ops_set_border_width (RenderOpBuilder *builder,
- const float *widths)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- OpBorder *op;
-
- g_assert (current_program_state);
-
- if (memcmp (current_program_state->border.widths,
- widths, sizeof (float) * 4) == 0)
- return;
-
- memcpy (&current_program_state->border.widths,
- widths, sizeof (float) * 4);
-
- op = ops_begin (builder, OP_CHANGE_BORDER_WIDTH);
- op->widths[0] = widths[0];
- op->widths[1] = widths[1];
- op->widths[2] = widths[2];
- op->widths[3] = widths[3];
-}
-
-void
-ops_set_border_color (RenderOpBuilder *builder,
- const GdkRGBA *color)
-{
- ProgramState *current_program_state = get_current_program_state (builder);
- OpBorder *op;
-
- if (gdk_rgba_equal (color, &current_program_state->border.color))
- return;
-
- op = op_buffer_add (&builder->render_ops, OP_CHANGE_BORDER_COLOR);
- op->color = color;
-
- current_program_state->border.color = *color;
-}
-
-GskQuadVertex *
-ops_draw (RenderOpBuilder *builder,
- const GskQuadVertex vertex_data[GL_N_VERTICES])
-{
- ProgramState *program_state = get_current_program_state (builder);
- OpDraw *op;
-
- if (memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
- {
- OpMatrix *opm;
-
- opm = ops_begin (builder, OP_CHANGE_PROJECTION);
- opm->matrix = builder->current_projection;
- program_state->projection = builder->current_projection;
- }
-
- if (program_state->modelview == NULL ||
- !gsk_transform_equal (builder->current_modelview, program_state->modelview))
- {
- OpMatrix *opm;
-
- opm = ops_begin (builder, OP_CHANGE_MODELVIEW);
- gsk_transform_to_matrix (builder->current_modelview, &opm->matrix);
- gsk_transform_unref (program_state->modelview);
- program_state->modelview = gsk_transform_ref (builder->current_modelview);
- }
-
- if (!rect_equal (&builder->current_viewport, &program_state->viewport))
- {
- OpViewport *opv;
-
- opv = ops_begin (builder, OP_CHANGE_VIEWPORT);
- opv->viewport = builder->current_viewport;
- program_state->viewport = builder->current_viewport;
- }
-
- if (!rounded_rect_equal (builder->current_clip, &program_state->clip))
- {
- OpClip *opc;
-
- opc = ops_begin (builder, OP_CHANGE_CLIP);
- opc->clip = *builder->current_clip;
- opc->send_corners = !rounded_rect_corners_equal (builder->current_clip, &program_state->clip);
- program_state->clip = *builder->current_clip;
- }
-
- if (program_state->opacity != builder->current_opacity)
- {
- OpOpacity *opo;
-
- opo = ops_begin (builder, OP_CHANGE_OPACITY);
- opo->opacity = builder->current_opacity;
- program_state->opacity = builder->current_opacity;
- }
-
- /* TODO: Did the additions above break the following optimization? */
- if ((op = op_buffer_peek_tail_checked (&builder->render_ops, OP_DRAW)))
- {
- op->vao_size += GL_N_VERTICES;
- }
- else
- {
- op = op_buffer_add (&builder->render_ops, OP_DRAW);
- op->vao_offset = builder->vertices->len;
- op->vao_size = GL_N_VERTICES;
- }
-
- if (vertex_data)
- {
- g_array_append_vals (builder->vertices, vertex_data, GL_N_VERTICES);
- return NULL; /* Better not use this on the caller side */
- }
-
- g_array_set_size (builder->vertices, builder->vertices->len + GL_N_VERTICES);
- return &g_array_index (builder->vertices, GskQuadVertex, builder->vertices->len - GL_N_VERTICES);
-}
-
-/* The offset is only valid for the current modelview.
- * Setting a new modelview will add the offset to that matrix
- * and reset the internal offset to 0. */
-void
-ops_offset (RenderOpBuilder *builder,
- float x,
- float y)
-{
- builder->dx += x;
- builder->dy += y;
-}
-
-gpointer
-ops_begin (RenderOpBuilder *builder,
- OpKind kind)
-{
- return op_buffer_add (&builder->render_ops, kind);
-}
-
-void
-ops_reset (RenderOpBuilder *builder)
-{
- op_buffer_clear (&builder->render_ops);
- g_array_set_size (builder->vertices, 0);
-}
-
-OpBuffer *
-ops_get_buffer (RenderOpBuilder *builder)
-{
- return &builder->render_ops;
-}
-
-void
-ops_set_inset_shadow (RenderOpBuilder *self,
- const GskRoundedRect outline,
- float spread,
- const GdkRGBA *color,
- float dx,
- float dy)
-{
- ProgramState *current_program_state = get_current_program_state (self);
- OpShadow *op;
-
- g_assert (current_program_state);
-
- op = ops_begin (self, OP_CHANGE_INSET_SHADOW);
-
- if (!rounded_rect_equal (&outline, &current_program_state->inset_shadow.outline))
- {
- op->outline.value = outline;
- op->outline.send = TRUE;
- op->outline.send_corners = !rounded_rect_corners_equal (&current_program_state->inset_shadow.outline,
- &outline);
- current_program_state->inset_shadow.outline = outline;
- }
- else
- op->outline.send = FALSE;
-
- if (spread != current_program_state->inset_shadow.spread)
- {
- op->spread.value = spread;
- op->spread.send = TRUE;
-
- current_program_state->inset_shadow.spread = spread;
- }
- else
- op->spread.send = FALSE;
-
- if (!gdk_rgba_equal (color, &current_program_state->inset_shadow.color))
- {
- op->color.value = color;
- op->color.send = TRUE;
-
- current_program_state->inset_shadow.color = *color;
- }
- else
- op->color.send = FALSE;
-
- if (dx != current_program_state->inset_shadow.dx ||
- dy != current_program_state->inset_shadow.dy)
- {
- op->offset.value[0] = dx;
- op->offset.value[1] = dy;
- op->offset.send = TRUE;
-
- current_program_state->inset_shadow.dx = dx;
- current_program_state->inset_shadow.dy = dy;
- }
- else
- op->offset.send = FALSE;
-
- if (!op->outline.send &&
- !op->spread.send &&
- !op->offset.send &&
- !op->color.send)
- {
- op_buffer_pop_tail (&self->render_ops);
- }
-}
-void
-ops_set_unblurred_outset_shadow (RenderOpBuilder *self,
- const GskRoundedRect outline,
- float spread,
- const GdkRGBA *color,
- float dx,
- float dy)
-{
- ProgramState *current_program_state = get_current_program_state (self);
- OpShadow *op;
-
- g_assert (current_program_state);
-
- op = ops_begin (self, OP_CHANGE_UNBLURRED_OUTSET_SHADOW);
-
- if (!rounded_rect_equal (&outline, &current_program_state->unblurred_outset_shadow.outline))
- {
- op->outline.value = outline;
- op->outline.send = TRUE;
- op->outline.send_corners = !rounded_rect_corners_equal (&current_program_state->unblurred_outset_shadow.outline,
- &outline);
- current_program_state->unblurred_outset_shadow.outline = outline;
- }
- else
- op->outline.send = FALSE;
-
- if (spread != current_program_state->unblurred_outset_shadow.spread)
- {
- op->spread.value = spread;
- op->spread.send = TRUE;
-
- current_program_state->unblurred_outset_shadow.spread = spread;
- }
- else
- op->spread.send = FALSE;
-
- if (!gdk_rgba_equal (color, &current_program_state->unblurred_outset_shadow.color))
- {
- op->color.value = color;
- op->color.send = TRUE;
-
- current_program_state->unblurred_outset_shadow.color = *color;
- }
- else
- op->color.send = FALSE;
-
- if (dx != current_program_state->unblurred_outset_shadow.dx ||
- dy != current_program_state->unblurred_outset_shadow.dy)
- {
- op->offset.value[0] = dx;
- op->offset.value[1] = dy;
- op->offset.send = TRUE;
-
- current_program_state->unblurred_outset_shadow.dx = dx;
- current_program_state->unblurred_outset_shadow.dy = dy;
- }
- else
- op->offset.send = FALSE;
-}
-
-void
-ops_set_linear_gradient (RenderOpBuilder *self,
- guint n_color_stops,
- const GskColorStop *color_stops,
- gboolean repeat,
- float start_x,
- float start_y,
- float end_x,
- float end_y)
-{
- ProgramState *current_program_state = get_current_program_state (self);
- OpLinearGradient *op;
- const guint real_n_color_stops = MIN (GL_MAX_GRADIENT_STOPS, n_color_stops);
-
- g_assert (current_program_state);
-
- op = ops_begin (self, OP_CHANGE_LINEAR_GRADIENT);
-
- /* We always save the n_color_stops value in the op so the renderer can use it in
- * cases where we send the color stops, but not n_color_stops */
- op->n_color_stops.value = real_n_color_stops;
- if (current_program_state->linear_gradient.n_color_stops != real_n_color_stops)
- {
- op->n_color_stops.send = TRUE;
- current_program_state->linear_gradient.n_color_stops = real_n_color_stops;
- }
- else
- op->n_color_stops.send = FALSE;
-
- op->color_stops.send = FALSE;
- if (!op->n_color_stops.send)
- {
- g_assert (current_program_state->linear_gradient.n_color_stops == real_n_color_stops);
-
- for (guint i = 0; i < real_n_color_stops; i ++)
- {
- const GskColorStop *s1 = &color_stops[i];
- const GskColorStop *s2 = &current_program_state->linear_gradient.color_stops[i];
-
- if (s1->offset != s2->offset ||
- !gdk_rgba_equal (&s1->color, &s2->color))
- {
- op->color_stops.send = TRUE;
- break;
- }
- }
- }
- else
- op->color_stops.send = TRUE;
-
- if (op->color_stops.send)
- {
- op->color_stops.value = color_stops;
- memcpy (&current_program_state->linear_gradient.color_stops,
- color_stops,
- sizeof (GskColorStop) * real_n_color_stops);
- }
-
- op->repeat = repeat;
- op->start_point[0] = start_x;
- op->start_point[1] = start_y;
- op->end_point[0] = end_x;
- op->end_point[1] = end_y;
-}
-
-void
-ops_set_radial_gradient (RenderOpBuilder *self,
- guint n_color_stops,
- const GskColorStop *color_stops,
- gboolean repeat,
- float center_x,
- float center_y,
- float start,
- float end,
- float hradius,
- float vradius)
-{
- const guint real_n_color_stops = MIN (GL_MAX_GRADIENT_STOPS, n_color_stops);
- OpRadialGradient *op;
-
- /* TODO: State tracking? */
-
- op = ops_begin (self, OP_CHANGE_RADIAL_GRADIENT);
- op->n_color_stops.value = real_n_color_stops;
- op->n_color_stops.send = true;
- op->color_stops.value = color_stops;
- op->color_stops.send = true;
- op->center[0] = center_x;
- op->center[1] = center_y;
- op->radius[0] = hradius;
- op->radius[1] = vradius;
- op->start = start;
- op->end = end;
- op->repeat = repeat;
-}
-
-void
-ops_set_conic_gradient (RenderOpBuilder *self,
- guint n_color_stops,
- const GskColorStop *color_stops,
- float center_x,
- float center_y,
- float angle)
-{
- const guint real_n_color_stops = MIN (GL_MAX_GRADIENT_STOPS, n_color_stops);
- OpConicGradient *op;
-
- /* TODO: State tracking? */
-
- op = ops_begin (self, OP_CHANGE_CONIC_GRADIENT);
- op->n_color_stops.value = real_n_color_stops;
- op->n_color_stops.send = true;
- op->color_stops.value = color_stops;
- op->color_stops.send = true;
- op->center[0] = center_x;
- op->center[1] = center_y;
- op->angle = angle;
-}
-
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
deleted file mode 100644
index 551a1afc05..0000000000
--- a/gsk/gl/gskglrenderopsprivate.h
+++ /dev/null
@@ -1,353 +0,0 @@
-#ifndef __GSK_GL_RENDER_OPS_H__
-#define __GSK_GL_RENDER_OPS_H__
-
-#include <glib.h>
-#include <graphene.h>
-#include <gdk/gdk.h>
-
-#include "gskgldriverprivate.h"
-#include "gskroundedrectprivate.h"
-#include "gskglrenderer.h"
-#include "gskrendernodeprivate.h"
-
-#include "opbuffer.h"
-
-#define GL_N_VERTICES 6
-#define GL_N_PROGRAMS 15
-#define GL_MAX_GRADIENT_STOPS 6
-
-typedef struct
-{
- float scale_x;
- float scale_y;
-
- float dx_before;
- float dy_before;
-} OpsMatrixMetadata;
-
-typedef struct
-{
- GskTransform *transform;
- OpsMatrixMetadata metadata;
-} MatrixStackEntry;
-
-typedef struct
-{
- GskTransform *modelview;
- GskRoundedRect clip;
- graphene_matrix_t projection;
- int source_texture;
- graphene_rect_t viewport;
- float opacity;
- /* Per-program state */
- union {
- GdkRGBA color;
- struct {
- graphene_matrix_t matrix;
- graphene_vec4_t offset;
- } color_matrix;
- struct {
- float widths[4];
- GdkRGBA color;
- GskRoundedRect outline;
- } border;
- struct {
- GskRoundedRect outline;
- float dx;
- float dy;
- float spread;
- GdkRGBA color;
- } inset_shadow;
- struct {
- GskRoundedRect outline;
- float dx;
- float dy;
- float spread;
- GdkRGBA color;
- } unblurred_outset_shadow;
- struct {
- int n_color_stops;
- GskColorStop color_stops[GL_MAX_GRADIENT_STOPS];
- float start_point[2];
- float end_point[2];
- } linear_gradient;
- struct {
- int n_color_stops;
- GskColorStop color_stops[GL_MAX_GRADIENT_STOPS];
- float center[2];
- float start;
- float end;
- float radius[2]; /* h/v */
- } radial_gradient;
- struct {
- float width;
- float height;
- int uniform_data_len;
- guchar uniform_data[32];
- } gl_shader;
- };
-} ProgramState;
-
-struct _Program
-{
- const char *name;
-
- int index; /* Into the renderer's program array -1 for custom */
-
- int id;
- /* Common locations (gl_common)*/
- int source_location;
- int position_location;
- int uv_location;
- int alpha_location;
- int viewport_location;
- int projection_location;
- int modelview_location;
- int clip_rect_location;
- union {
- struct {
- int color_location;
- } color;
- struct {
- int color_location;
- } coloring;
- struct {
- int color_matrix_location;
- int color_offset_location;
- } color_matrix;
- struct {
- int num_color_stops_location;
- int color_stops_location;
- int points_location;
- int repeat_location;
- } linear_gradient;
- struct {
- int num_color_stops_location;
- int color_stops_location;
- int geometry_location;
- int range_location;
- int repeat_location;
- } radial_gradient;
- struct {
- int num_color_stops_location;
- int color_stops_location;
- int geometry_location;
- } conic_gradient;
- struct {
- int blur_radius_location;
- int blur_size_location;
- int blur_dir_location;
- } blur;
- struct {
- int color_location;
- int spread_location;
- int offset_location;
- int outline_rect_location;
- } inset_shadow;
- struct {
- int color_location;
- int outline_rect_location;
- } outset_shadow;
- struct {
- int outline_rect_location;
- int color_location;
- int spread_location;
- int offset_location;
- } unblurred_outset_shadow;
- struct {
- int color_location;
- int widths_location;
- int outline_rect_location;
- } border;
- struct {
- int source2_location;
- int progress_location;
- } cross_fade;
- struct {
- int source2_location;
- int mode_location;
- } blend;
- struct {
- int child_bounds_location;
- int texture_rect_location;
- } repeat;
- struct {
- int size_location;
- int args_locations[8];
- int texture_locations[4];
- GError *compile_error;
- } glshader;
- };
- ProgramState state;
-};
-
-typedef struct {
- int ref_count;
- union {
- Program programs[GL_N_PROGRAMS];
- struct {
- Program blend_program;
- Program blit_program;
- Program blur_program;
- Program border_program;
- Program color_matrix_program;
- Program color_program;
- Program coloring_program;
- Program cross_fade_program;
- Program inset_shadow_program;
- Program linear_gradient_program;
- Program radial_gradient_program;
- Program conic_gradient_program;
- Program outset_shadow_program;
- Program repeat_program;
- Program unblurred_outset_shadow_program;
- };
- };
- GHashTable *custom_programs; /* GskGLShader -> Program* */
-} GskGLRendererPrograms;
-
-typedef struct
-{
- GskGLRendererPrograms *programs;
- Program *current_program;
- int current_render_target;
- int current_texture;
-
- graphene_matrix_t current_projection;
- graphene_rect_t current_viewport;
- float current_opacity;
- float dx, dy;
- float scale_x, scale_y;
-
- OpBuffer render_ops;
- GArray *vertices;
-
- GskGLRenderer *renderer;
-
- /* Stack of modelview matrices */
- GArray *mv_stack;
- GskTransform *current_modelview;
-
- /* Same thing */
- GArray *clip_stack;
- /* Pointer into clip_stack */
- const GskRoundedRect *current_clip;
- bool clip_is_rectilinear;
-} RenderOpBuilder;
-
-
-void ops_dump_framebuffer (RenderOpBuilder *builder,
- const char *filename,
- int width,
- int height);
-void ops_init (RenderOpBuilder *builder);
-void ops_free (RenderOpBuilder *builder);
-void ops_reset (RenderOpBuilder *builder);
-void ops_push_debug_group (RenderOpBuilder *builder,
- const char *text);
-void ops_pop_debug_group (RenderOpBuilder *builder);
-
-void ops_finish (RenderOpBuilder *builder);
-void ops_push_modelview (RenderOpBuilder *builder,
- GskTransform *transform);
-void ops_set_modelview (RenderOpBuilder *builder,
- GskTransform *transform);
-void ops_pop_modelview (RenderOpBuilder *builder);
-void ops_set_program (RenderOpBuilder *builder,
- Program *program);
-
-void ops_push_clip (RenderOpBuilder *builder,
- const GskRoundedRect *clip);
-void ops_pop_clip (RenderOpBuilder *builder);
-gboolean ops_has_clip (RenderOpBuilder *builder);
-
-void ops_transform_bounds_modelview (const RenderOpBuilder *builder,
- const graphene_rect_t *src,
- graphene_rect_t *dst);
-
-graphene_matrix_t ops_set_projection (RenderOpBuilder *builder,
- const graphene_matrix_t *projection);
-
-graphene_rect_t ops_set_viewport (RenderOpBuilder *builder,
- const graphene_rect_t *viewport);
-
-void ops_set_texture (RenderOpBuilder *builder,
- int texture_id);
-void ops_set_extra_texture (RenderOpBuilder *builder,
- int texture_id,
- int idx);
-
-int ops_set_render_target (RenderOpBuilder *builder,
- int render_target_id);
-
-float ops_set_opacity (RenderOpBuilder *builder,
- float opacity);
-void ops_set_color (RenderOpBuilder *builder,
- const GdkRGBA *color);
-
-void ops_set_color_matrix (RenderOpBuilder *builder,
- const graphene_matrix_t *matrix,
- const graphene_vec4_t *offset);
-
-void ops_set_border (RenderOpBuilder *builder,
- const GskRoundedRect *outline);
-void ops_set_border_width (RenderOpBuilder *builder,
- const float *widths);
-
-void ops_set_border_color (RenderOpBuilder *builder,
- const GdkRGBA *color);
-void ops_set_inset_shadow (RenderOpBuilder *self,
- const GskRoundedRect outline,
- float spread,
- const GdkRGBA *color,
- float dx,
- float dy);
-void ops_set_gl_shader_args (RenderOpBuilder *builder,
- GskGLShader *shader,
- float width,
- float height,
- const guchar *uniform_data);
-void ops_set_unblurred_outset_shadow (RenderOpBuilder *self,
- const GskRoundedRect outline,
- float spread,
- const GdkRGBA *color,
- float dx,
- float dy);
-
-void ops_set_linear_gradient (RenderOpBuilder *self,
- guint n_color_stops,
- const GskColorStop *color_stops,
- gboolean repeat,
- float start_x,
- float start_y,
- float end_x,
- float end_y);
-void ops_set_radial_gradient (RenderOpBuilder *self,
- guint n_color_stops,
- const GskColorStop *color_stops,
- gboolean repeat,
- float center_x,
- float center_y,
- float start,
- float end,
- float hradius,
- float vradius);
-void ops_set_conic_gradient (RenderOpBuilder *self,
- guint n_color_stops,
- const GskColorStop *color_stops,
- float center_x,
- float center_y,
- float angle);
-
-GskQuadVertex * ops_draw (RenderOpBuilder *builder,
- const GskQuadVertex vertex_data[GL_N_VERTICES]);
-
-void ops_offset (RenderOpBuilder *builder,
- float x,
- float y);
-
-gpointer ops_begin (RenderOpBuilder *builder,
- OpKind kind);
-OpBuffer *ops_get_buffer (RenderOpBuilder *builder);
-
-#endif
diff --git a/gsk/gl/gskglshaderbuilder.c b/gsk/gl/gskglshaderbuilder.c
deleted file mode 100644
index d16ad4feb5..0000000000
--- a/gsk/gl/gskglshaderbuilder.c
+++ /dev/null
@@ -1,271 +0,0 @@
-#include "config.h"
-
-#include "gskglshaderbuilderprivate.h"
-
-#include "gskdebugprivate.h"
-
-#include <gdk/gdk.h>
-#include <epoxy/gl.h>
-
-void
-gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
- const char *common_preamble_resource_path,
- const char *vs_preamble_resource_path,
- const char *fs_preamble_resource_path)
-{
- memset (self, 0, sizeof (*self));
-
- self->preamble = g_resources_lookup_data (common_preamble_resource_path, 0, NULL);
- self->vs_preamble = g_resources_lookup_data (vs_preamble_resource_path, 0, NULL);
- self->fs_preamble = g_resources_lookup_data (fs_preamble_resource_path, 0, NULL);
-
- g_assert (self->preamble);
- g_assert (self->vs_preamble);
- g_assert (self->fs_preamble);
-}
-
-void
-gsk_gl_shader_builder_finish (GskGLShaderBuilder *self)
-{
- g_bytes_unref (self->preamble);
- g_bytes_unref (self->vs_preamble);
- g_bytes_unref (self->fs_preamble);
-}
-
-void
-gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
- int version)
-{
- self->version = version;
-}
-
-static void
-prepend_line_numbers (char *code,
- GString *s)
-{
- char *p;
- int line;
-
- p = code;
- line = 1;
- while (*p)
- {
- char *end = strchr (p, '\n');
- if (end)
- end = end + 1; /* Include newline */
- else
- end = p + strlen (p);
-
- g_string_append_printf (s, "%3d| ", line++);
- g_string_append_len (s, p, end - p);
-
- p = end;
- }
-}
-
-static gboolean
-check_shader_error (int shader_id,
- int shader_type,
- const char *resource_path,
- GError **error)
-{
- int status;
- int log_len;
- char *buffer;
- int code_len;
- char *code;
- GString *s;
-
- glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
-
- if (G_LIKELY (status == GL_TRUE))
- return TRUE;
-
- glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &log_len);
- buffer = g_malloc0 (log_len + 1);
- glGetShaderInfoLog (shader_id, log_len, NULL, buffer);
-
- glGetShaderiv (shader_id, GL_SHADER_SOURCE_LENGTH, &code_len);
- code = g_malloc0 (code_len + 1);
- glGetShaderSource (shader_id, code_len, NULL, code);
-
- s = g_string_new ("");
- prepend_line_numbers (code, s);
-
- g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_COMPILATION_FAILED,
- "Compilation failure in %s shader %s.\nSource Code:\n%s\n\nError Message:\n%s\n\n",
- (shader_type == GL_FRAGMENT_SHADER ? "fragment" : "vertex"),
- resource_path,
- s->str,
- buffer);
-
- g_string_free (s, TRUE);
- g_free (buffer);
- g_free (code);
-
- return FALSE;
-}
-
-static void
-print_shader_info (const char *prefix,
- int shader_id,
- const char *resource_path)
-{
- if (GSK_DEBUG_CHECK(SHADERS))
- {
- int code_len;
- char *code;
- GString *s;
-
- glGetShaderiv (shader_id, GL_SHADER_SOURCE_LENGTH, &code_len);
- code = g_malloc0 (code_len + 1);
- glGetShaderSource (shader_id, code_len, NULL, code);
-
- s = g_string_new ("");
- prepend_line_numbers (code, s);
-
- g_message ("%s %d, %s:\n%s", prefix, shader_id, resource_path, s->str);
- g_string_free (s, TRUE);
- g_free (code);
- }
-}
-
-int
-gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
- const char *resource_path,
- const char *extra_fragment_snippet,
- gsize extra_fragment_length,
- GError **error)
-{
-
- GBytes *source_bytes = g_resources_lookup_data (resource_path, 0, NULL);
- char version_buffer[64];
- const char *source;
- const char *vertex_shader_start;
- const char *fragment_shader_start;
- int vertex_id;
- int fragment_id;
- int program_id = -1;
- int status;
-
- g_assert (source_bytes);
-
- source = g_bytes_get_data (source_bytes, NULL);
- vertex_shader_start = strstr (source, "VERTEX_SHADER");
- fragment_shader_start = strstr (source, "FRAGMENT_SHADER");
-
- g_assert (vertex_shader_start);
- g_assert (fragment_shader_start);
-
- /* They both start at the next newline */
- vertex_shader_start = strstr (vertex_shader_start, "\n");
- fragment_shader_start = strstr (fragment_shader_start, "\n");
-
- g_snprintf (version_buffer, sizeof (version_buffer),
- "#version %d\n", self->version);
-
- vertex_id = glCreateShader (GL_VERTEX_SHADER);
- glShaderSource (vertex_id, 8,
- (const char *[]) {
- version_buffer,
- self->debugging ? "#define GSK_DEBUG 1\n" : "",
- self->legacy ? "#define GSK_LEGACY 1\n" : "",
- self->gl3 ? "#define GSK_GL3 1\n" : "",
- self->gles ? "#define GSK_GLES 1\n" : "",
- g_bytes_get_data (self->preamble, NULL),
- g_bytes_get_data (self->vs_preamble, NULL),
- vertex_shader_start
- },
- (int[]) {
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- fragment_shader_start - vertex_shader_start
- });
- glCompileShader (vertex_id);
-
- if (!check_shader_error (vertex_id, GL_VERTEX_SHADER, resource_path, error))
- {
- glDeleteShader (vertex_id);
- goto out;
- }
-
- print_shader_info ("Vertex shader", vertex_id, resource_path);
-
- fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
- glShaderSource (fragment_id, 9,
- (const char *[]) {
- version_buffer,
- self->debugging ? "#define GSK_DEBUG 1\n" : "",
- self->legacy ? "#define GSK_LEGACY 1\n" : "",
- self->gl3 ? "#define GSK_GL3 1\n" : "",
- self->gles ? "#define GSK_GLES 1\n" : "",
- g_bytes_get_data (self->preamble, NULL),
- g_bytes_get_data (self->fs_preamble, NULL),
- fragment_shader_start,
- extra_fragment_snippet ? extra_fragment_snippet : ""
- },
- (int[]) {
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- -1,
- extra_fragment_length,
- });
- glCompileShader (fragment_id);
-
- if (!check_shader_error (fragment_id, GL_FRAGMENT_SHADER, resource_path, error))
- {
- glDeleteShader (fragment_id);
- goto out;
- }
-
- print_shader_info ("Fragment shader", fragment_id, resource_path);
-
- program_id = glCreateProgram ();
- glAttachShader (program_id, vertex_id);
- glAttachShader (program_id, fragment_id);
- glBindAttribLocation (program_id, 0, "aPosition");
- glBindAttribLocation (program_id, 1, "aUv");
- glLinkProgram (program_id);
- glDetachShader (program_id, vertex_id);
- glDetachShader (program_id, fragment_id);
-
- glGetProgramiv (program_id, GL_LINK_STATUS, &status);
- if (status == GL_FALSE)
- {
- char *buffer = NULL;
- int log_len = 0;
-
- glGetProgramiv (program_id, GL_INFO_LOG_LENGTH, &log_len);
-
- buffer = g_malloc0 (log_len + 1);
- glGetProgramInfoLog (program_id, log_len, NULL, buffer);
-
- g_warning ("Linking failure in shader:\n%s", buffer);
- g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_LINK_FAILED,
- "Linking failure in shader: %s", buffer);
-
- g_free (buffer);
-
- glDeleteProgram (program_id);
- program_id = -1;
- }
-
- glDeleteShader (vertex_id);
- glDeleteShader (fragment_id);
-
-out:
- g_bytes_unref (source_bytes);
-
- return program_id;
-}
-
diff --git a/gsk/gl/gskglshaderbuilderprivate.h b/gsk/gl/gskglshaderbuilderprivate.h
deleted file mode 100644
index 870df050d0..0000000000
--- a/gsk/gl/gskglshaderbuilderprivate.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __GSK_SHADER_BUILDER_PRIVATE_H__
-#define __GSK_SHADER_BUILDER_PRIVATE_H__
-
-#include <gdk/gdk.h>
-#include <graphene.h>
-
-G_BEGIN_DECLS
-
-typedef struct
-{
- GBytes *preamble;
- GBytes *vs_preamble;
- GBytes *fs_preamble;
-
- int version;
-
- guint debugging: 1;
- guint gles: 1;
- guint gl3: 1;
- guint legacy: 1;
-
-} GskGLShaderBuilder;
-
-
-void gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
- const char *common_preamble_resource_path,
- const char *vs_preamble_resource_path,
- const char *fs_preamble_resource_path);
-void gsk_gl_shader_builder_finish (GskGLShaderBuilder *self);
-
-void gsk_gl_shader_builder_set_glsl_version (GskGLShaderBuilder *self,
- int version);
-
-int gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
- const char *resource_path,
- const char *extra_fragment_snippet,
- gsize extra_fragment_length,
- GError **error);
-
-G_END_DECLS
-
-#endif /* __GSK_SHADER_BUILDER_PRIVATE_H__ */
diff --git a/gsk/gl/gskglshadowcache.c b/gsk/gl/gskglshadowcache.c
deleted file mode 100644
index a0eeef904d..0000000000
--- a/gsk/gl/gskglshadowcache.c
+++ /dev/null
@@ -1,141 +0,0 @@
-
-#include "gskglshadowcacheprivate.h"
-
-#define MAX_UNUSED_FRAMES (16 * 5)
-
-typedef struct
-{
- GskRoundedRect outline;
- float blur_radius;
-} CacheKey;
-
-typedef struct
-{
- GskRoundedRect outline;
- float blur_radius;
-
- int texture_id;
- int unused_frames;
-} CacheItem;
-
-static gboolean
-key_equal (const void *x,
- const void *y)
-{
- const CacheKey *a = x;
- const CacheKey *b = y;
-
- return a->blur_radius == b->blur_radius &&
- graphene_size_equal (&a->outline.corner[0], &b->outline.corner[0]) &&
- graphene_size_equal (&a->outline.corner[1], &b->outline.corner[1]) &&
- graphene_size_equal (&a->outline.corner[2], &b->outline.corner[2]) &&
- graphene_size_equal (&a->outline.corner[3], &b->outline.corner[3]) &&
- graphene_rect_equal (&a->outline.bounds, &b->outline.bounds);
-}
-
-void
-gsk_gl_shadow_cache_init (GskGLShadowCache *self)
-{
- self->textures = g_array_new (FALSE, TRUE, sizeof (CacheItem));
-}
-
-void
-gsk_gl_shadow_cache_free (GskGLShadowCache *self,
- GskGLDriver *gl_driver)
-{
- guint i, p;
-
- for (i = 0, p = self->textures->len; i < p; i ++)
- {
- const CacheItem *item = &g_array_index (self->textures, CacheItem, i);
-
- gsk_gl_driver_destroy_texture (gl_driver, item->texture_id);
- }
-
- g_array_free (self->textures, TRUE);
- self->textures = NULL;
-}
-
-void
-gsk_gl_shadow_cache_begin_frame (GskGLShadowCache *self,
- GskGLDriver *gl_driver)
-{
- guint i, p;
-
- for (i = 0, p = self->textures->len; i < p; i ++)
- {
- CacheItem *item = &g_array_index (self->textures, CacheItem, i);
-
- if (item->unused_frames > MAX_UNUSED_FRAMES)
- {
- gsk_gl_driver_destroy_texture (gl_driver, item->texture_id);
- g_array_remove_index_fast (self->textures, i);
- p --;
- i --;
- }
- else
- {
- item->unused_frames ++;
- }
- }
-}
-
-/* XXX
- * The offset origin should always be at 0/0, or the blur radius should just go
- * away since it defines the origin position anyway?
- */
-int
-gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache *self,
- GskGLDriver *gl_driver,
- const GskRoundedRect *shadow_rect,
- float blur_radius)
-{
- CacheItem *item= NULL;
- guint i;
-
- g_assert (self != NULL);
- g_assert (gl_driver != NULL);
- g_assert (shadow_rect != NULL);
-
- for (i = 0; i < self->textures->len; i ++)
- {
- CacheItem *k = &g_array_index (self->textures, CacheItem, i);
-
- if (key_equal (&(CacheKey){*shadow_rect, blur_radius},
- &(CacheKey){k->outline, k->blur_radius}))
- {
- item = k;
- break;
- }
- }
-
- if (item == NULL)
- return 0;
-
- item->unused_frames = 0;
-
- g_assert (item->texture_id != 0);
-
- return item->texture_id;
-}
-
-void
-gsk_gl_shadow_cache_commit (GskGLShadowCache *self,
- const GskRoundedRect *shadow_rect,
- float blur_radius,
- int texture_id)
-{
- CacheItem *item;
-
- g_assert (self != NULL);
- g_assert (shadow_rect != NULL);
- g_assert (texture_id > 0);
-
- g_array_set_size (self->textures, self->textures->len + 1);
- item = &g_array_index (self->textures, CacheItem, self->textures->len - 1);
-
- item->outline = *shadow_rect;
- item->blur_radius = blur_radius;
- item->unused_frames = 0;
- item->texture_id = texture_id;
-}
diff --git a/gsk/gl/gskglshadowcacheprivate.h b/gsk/gl/gskglshadowcacheprivate.h
deleted file mode 100644
index 6623f16235..0000000000
--- a/gsk/gl/gskglshadowcacheprivate.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-#ifndef __GSK_GL_SHADOW_CACHE_H__
-#define __GSK_GL_SHADOW_CACHE_H__
-
-#include <glib.h>
-#include "gskgldriverprivate.h"
-#include "gskroundedrect.h"
-
-typedef struct
-{
- GArray *textures;
-} GskGLShadowCache;
-
-
-void gsk_gl_shadow_cache_init (GskGLShadowCache *self);
-void gsk_gl_shadow_cache_free (GskGLShadowCache *self,
- GskGLDriver *gl_driver);
-void gsk_gl_shadow_cache_begin_frame (GskGLShadowCache *self,
- GskGLDriver *gl_driver);
-int gsk_gl_shadow_cache_get_texture_id (GskGLShadowCache *self,
- GskGLDriver *gl_driver,
- const GskRoundedRect *shadow_rect,
- float blur_radius);
-void gsk_gl_shadow_cache_commit (GskGLShadowCache *self,
- const GskRoundedRect *shadow_rect,
- float blur_radius,
- int texture_id);
-
-
-#endif
diff --git a/gsk/gl/gskgltextureatlas.c b/gsk/gl/gskgltextureatlas.c
deleted file mode 100644
index 9db2d8e262..0000000000
--- a/gsk/gl/gskgltextureatlas.c
+++ /dev/null
@@ -1,309 +0,0 @@
-
-#include "config.h"
-#include "gskgltextureatlasprivate.h"
-#include "gskdebugprivate.h"
-#include "gdkglcontextprivate.h"
-#include <epoxy/gl.h>
-
-#define ATLAS_SIZE (512)
-#define MAX_OLD_RATIO 0.5
-
-static void
-free_atlas (gpointer v)
-{
- GskGLTextureAtlas *atlas = v;
-
- gsk_gl_texture_atlas_free (atlas);
-
- g_free (atlas);
-}
-
-GskGLTextureAtlases *
-gsk_gl_texture_atlases_new (void)
-{
- GskGLTextureAtlases *self;
-
- self = g_new (GskGLTextureAtlases, 1);
- self->atlases = g_ptr_array_new_with_free_func (free_atlas);
-
- self->ref_count = 1;
-
- return self;
-}
-
-GskGLTextureAtlases *
-gsk_gl_texture_atlases_ref (GskGLTextureAtlases *self)
-{
- self->ref_count++;
-
- return self;
-}
-
-void
-gsk_gl_texture_atlases_unref (GskGLTextureAtlases *self)
-{
- g_assert (self->ref_count > 0);
-
- if (self->ref_count == 1)
- {
- g_ptr_array_unref (self->atlases);
- g_free (self);
- return;
- }
-
- self->ref_count--;
-}
-
-#if 0
-static void
-write_atlas_to_png (GskGLTextureAtlas *atlas,
- const char *filename)
-{
- int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, atlas->width);
- guchar *data = g_malloc (atlas->height * stride);
- cairo_surface_t *s;
-
- glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
- glGetTexImage (GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
- s = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, atlas->width, atlas->height, stride);
- cairo_surface_write_to_png (s, filename);
-
- cairo_surface_destroy (s);
- g_free (data);
-}
-#endif
-
-void
-gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *self,
- GPtrArray *removed)
-{
- int i;
-
- for (i = self->atlases->len - 1; i >= 0; i--)
- {
- GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i);
-
- if (gsk_gl_texture_atlas_get_unused_ratio (atlas) > MAX_OLD_RATIO)
- {
- GSK_NOTE(GLYPH_CACHE,
- g_message ("Dropping atlas %d (%g.2%% old)", i,
- 100.0 * gsk_gl_texture_atlas_get_unused_ratio (atlas)));
-
- if (atlas->texture_id != 0)
- {
- glDeleteTextures (1, &atlas->texture_id);
- atlas->texture_id = 0;
- }
-
- g_ptr_array_add (removed, atlas);
- g_ptr_array_remove_index (self->atlases, i);
- }
- }
-
- GSK_NOTE(GLYPH_CACHE, {
- static guint timestamp;
- if (timestamp++ % 60 == 0)
- g_message ("%d atlases", self->atlases->len);
- });
-
-
-#if 0
- {
- static guint timestamp;
-
- timestamp++;
- if (timestamp % 10 == 0)
- for (i = 0; i < self->atlases->len; i++)
- {
- GskGLTextureAtlas *atlas = g_ptr_array_index (self->atlases, i);
-
- if (atlas->texture_id)
- {
- char *filename;
-
- filename = g_strdup_printf ("textureatlas%d-%u.png", i, timestamp);
- write_atlas_to_png (atlas, filename);
- g_free (filename);
- }
- }
- }
-#endif
-}
-
-gboolean
-gsk_gl_texture_atlases_pack (GskGLTextureAtlases *self,
- int width,
- int height,
- GskGLTextureAtlas **atlas_out,
- int *out_x,
- int *out_y)
-{
- GskGLTextureAtlas *atlas;
- int x, y;
- int i;
-
- g_assert (width < ATLAS_SIZE);
- g_assert (height < ATLAS_SIZE);
-
- atlas = NULL;
-
- for (i = 0; i < self->atlases->len; i++)
- {
- atlas = g_ptr_array_index (self->atlases, i);
-
- if (gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
- break;
-
- atlas = NULL;
- }
-
- if (atlas == NULL)
- {
- /* No atlas has enough space, so create a new one... */
- atlas = g_malloc (sizeof (GskGLTextureAtlas));
- gsk_gl_texture_atlas_init (atlas, ATLAS_SIZE, ATLAS_SIZE);
- gsk_gl_texture_atlas_realize (atlas);
- g_ptr_array_add (self->atlases, atlas);
-
- /* Pack it onto that one, which surely has enough space... */
- if (!gsk_gl_texture_atlas_pack (atlas, width, height, &x, &y))
- g_assert_not_reached ();
-
- GSK_NOTE(GLYPH_CACHE, g_message ("adding new atlas"));
- }
-
- *atlas_out = atlas;
- *out_x = x;
- *out_y = y;
-
- return TRUE;
-}
-
-void
-gsk_gl_texture_atlas_init (GskGLTextureAtlas *self,
- int width,
- int height)
-{
- memset (self, 0, sizeof (*self));
-
- self->texture_id = 0;
- self->width = width;
- self->height = height;
-
- /* TODO: We might want to change the strategy about the amount of
- * nodes here? stb_rect_pack.h says with is optimal. */
- self->nodes = g_malloc0 (sizeof (struct stbrp_node) * width);
- stbrp_init_target (&self->context,
- width, height,
- self->nodes,
- width);
-
- gsk_gl_texture_atlas_realize (self);
-}
-
-void
-gsk_gl_texture_atlas_free (GskGLTextureAtlas *self)
-{
- if (self->texture_id != 0)
- {
- glDeleteTextures (1, &self->texture_id);
- self->texture_id = 0;
- }
-
- g_clear_pointer (&self->nodes, g_free);
-}
-
-void
-gsk_gl_texture_atlas_mark_unused (GskGLTextureAtlas *self,
- int width,
- int height)
-{
- self->unused_pixels += (width * height);
-}
-
-
-void
-gsk_gl_texture_atlas_mark_used (GskGLTextureAtlas *self,
- int width,
- int height)
-{
- self->unused_pixels -= (width * height);
-
- g_assert (self->unused_pixels >= 0);
-}
-
-gboolean
-gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self,
- int width,
- int height,
- int *out_x,
- int *out_y)
-{
- stbrp_rect rect;
-
- g_assert (out_x);
- g_assert (out_y);
-
- rect.w = width;
- rect.h = height;
-
- stbrp_pack_rects (&self->context, &rect, 1);
-
- if (rect.was_packed)
- {
- *out_x = rect.x;
- *out_y = rect.y;
- }
-
- return rect.was_packed;
-}
-
-double
-gsk_gl_texture_atlas_get_unused_ratio (const GskGLTextureAtlas *self)
-{
- if (self->unused_pixels > 0)
- return (double)(self->unused_pixels) / (double)(self->width * self->height);
-
- return 0.0;
-}
-
-/* Not using gdk_gl_driver_create_texture here, since we want
- * this texture to survive the driver and stay around until
- * the display gets closed.
- */
-static guint
-create_shared_texture (int width,
- int height)
-{
- guint texture_id;
-
- glGenTextures (1, &texture_id);
- glBindTexture (GL_TEXTURE_2D, texture_id);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- else
- glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
-
- glBindTexture (GL_TEXTURE_2D, 0);
-
- return texture_id;
-}
-
-void
-gsk_gl_texture_atlas_realize (GskGLTextureAtlas *atlas)
-{
- if (atlas->texture_id)
- return;
-
- atlas->texture_id = create_shared_texture (atlas->width, atlas->height);
- gdk_gl_context_label_object_printf (gdk_gl_context_get_current (),
- GL_TEXTURE, atlas->texture_id,
- "Texture atlas %d", atlas->texture_id);
-}
diff --git a/gsk/gl/gskgltextureatlasprivate.h b/gsk/gl/gskgltextureatlasprivate.h
deleted file mode 100644
index fc4f0365c0..0000000000
--- a/gsk/gl/gskgltextureatlasprivate.h
+++ /dev/null
@@ -1,72 +0,0 @@
-
-#ifndef __GSK_GL_TEXTURE_ATLAS_H__
-#define __GSK_GL_TEXTURE_ATLAS_H__
-
-#include "stb_rect_pack.h"
-#include "gskglimageprivate.h"
-#include "gskgldriverprivate.h"
-
-struct _GskGLTextureAtlas
-{
- struct stbrp_context context;
- struct stbrp_node *nodes;
-
- int width;
- int height;
-
- guint texture_id;
-
- int unused_pixels; /* Pixels of rects that have been used at some point,
- But are now unused. */
-
- void *user_data;
-};
-typedef struct _GskGLTextureAtlas GskGLTextureAtlas;
-
-struct _GskGLTextureAtlases
-{
- int ref_count;
-
- GPtrArray *atlases;
-};
-typedef struct _GskGLTextureAtlases GskGLTextureAtlases;
-
-GskGLTextureAtlases *gsk_gl_texture_atlases_new (void);
-GskGLTextureAtlases *gsk_gl_texture_atlases_ref (GskGLTextureAtlases *atlases);
-void gsk_gl_texture_atlases_unref (GskGLTextureAtlases *atlases);
-
-void gsk_gl_texture_atlases_begin_frame (GskGLTextureAtlases *atlases,
- GPtrArray *removed);
-gboolean gsk_gl_texture_atlases_pack (GskGLTextureAtlases *atlases,
- int width,
- int height,
- GskGLTextureAtlas **atlas_out,
- int *out_x,
- int *out_y);
-
-void gsk_gl_texture_atlas_init (GskGLTextureAtlas *self,
- int width,
- int height);
-
-void gsk_gl_texture_atlas_free (GskGLTextureAtlas *self);
-
-void gsk_gl_texture_atlas_realize (GskGLTextureAtlas *self);
-
-void gsk_gl_texture_atlas_mark_unused (GskGLTextureAtlas *self,
- int width,
- int height);
-
-void gsk_gl_texture_atlas_mark_used (GskGLTextureAtlas *self,
- int width,
- int height);
-
-
-gboolean gsk_gl_texture_atlas_pack (GskGLTextureAtlas *self,
- int width,
- int height,
- int *out_x,
- int *out_y);
-
-double gsk_gl_texture_atlas_get_unused_ratio (const GskGLTextureAtlas *self);
-
-#endif
diff --git a/gsk/gl/opbuffer.c b/gsk/gl/opbuffer.c
deleted file mode 100644
index 806b8f7ca4..0000000000
--- a/gsk/gl/opbuffer.c
+++ /dev/null
@@ -1,137 +0,0 @@
-#include "opbuffer.h"
-
-#include <string.h>
-
-static guint op_sizes[OP_LAST] = {
- 0,
- sizeof (OpOpacity),
- sizeof (OpColor),
- sizeof (OpMatrix),
- sizeof (OpMatrix),
- sizeof (OpProgram),
- sizeof (OpRenderTarget),
- sizeof (OpClip),
- sizeof (OpViewport),
- sizeof (OpTexture),
- sizeof (OpRepeat),
- sizeof (OpLinearGradient),
- sizeof (OpRadialGradient),
- sizeof (OpColorMatrix),
- sizeof (OpBlur),
- sizeof (OpShadow),
- sizeof (OpOutsetShadow),
- sizeof (OpBorder),
- sizeof (OpBorder),
- sizeof (OpBorder),
- sizeof (OpCrossFade),
- sizeof (OpShadow),
- 0,
- sizeof (OpDraw),
- sizeof (OpDumpFrameBuffer),
- sizeof (OpDebugGroup),
- 0,
- sizeof (OpBlend),
- sizeof (OpGLShader),
- sizeof (OpExtraTexture),
- sizeof (OpConicGradient),
-};
-
-void
-op_buffer_init (OpBuffer *buffer)
-{
- static gsize initialized = FALSE;
-
- if (g_once_init_enter (&initialized))
- {
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (op_sizes); i++)
- {
- guint size = op_sizes[i];
-
- if (size > 0)
- {
- /* Round all op entry sizes to the nearest 16 to ensure
- * that we guarantee proper alignments for all op entries.
- * This is only done once on first use.
- */
-#define CHECK_SIZE(s) else if (size < (s)) { size = s; }
- if (0) {}
- CHECK_SIZE (16)
- CHECK_SIZE (32)
- CHECK_SIZE (48)
- CHECK_SIZE (64)
- CHECK_SIZE (80)
- CHECK_SIZE (96)
- CHECK_SIZE (112)
- CHECK_SIZE (128)
- CHECK_SIZE (144)
- CHECK_SIZE (160)
- CHECK_SIZE (176)
- CHECK_SIZE (192)
- else g_assert_not_reached ();
-#undef CHECK_SIZE
-
- op_sizes[i] = size;
- }
- }
-
- g_once_init_leave (&initialized, TRUE);
- }
-
- memset (buffer, 0, sizeof *buffer);
-
- buffer->buflen = 4096;
- buffer->bufpos = 0;
- buffer->buf = g_malloc (buffer->buflen);
- buffer->index = g_array_new (FALSE, FALSE, sizeof (OpBufferEntry));
-
- /* Add dummy entry to guarantee non-empty index */
- op_buffer_add (buffer, OP_NONE);
-}
-
-void
-op_buffer_destroy (OpBuffer *buffer)
-{
- g_free (buffer->buf);
- g_array_unref (buffer->index);
-}
-
-void
-op_buffer_clear (OpBuffer *buffer)
-{
- if (buffer->index->len > 1)
- g_array_remove_range (buffer->index, 1, buffer->index->len - 1);
- buffer->bufpos = 0;
-}
-
-static inline void
-ensure_buffer_space_for (OpBuffer *buffer,
- guint size)
-{
- if G_UNLIKELY (buffer->bufpos + size >= buffer->buflen)
- {
- buffer->buflen *= 2;
- buffer->buf = g_realloc (buffer->buf, buffer->buflen);
- }
-}
-
-gpointer
-op_buffer_add (OpBuffer *buffer,
- OpKind kind)
-{
- guint size = op_sizes[kind];
- OpBufferEntry entry;
-
- entry.pos = buffer->bufpos;
- entry.kind = kind;
-
- if (size > 0)
- ensure_buffer_space_for (buffer, size);
-
- g_array_append_val (buffer->index, entry);
-
- buffer->bufpos += size;
-
- return &buffer->buf[entry.pos];
-}
diff --git a/gsk/gl/opbuffer.h b/gsk/gl/opbuffer.h
deleted file mode 100644
index ea954249c5..0000000000
--- a/gsk/gl/opbuffer.h
+++ /dev/null
@@ -1,306 +0,0 @@
-#ifndef __OP_BUFFER_H__
-#define __OP_BUFFER_H__
-
-#include <gdk/gdk.h>
-#include <gsk/gsk.h>
-#include <graphene.h>
-
-#include "gskgldriverprivate.h"
-
-typedef struct _Program Program;
-
-typedef enum
-{
- OP_NONE = 0,
- OP_CHANGE_OPACITY = 1,
- OP_CHANGE_COLOR = 2,
- OP_CHANGE_PROJECTION = 3,
- OP_CHANGE_MODELVIEW = 4,
- OP_CHANGE_PROGRAM = 5,
- OP_CHANGE_RENDER_TARGET = 6,
- OP_CHANGE_CLIP = 7,
- OP_CHANGE_VIEWPORT = 8,
- OP_CHANGE_SOURCE_TEXTURE = 9,
- OP_CHANGE_REPEAT = 10,
- OP_CHANGE_LINEAR_GRADIENT = 11,
- OP_CHANGE_RADIAL_GRADIENT = 12,
- OP_CHANGE_COLOR_MATRIX = 13,
- OP_CHANGE_BLUR = 14,
- OP_CHANGE_INSET_SHADOW = 15,
- OP_CHANGE_OUTSET_SHADOW = 16,
- OP_CHANGE_BORDER = 17,
- OP_CHANGE_BORDER_COLOR = 18,
- OP_CHANGE_BORDER_WIDTH = 19,
- OP_CHANGE_CROSS_FADE = 20,
- OP_CHANGE_UNBLURRED_OUTSET_SHADOW = 21,
- OP_CLEAR = 22,
- OP_DRAW = 23,
- OP_DUMP_FRAMEBUFFER = 24,
- OP_PUSH_DEBUG_GROUP = 25,
- OP_POP_DEBUG_GROUP = 26,
- OP_CHANGE_BLEND = 27,
- OP_CHANGE_GL_SHADER_ARGS = 28,
- OP_CHANGE_EXTRA_SOURCE_TEXTURE = 29,
- OP_CHANGE_CONIC_GRADIENT = 30,
- OP_LAST
-} OpKind;
-
-
-typedef struct { int value; guint send: 1; } IntUniformValue;
-typedef struct { float value; guint send: 1; } FloatUniformValue;
-typedef struct { float value[2]; guint send: 1; } Float2UniformValue;
-typedef struct { GskRoundedRect value; guint send: 1; guint send_corners: 1; } RRUniformValue;
-typedef struct { const GdkRGBA *value; guint send: 1; } RGBAUniformValue;
-typedef struct { const graphene_vec4_t *value; guint send: 1; } Vec4UniformValue;
-typedef struct { const GskColorStop *value; guint send: 1; } ColorStopUniformValue;
-typedef struct { const graphene_matrix_t *value; guint send: 1; } MatrixUniformValue;
-
-/* OpNode are allocated within OpBuffer.pos, but we keep
- * a secondary index into the locations of that buffer
- * from OpBuffer.index. This allows peeking at the kind
- * and quickly replacing existing entries when necessary.
- */
-typedef struct
-{
- RRUniformValue outline;
- FloatUniformValue spread;
- Float2UniformValue offset;
- RGBAUniformValue color;
-} OpShadow;
-
-typedef struct
-{
- RRUniformValue outline;
-} OpOutsetShadow;
-
-typedef struct
-{
- guint pos;
- OpKind kind;
-} OpBufferEntry;
-
-typedef struct
-{
- guint8 *buf;
- gsize buflen;
- gsize bufpos;
- GArray *index;
-} OpBuffer;
-
-typedef struct
-{
- float opacity;
-} OpOpacity;
-
-typedef struct
-{
- graphene_matrix_t matrix;
-} OpMatrix;
-
-typedef struct
-{
- const Program *program;
-} OpProgram;
-
-typedef struct
-{
- const GdkRGBA *rgba;
-} OpColor;
-
-typedef struct
-{
- int render_target_id;
-} OpRenderTarget;
-
-typedef struct
-{
- GskRoundedRect clip;
- guint send_corners: 1;
-} OpClip;
-
-typedef struct
-{
- graphene_rect_t viewport;
-} OpViewport;
-
-typedef struct
-{
- int texture_id;
-} OpTexture;
-
-typedef struct
-{
- int texture_id;
- int idx;
-} OpExtraTexture;
-
-typedef struct
-{
- gsize vao_offset;
- gsize vao_size;
-} OpDraw;
-
-typedef struct
-{
- ColorStopUniformValue color_stops;
- IntUniformValue n_color_stops;
- float start_point[2];
- float end_point[2];
- gboolean repeat;
-} OpLinearGradient;
-
-typedef struct
-{
- ColorStopUniformValue color_stops;
- IntUniformValue n_color_stops;
- float start;
- float end;
- float radius[2];
- float center[2];
- gboolean repeat;
-} OpRadialGradient;
-
-typedef struct
-{
- ColorStopUniformValue color_stops;
- IntUniformValue n_color_stops;
- float center[2];
- float angle;
-} OpConicGradient;
-
-typedef struct
-{
- MatrixUniformValue matrix;
- Vec4UniformValue offset;
-} OpColorMatrix;
-
-typedef struct
-{
- float radius;
- graphene_size_t size;
- float dir[2];
-} OpBlur;
-
-typedef struct
-{
- float widths[4];
- const GdkRGBA *color;
- GskRoundedRect outline;
-} OpBorder;
-
-typedef struct
-{
- float progress;
- int source2;
-} OpCrossFade;
-
-typedef struct
-{
- char *filename;
- int width;
- int height;
-} OpDumpFrameBuffer;
-
-typedef struct
-{
- char text[64];
-} OpDebugGroup;
-
-typedef struct
-{
- int source2;
- int mode;
-} OpBlend;
-
-typedef struct
-{
- float child_bounds[4];
- float texture_rect[4];
-} OpRepeat;
-
-typedef struct
-{
- float size[2];
- GskGLShader *shader;
- const guchar *uniform_data;
-} OpGLShader;
-
-void op_buffer_init (OpBuffer *buffer);
-void op_buffer_destroy (OpBuffer *buffer);
-void op_buffer_clear (OpBuffer *buffer);
-gpointer op_buffer_add (OpBuffer *buffer,
- OpKind kind);
-
-typedef struct
-{
- GArray *index;
- OpBuffer *buffer;
- guint pos;
-} OpBufferIter;
-
-static inline void
-op_buffer_iter_init (OpBufferIter *iter,
- OpBuffer *buffer)
-{
- iter->index = buffer->index;
- iter->buffer = buffer;
- iter->pos = 1; /* Skip first OP_NONE */
-}
-
-static inline gpointer
-op_buffer_iter_next (OpBufferIter *iter,
- OpKind *kind)
-{
- const OpBufferEntry *entry;
-
- if (iter->pos == iter->index->len)
- return NULL;
-
- entry = &g_array_index (iter->index, OpBufferEntry, iter->pos);
-
- iter->pos++;
-
- *kind = entry->kind;
- return &iter->buffer->buf[entry->pos];
-}
-
-static inline void
-op_buffer_pop_tail (OpBuffer *buffer)
-{
- /* Never truncate the first OP_NONE */
- if G_LIKELY (buffer->index->len > 0)
- buffer->index->len--;
-}
-
-static inline gpointer
-op_buffer_peek_tail (OpBuffer *buffer,
- OpKind *kind)
-{
- const OpBufferEntry *entry;
-
- entry = &g_array_index (buffer->index, OpBufferEntry, buffer->index->len - 1);
- *kind = entry->kind;
- return &buffer->buf[entry->pos];
-}
-
-static inline gpointer
-op_buffer_peek_tail_checked (OpBuffer *buffer,
- OpKind kind)
-{
- const OpBufferEntry *entry;
-
- entry = &g_array_index (buffer->index, OpBufferEntry, buffer->index->len - 1);
-
- if (entry->kind == kind)
- return &buffer->buf[entry->pos];
-
- return NULL;
-}
-
-static inline guint
-op_buffer_n_ops (OpBuffer *buffer)
-{
- return buffer->index->len - 1;
-}
-
-#endif /* __OP_BUFFER_H__ */
diff --git a/gsk/gl/resources/blend.glsl b/gsk/gl/resources/blend.glsl
deleted file mode 100644
index 22323402ac..0000000000
--- a/gsk/gl/resources/blend.glsl
+++ /dev/null
@@ -1,310 +0,0 @@
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform int u_mode;
-uniform sampler2D u_source2;
-
-float
-combine (float source, float backdrop)
-{
- return source + backdrop * (1.0 - source);
-}
-
-vec4
-composite (vec4 Cs, vec4 Cb, vec3 B)
-{
- float ao = Cs.a + Cb.a * (1.0 - Cs.a);
- vec3 Co = (Cs.a*(1.0 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1.0 - Cs.a)*Cb.a*Cb.rgb) / ao;
- return vec4(Co, ao);
-}
-
-vec4
-normal (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb);
-}
-
-vec4
-multiply (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb * Cb.rgb);
-}
-
-vec4
-difference (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb));
-}
-
-vec4
-screen (vec4 Cs, vec4 Cb)
-{
- return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb);
-}
-
-float
-hard_light (float source, float backdrop)
-{
- if (source <= 0.5)
- return 2.0 * backdrop * source;
- else
- return 2.0 * (backdrop + source - backdrop * source) - 1.0;
-}
-
-vec4
-hard_light (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (hard_light (Cs.r, Cb.r),
- hard_light (Cs.g, Cb.g),
- hard_light (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-float
-soft_light (float source, float backdrop)
-{
- float db;
-
- if (backdrop <= 0.25)
- db = ((16.0 * backdrop - 12.0) * backdrop + 4.0) * backdrop;
- else
- db = sqrt (backdrop);
-
- if (source <= 0.5)
- return backdrop - (1.0 - 2.0 * source) * backdrop * (1.0 - backdrop);
- else
- return backdrop + (2.0 * source - 1.0) * (db - backdrop);
-}
-
-vec4
-soft_light (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (soft_light (Cs.r, Cb.r),
- soft_light (Cs.g, Cb.g),
- soft_light (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-overlay (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (hard_light (Cb.r, Cs.r),
- hard_light (Cb.g, Cs.g),
- hard_light (Cb.b, Cs.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-darken (vec4 Cs, vec4 Cb)
-{
- vec3 B = min (Cs.rgb, Cb.rgb);
- return composite (Cs, Cb, B);
-}
-
-vec4
-lighten (vec4 Cs, vec4 Cb)
-{
- vec3 B = max (Cs.rgb, Cb.rgb);
- return composite (Cs, Cb, B);
-}
-
-float
-color_dodge (float source, float backdrop)
-{
- return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0);
-}
-
-vec4
-color_dodge (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (color_dodge (Cs.r, Cb.r),
- color_dodge (Cs.g, Cb.g),
- color_dodge (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-
-float
-color_burn (float source, float backdrop)
-{
- return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0);
-}
-
-vec4
-color_burn (vec4 Cs, vec4 Cb)
-{
- vec3 B = vec3 (color_burn (Cs.r, Cb.r),
- color_burn (Cs.g, Cb.g),
- color_burn (Cs.b, Cb.b));
- return composite (Cs, Cb, B);
-}
-
-vec4
-exclusion (vec4 Cs, vec4 Cb)
-{
- vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb;
- return composite (Cs, Cb, B);
-}
-
-float
-lum (vec3 c)
-{
- return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
-}
-
-vec3
-clip_color (vec3 c)
-{
- float l = lum (c);
- float n = min (c.r, min (c.g, c.b));
- float x = max (c.r, max (c.g, c.b));
- if (n < 0.0) c = l + (((c - l) * l) / (l - n));
- if (x > 1.0) c = l + (((c - l) * (1.0 - l)) / (x - l));
- return c;
-}
-
-vec3
-set_lum (vec3 c, float l)
-{
- float d = l - lum (c);
- return clip_color (vec3 (c.r + d, c.g + d, c.b + d));
-}
-
-float
-sat (vec3 c)
-{
- return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b));
-}
-
-vec3
-set_sat (vec3 c, float s)
-{
- float cmin = min (c.r, min (c.g, c.b));
- float cmax = max (c.r, max (c.g, c.b));
- vec3 res;
-
- if (cmax == cmin)
- res = vec3 (0, 0, 0);
- else
- {
- if (c.r == cmax)
- {
- if (c.g == cmin)
- {
- res.b = ((c.b - cmin) * s) / (cmax - cmin);
- res.g = 0.0;
- }
- else
- {
- res.g = ((c.g - cmin) * s) / (cmax - cmin);
- res.b = 0.0;
- }
- res.r = s;
- }
- else if (c.g == cmax)
- {
- if (c.r == cmin)
- {
- res.b = ((c.b - cmin) * s) / (cmax - cmin);
- res.r = 0.0;
- }
- else
- {
- res.r = ((c.r - cmin) * s) / (cmax - cmin);
- res.b = 0.0;
- }
- res.g = s;
- }
- else
- {
- if (c.r == cmin)
- {
- res.g = ((c.g - cmin) * s) / (cmax - cmin);
- res.r = 0.0;
- }
- else
- {
- res.r = ((c.r - cmin) * s) / (cmax - cmin);
- res.g = 0.0;
- }
- res.b = s;
- }
- }
- return res;
-}
-
-vec4
-color (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (Cs.rgb, lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-hue (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-saturation (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb));
- return composite (Cs, Cb, B);
-}
-
-vec4
-luminosity (vec4 Cs, vec4 Cb)
-{
- vec3 B = set_lum (Cb.rgb, lum (Cs.rgb));
- return composite (Cs, Cb, B);
-}
-
-void main() {
- vec4 bottom_color = GskTexture(u_source, vUv);
- vec4 top_color = GskTexture(u_source2, vUv);
-
- vec4 result;
- if (u_mode == 0)
- result = normal(top_color, bottom_color);
- else if (u_mode == 1)
- result = multiply(top_color, bottom_color);
- else if (u_mode == 2)
- result = screen(top_color, bottom_color);
- else if (u_mode == 3)
- result = overlay(top_color, bottom_color);
- else if (u_mode == 4)
- result = darken(top_color, bottom_color);
- else if (u_mode == 5)
- result = lighten(top_color, bottom_color);
- else if (u_mode == 6)
- result = color_dodge(top_color, bottom_color);
- else if (u_mode == 7)
- result = color_burn(top_color, bottom_color);
- else if (u_mode == 8)
- result = hard_light(top_color, bottom_color);
- else if (u_mode == 9)
- result = soft_light(top_color, bottom_color);
- else if (u_mode == 10)
- result = difference(top_color, bottom_color);
- else if (u_mode == 11)
- result = exclusion(top_color, bottom_color);
- else if (u_mode == 12)
- result = color(top_color, bottom_color);
- else if (u_mode == 13)
- result = hue(top_color, bottom_color);
- else if (u_mode == 14)
- result = saturation(top_color, bottom_color);
- else if (u_mode == 15)
- result = luminosity(top_color, bottom_color);
- else
- discard;
-
- gskSetOutputColor(result * u_alpha);
-}
diff --git a/gsk/gl/resources/blit.glsl b/gsk/gl/resources/blit.glsl
deleted file mode 100644
index f01cd238ec..0000000000
--- a/gsk/gl/resources/blit.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-void main() {
- vec4 diffuse = GskTexture(u_source, vUv);
-
- gskSetOutputColor(diffuse * u_alpha);
-}
diff --git a/gsk/gl/resources/blur.glsl b/gsk/gl/resources/blur.glsl
deleted file mode 100644
index f782ab48cc..0000000000
--- a/gsk/gl/resources/blur.glsl
+++ /dev/null
@@ -1,55 +0,0 @@
-// VERTEX_SHADER:
-uniform float u_blur_radius;
-uniform vec2 u_blur_size;
-uniform vec2 u_blur_dir;
-
-_OUT_ vec2 pixel_step;
-_OUT_ float pixels_per_side;
-_OUT_ vec3 initial_gaussian;
-
-const float PI = 3.14159265;
-const float RADIUS_MULTIPLIER = 2.0;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-
- pixel_step = (vec2(1.0) / u_blur_size) * u_blur_dir;
- pixels_per_side = floor(u_blur_radius * RADIUS_MULTIPLIER / 2.0);
-
- float sigma = u_blur_radius / 2.0; // *shrug*
- initial_gaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);
- initial_gaussian.y = exp(-0.5 / (sigma * sigma));
- initial_gaussian.z = initial_gaussian.y * initial_gaussian.y;
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec2 pixel_step;
-_IN_ float pixels_per_side;
-_IN_ vec3 initial_gaussian;
-
-// blur_radius 0 is NOT supported and MUST be caught before.
-
-// Partially from http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html
-void main() {
- vec3 incrementalGaussian = initial_gaussian;
-
- float coefficientSum = 0.0;
- vec4 sum = GskTexture(u_source, vUv) * incrementalGaussian.x;
- coefficientSum += incrementalGaussian.x;
- incrementalGaussian.xy *= incrementalGaussian.yz;
-
- vec2 p = pixel_step;
- for (int i = 1; i <= int(pixels_per_side); i++) {
- sum += GskTexture(u_source, vUv - p) * incrementalGaussian.x;
- sum += GskTexture(u_source, vUv + p) * incrementalGaussian.x;
-
- coefficientSum += 2.0 * incrementalGaussian.x;
- incrementalGaussian.xy *= incrementalGaussian.yz;
-
- p += pixel_step;
- }
-
- gskSetOutputColor(sum / coefficientSum);
-}
diff --git a/gsk/gl/resources/border.glsl b/gsk/gl/resources/border.glsl
deleted file mode 100644
index 677a0df7cd..0000000000
--- a/gsk/gl/resources/border.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform vec4 u_widths;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect outside = gsk_create_rect(u_outline_rect);
- GskRoundedRect inside = gsk_rounded_rect_shrink (outside, u_widths);
-
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
-
- gsk_rounded_rect_encode(outside, transformed_outside_outline);
- gsk_rounded_rect_encode(inside, transformed_inside_outline);
-}
-
-// FRAGMENT_SHADER:
-uniform vec4[3] u_outline_rect;
-
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
- gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
- 0.0, 1.0);
-
- gskSetOutputColor(final_color * alpha);
-}
diff --git a/gsk/gl/resources/color.glsl b/gsk/gl/resources/color.glsl
deleted file mode 100644
index 636456ce0d..0000000000
--- a/gsk/gl/resources/color.glsl
+++ /dev/null
@@ -1,18 +0,0 @@
-// VERTEX_SHADER:
-uniform vec4 u_color;
-
-_OUT_ vec4 final_color;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-
-void main() {
- gskSetOutputColor(final_color);
-}
-
diff --git a/gsk/gl/resources/color_matrix.glsl b/gsk/gl/resources/color_matrix.glsl
deleted file mode 100644
index 79cb36434e..0000000000
--- a/gsk/gl/resources/color_matrix.glsl
+++ /dev/null
@@ -1,25 +0,0 @@
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform mat4 u_color_matrix;
-uniform vec4 u_color_offset;
-
-void main() {
- vec4 color = GskTexture(u_source, vUv);
-
- // Un-premultilpy
- if (color.a != 0.0)
- color.rgb /= color.a;
-
- color = u_color_matrix * color + u_color_offset;
- color = clamp(color, 0.0, 1.0);
-
- color.rgb *= color.a;
-
- gskSetOutputColor(color * u_alpha);
-}
diff --git a/gsk/gl/resources/coloring.glsl b/gsk/gl/resources/coloring.glsl
deleted file mode 100644
index a675493030..0000000000
--- a/gsk/gl/resources/coloring.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// VERTEX_SHADER:
-uniform vec4 u_color;
-
-_OUT_ vec4 final_color;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-}
-
-// FRAGMENT_SHADER:
-
-_IN_ vec4 final_color;
-
-void main() {
- vec4 diffuse = GskTexture(u_source, vUv);
-
- gskSetOutputColor(final_color * diffuse.a);
-}
diff --git a/gsk/gl/resources/conic_gradient.glsl b/gsk/gl/resources/conic_gradient.glsl
deleted file mode 100644
index 630a42c5e6..0000000000
--- a/gsk/gl/resources/conic_gradient.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-// VERTEX_SHADER
-uniform vec4 u_geometry;
-
-_NOPERSPECTIVE_ _OUT_ vec2 coord;
-
-void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
-
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
- vec2 offset = aPosition - u_geometry.xy;
-
- coord = vec2(dot(mv0, offset),
- dot(mv1, offset));
-}
-
-// FRAGMENT_SHADER:
-#ifdef GSK_LEGACY
-uniform int u_num_color_stops;
-#else
-uniform highp int u_num_color_stops; // Why? Because it works like this.
-#endif
-
-uniform vec4 u_geometry;
-uniform float u_color_stops[6 * 5];
-
-_NOPERSPECTIVE_ _IN_ vec2 coord;
-
-float get_offset(int index) {
- return u_color_stops[5 * index];
-}
-
-vec4 get_color(int index) {
- int base = 5 * index + 1;
-
- return vec4(u_color_stops[base],
- u_color_stops[base + 1],
- u_color_stops[base + 2],
- u_color_stops[base + 3]);
-}
-
-void main() {
- // direction of point in range [-PI, PI]
- vec2 pos = floor(coord);
- float angle = atan(pos.y, pos.x);
-
- // fract() does the modulo here, so now we have progress
- // into the current conic
- float offset = fract(angle * u_geometry.z + u_geometry.w);
-
- if (offset < get_offset(0)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
- return;
- }
-
- int n = u_num_color_stops - 1;
- for (int i = 0; i < n; i++) {
- float curr_offset = get_offset(i);
- float next_offset = get_offset(i + 1);
-
- if (offset >= curr_offset && offset < next_offset) {
- float f = (offset - curr_offset) / (next_offset - curr_offset);
- vec4 curr_color = gsk_premultiply(get_color(i));
- vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
-
- gskSetOutputColor(color * u_alpha);
- return;
- }
- }
-
- gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
-}
diff --git a/gsk/gl/resources/cross_fade.glsl b/gsk/gl/resources/cross_fade.glsl
deleted file mode 100644
index f824430f9d..0000000000
--- a/gsk/gl/resources/cross_fade.glsl
+++ /dev/null
@@ -1,20 +0,0 @@
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform float u_progress;
-uniform sampler2D u_source2;
-
-void main() {
- vec4 source1 = GskTexture(u_source, vUv); // start child
- vec4 source2 = GskTexture(u_source2, vUv); // end child
-
- float p_start = (1.0 - u_progress) * u_alpha;
- float p_end = u_progress * u_alpha;
- vec4 color = (p_start * source1) + (p_end * source2);
- gskSetOutputColor(color);
-}
diff --git a/gsk/gl/resources/custom.glsl b/gsk/gl/resources/custom.glsl
deleted file mode 100644
index d2aed97fc8..0000000000
--- a/gsk/gl/resources/custom.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-// The shader supplies:
-void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv);
-
-uniform vec2 u_size;
-uniform sampler2D u_source2;
-uniform sampler2D u_source3;
-uniform sampler2D u_source4;
-
-void main() {
- vec4 fragColor;
- vec2 fragCoord = vec2(vUv.x * u_size.x, (1.0-vUv.y) * u_size.y);
- mainImage(fragColor, fragCoord, u_size, vUv);
- gskSetOutputColor(fragColor);
-}
diff --git a/gsk/gl/resources/inset_shadow.glsl b/gsk/gl/resources/inset_shadow.glsl
deleted file mode 100644
index 9a21cdef09..0000000000
--- a/gsk/gl/resources/inset_shadow.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform float u_spread;
-uniform vec2 u_offset;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect outside = gsk_create_rect(u_outline_rect);
- GskRoundedRect inside = gsk_rounded_rect_shrink(outside, vec4(u_spread));
-
- gsk_rounded_rect_offset(inside, u_offset);
-
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
-
- gsk_rounded_rect_encode(outside, transformed_outside_outline);
- gsk_rounded_rect_encode(inside, transformed_inside_outline);
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
- gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
- 0.0, 1.0);
-
- gskSetOutputColor(final_color * alpha);
-}
diff --git a/gsk/gl/resources/linear_gradient.glsl b/gsk/gl/resources/linear_gradient.glsl
deleted file mode 100644
index cc90392c06..0000000000
--- a/gsk/gl/resources/linear_gradient.glsl
+++ /dev/null
@@ -1,95 +0,0 @@
-// VERTEX_SHADER
-uniform vec4 u_points;
-
-_NOPERSPECTIVE_ _OUT_ vec4 info;
-
-void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
-
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
- vec2 offset = aPosition - u_points.xy;
- vec2 coord = vec2(dot(mv0, offset),
- dot(mv1, offset));
-
- // Original equation:
- // VS | maxDist = length(end - start);
- // VS | gradient = end - start;
- // VS | gradientLength = length(gradient);
- // FS | pos = frag_coord - start
- // FS | proj = (dot(gradient, pos) / (gradientLength * gradientLength)) * gradient
- // FS | offset = length(proj) / maxDist
-
- // Simplified formula derivation:
- // 1. Notice that maxDist = gradientLength:
- // offset = length(proj) / gradientLength
- // 2. Let gnorm = gradient / gradientLength, then:
- // proj = (dot(gnorm * gradientLength, pos) / (gradientLength * gradientLength)) * (gnorm * gradientLength) =
- // = dot(gnorm, pos) * gnorm
- // 3. Since gnorm is unit length then:
- // length(proj) = length(dot(gnorm, pos) * gnorm) = dot(gnorm, pos)
- // 4. We can avoid the FS division by passing a scaled pos from the VS:
- // offset = dot(gnorm, pos) / gradientLength = dot(gnorm, pos / gradientLength)
- // 5. 1.0 / length(gradient) is inversesqrt(dot(gradient, gradient)) in GLSL
- vec2 gradient = vec2(dot(mv0, u_points.zw),
- dot(mv1, u_points.zw));
- float rcp_gradient_length = inversesqrt(dot(gradient, gradient));
-
- info = rcp_gradient_length * vec4(coord, gradient);
-}
-
-// FRAGMENT_SHADER:
-#ifdef GSK_LEGACY
-uniform int u_num_color_stops;
-#else
-uniform highp int u_num_color_stops; // Why? Because it works like this.
-#endif
-
-uniform float u_color_stops[6 * 5];
-uniform bool u_repeat;
-
-_NOPERSPECTIVE_ _IN_ vec4 info;
-
-float get_offset(int index) {
- return u_color_stops[5 * index];
-}
-
-vec4 get_color(int index) {
- int base = 5 * index + 1;
-
- return vec4(u_color_stops[base],
- u_color_stops[base + 1],
- u_color_stops[base + 2],
- u_color_stops[base + 3]);
-}
-
-void main() {
- float offset = dot(info.xy, info.zw);
-
- if (u_repeat) {
- offset = fract(offset);
- }
-
- if (offset < get_offset(0)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
- return;
- }
-
- int n = u_num_color_stops - 1;
- for (int i = 0; i < n; i++) {
- float curr_offset = get_offset(i);
- float next_offset = get_offset(i + 1);
-
- if (offset >= curr_offset && offset < next_offset) {
- float f = (offset - curr_offset) / (next_offset - curr_offset);
- vec4 curr_color = gsk_premultiply(get_color(i));
- vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
-
- gskSetOutputColor(color * u_alpha);
- return;
- }
- }
-
- gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
-}
diff --git a/gsk/gl/resources/outset_shadow.glsl b/gsk/gl/resources/outset_shadow.glsl
deleted file mode 100644
index 373c650179..0000000000
--- a/gsk/gl/resources/outset_shadow.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect outline = gsk_create_rect(u_outline_rect);
- gsk_rounded_rect_transform(outline, u_modelview);
- gsk_rounded_rect_encode(outline, transformed_outline);
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = GskTexture(u_source, vUv).a;
- alpha *= (1.0 - clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outline), frag), 0.0, 1.0));
-
- vec4 color = final_color * alpha;
-
- gskSetOutputColor(color);
-}
diff --git a/gsk/gl/resources/preamble.fs.glsl b/gsk/gl/resources/preamble.fs.glsl
deleted file mode 100644
index 3a2fe49240..0000000000
--- a/gsk/gl/resources/preamble.fs.glsl
+++ /dev/null
@@ -1,139 +0,0 @@
-uniform sampler2D u_source;
-uniform mat4 u_projection;
-uniform mat4 u_modelview;
-uniform float u_alpha;// = 1.0;
-uniform vec4 u_viewport;
-uniform vec4[3] u_clip_rect;
-
-#if defined(GSK_LEGACY)
-_OUT_ vec4 outputColor;
-#elif !defined(GSK_GLES)
-_OUT_ vec4 outputColor;
-#endif
-
-_IN_ vec2 vUv;
-
-
-
-GskRoundedRect gsk_decode_rect(_GSK_ROUNDED_RECT_UNIFORM_ r)
-{
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- return GskRoundedRect(r[0], r[1], r[2]);
-#else
- return r;
-#endif
-}
-
-float
-gsk_ellipsis_dist (vec2 p, vec2 radius)
-{
- if (radius == vec2(0, 0))
- return 0.0;
-
- vec2 p0 = p / radius;
- vec2 p1 = 2.0 * p0 / radius;
-
- return (dot(p0, p0) - 1.0) / length (p1);
-}
-
-float
-gsk_ellipsis_coverage (vec2 point, vec2 center, vec2 radius)
-{
- float d = gsk_ellipsis_dist (point - center, radius);
- return clamp (0.5 - d, 0.0, 1.0);
-}
-
-float
-gsk_rounded_rect_coverage (GskRoundedRect r, vec2 p)
-{
- if (p.x < r.bounds.x || p.y < r.bounds.y ||
- p.x >= r.bounds.z || p.y >= r.bounds.w)
- return 0.0;
-
- vec2 ref_tl = r.corner_points1.xy;
- vec2 ref_tr = r.corner_points1.zw;
- vec2 ref_br = r.corner_points2.xy;
- vec2 ref_bl = r.corner_points2.zw;
-
- if (p.x >= ref_tl.x && p.x >= ref_bl.x &&
- p.x <= ref_tr.x && p.x <= ref_br.x)
- return 1.0;
-
- if (p.y >= ref_tl.y && p.y >= ref_tr.y &&
- p.y <= ref_bl.y && p.y <= ref_br.y)
- return 1.0;
-
- vec2 rad_tl = r.corner_points1.xy - r.bounds.xy;
- vec2 rad_tr = r.corner_points1.zw - r.bounds.zy;
- vec2 rad_br = r.corner_points2.xy - r.bounds.zw;
- vec2 rad_bl = r.corner_points2.zw - r.bounds.xw;
-
- float d_tl = gsk_ellipsis_coverage(p, ref_tl, rad_tl);
- float d_tr = gsk_ellipsis_coverage(p, ref_tr, rad_tr);
- float d_br = gsk_ellipsis_coverage(p, ref_br, rad_br);
- float d_bl = gsk_ellipsis_coverage(p, ref_bl, rad_bl);
-
- vec4 corner_coverages = 1.0 - vec4(d_tl, d_tr, d_br, d_bl);
-
- bvec4 is_out = bvec4(p.x < ref_tl.x && p.y < ref_tl.y,
- p.x > ref_tr.x && p.y < ref_tr.y,
- p.x > ref_br.x && p.y > ref_br.y,
- p.x < ref_bl.x && p.y > ref_bl.y);
-
- return 1.0 - dot(vec4(is_out), corner_coverages);
-}
-
-float
-gsk_rect_coverage (vec4 r, vec2 p)
-{
- if (p.x < r.x || p.y < r.y ||
- p.x >= r.z || p.y >= r.w)
- return 0.0;
-
- return 1.0;
-}
-
-vec4 GskTexture(sampler2D sampler, vec2 texCoords) {
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- return texture2D(sampler, texCoords);
-#else
- return texture(sampler, texCoords);
-#endif
-}
-
-#ifdef GSK_GL3
-layout(origin_upper_left) in vec4 gl_FragCoord;
-#endif
-
-vec2 gsk_get_frag_coord() {
- vec2 fc = gl_FragCoord.xy;
-
-#ifdef GSK_GL3
- fc += u_viewport.xy;
-#else
- fc.x += u_viewport.x;
- fc.y = (u_viewport.y + u_viewport.w) - fc.y;
-#endif
-
- return fc;
-}
-
-void gskSetOutputColor(vec4 color) {
- vec4 result;
-
-#if defined(NO_CLIP)
- result = color;
-#elif defined(RECT_CLIP)
- result = color * gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
- gsk_get_frag_coord());
-#else
- result = color * gsk_rounded_rect_coverage(gsk_create_rect(u_clip_rect),
- gsk_get_frag_coord());
-#endif
-
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
- gl_FragColor = result;
-#else
- outputColor = result;
-#endif
-}
diff --git a/gsk/gl/resources/preamble.glsl b/gsk/gl/resources/preamble.glsl
deleted file mode 100644
index 8bc007ba67..0000000000
--- a/gsk/gl/resources/preamble.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef GSK_LEGACY
-precision highp float;
-#endif
-
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
-#define _OUT_ varying
-#define _IN_ varying
-#define _NOPERSPECTIVE_
-#define _GSK_ROUNDED_RECT_UNIFORM_ vec4[3]
-#else
-#define _OUT_ out
-#define _IN_ in
-#define _NOPERSPECTIVE_ noperspective
-#define _GSK_ROUNDED_RECT_UNIFORM_ GskRoundedRect
-#endif
-
-
-struct GskRoundedRect
-{
- vec4 bounds; // Top left and bottom right
- // Look, arrays can't be in structs if you want to return the struct
- // from a function in gles or whatever. Just kill me.
- vec4 corner_points1; // xy = top left, zw = top right
- vec4 corner_points2; // xy = bottom right, zw = bottom left
-};
-
-// Transform from a C GskRoundedRect to what we need.
-GskRoundedRect
-gsk_create_rect(vec4[3] data)
-{
- vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
-
- vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
- bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
- vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
- bounds.xw + vec2(data[2].zw * vec2(1, -1)));
-
- return GskRoundedRect(bounds, corner_points1, corner_points2);
-}
-
-vec4
-gsk_get_bounds(vec4[3] data)
-{
- return vec4(data[0].xy, data[0].xy + data[0].zw);
-}
-
-vec4 gsk_premultiply(vec4 c) {
- return vec4(c.rgb * c.a, c.a);
-}
-
-vec4 gsk_scaled_premultiply(vec4 c, float s) {
- // Fast version of gsk_premultiply(c) * s
- // 4 muls instead of 7
- float a = s * c.a;
-
- return vec4(c.rgb * a, a);
-}
diff --git a/gsk/gl/resources/preamble.vs.glsl b/gsk/gl/resources/preamble.vs.glsl
deleted file mode 100644
index 89ee6f74e0..0000000000
--- a/gsk/gl/resources/preamble.vs.glsl
+++ /dev/null
@@ -1,69 +0,0 @@
-uniform mat4 u_projection;
-uniform mat4 u_modelview;
-uniform float u_alpha;
-
-#if defined(GSK_GLES) || defined(GSK_LEGACY)
-attribute vec2 aPosition;
-attribute vec2 aUv;
-_OUT_ vec2 vUv;
-#else
-_IN_ vec2 aPosition;
-_IN_ vec2 aUv;
-_OUT_ vec2 vUv;
-#endif
-
-// amount is: top, right, bottom, left
-GskRoundedRect
-gsk_rounded_rect_shrink (GskRoundedRect r, vec4 amount)
-{
- vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
- vec4 new_corner_points1 = r.corner_points1;
- vec4 new_corner_points2 = r.corner_points2;
-
- if (r.corner_points1.xy == r.bounds.xy) new_corner_points1.xy = new_bounds.xy;
- if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
- if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
- if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
-
- return GskRoundedRect (new_bounds, new_corner_points1, new_corner_points2);
-}
-
-void
-gsk_rounded_rect_offset(inout GskRoundedRect r, vec2 offset)
-{
- r.bounds.xy += offset;
- r.bounds.zw += offset;
- r.corner_points1.xy += offset;
- r.corner_points1.zw += offset;
- r.corner_points2.xy += offset;
- r.corner_points2.zw += offset;
-}
-
-void gsk_rounded_rect_transform(inout GskRoundedRect r, mat4 mat)
-{
- r.bounds.xy = (mat * vec4(r.bounds.xy, 0.0, 1.0)).xy;
- r.bounds.zw = (mat * vec4(r.bounds.zw, 0.0, 1.0)).xy;
-
- r.corner_points1.xy = (mat * vec4(r.corner_points1.xy, 0.0, 1.0)).xy;
- r.corner_points1.zw = (mat * vec4(r.corner_points1.zw, 0.0, 1.0)).xy;
-
- r.corner_points2.xy = (mat * vec4(r.corner_points2.xy, 0.0, 1.0)).xy;
- r.corner_points2.zw = (mat * vec4(r.corner_points2.zw, 0.0, 1.0)).xy;
-}
-
-#if defined(GSK_LEGACY)
-// Can't have out or inout array parameters...
-#define gsk_rounded_rect_encode(r, uni) uni[0] = r.bounds; uni[1] = r.corner_points1; uni[2] = r.corner_points2;
-#else
-void gsk_rounded_rect_encode(GskRoundedRect r, out _GSK_ROUNDED_RECT_UNIFORM_ out_r)
-{
-#if defined(GSK_GLES)
- out_r[0] = r.bounds;
- out_r[1] = r.corner_points1;
- out_r[2] = r.corner_points2;
-#else
- out_r = r;
-#endif
-}
-
-#endif
diff --git a/gsk/gl/resources/radial_gradient.glsl b/gsk/gl/resources/radial_gradient.glsl
deleted file mode 100644
index 0ab3fdf07a..0000000000
--- a/gsk/gl/resources/radial_gradient.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-// VERTEX_SHADER
-uniform vec4 u_geometry;
-
-_NOPERSPECTIVE_ _OUT_ vec2 coord;
-
-void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
-
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
- vec2 offset = aPosition - u_geometry.xy;
- vec2 dir = vec2(dot(mv0, offset),
- dot(mv1, offset));
-
- coord = dir * u_geometry.zw;
-}
-
-// FRAGMENT_SHADER:
-#ifdef GSK_LEGACY
-uniform int u_num_color_stops;
-#else
-uniform highp int u_num_color_stops;
-#endif
-
-uniform bool u_repeat;
-uniform vec2 u_range;
-uniform float u_color_stops[6 * 5];
-
-_NOPERSPECTIVE_ _IN_ vec2 coord;
-
-float get_offset(int index) {
- return u_color_stops[5 * index];
-}
-
-vec4 get_color(int index) {
- int base = 5 * index + 1;
-
- return vec4(u_color_stops[base],
- u_color_stops[base + 1],
- u_color_stops[base + 2],
- u_color_stops[base + 3]);
-}
-
-void main() {
- // Reverse scale
- float offset = length(coord) * u_range.x + u_range.y;
-
- if (u_repeat) {
- offset = fract(offset);
- }
-
- if (offset < get_offset(0)) {
- gskSetOutputColor(gsk_scaled_premultiply(get_color(0), u_alpha));
- return;
- }
-
- int n = u_num_color_stops - 1;
- for (int i = 0; i < n; i++) {
- float curr_offset = get_offset(i);
- float next_offset = get_offset(i + 1);
-
- if (offset >= curr_offset && offset < next_offset) {
- float f = (offset - curr_offset) / (next_offset - curr_offset);
- vec4 curr_color = gsk_premultiply(get_color(i));
- vec4 next_color = gsk_premultiply(get_color(i + 1));
- vec4 color = mix(curr_color, next_color, f);
-
- gskSetOutputColor(color * u_alpha);
- return;
- }
- }
-
- gskSetOutputColor(gsk_scaled_premultiply(get_color(n), u_alpha));
-}
diff --git a/gsk/gl/resources/repeat.glsl b/gsk/gl/resources/repeat.glsl
deleted file mode 100644
index a9ebcc5e10..0000000000
--- a/gsk/gl/resources/repeat.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-// VERTEX_SHADER:
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- vUv = vec2(aUv.x, aUv.y);
-}
-
-// FRAGMENT_SHADER:
-uniform vec4 u_child_bounds;
-uniform vec4 u_texture_rect;
-
-
-float wrap(float f, float wrap_for) {
- return mod(f, wrap_for);
-}
-
-/* We get the texture coordinates via vUv,
- * but that might be on a texture atlas, so we need to do the
- * wrapping ourselves.
- */
-void main() {
-
- /* We map the texture coordinate to [1;0], then wrap it and scale the result again */
-
- float tw = u_texture_rect.z - u_texture_rect.x;
- float th = u_texture_rect.w - u_texture_rect.y;
-
- float mapped_x = (vUv.x - u_texture_rect.x) / tw;
- float mapped_y = (vUv.y - u_texture_rect.y) / th;
-
- float wrapped_x = wrap(u_child_bounds.x + mapped_x * u_child_bounds.z, 1.0);
- float wrapped_y = wrap(u_child_bounds.y + mapped_y * u_child_bounds.w, 1.0);
-
- vec2 tp;
- tp.x = u_texture_rect.x + (wrapped_x * tw);
- tp.y = u_texture_rect.y + (wrapped_y * th);
-
- vec4 diffuse = GskTexture(u_source, tp);
-
- gskSetOutputColor(diffuse * u_alpha);
-}
diff --git a/gsk/gl/resources/unblurred_outset_shadow.glsl b/gsk/gl/resources/unblurred_outset_shadow.glsl
deleted file mode 100644
index f110370412..0000000000
--- a/gsk/gl/resources/unblurred_outset_shadow.glsl
+++ /dev/null
@@ -1,42 +0,0 @@
-// VERTEX_SHADER:
-uniform vec4 u_color;
-uniform float u_spread;
-uniform vec2 u_offset;
-uniform vec4[3] u_outline_rect;
-
-_OUT_ vec4 final_color;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
- final_color = gsk_premultiply(u_color) * u_alpha;
-
- GskRoundedRect inside = gsk_create_rect(u_outline_rect);
- GskRoundedRect outside = gsk_rounded_rect_shrink(inside, vec4(- u_spread));
-
- gsk_rounded_rect_offset(outside, u_offset);
-
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
-
- gsk_rounded_rect_encode(outside, transformed_outside_outline);
- gsk_rounded_rect_encode(inside, transformed_inside_outline);
-}
-
-// FRAGMENT_SHADER:
-_IN_ vec4 final_color;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
-_IN_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
-
-void main() {
- vec2 frag = gsk_get_frag_coord();
-
- float alpha = clamp(gsk_rounded_rect_coverage(gsk_decode_rect(transformed_outside_outline), frag) -
- gsk_rounded_rect_coverage(gsk_decode_rect(transformed_inside_outline), frag),
- 0.0, 1.0);
-
- gskSetOutputColor(final_color * alpha);
-}
-
diff --git a/gsk/gskglshader.c b/gsk/gskglshader.c
index 996601d9c6..af6704a556 100644
--- a/gsk/gskglshader.c
+++ b/gsk/gskglshader.c
@@ -139,7 +139,6 @@
#include "gskglshaderprivate.h"
#include "gskdebugprivate.h"
-#include "gl/gskglrendererprivate.h"
#include "ngl/gsknglrendererprivate.h"
static GskGLUniformType
@@ -544,9 +543,7 @@ gsk_gl_shader_compile (GskGLShader *shader,
{
g_return_val_if_fail (GSK_IS_GL_SHADER (shader), FALSE);
- if (GSK_IS_GL_RENDERER (renderer))
- return gsk_gl_renderer_try_compile_gl_shader (GSK_GL_RENDERER (renderer), shader, error);
- else if (GSK_IS_NGL_RENDERER (renderer))
+ if (GSK_IS_NGL_RENDERER (renderer))
return gsk_ngl_renderer_try_compile_gl_shader (GSK_NGL_RENDERER (renderer), shader, error);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c
index 082ec4c1e8..77fc9a0dfa 100644
--- a/gsk/gskrenderer.c
+++ b/gsk/gskrenderer.c
@@ -38,7 +38,6 @@
#include "gskcairorenderer.h"
#include "gskdebugprivate.h"
-#include "gl/gskglrenderer.h"
#include "ngl/gsknglrenderer.h"
#include "gskprofilerprivate.h"
#include "gskrendernodeprivate.h"
@@ -508,8 +507,6 @@ get_renderer_for_name (const char *renderer_name)
else if (g_ascii_strcasecmp (renderer_name, "opengl") == 0 ||
g_ascii_strcasecmp (renderer_name, "ngl") == 0)
return GSK_TYPE_NGL_RENDERER;
- else if (g_ascii_strcasecmp (renderer_name, "gl") == 0)
- return GSK_TYPE_GL_RENDERER;
#ifdef GDK_RENDERING_VULKAN
else if (g_ascii_strcasecmp (renderer_name, "vulkan") == 0)
return GSK_TYPE_VULKAN_RENDERER;
@@ -520,12 +517,11 @@ get_renderer_for_name (const char *renderer_name)
#ifdef GDK_WINDOWING_BROADWAY
g_print ("broadway - Use the Broadway specific renderer\n");
#else
- g_print ("broadway - disabled during GTK build\n");
+ g_print ("broadway - Disabled during GTK build\n");
#endif
g_print (" cairo - Use the Cairo fallback renderer\n");
g_print (" opengl - Use the default OpenGL renderer\n");
- g_print (" gl - An OpenGL renderer\n");
- g_print (" ngl - Another OpenGL renderer\n");
+ g_print (" ngl - An OpenGL renderer\n");
#ifdef GDK_RENDERING_VULKAN
g_print (" vulkan - Use the Vulkan renderer\n");
#else
diff --git a/gsk/meson.build b/gsk/meson.build
index 7b82108286..20fd33185d 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -1,25 +1,3 @@
-gsk_private_gl_shaders = [
- 'gl/resources/preamble.glsl',
- 'gl/resources/preamble.fs.glsl',
- 'gl/resources/preamble.vs.glsl',
- 'gl/resources/border.glsl',
- 'gl/resources/blit.glsl',
- 'gl/resources/coloring.glsl',
- 'gl/resources/color.glsl',
- 'gl/resources/linear_gradient.glsl',
- 'gl/resources/radial_gradient.glsl',
- 'gl/resources/conic_gradient.glsl',
- 'gl/resources/color_matrix.glsl',
- 'gl/resources/blur.glsl',
- 'gl/resources/inset_shadow.glsl',
- 'gl/resources/outset_shadow.glsl',
- 'gl/resources/unblurred_outset_shadow.glsl',
- 'gl/resources/cross_fade.glsl',
- 'gl/resources/blend.glsl',
- 'gl/resources/repeat.glsl',
- 'gl/resources/custom.glsl',
-]
-
gsk_private_ngl_shaders = [
'ngl/resources/preamble.glsl',
'ngl/resources/preamble.fs.glsl',
@@ -53,7 +31,6 @@ gsk_public_sources = files([
'gskrendernodeparser.c',
'gskroundedrect.c',
'gsktransform.c',
- 'gl/gskglrenderer.c',
'ngl/gsknglrenderer.c',
])
@@ -62,16 +39,6 @@ gsk_private_sources = files([
'gskdebug.c',
'gskprivate.c',
'gskprofiler.c',
- 'gl/gskglshaderbuilder.c',
- 'gl/gskglprofiler.c',
- 'gl/gskglglyphcache.c',
- 'gl/gskgldriver.c',
- 'gl/gskglrenderops.c',
- 'gl/gskglshadowcache.c',
- 'gl/gskgltextureatlas.c',
- 'gl/gskgliconcache.c',
- 'gl/opbuffer.c',
- 'gl/stb_rect_pack.c',
'ngl/gsknglattachmentstate.c',
'ngl/gsknglbuffer.c',
'ngl/gsknglcommandqueue.c',
@@ -85,6 +52,8 @@ gsk_private_sources = files([
'ngl/gskngltexturelibrary.c',
'ngl/gskngluniformstate.c',
'ngl/gskngltexturepool.c',
+ 'ngl/gskglprofiler.c',
+ 'ngl/stb_rect_pack.c',
'ngl/fp16.c',
])
@@ -106,7 +75,6 @@ gsk_public_headers = files([
install_headers(gsk_public_headers, 'gsk.h', subdir: 'gtk-4.0/gsk')
gsk_public_gl_headers = files([
- 'gl/gskglrenderer.h',
'ngl/gsknglrenderer.h',
])
install_headers(gsk_public_gl_headers, subdir: 'gtk-4.0/gsk/gl')
@@ -177,7 +145,6 @@ gsk_resources_xml = configure_file(output: 'gsk.resources.xml',
command: [
find_program('gen-gsk-gresources-xml.py'),
'@OUTPUT@',
- gsk_private_gl_shaders,
gsk_private_ngl_shaders,
gsk_private_vulkan_compiled_shaders,
gsk_private_vulkan_shaders
diff --git a/gsk/gl/gskglprofiler.c b/gsk/ngl/gskglprofiler.c
index 9b834e5fc8..9b834e5fc8 100644
--- a/gsk/gl/gskglprofiler.c
+++ b/gsk/ngl/gskglprofiler.c
diff --git a/gsk/gl/gskglprofilerprivate.h b/gsk/ngl/gskglprofilerprivate.h
index 5b2a24b09f..5b2a24b09f 100644
--- a/gsk/gl/gskglprofilerprivate.h
+++ b/gsk/ngl/gskglprofilerprivate.h
diff --git a/gsk/ngl/gsknglcommandqueueprivate.h b/gsk/ngl/gsknglcommandqueueprivate.h
index a2f50c485d..b13838d48e 100644
--- a/gsk/ngl/gsknglcommandqueueprivate.h
+++ b/gsk/ngl/gsknglcommandqueueprivate.h
@@ -30,7 +30,7 @@
#include "inlinearray.h"
-#include "../gl/gskglprofilerprivate.h"
+#include "gskglprofilerprivate.h"
G_BEGIN_DECLS
diff --git a/gsk/ngl/gskngltexturelibraryprivate.h b/gsk/ngl/gskngltexturelibraryprivate.h
index 05c2216ed7..13e651e0d7 100644
--- a/gsk/ngl/gskngltexturelibraryprivate.h
+++ b/gsk/ngl/gskngltexturelibraryprivate.h
@@ -24,7 +24,7 @@
#include "gskngltypesprivate.h"
#include "gskngltexturepoolprivate.h"
-#include "../gl/stb_rect_pack.h"
+#include "stb_rect_pack.h"
G_BEGIN_DECLS
diff --git a/gsk/gl/stb_rect_pack.c b/gsk/ngl/stb_rect_pack.c
index ff658466a1..ff658466a1 100644
--- a/gsk/gl/stb_rect_pack.c
+++ b/gsk/ngl/stb_rect_pack.c
diff --git a/gsk/gl/stb_rect_pack.h b/gsk/ngl/stb_rect_pack.h
index 3ecb1c2fa2..3ecb1c2fa2 100644
--- a/gsk/gl/stb_rect_pack.h
+++ b/gsk/ngl/stb_rect_pack.h