mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-12-01 03:28:53 +08:00
fix vgcanvas_cairo_ensure_image and refactor
This commit is contained in:
parent
1335c176d7
commit
9fa41cb960
@ -433,6 +433,7 @@ bitmap_t* bitmap_clone(bitmap_t* bitmap) {
|
||||
return_value_if_fail(b != NULL, NULL);
|
||||
|
||||
if (b->data != NULL) {
|
||||
b->name = bitmap->name;
|
||||
memcpy((char*)(b->data), bitmap->data, b->line_length * b->h);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ struct _main_loop_t {
|
||||
uint32_t last_loop_time;
|
||||
widget_t* wm;
|
||||
canvas_t canvas;
|
||||
lcd_t* lcd;
|
||||
};
|
||||
|
||||
main_loop_t* main_loop_init(int w, int h);
|
||||
|
@ -35,6 +35,7 @@ typedef struct _lcd_mem_t {
|
||||
|
||||
uint32_t line_length;
|
||||
bitmap_format_t format;
|
||||
bool_t own_offline_fb;
|
||||
} lcd_mem_t;
|
||||
|
||||
#define lcd_mem_set_line_length(lcd, value) ((lcd_mem_t*)lcd)->line_length = value;
|
||||
|
@ -322,18 +322,15 @@ static ret_t lcd_mem_end_frame(lcd_t* lcd) {
|
||||
static ret_t lcd_mem_destroy(lcd_t* lcd) {
|
||||
lcd_mem_t* mem = (lcd_mem_t*)lcd;
|
||||
|
||||
if (mem->vgcanvas) {
|
||||
if (mem->vgcanvas != NULL) {
|
||||
vgcanvas_destroy(mem->vgcanvas);
|
||||
mem->vgcanvas = NULL;
|
||||
}
|
||||
TKMEM_FREE(lcd);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
if (mem->own_offline_fb) {
|
||||
TKMEM_FREE(mem->offline_fb);
|
||||
}
|
||||
|
||||
static ret_t lcd_mem_destroy_offline_fb(lcd_t* lcd) {
|
||||
lcd_mem_t* mem = (lcd_mem_t*)lcd;
|
||||
TKMEM_FREE(mem->offline_fb);
|
||||
TKMEM_FREE(lcd);
|
||||
|
||||
return RET_OK;
|
||||
@ -369,6 +366,8 @@ static lcd_t* lcd_mem_create(wh_t w, wh_t h, bool_t alloc) {
|
||||
return_value_if_fail(lcd->offline_fb != NULL, NULL);
|
||||
}
|
||||
|
||||
lcd->own_offline_fb = alloc;
|
||||
|
||||
base = &(lcd->base);
|
||||
base->begin_frame = lcd_mem_begin_frame;
|
||||
base->draw_vline = lcd_mem_draw_vline;
|
||||
@ -383,7 +382,7 @@ static lcd_t* lcd_mem_create(wh_t w, wh_t h, bool_t alloc) {
|
||||
base->take_snapshot = lcd_mem_take_snapshot;
|
||||
base->get_desired_bitmap_format = lcd_mem_get_desired_bitmap_format;
|
||||
base->end_frame = lcd_mem_end_frame;
|
||||
base->destroy = alloc ? lcd_mem_destroy_offline_fb : lcd_mem_destroy;
|
||||
base->destroy = lcd_mem_destroy;
|
||||
base->resize = lcd_mem_resize;
|
||||
base->flush = lcd_mem_flush;
|
||||
base->w = w;
|
||||
|
@ -124,7 +124,10 @@ static ret_t lcd_sdl2_end_frame(lcd_t* lcd) {
|
||||
|
||||
static ret_t lcd_sdl2_destroy(lcd_t* lcd) {
|
||||
lcd_sdl2_t* sdl = (lcd_sdl2_t*)lcd;
|
||||
|
||||
lcd_destroy((lcd_t*)(sdl->lcd_mem));
|
||||
SDL_DestroyTexture(sdl->texture);
|
||||
memset(sdl, 0x00, sizeof(lcd_sdl2_t));
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -161,7 +164,7 @@ static ret_t lcd_sdl2_take_snapshot(lcd_t* lcd, bitmap_t* img, bool_t auto_rotat
|
||||
return lcd_take_snapshot((lcd_t*)(sdl->lcd_mem), img, auto_rotate);
|
||||
}
|
||||
|
||||
static ret_t lcd_sdl2_get_desired_bitmap_format(lcd_t* lcd) {
|
||||
static bitmap_format_t lcd_sdl2_get_desired_bitmap_format(lcd_t* lcd) {
|
||||
lcd_sdl2_t* sdl = (lcd_sdl2_t*)lcd;
|
||||
|
||||
return lcd_get_desired_bitmap_format((lcd_t*)(sdl->lcd_mem));
|
||||
|
@ -74,7 +74,8 @@ static ret_t main_loop_sdl_fb_create_window(main_loop_simple_t* l) {
|
||||
LOOP_SDL_RENDER_SET(l, SDL_CreateRenderer(LOOP_SDL_WINDOW(l), -1, flags));
|
||||
return_value_if_fail(LOOP_SDL_RENDER(l) != NULL, RET_FAIL);
|
||||
|
||||
canvas_init(&(l->base.canvas), lcd_sdl2_init(LOOP_SDL_RENDER(l)), font_manager());
|
||||
l->base.lcd = lcd_sdl2_init(LOOP_SDL_RENDER(l));
|
||||
canvas_init(&(l->base.canvas), l->base.lcd, font_manager());
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ ret_t main_loop_simple_reset(main_loop_simple_t* loop) {
|
||||
return_value_if_fail(loop != NULL, RET_BAD_PARAMS);
|
||||
event_queue_destroy(loop->queue);
|
||||
tk_mutex_destroy(loop->mutex);
|
||||
lcd_destroy(loop->base.lcd);
|
||||
|
||||
memset(loop, 0x00, sizeof(main_loop_simple_t));
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "base/vgcanvas.h"
|
||||
#include "cairo.h"
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/darray.h"
|
||||
|
||||
typedef enum _cairo_source_type_t {
|
||||
CAIRO_SOURCE_NONE = 0,
|
||||
@ -33,6 +34,7 @@ typedef enum _cairo_source_type_t {
|
||||
CAIRO_SOURCE_IMAGE,
|
||||
CAIRO_SOURCE_GRADIENT,
|
||||
} cairo_source_type_t;
|
||||
|
||||
typedef struct _vgcanvas_cairo_t {
|
||||
vgcanvas_t base;
|
||||
|
||||
@ -42,6 +44,8 @@ typedef struct _vgcanvas_cairo_t {
|
||||
|
||||
cairo_source_type_t stroke_source_type;
|
||||
cairo_source_type_t fill_source_type;
|
||||
|
||||
darray_t images;
|
||||
} vgcanvas_cairo_t;
|
||||
|
||||
ret_t vgcanvas_cairo_begin_frame(vgcanvas_t* vgcanvas, rect_t* dirty_rect) {
|
||||
@ -426,17 +430,27 @@ static ret_t cairo_on_bitmap_destroy(bitmap_t* img) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static cairo_surface_t* vgcanvas_cairo_ensure_image(bitmap_t* img) {
|
||||
cairo_surface_t* surface = (cairo_surface_t*)img->specific;
|
||||
static cairo_surface_t* vgcanvas_cairo_ensure_image(vgcanvas_cairo_t* vg, bitmap_t* img) {
|
||||
cairo_surface_t* surface = NULL;
|
||||
darray_t* images = &(vg->images);
|
||||
bitmap_t* cairo_img = (bitmap_t*)darray_find(images, img);
|
||||
|
||||
if (cairo_img == NULL) {
|
||||
cairo_img = bitmap_clone(img);
|
||||
return_value_if_fail(cairo_img != NULL, NULL);
|
||||
darray_push(images, cairo_img);
|
||||
bitmap_premulti_alpha(cairo_img);
|
||||
}
|
||||
|
||||
surface = (cairo_surface_t*)(cairo_img->specific);
|
||||
if (surface == NULL) {
|
||||
bitmap_premulti_alpha(img);
|
||||
surface = create_surface(img->w, img->h, img->format, (void*)(img->data));
|
||||
surface =
|
||||
create_surface(cairo_img->w, cairo_img->h, cairo_img->format, (void*)(cairo_img->data));
|
||||
|
||||
if (surface != NULL) {
|
||||
img->specific = surface;
|
||||
img->specific_ctx = NULL;
|
||||
img->specific_destroy = cairo_on_bitmap_destroy;
|
||||
cairo_img->specific = surface;
|
||||
cairo_img->specific_ctx = NULL;
|
||||
cairo_img->specific_destroy = cairo_on_bitmap_destroy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,7 +464,7 @@ static ret_t vgcanvas_cairo_draw_image(vgcanvas_t* vgcanvas, bitmap_t* img, floa
|
||||
float fy = (float)dh / sh;
|
||||
float_t global_alpha = 1;
|
||||
cairo_t* vg = ((vgcanvas_cairo_t*)vgcanvas)->vg;
|
||||
cairo_surface_t* surface = vgcanvas_cairo_ensure_image(img);
|
||||
cairo_surface_t* surface = vgcanvas_cairo_ensure_image((vgcanvas_cairo_t*)vgcanvas, img);
|
||||
|
||||
cairo_save(vg);
|
||||
|
||||
@ -608,6 +622,8 @@ static ret_t vgcanvas_cairo_destroy(vgcanvas_t* vgcanvas) {
|
||||
cairo_pattern_destroy(canvas->fill_gradient);
|
||||
}
|
||||
|
||||
darray_deinit(&(canvas->images));
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@ -728,7 +744,7 @@ static ret_t vgcanvas_cairo_reinit(vgcanvas_t* vgcanvas, uint32_t w, uint32_t h,
|
||||
|
||||
static ret_t vgcanvas_cairo_paint(vgcanvas_t* vgcanvas, bool_t stroke, bitmap_t* img) {
|
||||
cairo_t* vg = ((vgcanvas_cairo_t*)vgcanvas)->vg;
|
||||
cairo_surface_t* surface = vgcanvas_cairo_ensure_image(img);
|
||||
cairo_surface_t* surface = vgcanvas_cairo_ensure_image((vgcanvas_cairo_t*)vgcanvas, img);
|
||||
|
||||
cairo_set_source_surface(vg, surface, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(vg), CAIRO_FILTER_BEST);
|
||||
@ -796,6 +812,16 @@ static const vgcanvas_vtable_t vt = {
|
||||
.unbind_fbo = vgcanvas_cairo_unbind_fbo,
|
||||
.destroy = vgcanvas_cairo_destroy};
|
||||
|
||||
static int cairo_bitmap_cmp(const bitmap_t* a, bitmap_t* b) {
|
||||
return_value_if_fail(a != NULL && a->name != NULL && b != NULL && b->name != NULL, -1);
|
||||
|
||||
if (tk_str_eq(a->name, b->name)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
vgcanvas_t* vgcanvas_create(uint32_t w, uint32_t h, uint32_t stride, bitmap_format_t format,
|
||||
void* data) {
|
||||
cairo_surface_t* surface = NULL;
|
||||
@ -814,6 +840,7 @@ vgcanvas_t* vgcanvas_create(uint32_t w, uint32_t h, uint32_t stride, bitmap_form
|
||||
|
||||
cairo->vg = cairo_create(surface);
|
||||
return_value_if_fail(cairo->vg, NULL);
|
||||
darray_init(&(cairo->images), 10, (tk_destroy_t)bitmap_destroy, (tk_compare_t)cairo_bitmap_cmp);
|
||||
|
||||
log_debug("vgcanvas_cairo created\n");
|
||||
return &(cairo->base);
|
||||
|
Loading…
Reference in New Issue
Block a user