naïve row-based clipping

This commit is contained in:
K. Lange 2018-03-01 12:34:58 +09:00 committed by Kevin Lange
parent 5d6317f122
commit 0cbfde23da
3 changed files with 54 additions and 0 deletions

View File

@ -573,6 +573,8 @@ static void load_fonts(yutani_globals_t * yg) {
* Add a clip region from a rectangle.
*/
static void yutani_add_clip(yutani_globals_t * yg, double x, double y, double w, double h) {
gfx_add_clip(yg->backend_ctx, (int)x, (int)y, (int)w, (int)h);
#if 0
cairo_rectangle(yg->framebuffer_ctx, x, y, w, h);
if (yg->width > 2490) {
@ -603,6 +605,12 @@ static void restore_cairo_states(yutani_globals_t * yg) {
#endif
}
typedef struct {
int32_t start;
int32_t end;
void * next;
} _clip_t;
/**
* Apply the clips we built earlier.
*/
@ -1179,12 +1187,14 @@ static void redraw_windows(yutani_globals_t * yg) {
}
if (yg->screenshot_frame) {
yutani_screenshot(yg);
}
/* Restore the cairo contexts to reset clip regions */
restore_cairo_states(yg);
gfx_clear_clip(yg->backend_ctx);
if (yg->resize_on_next) {
spin_lock(&yg->redraw_lock);

View File

@ -37,9 +37,35 @@ static inline uint16_t max16(uint16_t a, uint16_t b) {
}
typedef struct {
int32_t start;
int32_t end;
void * next;
} _clip_t;
void gfx_add_clip(gfx_context_t * ctx, int32_t x, int32_t y, int32_t w, int32_t h) {
_clip_t * clip = malloc(sizeof(_clip_t));
clip->start = max(y,0);
clip->end = min(y+h,ctx->height);
clip->next = ctx->clips;
ctx->clips = clip;
}
void gfx_clear_clip(gfx_context_t * ctx) {
_clip_t * clip = ctx->clips;
while (clip) {
_clip_t * tmp = clip->next;
free(clip);
clip = tmp;
}
ctx->clips = NULL;
}
/* Pointer to graphics memory */
void flip(gfx_context_t * ctx) {
if (ctx->clips) {
/// do this differently
}
memcpy(ctx->buffer, ctx->backbuffer, ctx->size);
}
@ -51,6 +77,7 @@ void clearbuffer(gfx_context_t * ctx) {
static int framebuffer_fd = 0;
gfx_context_t * init_graphics_fullscreen() {
gfx_context_t * out = malloc(sizeof(gfx_context_t));
out->clips = NULL;
if (!framebuffer_fd) {
framebuffer_fd = syscall_open("/dev/fb0", 0, 0);
@ -105,6 +132,7 @@ void reinit_graphics_fullscreen(gfx_context_t * out) {
gfx_context_t * init_graphics_sprite(sprite_t * sprite) {
gfx_context_t * out = malloc(sizeof(gfx_context_t));
out->clips = NULL;
out->width = sprite->width;
out->height = sprite->height;
@ -516,12 +544,25 @@ _cleanup_sprite:
free(bufferb);
}
static int _is_in_clip(gfx_context_t * ctx, int32_t y) {
if (!ctx->clips) return 1;
_clip_t * clip = ctx->clips;
while (clip) {
if (y >= clip->start && y <= clip->end) {
return 1;
}
clip = (_clip_t *)clip->next;
}
return 0;
}
void draw_sprite(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_t y) {
int32_t _left = max(x, 0);
int32_t _top = max(y, 0);
int32_t _right = min(x + sprite->width, ctx->width - 1);
int32_t _bottom = min(y + sprite->height, ctx->height - 1);
for (uint16_t _y = 0; _y < sprite->height; ++_y) {
if (!_is_in_clip(ctx, y + _y)) continue;
for (uint16_t _x = 0; _x < sprite->width; ++_x) {
if (x + _x < _left || x + _x > _right || y + _y < _top || y + _y > _bottom)
continue;

View File

@ -38,6 +38,7 @@ typedef struct context {
uint32_t size;
char * buffer;
char * backbuffer;
void * clips;
} gfx_context_t;
gfx_context_t * init_graphics_fullscreen();
@ -81,3 +82,5 @@ void draw_sprite_alpha(gfx_context_t * ctx, sprite_t * sprite, int32_t x, int32_
uint32_t premultiply(uint32_t color);
void gfx_add_clip(gfx_context_t * ctx, int32_t x, int32_t y, int32_t w, int32_t h);
void gfx_clear_clip(gfx_context_t * ctx);