gsk: move begin/end_frame vfuncs into the renderers

This commit is contained in:
Benjamin Otte 2018-03-28 15:01:34 +02:00
parent d0873c7dec
commit 7c313c7b25
8 changed files with 154 additions and 247 deletions

View File

@ -178,12 +178,6 @@ static void gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder);
typedef enum
{
RENDER_FULL,
RENDER_SCISSOR
} RenderMode;
struct _GskGLRenderer
{
GskRenderer parent_instance;
@ -229,7 +223,7 @@ struct _GskGLRenderer
} profile_timers;
#endif
RenderMode render_mode;
cairo_region_t *render_region;
gboolean has_buffers : 1;
};
@ -1942,51 +1936,6 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer)
g_clear_object (&self->gl_context);
}
static GdkDrawingContext *
gsk_gl_renderer_begin_draw_frame (GskRenderer *renderer,
const cairo_region_t *update_area)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
cairo_region_t *damage;
GdkDrawingContext *result;
GdkRectangle whole_surface;
GdkSurface *surface;
surface = gsk_renderer_get_surface (renderer);
whole_surface = (GdkRectangle) {
0, 0,
gdk_surface_get_width (surface) * self->scale_factor,
gdk_surface_get_height (surface) * self->scale_factor
};
damage = gdk_gl_context_get_damage (self->gl_context);
cairo_region_union (damage, update_area);
if (cairo_region_contains_rectangle (damage, &whole_surface) == CAIRO_REGION_OVERLAP_IN)
{
self->render_mode = RENDER_FULL;
}
else
{
GdkRectangle extents;
cairo_region_get_extents (damage, &extents);
cairo_region_union_rectangle (damage, &extents);
if (gdk_rectangle_equal (&extents, &whole_surface))
self->render_mode = RENDER_FULL;
else
self->render_mode = RENDER_SCISSOR;
}
result = gdk_surface_begin_draw_frame (surface,
GDK_DRAW_CONTEXT (self->gl_context),
damage);
cairo_region_destroy (damage);
return result;
}
static void
gsk_gl_renderer_resize_viewport (GskGLRenderer *self,
const graphene_rect_t *viewport)
@ -2032,48 +1981,27 @@ gsk_gl_renderer_clear (GskGLRenderer *self)
static void
gsk_gl_renderer_setup_render_mode (GskGLRenderer *self)
{
switch (self->render_mode)
{
case RENDER_FULL:
if (self->render_region == NULL)
{
glDisable (GL_SCISSOR_TEST);
break;
}
else
{
GdkSurface *surface = gsk_renderer_get_surface (GSK_RENDERER (self));
cairo_rectangle_int_t extents;
int surface_height;
case RENDER_SCISSOR:
{
GdkDrawingContext *context = gsk_renderer_get_drawing_context (GSK_RENDERER (self));
GdkSurface *surface = gsk_renderer_get_surface (GSK_RENDERER (self));
cairo_region_t *clip = gdk_drawing_context_get_clip (context);
cairo_rectangle_int_t extents;
int surface_height;
g_assert (cairo_region_num_rectangles (self->render_region) == 1);
/* Fall back to RENDER_FULL */
if (clip == NULL)
{
glDisable (GL_SCISSOR_TEST);
return;
}
surface_height = gdk_surface_get_height (surface) * self->scale_factor;
cairo_region_get_rectangle (self->render_region, 0, &extents);
g_assert (cairo_region_num_rectangles (clip) == 1);
surface_height = gdk_surface_get_height (surface) * self->scale_factor;
/*cairo_region_get_extents (clip, &extents);*/
cairo_region_get_rectangle (clip, 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);
cairo_region_destroy (clip);
break;
}
default:
g_assert_not_reached ();
break;
}
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);
}
}
@ -2562,7 +2490,6 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
g_return_val_if_fail (self->gl_context != NULL, NULL);
self->render_mode = RENDER_FULL;
width = ceilf (viewport->size.width);
height = ceilf (viewport->size.height);
@ -2600,16 +2527,58 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
}
static void
gsk_gl_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
gsk_gl_renderer_render (GskRenderer *renderer,
GskRenderNode *root,
const cairo_region_t *update_area)
{
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
GdkSurface *surface = gsk_renderer_get_surface (renderer);
graphene_rect_t viewport;
cairo_region_t *damage;
GdkDrawingContext *context;
GdkRectangle whole_surface;
GdkSurface *surface;
if (self->gl_context == NULL)
return;
surface = gsk_renderer_get_surface (renderer);
whole_surface = (GdkRectangle) {
0, 0,
gdk_surface_get_width (surface) * self->scale_factor,
gdk_surface_get_height (surface) * self->scale_factor
};
damage = gdk_gl_context_get_damage (self->gl_context);
cairo_region_union (damage, update_area);
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);
cairo_region_union_rectangle (damage, &extents);
if (gdk_rectangle_equal (&extents, &whole_surface))
self->render_region = NULL;
else
self->render_region = cairo_region_reference (damage);
}
context = gdk_surface_begin_draw_frame (surface,
GDK_DRAW_CONTEXT (self->gl_context),
damage);
cairo_region_destroy (damage);
if (self->render_region)
{
damage = gdk_drawing_context_get_clip (context);
cairo_region_union (self->render_region, damage);
cairo_region_destroy (damage);
}
self->scale_factor = gdk_surface_get_scale_factor (surface);
gdk_gl_context_make_current (self->gl_context);
@ -2622,6 +2591,10 @@ gsk_gl_renderer_render (GskRenderer *renderer,
gdk_gl_context_make_current (self->gl_context);
gsk_gl_renderer_clear_tree (self);
gdk_surface_end_draw_frame (surface, context);
g_clear_pointer (&self->render_region, cairo_region_destroy);
}
static void
@ -2634,7 +2607,6 @@ gsk_gl_renderer_class_init (GskGLRendererClass *klass)
renderer_class->realize = gsk_gl_renderer_realize;
renderer_class->unrealize = gsk_gl_renderer_unrealize;
renderer_class->begin_draw_frame = gsk_gl_renderer_begin_draw_frame;
renderer_class->render = gsk_gl_renderer_render;
renderer_class->render_texture = gsk_gl_renderer_render_texture;
}

