Commit f7d8ee04 authored by Alexander Larsson's avatar Alexander Larsson

broadway: Initial version of using actual render nodes

parent cc742385
......@@ -297,6 +297,21 @@ broadway_output_window_update (BroadwayOutput *output,
append_uint32 (output, texture);
}
void
broadway_output_window_set_nodes (BroadwayOutput *output,
int id,
guint32 *data,
guint32 data_len)
{
write_header (output, BROADWAY_OP_SET_NODES);
guint32 i;
append_uint16 (output, id);
append_uint32 (output, data_len);
for (i = 0; i < data_len; i++)
append_uint32 (output, data[i]);
}
void
broadway_output_upload_texture (BroadwayOutput *output,
guint32 id,
......
......@@ -56,6 +56,10 @@ void broadway_output_set_transient_for (BroadwayOutput *output,
void broadway_output_window_update (BroadwayOutput *output,
int id,
guint32 texture);
void broadway_output_window_set_nodes (BroadwayOutput *output,
int id,
guint32 *data,
guint32 data_len);
void broadway_output_upload_texture (BroadwayOutput *output,
guint32 id,
GBytes *texture);
......
......@@ -8,6 +8,11 @@ typedef struct {
gint32 width, height;
} BroadwayRect;
typedef enum { /* Sync changes with broadway.js */
BROADWAY_NODE_TEXTURE,
BROADWAY_NODE_CONTAINER,
} BroadwayNodeType;
typedef enum {
BROADWAY_EVENT_ENTER = 'e',
BROADWAY_EVENT_LEAVE = 'l',
......@@ -45,6 +50,7 @@ typedef enum {
BROADWAY_OP_SET_SHOW_KEYBOARD = 'k',
BROADWAY_OP_UPLOAD_TEXTURE = 't',
BROADWAY_OP_RELEASE_TEXTURE = 'T',
BROADWAY_OP_SET_NODES = 'n',
} BroadwayOpType;
typedef struct {
......@@ -162,6 +168,7 @@ typedef enum {
BROADWAY_REQUEST_SET_SHOW_KEYBOARD,
BROADWAY_REQUEST_UPLOAD_TEXTURE,
BROADWAY_REQUEST_RELEASE_TEXTURE,
BROADWAY_REQUEST_SET_NODES,
} BroadwayRequestType;
typedef struct {
......@@ -181,15 +188,6 @@ typedef struct {
guint32 parent;
} BroadwayRequestSetTransientFor;
typedef struct {
BroadwayRequestBase base;
guint32 id;
gint32 dx;
gint32 dy;
guint32 n_rects;
BroadwayRect rects[1];
} BroadwayRequestTranslate;
typedef struct {
BroadwayRequestBase base;
guint32 id;
......@@ -208,6 +206,13 @@ typedef struct {
guint32 id;
} BroadwayRequestReleaseTexture;
typedef struct {
BroadwayRequestBase base;
guint32 id;
guint32 data[1];
} BroadwayRequestSetNodes;
typedef struct {
BroadwayRequestBase base;
guint32 id;
......@@ -259,11 +264,11 @@ typedef union {
BroadwayRequestMoveResize move_resize;
BroadwayRequestGrabPointer grab_pointer;
BroadwayRequestUngrabPointer ungrab_pointer;
BroadwayRequestTranslate translate;
BroadwayRequestFocusWindow focus_window;
BroadwayRequestSetShowKeyboard set_show_keyboard;
BroadwayRequestUploadTexture upload_texture;
BroadwayRequestReleaseTexture release_texture;
BroadwayRequestSetNodes set_nodes;
} BroadwayRequest;
typedef enum {
......
......@@ -117,6 +117,8 @@ struct BroadwayWindow {
gboolean visible;
gint32 transient_for;
guint32 texture;
guint32 *nodes;
gint nodes_len;
};
static void broadway_server_resync_windows (BroadwayServer *server);
......@@ -173,6 +175,13 @@ broadway_server_class_init (BroadwayServerClass * class)
object_class->finalize = broadway_server_finalize;
}
static void
broadway_window_free (BroadwayWindow *window)
{
g_free (window->nodes);
g_free (window);
}
static void start (BroadwayInput *input);
static void
......@@ -1375,9 +1384,8 @@ broadway_server_destroy_window (BroadwayServer *server,
{
server->toplevels = g_list_remove (server->toplevels, window);
g_hash_table_remove (server->id_ht,
GINT_TO_POINTER (id));
g_free (window);
GINT_TO_POINTER (id));
broadway_window_free (window);
}
}
......@@ -1512,13 +1520,12 @@ broadway_server_has_client (BroadwayServer *server)
void
broadway_server_window_update (BroadwayServer *server,
gint id,
guint32 texture)
gint id,
guint32 texture)
{
BroadwayWindow *window;
window = g_hash_table_lookup (server->id_ht,
GINT_TO_POINTER (id));
window = g_hash_table_lookup (server->id_ht, GINT_TO_POINTER (id));
if (window == NULL)
return;
......@@ -1526,7 +1533,28 @@ broadway_server_window_update (BroadwayServer *server,
if (server->output != NULL)
broadway_output_window_update (server->output, window->id,
window->texture);
window->texture);
}
void
broadway_server_window_set_nodes (BroadwayServer *server,
gint id,
gint n_data,
guint32 *data)
{
BroadwayWindow *window;
window = g_hash_table_lookup (server->id_ht, GINT_TO_POINTER (id));
if (window == NULL)
return;
g_free (window->nodes);
window->nodes = g_memdup (data, sizeof (guint32)*n_data);
window->nodes_len = n_data;
if (server->output != NULL)
broadway_output_window_set_nodes (server->output, window->id,
window->nodes, window->nodes_len);
}
guint32
......@@ -1771,6 +1799,10 @@ broadway_server_resync_windows (BroadwayServer *server)
broadway_output_set_transient_for (server->output, window->id,
window->transient_for);
if (window->nodes)
broadway_output_window_set_nodes (server->output, window->id,
window->nodes, window->nodes_len);
broadway_output_window_update (server->output, window->id,
window->texture);
......
......@@ -85,6 +85,10 @@ cairo_surface_t * broadway_server_create_surface (int
void broadway_server_window_update (BroadwayServer *server,
gint id,
guint32 texture);
void broadway_server_window_set_nodes (BroadwayServer *server,
gint id,
gint n_data,
guint32 *data);
gboolean broadway_server_window_move_resize (BroadwayServer *server,
gint id,
gboolean with_move,
......
This diff is collapsed.
......@@ -289,9 +289,20 @@ client_handle_request (BroadwayClient *client,
request->update.id,
global_id);
break;
case BROADWAY_REQUEST_SET_NODES:
{
gsize array_size = request->base.size - sizeof (BroadwayRequestSetNodes) + sizeof(guint32);
int n_data = array_size / sizeof(guint32);
broadway_server_window_set_nodes (server,
request->set_nodes.id,
n_data,
request->set_nodes.data);
}
break;
case BROADWAY_REQUEST_UPLOAD_TEXTURE:
if (client->fds == NULL)
g_warning ("FD passing mismatch");
g_warning ("FD passing mismatch for texture upload %d", request->release_texture.id);
else
{
char *data, *p;
......
......@@ -668,6 +668,7 @@ gdk_broadway_server_upload_texture (GdkBroadwayServer *server,
return id;
}
void
gdk_broadway_server_release_texture (GdkBroadwayServer *server,
guint32 id)
......@@ -680,6 +681,22 @@ gdk_broadway_server_release_texture (GdkBroadwayServer *server,
BROADWAY_REQUEST_RELEASE_TEXTURE);
}
void
gdk_broadway_server_window_set_nodes (GdkBroadwayServer *server,
guint32 id,
GArray *nodes)
{
gsize size = sizeof(BroadwayRequestSetNodes) + sizeof(guint32) * (nodes->len - 1);
BroadwayRequestSetNodes *msg = g_alloca (size);
int i;
for (i = 0; i < nodes->len; i++)
msg->data[i] = g_array_index (nodes, guint32, i);
msg->id = id;
gdk_broadway_server_send_message_with_size (server, (BroadwayRequestBase *) msg, size, BROADWAY_REQUEST_SET_NODES, -1);
}
gboolean
_gdk_broadway_server_window_move_resize (GdkBroadwayServer *server,
gint id,
......
......@@ -66,6 +66,9 @@ void gdk_broadway_server_release_texture (GdkBroadwaySer
void _gdk_broadway_server_window_update (GdkBroadwayServer *server,
gint id,
guint32 texture);
void gdk_broadway_server_window_set_nodes (GdkBroadwayServer *server,
guint32 id,
GArray *nodes);
gboolean _gdk_broadway_server_window_move_resize (GdkBroadwayServer *server,
gint id,
gboolean with_move,
......
......@@ -324,6 +324,45 @@ gdk_broadway_display_get_last_seen_time (GdkDisplay *display)
return _gdk_broadway_server_get_last_seen_time (GDK_BROADWAY_DISPLAY (display)->server);
}
typedef struct {
int id;
GdkDisplay *display;
} BroadwayTextureData;
static void
broadway_texture_data_free (BroadwayTextureData *data)
{
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (data->display);
gdk_broadway_server_release_texture (broadway_display->server, data->id);
g_object_unref (data->display);
g_free (data);
}
guint32
gdk_broadway_display_ensure_texture (GdkDisplay *display,
GdkTexture *texture)
{
GdkBroadwayDisplay *broadway_display = GDK_BROADWAY_DISPLAY (display);
BroadwayTextureData *data;
guint32 id;
data = gdk_texture_get_render_data (texture, display);
if (data != NULL)
return data->id;
id = gdk_broadway_server_upload_texture (broadway_display->server, texture);
data = g_new0 (BroadwayTextureData, 1);
data->id = id;
data->display = g_object_ref (display);
if (!gdk_texture_set_render_data (texture, display, data, (GDestroyNotify)broadway_texture_data_free))
g_warning ("Failed to set render data, will leak texture");
return id;
}
static void
gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
{
......
......@@ -39,6 +39,13 @@
void _gdk_broadway_resync_windows (void);
guint32 gdk_broadway_display_ensure_texture (GdkDisplay *display,
GdkTexture *texture);
void gdk_broadway_window_set_nodes (GdkWindow *window,
GArray *nodes,
GPtrArray *node_textures);
void _gdk_broadway_window_register_dnd (GdkWindow *window);
GdkDragContext * _gdk_broadway_window_drag_begin (GdkWindow *window,
GdkDevice *device,
......
This diff is collapsed.
......@@ -72,6 +72,9 @@ struct _GdkWindowImplBroadway
GdkGeometry geometry_hints;
GdkWindowHints geometry_hints_mask;
GArray *node_data;
GPtrArray *node_data_textures;
};
struct _GdkWindowImplBroadwayClass
......
......@@ -23,7 +23,7 @@ struct _GskBroadwayRendererClass
G_DEFINE_TYPE (GskBroadwayRenderer, gsk_broadway_renderer, GSK_TYPE_RENDERER)
static gboolean
gsk_broadway_renderer_realize (GskRenderer *renderer,
gsk_broadway_renderer_realize (GskRenderer *self,
GdkWindow *window,
GError **error)
{
......@@ -31,13 +31,36 @@ gsk_broadway_renderer_realize (GskRenderer *renderer,
}
static void
gsk_broadway_renderer_unrealize (GskRenderer *renderer)
gsk_broadway_renderer_unrealize (GskRenderer *self)
{
}
static GdkDrawingContext *
gsk_broadway_renderer_begin_draw_frame (GskRenderer *renderer,
const cairo_region_t *update_area)
{
cairo_region_t *region;
GdkDrawingContext *result;
cairo_rectangle_int_t whole_window;
GdkWindow *window;
window = gsk_renderer_get_window (renderer);
whole_window = (cairo_rectangle_int_t) {
0, 0,
gdk_window_get_width (window),
gdk_window_get_height (window)
};
region = cairo_region_create_rectangle (&whole_window);
result = gdk_window_begin_draw_frame (window, NULL, region);
cairo_region_destroy (region);
return result;
}
static GdkTexture *
gsk_broadway_renderer_render_texture (GskRenderer *renderer,
gsk_broadway_renderer_render_texture (GskRenderer *self,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
......@@ -61,34 +84,80 @@ gsk_broadway_renderer_render_texture (GskRenderer *renderer,
}
static void
gsk_broadway_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
add_uint32 (GArray *nodes, guint32 v)
{
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
graphene_rect_t viewport;
cairo_t *cr;
cr = gdk_drawing_context_get_cairo_context (context);
g_return_if_fail (cr != NULL);
g_array_append_val (nodes, v);
}
gsk_renderer_get_viewport (renderer, &viewport);
static void
gsk_broadway_renderer_add_node (GskRenderer *self,
GArray *nodes,
GPtrArray *node_textures,
GskRenderNode *node)
{
GdkDisplay *display = gsk_renderer_get_display (self);
if (GSK_RENDER_MODE_CHECK (GEOMETRY))
switch (gsk_render_node_get_node_type (node))
{
cairo_save (cr);
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
cairo_rectangle (cr,
viewport.origin.x,
viewport.origin.y,
viewport.size.width,
viewport.size.height);
cairo_set_source_rgba (cr, 0, 0, 0.85, 0.5);
cairo_stroke (cr);
cairo_restore (cr);
case GSK_NOT_A_RENDER_NODE:
g_assert_not_reached ();
return;
case GSK_CONTAINER_NODE:
{
guint i;
add_uint32 (nodes, BROADWAY_NODE_CONTAINER);
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_container_node_get_child (node, i));
}
return;
default:
{
int x = floorf (node->bounds.origin.x);
int y = floorf (node->bounds.origin.y);
int width = ceil (node->bounds.origin.x + node->bounds.size.width) - x;
int height = ceil (node->bounds.origin.y + node->bounds.size.height) - y;
cairo_surface_t *surface;
GdkTexture *texture;
guint32 texture_id;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
cr = cairo_create (surface);
cairo_translate (cr, -x, -y);
gsk_render_node_draw (node, cr);
cairo_destroy (cr);
texture = gdk_texture_new_for_surface (surface);
g_ptr_array_add (node_textures, texture); /* Transfers ownership to node_textures */
texture_id = gdk_broadway_display_ensure_texture (display, texture);
add_uint32 (nodes, BROADWAY_NODE_TEXTURE);
add_uint32 (nodes, x);
add_uint32 (nodes, y);
add_uint32 (nodes, width);
add_uint32 (nodes, height);
add_uint32 (nodes, texture_id);
}
return;
}
}
gsk_render_node_draw (root, cr);
static void
gsk_broadway_renderer_render (GskRenderer *self,
GskRenderNode *root)
{
GdkWindow *window = gsk_renderer_get_window (self);
GArray *nodes = g_array_new (FALSE, FALSE, sizeof(guint32));
GPtrArray *node_textures = g_ptr_array_new_with_free_func (g_object_unref);
gsk_broadway_renderer_add_node (self, nodes, node_textures, root);
gdk_broadway_window_set_nodes (window, nodes, node_textures);
g_array_unref (nodes);
g_ptr_array_unref (node_textures);
}
static void
......@@ -96,6 +165,7 @@ gsk_broadway_renderer_class_init (GskBroadwayRendererClass *klass)
{
GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass);
renderer_class->begin_draw_frame = gsk_broadway_renderer_begin_draw_frame;
renderer_class->realize = gsk_broadway_renderer_realize;
renderer_class->unrealize = gsk_broadway_renderer_unrealize;
renderer_class->render = gsk_broadway_renderer_render;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment