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_convert_main.h"
#include "evas_private.h" #include "evas_private.h"
EAPI Cutout_Rects* EAPI Cutout_Rects *
evas_common_draw_context_cutouts_new(void) evas_common_draw_context_cutouts_new(void)
{ {
Cutout_Rects *rects; Cutout_Rects *rects;
@ -17,6 +17,7 @@ evas_common_draw_context_cutouts_dup(Cutout_Rects *rects2, const Cutout_Rects *r
if (!rects) return; if (!rects) return;
rects2->active = rects->active; rects2->active = rects->active;
rects2->max = rects->max; rects2->max = rects->max;
rects2->last_add = rects->last_add;
if (rects->max > 0) if (rects->max > 0)
{ {
const size_t sz = sizeof(Cutout_Rect) * rects->max; 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; if (!rects) return;
rects->active = 0; rects->active = 0;
rects->last_add.w = 0;
} }
EAPI void EAPI void
@ -39,10 +41,11 @@ evas_common_draw_context_cutouts_del(Cutout_Rects* rects, int idx)
{ {
Cutout_Rect *rect; Cutout_Rect *rect;
rect = rects->rects + idx; rect = rects->rects + idx;
memmove(rect, rect + 1, memmove(rect, rect + 1,
sizeof(Cutout_Rect) * (rects->active - idx - 1)); sizeof(Cutout_Rect) * (rects->active - idx - 1));
rects->active--; 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 (dc->clip.use)
{ {
#if 1 // this is a bit faster #if 1 // this is a bit faster
int xa1, xa2, xb1, xb2; int x1, x2, y1, y2;
int cx1, cx2, cy1, cy2;
xa1 = x; x2 = x + w;
xa2 = xa1 + w - 1; cx1 = dc->clip.x;
xb1 = dc->clip.x; if (x2 <= cx1) return;
if (xa2 < xb1) return; x1 = x;
xb2 = xb1 + dc->clip.w - 1; cx2 = cx1 + dc->clip.w;
if (xa1 >= xb2) return; if (x1 >= cx2) return;
if (xa2 > xb2) xa2 = xb2;
if (xb1 > xa1) xa1 = xb1;
x = xa1;
w = xa2 - xa1 + 1;
xa1 = y; if (x1 < cx1) x1 = cx1;
xa2 = xa1 + h - 1; if (x2 > cx2) x2 = cx2;
xb1 = dc->clip.y;
if (xa2 < xb1) return; y2 = y + h;
xb2 = xb1 + dc->clip.h - 1; cy1 = dc->clip.y;
if (xa1 >= xb2) return; if (y2 <= cy1) return;
if (xa2 > xb2) xa2 = xb2; y1 = y;
if (xb1 > xa1) xa1 = xb1; cy2 = cy1 + dc->clip.h;
y = xa1; if (y1 >= cy2) return;
h = xa2 - xa1 + 1;
if (y1 < cy1) y1 = cy1;
if (y2 > cy2) y2 = cy2;
x = x1;
y = y1;
w = x2 - x1;
h = y2 - y1;
#else #else
RECTS_CLIP_TO_RECT(x, y, w, h, 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 #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); evas_common_draw_context_cutouts_add(&dc->cutout, x, y, w, h);
} }
int static int
evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *split) evas_common_draw_context_cutout_split(Cutout_Rects *res, int idx, Cutout_Rect *split)
{ {
/* 1 input rect, multiple out */ /* 1 input rect, multiple out */
Cutout_Rect in = res->rects[idx]; 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 #undef R_NEW
} }
EAPI Cutout_Rects* EAPI Cutout_Rects *
evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse) evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse)
{ {
Cutout_Rects* res = NULL; Cutout_Rects *res = NULL;
int i; int i;
int j; int j;
@ -595,7 +611,7 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reus
if (res->active > 1) if (res->active > 1)
{ {
int found = 1; int found = 1;
while (found) while (found)
{ {
found = 0; found = 0;
@ -659,19 +675,20 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reus
} }
EAPI void 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); evas_common_draw_context_apply_clean_cutouts(rects);
free(rects); free(rects);
} }
EAPI void 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); free(rects->rects);
rects->rects = NULL; rects->rects = NULL;
rects->active = 0; rects->active = 0;
rects->max = 0; rects->max = 0;
rects->last_add.w = 0;
} }
EAPI void 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_Font_Glyph_Out RGBA_Font_Glyph_Out;
typedef struct _RGBA_Gfx_Compositor RGBA_Gfx_Compositor; 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 _Cutout_Rects Cutout_Rects;
typedef struct _Convert_Pal Convert_Pal; typedef struct _Convert_Pal Convert_Pal;
@ -706,9 +706,12 @@ struct _Cutout_Rect
struct _Cutout_Rects struct _Cutout_Rects
{ {
Cutout_Rect* rects; Cutout_Rect *rects;
int active; int active;
int max; int max;
struct {
int x, w, y, h;
} last_add;
}; };
struct _Evas_Common_Transform 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)) if (rects->max < (rects->active + 1))
{ {
rects->max += 128; rects->max += 512;
rects->rects = (Cutout_Rect *)realloc(rects->rects, sizeof(Cutout_Rect) * rects->max); 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 etc1_subimage : 1;
Eina_Bool s3tc : 1; Eina_Bool s3tc : 1;
// tuning params - per gpu/cpu combo? // tuning params - per gpu/cpu combo?
#define MAX_CUTOUT 512 #define DEF_CUTOUT 4096
#define DEF_CUTOUT 512
#define MAX_PIPES 128 #define MAX_PIPES 128
#define DEF_PIPES 32 #define DEF_PIPES 32