forked from AuroraMiddleware/gtk
rendernode: Limit diff region
Limit the diff region to 30 rectangles (randomly chosen because it looked big enough to not trigger by accident and small enough to not cause performance issues). If the diff region gets more complicated, we abort to the parent node and use its bounds as the diff region instead and then continue diffing the rest of the node tree. Fixes: #4560 Fixes: #2396
This commit is contained in:
parent
4e6ee28bcb
commit
20dcc31d19
@ -33,6 +33,12 @@
|
||||
|
||||
#include <hb-ot.h>
|
||||
|
||||
/* maximal number of rectangles we keep in a diff region before we throw
|
||||
* the towel and just use the bounding box of the parent node.
|
||||
* Meant to avoid performance corner cases.
|
||||
*/
|
||||
#define MAX_RECTS_IN_DIFF 30
|
||||
|
||||
static inline void
|
||||
gsk_cairo_rectangle (cairo_t *cr,
|
||||
const graphene_rect_t *rect)
|
||||
@ -2611,6 +2617,8 @@ static GskDiffResult
|
||||
gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
|
||||
{
|
||||
gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data);
|
||||
if (cairo_region_num_rectangles (data) > MAX_RECTS_IN_DIFF)
|
||||
return GSK_DIFF_ABORTED;
|
||||
|
||||
return GSK_DIFF_OK;
|
||||
}
|
||||
@ -2624,6 +2632,8 @@ gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data)
|
||||
|
||||
rectangle_init_from_graphene (&rect, &node->bounds);
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
if (cairo_region_num_rectangles (region) > MAX_RECTS_IN_DIFF)
|
||||
return GSK_DIFF_ABORTED;
|
||||
|
||||
return GSK_DIFF_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user