View File

@ -36,29 +36,6 @@ 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_surface;
GdkSurface *surface;
surface = gsk_renderer_get_surface (renderer);
whole_surface = (cairo_rectangle_int_t) {
0, 0,
gdk_surface_get_width (surface),
gdk_surface_get_height (surface)
};
region = cairo_region_create_rectangle (&whole_surface);
result = gdk_surface_begin_draw_frame (surface, NULL, region);
cairo_region_destroy (region);
return result;
}
static GdkTexture *
gsk_broadway_renderer_render_texture (GskRenderer *self,
GskRenderNode *root,
@ -684,17 +661,33 @@ gsk_broadway_renderer_add_node (GskRenderer *self,
}
static void
gsk_broadway_renderer_render (GskRenderer *self,
GskRenderNode *root)
gsk_broadway_renderer_render (GskRenderer *self,
GskRenderNode *root,
const cairo_region_t *update_area)
{
GdkSurface *surface = gsk_renderer_get_surface (self);
GArray *nodes = g_array_new (FALSE, FALSE, sizeof(guint32));
GPtrArray *node_textures = g_ptr_array_new_with_free_func (g_object_unref);
GArray *nodes;
GPtrArray *node_textures;
cairo_region_t *whole;
GdkDrawingContext *context;
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)
});
context = gdk_surface_begin_draw_frame (surface, 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_surface_end_draw_frame (surface, context);
}
static void
@ -702,7 +695,6 @@ 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;

View File

@ -95,14 +95,15 @@ gsk_cairo_renderer_render_texture (GskRenderer *renderer,
}
static void
gsk_cairo_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
gsk_cairo_renderer_render (GskRenderer *renderer,
GskRenderNode *root,
const cairo_region_t *region)
{
GdkDrawingContext *context = gsk_renderer_get_drawing_context (renderer);
GdkSurface *surface = gsk_renderer_get_surface (renderer);
GdkDrawingContext *context;
cairo_t *cr;
context = gdk_surface_begin_draw_frame (surface, NULL, region);
cr = gdk_drawing_context_get_cairo_context (context);
g_return_if_fail (cr != NULL);
@ -122,6 +123,8 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
#endif
gsk_cairo_renderer_do_render (renderer, cr, root);
gdk_surface_end_draw_frame (surface, context);
}
static void

View File

@ -66,7 +66,6 @@ typedef struct
GObject parent_instance;
GdkSurface *surface;
GdkDrawingContext *drawing_context;
GskRenderNode *root_node;
GdkDisplay *display;
@ -82,7 +81,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GskRenderer, gsk_renderer, G_TYPE_OBJECT)
enum {
PROP_SURFACE = 1,
PROP_DISPLAY,
PROP_DRAWING_CONTEXT,
N_PROPS
};
@ -116,30 +114,10 @@ gsk_renderer_real_render_texture (GskRenderer *self,
return NULL;
}
static GdkDrawingContext *
gsk_renderer_real_begin_draw_frame (GskRenderer *self,
const cairo_region_t *region)
{
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
return gdk_surface_begin_draw_frame (priv->surface,
NULL,
region);
}
static void
gsk_renderer_real_end_draw_frame (GskRenderer *self,
GdkDrawingContext *context)
{
GskRendererPrivate *priv = gsk_renderer_get_instance_private (self);
gdk_surface_end_draw_frame (priv->surface,
context);
}
static void
gsk_renderer_real_render (GskRenderer *self,
GskRenderNode *root)
gsk_renderer_real_render (GskRenderer *self,
GskRenderNode *root,
const cairo_region_t *region)
{
GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render);
}
@ -197,10 +175,6 @@ gsk_renderer_get_property (GObject *gobject,
g_value_set_object (value, priv->surface);
break;
case PROP_DRAWING_CONTEXT:
g_value_set_object (value, priv->drawing_context);
break;
case PROP_DISPLAY:
g_value_set_object (value, priv->display);
break;
@ -235,8 +209,6 @@ gsk_renderer_class_init (GskRendererClass *klass)
klass->realize = gsk_renderer_real_realize;
klass->unrealize = gsk_renderer_real_unrealize;
klass->begin_draw_frame = gsk_renderer_real_begin_draw_frame;
klass->end_draw_frame = gsk_renderer_real_end_draw_frame;
klass->render = gsk_renderer_real_render;
klass->render_texture = gsk_renderer_real_render_texture;
@ -267,19 +239,6 @@ gsk_renderer_class_init (GskRendererClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/**
* GskRenderer:drawing-context:
*
* The drawing context used when rendering.
*/
gsk_renderer_properties[PROP_DRAWING_CONTEXT] =
g_param_spec_object ("drawing-context",
"Drawing Context",
"The drawing context used by the renderer",
GDK_TYPE_DRAWING_CONTEXT,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, gsk_renderer_properties);
}
@ -329,24 +288,6 @@ gsk_renderer_get_root_node (GskRenderer *renderer)
return priv->root_node;
}
/*< private >
* gsk_renderer_get_drawing_context:
* @renderer: a #GskRenderer
*
* Retrieves the #GdkDrawingContext used by @renderer.
*
* Returns: (transfer none) (nullable): a #GdkDrawingContext
*/
GdkDrawingContext *
gsk_renderer_get_drawing_context (GskRenderer *renderer)
{
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
return priv->drawing_context;
}
/**
* gsk_renderer_get_display:
* @renderer: a #GskRenderer
@ -524,6 +465,7 @@ gsk_renderer_render (GskRenderer *renderer,
const cairo_region_t *region)
{
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
cairo_region_t *real_region;
g_return_if_fail (GSK_IS_RENDERER (renderer));
g_return_if_fail (priv->is_realized);
@ -534,22 +476,20 @@ gsk_renderer_render (GskRenderer *renderer,
if (region == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW))
{
cairo_region_t *full_surface;
full_surface = cairo_region_create_rectangle (&(GdkRectangle) {
real_region = cairo_region_create_rectangle (&(GdkRectangle) {
0, 0,
gdk_surface_get_width (priv->surface),
gdk_surface_get_height (priv->surface)
});
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, full_surface);
GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, real_region);
cairo_region_destroy (full_surface);
cairo_region_destroy (real_region);
}
else
priv->drawing_context = GSK_RENDERER_GET_CLASS (renderer)->begin_draw_frame (renderer, region);
GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root);
{
GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, region);
}
#ifdef G_ENABLE_DEBUG
if (GSK_RENDERER_DEBUG_CHECK (renderer, RENDERER))
@ -568,9 +508,6 @@ gsk_renderer_render (GskRenderer *renderer,
}
#endif
GSK_RENDERER_GET_CLASS (renderer)->end_draw_frame (renderer, priv->drawing_context);
priv->drawing_context = NULL;
g_clear_pointer (&priv->root_node, gsk_render_node_unref);
}

View File

@ -38,32 +38,28 @@ struct _GskRendererClass
{
GObjectClass parent_class;
gboolean (* realize) (GskRenderer *renderer,
GdkSurface *surface,
GError **error);
void (* unrealize) (GskRenderer *renderer);
gboolean (* realize) (GskRenderer *renderer,
GdkSurface *surface,
GError **error);
void (* unrealize) (GskRenderer *renderer);
GdkTexture * (* render_texture) (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport);
GdkDrawingContext * (* begin_draw_frame) (GskRenderer *renderer,
const cairo_region_t *region);
void (* end_draw_frame) (GskRenderer *renderer,
GdkDrawingContext *context);
void (* render) (GskRenderer *renderer,
GskRenderNode *root);
GdkTexture * (* render_texture) (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport);
void (* render) (GskRenderer *renderer,
GskRenderNode *root,
const cairo_region_t *invalid);
};
gboolean gsk_renderer_is_realized (GskRenderer *renderer);
gboolean gsk_renderer_is_realized (GskRenderer *renderer);
GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer);
GdkDrawingContext * gsk_renderer_get_drawing_context (GskRenderer *renderer);
GskProfiler * gsk_renderer_get_profiler (GskRenderer *renderer);
GskDebugFlags gsk_renderer_get_debug_flags (GskRenderer *renderer);
void gsk_renderer_set_debug_flags (GskRenderer *renderer,
GskDebugFlags flags);
GskDebugFlags gsk_renderer_get_debug_flags (GskRenderer *renderer);
void gsk_renderer_set_debug_flags (GskRenderer *renderer,
GskDebugFlags flags);
G_END_DECLS

View File

@ -65,7 +65,8 @@ struct _GskVulkanRender
static void
gsk_vulkan_render_setup (GskVulkanRender *self,
GskVulkanImage *target,
const graphene_rect_t *rect)
const graphene_rect_t *rect,
const cairo_region_t *clip)
{
GdkSurface *window = gsk_renderer_get_surface (self->renderer);
@ -75,11 +76,6 @@ gsk_vulkan_render_setup (GskVulkanRender *self,
{
self->viewport = *rect;
self->scale_factor = 1;
self->clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (target),
gsk_vulkan_image_get_height (target)
});
}
else
{
@ -87,7 +83,18 @@ gsk_vulkan_render_setup (GskVulkanRender *self,
self->viewport = GRAPHENE_RECT_INIT (0, 0,
gdk_surface_get_width (window) * self->scale_factor,
gdk_surface_get_height (window) * self->scale_factor);
self->clip = gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer));
}
if (clip)
{
self->clip = cairo_region_reference ((cairo_region_t *) clip);
}
else
{
self->clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
0, 0,
gsk_vulkan_image_get_width (target),
gsk_vulkan_image_get_height (target)
});
}
}
@ -749,11 +756,12 @@ gsk_vulkan_render_is_busy (GskVulkanRender *self)
void
gsk_vulkan_render_reset (GskVulkanRender *self,
GskVulkanImage *target,
const graphene_rect_t *rect)
const graphene_rect_t *rect,
const cairo_region_t *clip)
{
gsk_vulkan_render_cleanup (self);
gsk_vulkan_render_setup (self, target, rect);
gsk_vulkan_render_setup (self, target, rect, clip);
}
GskRenderer *

View File

@ -187,7 +187,7 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
ceil (viewport->size.width),
ceil (viewport->size.height));
gsk_vulkan_render_reset (render, image, viewport);
gsk_vulkan_render_reset (render, image, viewport, NULL);
gsk_vulkan_render_add_node (render, root);
@ -211,16 +211,22 @@ gsk_vulkan_renderer_render_texture (GskRenderer *renderer,
}
static void
gsk_vulkan_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
gsk_vulkan_renderer_render (GskRenderer *renderer,
GskRenderNode *root,
const cairo_region_t *region)
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
GskVulkanRender *render;
GdkDrawingContext *context;
GdkSurface *surface;
cairo_region_t *clip;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time;
#endif
surface = gsk_renderer_get_surface (renderer);
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
gsk_profiler_counter_set (profiler, self->profile_counters.fallback_pixels, 0);
@ -229,9 +235,14 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
#endif
context = gdk_surface_begin_draw_frame (surface,
GDK_DRAW_CONTEXT (self->vulkan),
region);
render = self->render;
gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)], NULL);
clip = gdk_drawing_context_get_clip (context);
gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)], NULL, clip);
cairo_region_destroy (clip);
gsk_vulkan_render_add_node (render, root);
@ -247,20 +258,8 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
gsk_profiler_push_samples (profiler);
#endif
}
static GdkDrawingContext *
gsk_vulkan_renderer_begin_draw_frame (GskRenderer *renderer,
const cairo_region_t *region)
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
GdkDrawingContext *result;
result = gdk_surface_begin_draw_frame (gsk_renderer_get_surface (renderer),
GDK_DRAW_CONTEXT (self->vulkan),
region);
return result;
gdk_surface_end_draw_frame (surface, context);
}
static void
@ -272,7 +271,6 @@ gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
renderer_class->unrealize = gsk_vulkan_renderer_unrealize;
renderer_class->render = gsk_vulkan_renderer_render;
renderer_class->render_texture = gsk_vulkan_renderer_render_texture;
renderer_class->begin_draw_frame = gsk_vulkan_renderer_begin_draw_frame;
}
static void

View File

@ -59,7 +59,8 @@ void gsk_vulkan_render_free (GskVulk
gboolean gsk_vulkan_render_is_busy (GskVulkanRender *self);
void gsk_vulkan_render_reset (GskVulkanRender *self,
GskVulkanImage *target,
const graphene_rect_t *rect);
const graphene_rect_t *rect,
const cairo_region_t *clip);
GskRenderer * gsk_vulkan_render_get_renderer (GskVulkanRender *self);