From: Alexander Larsson Date: Tue, 24 Apr 2018 13:39:53 +0000 (+0200) Subject: broadway: Add and use GdkBroadwayDrawContext X-Git-Tag: archive/raspbian/4.4.1+ds1-2+rpi1^2~18^2~22^2~382 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a329de63ea865cd8a5e75012fe41141040d567c3;p=gtk4.git broadway: Add and use GdkBroadwayDrawContext --- diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c index 254e0a2bc7..f27af0b3ef 100644 --- a/gdk/broadway/gdkdisplay-broadway.c +++ b/gdk/broadway/gdkdisplay-broadway.c @@ -44,92 +44,6 @@ #endif #include -static gboolean -compare_surface (cairo_surface_t *a, - cairo_surface_t *b, - int width, - int height) -{ - unsigned char *data_a, *data_b; - int stride_a, stride_b; - int y; - - data_a = cairo_image_surface_get_data (a); - stride_a = cairo_image_surface_get_stride (a); - - data_b = cairo_image_surface_get_data (b); - stride_b = cairo_image_surface_get_stride (b); - - for (y = 0; y < height; y++) - { - if (memcmp (data_a, data_b, 4 * width) != 0) - return FALSE; - data_a += stride_a; - data_b += stride_b; - } - - return TRUE; -} - -static gboolean -gdk_texture_equal (GdkTexture *a, - GdkTexture *b) -{ - cairo_surface_t *surface_a; - cairo_surface_t *surface_b; - gboolean res; - - if (a == b) - return TRUE; - - if (a->width != b->width || - a->height != b->height) - return FALSE; - - surface_a = gdk_texture_download_surface (a); - surface_b = gdk_texture_download_surface (b); - - res = compare_surface (surface_a, surface_b, a->width, a->height); - - cairo_surface_destroy (surface_a); - cairo_surface_destroy (surface_b); - - return res; -} - -static guint -gdk_texture_hash (GdkTexture *self) -{ - cairo_surface_t *surface; - unsigned char *data; - int stride; - guint32 *row; - guint64 sum; - int x, y, width, height; - guint h; - - surface = gdk_texture_download_surface (self); - data = cairo_image_surface_get_data (surface); - stride = cairo_image_surface_get_stride (surface); - - width = MIN (self->width, 4); - height = MIN (self->height, 4); - - sum = 0; - for (y = 0; y < height; y++, data += stride) - { - row = (guint32 *)data; - for (x = 0; x < width; x++) - sum += row[x]; - } - - cairo_surface_destroy (surface); - - h = sum / (width * height); - - return h ^ self->width ^ (self->height << 16); -} - static void gdk_broadway_display_dispose (GObject *object); static void gdk_broadway_display_finalize (GObject *object); @@ -149,7 +63,6 @@ gdk_broadway_display_init (GdkBroadwayDisplay *display) NULL); gdk_monitor_set_manufacturer (display->monitor, "browser"); gdk_monitor_set_model (display->monitor, "0"); - display->texture_cache = g_hash_table_new ((GHashFunc)gdk_texture_hash, (GEqualFunc)gdk_texture_equal); } static void @@ -439,39 +352,17 @@ gdk_broadway_display_get_last_seen_time (GdkDisplay *display) typedef struct { int id; GdkDisplay *display; - GdkTexture *in_cache; GList *textures; } BroadwayTextureData; static void -broadway_texture_data_notify (BroadwayTextureData *data, - GdkTexture *disposed_texture) +broadway_texture_data_free (BroadwayTextureData *data) { GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (data->display); - if (data->in_cache == disposed_texture) - { - g_hash_table_remove (broadway_display->texture_cache, disposed_texture); - data->in_cache = NULL; - } - - g_object_set_data (G_OBJECT (disposed_texture), "broadway-data", NULL); - - data->textures = g_list_remove (data->textures, disposed_texture); - if (data->textures == NULL) - { - gdk_broadway_server_release_texture (broadway_display->server, data->id); - g_object_unref (data->display); - g_free (data); - } - else if (data->in_cache == NULL) - { - GdkTexture *first = data->textures->data; - - data->in_cache = first; - g_hash_table_replace (broadway_display->texture_cache, - data->in_cache, data->in_cache); - } + gdk_broadway_server_release_texture (broadway_display->server, data->id); + g_object_unref (data->display); + g_free (data); } guint32 @@ -480,35 +371,18 @@ gdk_broadway_display_ensure_texture (GdkDisplay *display, { GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display); BroadwayTextureData *data; - guint32 id; - GdkTexture *cached; data = g_object_get_data (G_OBJECT (texture), "broadway-data"); - if (data != NULL) - return data->id; - - cached = g_hash_table_lookup (broadway_display->texture_cache, texture); - if (cached) - data = g_object_get_data (G_OBJECT (cached), "broadway-data"); - if (data == NULL) { - id = gdk_broadway_server_upload_texture (broadway_display->server, texture); + guint32 id = gdk_broadway_server_upload_texture (broadway_display->server, texture); data = g_new0 (BroadwayTextureData, 1); data->id = id; data->display = g_object_ref (display); - - data->in_cache = texture; - g_hash_table_replace (broadway_display->texture_cache, - data->in_cache, data->in_cache); + g_object_set_data_full (G_OBJECT (texture), "broadway-data", data, (GDestroyNotify)broadway_texture_data_free); } - data->textures = g_list_prepend (data->textures, texture); - - g_object_weak_ref (G_OBJECT (texture), (GWeakNotify)broadway_texture_data_notify, data); - g_object_set_data (G_OBJECT (texture), "broadway-data", data); - return data->id; } diff --git a/gdk/broadway/gdkdrawcontext-broadway.c b/gdk/broadway/gdkdrawcontext-broadway.c new file mode 100644 index 0000000000..889b52fb30 --- /dev/null +++ b/gdk/broadway/gdkdrawcontext-broadway.c @@ -0,0 +1,100 @@ +/* GDK - The GIMP Drawing Kit + * + * Copyright © 2018 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gdkconfig.h" + +#include "gdkdrawcontext-broadway.h" +#include "gdktextureprivate.h" +#include "gdkprivate-broadway.h" + +G_DEFINE_TYPE (GdkBroadwayDrawContext, gdk_broadway_draw_context, GDK_TYPE_DRAW_CONTEXT) + +static void +gdk_broadway_draw_context_dispose (GObject *object) +{ + G_OBJECT_CLASS (gdk_broadway_draw_context_parent_class)->dispose (object); +} + +static void +gdk_broadway_draw_context_begin_frame (GdkDrawContext *draw_context, + cairo_region_t *region) +{ + GdkBroadwayDrawContext *self = GDK_BROADWAY_DRAW_CONTEXT (draw_context); + GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self)); + + cairo_region_union_rectangle (region, + &(cairo_rectangle_int_t) { + 0, 0, + gdk_surface_get_width (surface), + gdk_surface_get_height (surface) + }); + + g_assert (self->nodes == NULL); + g_assert (self->node_textures == NULL); + + self->nodes = g_array_new (FALSE, FALSE, sizeof(guint32)); + self->node_textures = g_ptr_array_new_with_free_func (g_object_unref); +} + +static void +gdk_broadway_draw_context_end_frame (GdkDrawContext *draw_context, + cairo_region_t *painted) +{ + GdkBroadwayDrawContext *self = GDK_BROADWAY_DRAW_CONTEXT (draw_context); + GdkSurface *surface = gdk_draw_context_get_surface (draw_context); + + gdk_broadway_surface_set_nodes (surface, self->nodes, self->node_textures); + + g_array_unref (self->nodes); + self->nodes = NULL; + g_ptr_array_unref (self->node_textures); + self->node_textures = NULL; +} + +static void +gdk_broadway_draw_context_surface_resized (GdkDrawContext *draw_context) +{ +} + +static void +gdk_broadway_draw_context_class_init (GdkBroadwayDrawContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass); + + gobject_class->dispose = gdk_broadway_draw_context_dispose; + + draw_context_class->begin_frame = gdk_broadway_draw_context_begin_frame; + draw_context_class->end_frame = gdk_broadway_draw_context_end_frame; + draw_context_class->surface_resized = gdk_broadway_draw_context_surface_resized; +} + +static void +gdk_broadway_draw_context_init (GdkBroadwayDrawContext *self) +{ +} + +GdkBroadwayDrawContext * +gdk_broadway_draw_context_context (GdkSurface *surface) +{ + return g_object_new (GDK_TYPE_BROADWAY_DRAW_CONTEXT, + "surface", surface, + NULL); +} diff --git a/gdk/broadway/gdkdrawcontext-broadway.h b/gdk/broadway/gdkdrawcontext-broadway.h new file mode 100644 index 0000000000..ccb0e0961b --- /dev/null +++ b/gdk/broadway/gdkdrawcontext-broadway.h @@ -0,0 +1,58 @@ +/* GDK - The GIMP Drawing Kit + * + * Copyright © 2018 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GDK_BROADWAY_DRAW_CONTEXT__ +#define __GDK_BROADWAY_DRAW_CONTEXT__ + +#include "gdkconfig.h" + +#include "gdkdrawcontextprivate.h" + +G_BEGIN_DECLS + +#define GDK_TYPE_BROADWAY_DRAW_CONTEXT (gdk_broadway_draw_context_get_type ()) +#define GDK_BROADWAY_DRAW_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_BROADWAY_DRAW_CONTEXT, GdkBroadwayDrawContext)) +#define GDK_IS_BROADWAY_DRAW_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_BROADWAY_DRAW_CONTEXT)) +#define GDK_BROADWAY_DRAW_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_BROADWAY_DRAW_CONTEXT, GdkBroadwayDrawContextClass)) +#define GDK_IS_BROADWAY_DRAW_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_BROADWAY_DRAW_CONTEXT)) +#define GDK_BROADWAY_DRAW_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_BROADWAY_DRAW_CONTEXT, GdkBroadwayDrawContextClass)) + +typedef struct _GdkBroadwayDrawContext GdkBroadwayDrawContext; +typedef struct _GdkBroadwayDrawContextClass GdkBroadwayDrawContextClass; + +struct _GdkBroadwayDrawContext +{ + GdkDrawContext parent_instance; + + GPtrArray *node_textures; + GArray *nodes; +}; + +struct _GdkBroadwayDrawContextClass +{ + GdkDrawContextClass parent_class; +}; + +GDK_AVAILABLE_IN_ALL +GType gdk_broadway_draw_context_get_type (void) G_GNUC_CONST; + +GdkBroadwayDrawContext *gdk_broadway_draw_context_context (GdkSurface *surface); + +G_END_DECLS + +#endif /* __GDK_BROADWAY_DRAW_CONTEXT__ */ diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h index db4ce7619b..bfca42173a 100644 --- a/gdk/broadway/gdkprivate-broadway.h +++ b/gdk/broadway/gdkprivate-broadway.h @@ -33,6 +33,7 @@ #include #include "gdksurface-broadway.h" #include "gdkdisplay-broadway.h" +#include "gdkdrawcontext-broadway.h" #include "gdkbroadwaycursor.h" #include "gdkbroadwaysurface.h" diff --git a/gdk/broadway/meson.build b/gdk/broadway/meson.build index aaa517ee6f..0306770f3f 100644 --- a/gdk/broadway/meson.build +++ b/gdk/broadway/meson.build @@ -4,6 +4,7 @@ gdk_broadway_sources = files([ 'broadwayd.c', 'gdkbroadway-server.c', 'gdkcairocontext-broadway.c', + 'gdkdrawcontext-broadway.c', 'gdkcursor-broadway.c', 'gdkdevice-broadway.c', 'gdkdisplay-broadway.c', diff --git a/gsk/gskbroadwayrenderer.c b/gsk/gskbroadwayrenderer.c index 0c118859cc..9eeec7ce46 100644 --- a/gsk/gskbroadwayrenderer.c +++ b/gsk/gskbroadwayrenderer.c @@ -8,11 +8,10 @@ #include "gskrendernodeprivate.h" #include "gdk/gdktextureprivate.h" - struct _GskBroadwayRenderer { GskRenderer parent_instance; - + GdkBroadwayDrawContext *draw_context; }; struct _GskBroadwayRendererClass @@ -23,21 +22,33 @@ struct _GskBroadwayRendererClass G_DEFINE_TYPE (GskBroadwayRenderer, gsk_broadway_renderer, GSK_TYPE_RENDERER) static gboolean -gsk_broadway_renderer_realize (GskRenderer *self, - GdkSurface *surface, +gsk_broadway_renderer_realize (GskRenderer *renderer, + GdkSurface *surface, GError **error) { + GskBroadwayRenderer *self = GSK_BROADWAY_RENDERER (renderer); + + if (!GDK_IS_BROADWAY_SURFACE (surface)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Broadway renderer only works for broadway surfaces"); + return FALSE; + } + + self->draw_context = gdk_broadway_draw_context_context (surface); + return TRUE; } static void -gsk_broadway_renderer_unrealize (GskRenderer *self) +gsk_broadway_renderer_unrealize (GskRenderer *renderer) { - + GskBroadwayRenderer *self = GSK_BROADWAY_RENDERER (renderer); + g_clear_object (&self->draw_context); } static GdkTexture * -gsk_broadway_renderer_render_texture (GskRenderer *self, +gsk_broadway_renderer_render_texture (GskRenderer *renderer, GskRenderNode *root, const graphene_rect_t *viewport) { @@ -443,14 +454,14 @@ node_texture_fallback (GskRenderNode *node, parent-relative which is what the dom uses, and which is good for re-using subtrees. */ static void -gsk_broadway_renderer_add_node (GskRenderer *self, +gsk_broadway_renderer_add_node (GskRenderer *renderer, GArray *nodes, GPtrArray *node_textures, GskRenderNode *node, float offset_x, float offset_y) { - GdkDisplay *display = gsk_renderer_get_display (self); + GdkDisplay *display = gsk_renderer_get_display (renderer); switch (gsk_render_node_get_node_type (node)) { @@ -564,7 +575,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, add_float (nodes, shadow->dy); add_float (nodes, shadow->radius); } - gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_broadway_renderer_add_node (renderer, nodes, node_textures, gsk_shadow_node_get_child (node), offset_x, offset_y); } @@ -574,7 +585,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, { add_uint32 (nodes, BROADWAY_NODE_OPACITY); add_float (nodes, gsk_opacity_node_get_opacity (node)); - gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_broadway_renderer_add_node (renderer, nodes, node_textures, gsk_opacity_node_get_child (node), offset_x, offset_y); } @@ -585,7 +596,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, const GskRoundedRect *rclip = gsk_rounded_clip_node_peek_clip (node); add_uint32 (nodes, BROADWAY_NODE_ROUNDED_CLIP); add_rounded_rect (nodes, rclip, offset_x, offset_y); - gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_broadway_renderer_add_node (renderer, nodes, node_textures, gsk_rounded_clip_node_get_child (node), rclip->bounds.origin.x, rclip->bounds.origin.y); @@ -597,7 +608,7 @@ gsk_broadway_renderer_add_node (GskRenderer *self, const graphene_rect_t *clip = gsk_clip_node_peek_clip (node); add_uint32 (nodes, BROADWAY_NODE_CLIP); add_rect (nodes, clip, offset_x, offset_y); - gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_broadway_renderer_add_node (renderer, nodes, node_textures, gsk_clip_node_get_child (node), clip->origin.x, clip->origin.y); @@ -614,13 +625,13 @@ gsk_broadway_renderer_add_node (GskRenderer *self, add_uint32 (nodes, gsk_container_node_get_n_children (node)); for (i = 0; i < gsk_container_node_get_n_children (node); i++) - gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_broadway_renderer_add_node (renderer, nodes, node_textures, gsk_container_node_get_child (node, i), offset_x, offset_y); } return; case GSK_DEBUG_NODE: - gsk_broadway_renderer_add_node (self, nodes, node_textures, + gsk_broadway_renderer_add_node (renderer, nodes, node_textures, gsk_debug_node_get_child (node), offset_x, offset_y); return; @@ -666,32 +677,15 @@ gsk_broadway_renderer_add_node (GskRenderer *self, } static void -gsk_broadway_renderer_render (GskRenderer *self, +gsk_broadway_renderer_render (GskRenderer *renderer, GskRenderNode *root, const cairo_region_t *update_area) { - GArray *nodes; - GPtrArray *node_textures; - cairo_region_t *whole; - GdkSurface *surface; - - surface = gsk_renderer_get_surface (self); - whole = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { - 0, 0, - gdk_surface_get_width (surface), - gdk_surface_get_height (surface) - }); - gdk_draw_context_begin_frame (NULL, whole); - cairo_region_destroy (whole); - - nodes = g_array_new (FALSE, FALSE, sizeof(guint32)); - node_textures = g_ptr_array_new_with_free_func (g_object_unref); - gsk_broadway_renderer_add_node (self, nodes, node_textures, root, 0, 0); - gdk_broadway_surface_set_nodes (surface, nodes, node_textures); - g_array_unref (nodes); - g_ptr_array_unref (node_textures); - - gdk_draw_context_end_frame (NULL); + GskBroadwayRenderer *self = GSK_BROADWAY_RENDERER (renderer); + + gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->draw_context), update_area); + gsk_broadway_renderer_add_node (renderer, self->draw_context->nodes, self->draw_context->node_textures, root, 0, 0); + gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->draw_context)); } static void