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);
|
return_value_if_fail(b != NULL, NULL);
|
||||||
|
|
||||||
if (b->data != NULL) {
|
if (b->data != NULL) {
|
||||||
|
b->name = bitmap->name;
|
||||||
memcpy((char*)(b->data), bitmap->data, b->line_length * b->h);
|
memcpy((char*)(b->data), bitmap->data, b->line_length * b->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ struct _main_loop_t {
|
|||||||
uint32_t last_loop_time;
|
uint32_t last_loop_time;
|
||||||
widget_t* wm;
|
widget_t* wm;
|
||||||
canvas_t canvas;
|
canvas_t canvas;
|
||||||
|
lcd_t* lcd;
|
||||||
};
|
};
|
||||||
|
|
||||||
main_loop_t* main_loop_init(int w, int h);
|
main_loop_t* main_loop_init(int w, int h);
|
||||||
|
@ -35,6 +35,7 @@ typedef struct _lcd_mem_t {
|
|||||||
|
|
||||||
uint32_t line_length;
|
uint32_t line_length;
|
||||||
bitmap_format_t format;
|
bitmap_format_t format;
|
||||||
|
bool_t own_offline_fb;
|
||||||
} lcd_mem_t;
|
} lcd_mem_t;
|
||||||
|
|
||||||
#define lcd_mem_set_line_length(lcd, value) ((lcd_mem_t*)lcd)->line_length = value;
|
#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) {
|
static ret_t lcd_mem_destroy(lcd_t* lcd) {
|
||||||
lcd_mem_t* mem = (lcd_mem_t*)lcd;
|
lcd_mem_t* mem = (lcd_mem_t*)lcd;
|
||||||
|
|
||||||
if (mem->vgcanvas) {
|
if (mem->vgcanvas != NULL) {
|
||||||
vgcanvas_destroy(mem->vgcanvas);
|
vgcanvas_destroy(mem->vgcanvas);
|
||||||
mem->vgcanvas = NULL;
|
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);
|
TKMEM_FREE(lcd);
|
||||||
|
|
||||||
return RET_OK;
|
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);
|
return_value_if_fail(lcd->offline_fb != NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcd->own_offline_fb = alloc;
|
||||||
|
|
||||||
base = &(lcd->base);
|
base = &(lcd->base);
|
||||||
base->begin_frame = lcd_mem_begin_frame;
|
base->begin_frame = lcd_mem_begin_frame;
|
||||||
base->draw_vline = lcd_mem_draw_vline;
|
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->take_snapshot = lcd_mem_take_snapshot;
|
||||||
base->get_desired_bitmap_format = lcd_mem_get_desired_bitmap_format;
|
base->get_desired_bitmap_format = lcd_mem_get_desired_bitmap_format;
|
||||||
base->end_frame = lcd_mem_end_frame;
|
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->resize = lcd_mem_resize;
|
||||||
base->flush = lcd_mem_flush;
|
base->flush = lcd_mem_flush;
|
||||||
base->w = w;
|
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) {
|
static ret_t lcd_sdl2_destroy(lcd_t* lcd) {
|
||||||
lcd_sdl2_t* sdl = (lcd_sdl2_t*)lcd;
|
lcd_sdl2_t* sdl = (lcd_sdl2_t*)lcd;
|
||||||
|
|
||||||
|
lcd_destroy((lcd_t*)(sdl->lcd_mem));
|
||||||
SDL_DestroyTexture(sdl->texture);
|
SDL_DestroyTexture(sdl->texture);
|
||||||
|
memset(sdl, 0x00, sizeof(lcd_sdl2_t));
|
||||||
|
|
||||||
return RET_OK;
|
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);
|
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;
|
lcd_sdl2_t* sdl = (lcd_sdl2_t*)lcd;
|
||||||
|
|
||||||
return lcd_get_desired_bitmap_format((lcd_t*)(sdl->lcd_mem));
|
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));
|
LOOP_SDL_RENDER_SET(l, SDL_CreateRenderer(LOOP_SDL_WINDOW(l), -1, flags));
|
||||||
return_value_if_fail(LOOP_SDL_RENDER(l) != NULL, RET_FAIL);
|
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;
|
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);
|
return_value_if_fail(loop != NULL, RET_BAD_PARAMS);
|
||||||
event_queue_destroy(loop->queue);
|
event_queue_destroy(loop->queue);
|
||||||
tk_mutex_destroy(loop->mutex);
|
tk_mutex_destroy(loop->mutex);
|
||||||
|
lcd_destroy(loop->base.lcd);
|
||||||
|
|
||||||
memset(loop, 0x00, sizeof(main_loop_simple_t));
|
memset(loop, 0x00, sizeof(main_loop_simple_t));
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "base/vgcanvas.h"
|
#include "base/vgcanvas.h"
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
#include "tkc/mem.h"
|
#include "tkc/mem.h"
|
||||||
|
#include "tkc/darray.h"
|
||||||
|
|
||||||
typedef enum _cairo_source_type_t {
|
typedef enum _cairo_source_type_t {
|
||||||
CAIRO_SOURCE_NONE = 0,
|
CAIRO_SOURCE_NONE = 0,
|
||||||
@ -33,6 +34,7 @@ typedef enum _cairo_source_type_t {
|
|||||||
CAIRO_SOURCE_IMAGE,
|
CAIRO_SOURCE_IMAGE,
|
||||||
CAIRO_SOURCE_GRADIENT,
|
CAIRO_SOURCE_GRADIENT,
|
||||||
} cairo_source_type_t;
|
} cairo_source_type_t;
|
||||||
|
|
||||||
typedef struct _vgcanvas_cairo_t {
|
typedef struct _vgcanvas_cairo_t {
|
||||||
vgcanvas_t base;
|
vgcanvas_t base;
|
||||||
|
|
||||||
@ -42,6 +44,8 @@ typedef struct _vgcanvas_cairo_t {
|
|||||||
|
|
||||||
cairo_source_type_t stroke_source_type;
|
cairo_source_type_t stroke_source_type;
|
||||||
cairo_source_type_t fill_source_type;
|
cairo_source_type_t fill_source_type;
|
||||||
|
|
||||||
|
darray_t images;
|
||||||
} vgcanvas_cairo_t;
|
} vgcanvas_cairo_t;
|
||||||
|
|
||||||
ret_t vgcanvas_cairo_begin_frame(vgcanvas_t* vgcanvas, rect_t* dirty_rect) {
|
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;
|
return RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t* vgcanvas_cairo_ensure_image(bitmap_t* img) {
|
static cairo_surface_t* vgcanvas_cairo_ensure_image(vgcanvas_cairo_t* vg, bitmap_t* img) {
|
||||||
cairo_surface_t* surface = (cairo_surface_t*)img->specific;
|
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) {
|
if (surface == NULL) {
|
||||||
bitmap_premulti_alpha(img);
|
surface =
|
||||||
surface = create_surface(img->w, img->h, img->format, (void*)(img->data));
|
create_surface(cairo_img->w, cairo_img->h, cairo_img->format, (void*)(cairo_img->data));
|
||||||
|
|
||||||
if (surface != NULL) {
|
if (surface != NULL) {
|
||||||
img->specific = surface;
|
cairo_img->specific = surface;
|
||||||
img->specific_ctx = NULL;
|
cairo_img->specific_ctx = NULL;
|
||||||
img->specific_destroy = cairo_on_bitmap_destroy;
|
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 fy = (float)dh / sh;
|
||||||
float_t global_alpha = 1;
|
float_t global_alpha = 1;
|
||||||
cairo_t* vg = ((vgcanvas_cairo_t*)vgcanvas)->vg;
|
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);
|
cairo_save(vg);
|
||||||
|
|
||||||
@ -608,6 +622,8 @@ static ret_t vgcanvas_cairo_destroy(vgcanvas_t* vgcanvas) {
|
|||||||
cairo_pattern_destroy(canvas->fill_gradient);
|
cairo_pattern_destroy(canvas->fill_gradient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
darray_deinit(&(canvas->images));
|
||||||
|
|
||||||
return RET_OK;
|
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) {
|
static ret_t vgcanvas_cairo_paint(vgcanvas_t* vgcanvas, bool_t stroke, bitmap_t* img) {
|
||||||
cairo_t* vg = ((vgcanvas_cairo_t*)vgcanvas)->vg;
|
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_set_source_surface(vg, surface, 0, 0);
|
||||||
cairo_pattern_set_filter(cairo_get_source(vg), CAIRO_FILTER_BEST);
|
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,
|
.unbind_fbo = vgcanvas_cairo_unbind_fbo,
|
||||||
.destroy = vgcanvas_cairo_destroy};
|
.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,
|
vgcanvas_t* vgcanvas_create(uint32_t w, uint32_t h, uint32_t stride, bitmap_format_t format,
|
||||||
void* data) {
|
void* data) {
|
||||||
cairo_surface_t* surface = NULL;
|
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);
|
cairo->vg = cairo_create(surface);
|
||||||
return_value_if_fail(cairo->vg, NULL);
|
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");
|
log_debug("vgcanvas_cairo created\n");
|
||||||
return &(cairo->base);
|
return &(cairo->base);
|
||||||
|
Loading…
Reference in New Issue
Block a user