#endif
#include <sys/types.h>
-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);
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
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
{
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;
}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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);
+}
--- /dev/null
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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__ */
#include <gdk/gdkinternals.h>
#include "gdksurface-broadway.h"
#include "gdkdisplay-broadway.h"
+#include "gdkdrawcontext-broadway.h"
#include "gdkbroadwaycursor.h"
#include "gdkbroadwaysurface.h"
'broadwayd.c',
'gdkbroadway-server.c',
'gdkcairocontext-broadway.c',
+ 'gdkdrawcontext-broadway.c',
'gdkcursor-broadway.c',
'gdkdevice-broadway.c',
'gdkdisplay-broadway.c',
#include "gskrendernodeprivate.h"
#include "gdk/gdktextureprivate.h"
-
struct _GskBroadwayRenderer
{
GskRenderer parent_instance;
-
+ GdkBroadwayDrawContext *draw_context;
};
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)
{
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))
{
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);
}
{
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);
}
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);
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);
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;
}
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