diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index ca6be0c0bc..7416d77441 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -16052,27 +16052,116 @@ gtk_widget_reset_controllers (GtkWidget *widget) } } +GskRenderer * +gtk_widget_get_renderer (GtkWidget *widget) +{ + GtkWidget *toplevel; + + toplevel = _gtk_widget_get_toplevel (widget); + if (_gtk_widget_is_toplevel (toplevel)) + return gtk_window_get_renderer (GTK_WINDOW (toplevel)); + + return NULL; +} + +GskRenderNode * +gtk_widget_get_render_node (GtkWidget *widget, + GskRenderer *renderer) +{ + GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS (widget); + GskRenderNode *node; + + if (klass->get_render_node == NULL) + { + GskRenderNode *tmp; + graphene_rect_t bounds; + GtkAllocation clip; + cairo_t *cr; + + gtk_widget_get_clip (widget, &clip); + graphene_rect_init (&bounds, clip.x, clip.y, clip.width, clip.height); + + tmp = gsk_render_node_new (); + gsk_render_node_set_bounds (tmp, &bounds); + cr = gsk_render_node_get_draw_context (tmp); + + gtk_widget_draw (widget, cr); + + cairo_destroy (cr); + + node = tmp; + } + else + { + node = klass->get_render_node (widget, renderer); + + if (klass->draw != NULL || + g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE)) + { + GskRenderNode *tmp; + graphene_rect_t bounds; + GtkAllocation clip; + gboolean result; + cairo_t *cr; + + gtk_widget_get_clip (widget, &clip); + graphene_rect_init (&bounds, clip.x, clip.y, clip.width, clip.height); + + tmp = gsk_render_node_new (); + gsk_render_node_set_bounds (tmp, &bounds); + cr = gsk_render_node_get_draw_context (tmp); + + if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE)) + { + g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result); + } + else if (klass->draw != NULL) + { + klass->draw (widget, cr); + } + + cairo_destroy (cr); + + if (node != NULL) + { + gsk_render_node_append_child (node, tmp); + gsk_render_node_unref (tmp); + } + else + { + node = tmp; + } + } + } + + return node; +} + void gtk_widget_render (GtkWidget *widget, GdkWindow *window, const cairo_region_t *region) { GdkDrawingContext *context; - gboolean do_clip; - cairo_t *cr; - int x, y; + GskRenderer *renderer; + GskRenderNode *root; /* We only render double buffered on native windows */ if (!gdk_window_has_native (window)) return; + renderer = gtk_widget_get_renderer (widget); + if (renderer == NULL) + return; + + root = gtk_widget_get_render_node (widget, renderer); + if (root == NULL) + return; + context = gdk_window_begin_draw_frame (window, region); - cr = gdk_drawing_context_get_cairo_context (context); - do_clip = _gtk_widget_get_translation_to_window (widget, window, &x, &y); - cairo_translate (cr, -x, -y); - - gtk_widget_draw_internal (widget, cr, do_clip); + gsk_renderer_render (renderer, root, context); + gsk_render_node_unref (root); gdk_window_end_draw_frame (window, context); } diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 4c5ac48f71..65327f7484 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -30,6 +30,7 @@ #endif #include +#include #include #include #include @@ -595,12 +596,14 @@ struct _GtkWidgetClass void (*queue_draw_region) (GtkWidget *widget, const cairo_region_t *region); + GskRenderNode *(* get_render_node) (GtkWidget *widget, + GskRenderer *renderer); + /*< private >*/ GtkWidgetClassPrivate *priv; /* Padding for future expansion */ - void (*_gtk_reserved6) (void); void (*_gtk_reserved7) (void); }; diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index 1fe2c0365d..65f2bc8bf9 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -297,6 +297,9 @@ void gtk_widget_render (GtkWidget const cairo_region_t *region); +GskRenderNode * gtk_widget_get_render_node (GtkWidget *widget, + GskRenderer *renderer); + /* inline getters */ static inline gboolean diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index b790c4ae75..923aa2c38f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -7328,6 +7328,8 @@ _gtk_window_set_allocation (GtkWindow *window, { graphene_rect_t viewport; graphene_matrix_t projection; + graphene_matrix_t modelview; + graphene_point3d_t tmp; graphene_rect_init (&viewport, 0, 0, allocation->width, allocation->height); gsk_renderer_set_viewport (priv->renderer, &viewport); @@ -7337,6 +7339,10 @@ _gtk_window_set_allocation (GtkWindow *window, 0, allocation->height, -1, 1); gsk_renderer_set_projection (priv->renderer, &projection); + + graphene_matrix_init_translate (&modelview, + graphene_point3d_init (&tmp, 0.f, 0.f, 0.f)); + gsk_renderer_set_modelview (priv->renderer, &modelview); } get_shadow_width (window, &window_border);