evas cutouts - optimize to use less cpu

this optimizes draw ctxt cutouts by skipping small ones and
remembering the last cutout added so it isn't double-added as well as
extending the minimum cutout array to 512 and going up in blocks of
512 instead of 128. also optimize the clipping code a bit more.
This commit is contained in:
Carsten Haitzler 2015-09-24 14:06:40 +09:00
parent 49adf8aa47
commit 217faeebe8
4 changed files with 57 additions and 38 deletions

View File

@ -2,7 +2,7 @@
#include "evas_convert_main.h"
#include "evas_private.h"
EAPI Cutout_Rects*
EAPI Cutout_Rects *
evas_common_draw_context_cutouts_new(void)
{
Cutout_Rects *rects;
@ -17,6 +17,7 @@ evas_common_draw_context_cutouts_dup(Cutout_Rects *rects2, const Cutout_Rects *r
if (!rects) return;
rects2->active = rects->active;
rects2->max = rects->max;
rects2->last_add = rects->last_add;
if (rects->max > 0)
{
const size_t sz = sizeof(Cutout_Rect) * rects->max;
@ -30,6 +31,7 @@ evas_common_draw_context_cutouts_free(Cutout_Rects* rects)
{
if (!rects) return;
rects->active = 0;
rects->last_add.w = 0;
}
EAPI void
@ -39,10 +41,11 @@ evas_common_draw_context_cutouts_del(Cutout_Rects* rects, int idx)
{
Cutout_Rect *rect;
rect = rects->rects + idx;
rect = rects->rects + idx;
memmove(rect, rect + 1,
sizeof(Cutout_Rect) * (rects->active - idx - 1));
sizeof(Cutout_Rect) * (rects->active - idx - 1));
rects->active--;
rects->last_add.w = 0;
}
}
@ -228,40 +231,53 @@ evas_common_draw_context_add_cutout(RGBA_Draw_Context *dc, int x, int y, int w,
if (dc->clip.use)
{
#if 1 // this is a bit faster
int xa1, xa2, xb1, xb2;
int x1, x2, y1, y2;
int cx1, cx2, cy1, cy2;
xa1 = x;
xa2 = xa1 + w - 1;
xb1 = dc->clip.x;
if (xa2 < xb1) return;
xb2 = xb1 + dc->clip.w - 1;
if (xa1 >= xb2) return;
if (xa2 > xb2) xa2 = xb2;
if (xb1 > xa1) xa1 = xb1;
x = xa1;
w = xa2 - xa1 + 1;
x2 = x + w;
cx1 = dc->clip.x;
if (x2 <= cx1) return;
x1 = x;
cx2 = cx1 + dc->clip.w;
if (x1 >= cx2) return;
xa1 = y;
xa2 = xa1 + h - 1;
xb1 = dc->clip.y;
if (xa2 < xb1) return;
xb2 = xb1 + dc->clip.h - 1;
if (xa1 >= xb2) return;
if (xa2 > xb2) xa2 = xb2;
if (xb1 > xa1) xa1 = xb1;
y = xa1;
h = xa2 - xa1 + 1;
if (x1 < cx1) x1 = cx1;
if (x2 > cx2) x2 = cx2;
y2 = y + h;
cy1 = dc->clip.y;
if (y2 <= cy1) return;
y1 = y;
cy2 = cy1 + dc->clip.h;
if (y1 >= cy2) return;
if (y1 < cy1) y1 = cy1;
if (y2 > cy2) y2 = cy2;
x = x1;
y = y1;
w = x2 - x1;
h = y2 - y1;
#else
RECTS_CLIP_TO_RECT(x, y, w, h,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
#endif
if ((w < 1) || (h < 1)) return;
}
if ((w * h) <= (8 * 8)) return;
if (dc->cutout.last_add.w > 0)
{
if ((dc->cutout.last_add.x == x) && (dc->cutout.last_add.y == y) &&
(dc->cutout.last_add.w == w) && (dc->cutout.last_add.h == h)) return;
}
dc->cutout.last_add.x = x;
dc->cutout.last_add.y = y;
dc->cutout.last_add.w = w;
dc->cutout.last_add.h = h;
evas_common_draw_context_cutouts_add(&dc->cutout, x, y, w, h);
}
int
evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *split)
static int
evas_common_draw_context_cutout_split(Cutout_Rects *res, int idx, Cutout_Rect *split)
{
/* 1 input rect, multiple out */
Cutout_Rect in = res->rects[idx];
@ -554,10 +570,10 @@ evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *s
#undef R_NEW
}
EAPI Cutout_Rects*
EAPI Cutout_Rects *
evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse)
{
Cutout_Rects* res = NULL;
Cutout_Rects *res = NULL;
int i;
int j;
@ -595,7 +611,7 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reus
if (res->active > 1)
{
int found = 1;
while (found)
{
found = 0;
@ -659,19 +675,20 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reus
}
EAPI void
evas_common_draw_context_apply_clear_cutouts(Cutout_Rects* rects)
evas_common_draw_context_apply_clear_cutouts(Cutout_Rects *rects)
{
evas_common_draw_context_apply_clean_cutouts(rects);
free(rects);
}
EAPI void
evas_common_draw_context_apply_clean_cutouts(Cutout_Rects* rects)
evas_common_draw_context_apply_clean_cutouts(Cutout_Rects *rects)
{
free(rects->rects);
rects->rects = NULL;
rects->active = 0;
rects->max = 0;
rects->last_add.w = 0;
}
EAPI void

View File

@ -427,7 +427,7 @@ typedef struct _RGBA_Font_Glyph RGBA_Font_Glyph;
typedef struct _RGBA_Font_Glyph_Out RGBA_Font_Glyph_Out;
typedef struct _RGBA_Gfx_Compositor RGBA_Gfx_Compositor;
typedef struct _Cutout_Rect Cutout_Rect;
typedef struct _Cutout_Rect Cutout_Rect;
typedef struct _Cutout_Rects Cutout_Rects;
typedef struct _Convert_Pal Convert_Pal;
@ -706,9 +706,12 @@ struct _Cutout_Rect
struct _Cutout_Rects
{
Cutout_Rect* rects;
Cutout_Rect *rects;
int active;
int max;
struct {
int x, w, y, h;
} last_add;
};
struct _Evas_Common_Transform

View File

@ -49,7 +49,7 @@ evas_common_draw_context_cutouts_add(Cutout_Rects* rects,
if (rects->max < (rects->active + 1))
{
rects->max += 128;
rects->max += 512;
rects->rects = (Cutout_Rect *)realloc(rects->rects, sizeof(Cutout_Rect) * rects->max);
}

View File

@ -381,8 +381,7 @@ struct _Evas_GL_Shared
Eina_Bool etc1_subimage : 1;
Eina_Bool s3tc : 1;
// tuning params - per gpu/cpu combo?
#define MAX_CUTOUT 512
#define DEF_CUTOUT 512
#define DEF_CUTOUT 4096
#define MAX_PIPES 128
#define DEF_PIPES 32