perf(sdl): optimize the use of SDL_RenderSetClipRect (#2941)
* reduce SDL_RenderSetClipRect as much as possible * added some comments * removing draw_sw usage * fixed import * implemented polygon drawing * supports subimage for sdl texture based images * fixed formatting * removed unused code * cleanup * cleanup * formatted code
This commit is contained in:
@@ -28,6 +28,7 @@ extern "C" {
|
|||||||
void lv_example_event_1(void);
|
void lv_example_event_1(void);
|
||||||
void lv_example_event_2(void);
|
void lv_example_event_2(void);
|
||||||
void lv_example_event_3(void);
|
void lv_example_event_3(void);
|
||||||
|
void lv_example_event_4(void);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
|
|||||||
65
examples/event/lv_example_event_4.c
Normal file
65
examples/event/lv_example_event_4.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#include "../lv_examples.h"
|
||||||
|
|
||||||
|
#if LV_BUILD_EXAMPLES
|
||||||
|
|
||||||
|
static int n = 3;
|
||||||
|
static lv_obj_t * label = NULL;
|
||||||
|
|
||||||
|
static void timer_cb(lv_timer_t * timer)
|
||||||
|
{
|
||||||
|
if (n < 3 || n > 32) {
|
||||||
|
n = 3;
|
||||||
|
} else {
|
||||||
|
static uint32_t old_tick = 0;
|
||||||
|
uint32_t tick = lv_tick_get();
|
||||||
|
if (!old_tick) {
|
||||||
|
old_tick = tick;
|
||||||
|
}
|
||||||
|
if (tick - old_tick > 3000) {
|
||||||
|
n++;
|
||||||
|
lv_label_set_text_fmt(label, "%d sides", n);
|
||||||
|
old_tick = tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lv_obj_invalidate(timer->user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void event_cb(lv_event_t * e)
|
||||||
|
{
|
||||||
|
/*The original target of the event. Can be the buttons or the container*/
|
||||||
|
lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);
|
||||||
|
lv_draw_rect_dsc_t draw_dsc;
|
||||||
|
lv_draw_rect_dsc_init(&draw_dsc);
|
||||||
|
draw_dsc.bg_color = lv_palette_main(LV_PALETTE_LIGHT_GREEN);
|
||||||
|
draw_dsc.bg_opa = LV_OPA_COVER;
|
||||||
|
lv_point_t points[32];
|
||||||
|
int i, r = 150;
|
||||||
|
uint32_t tick = lv_tick_get();
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int angle = i * 360 / n + ((tick % 36000) / 100);
|
||||||
|
lv_coord_t x = 150 + (r * lv_trigo_cos(angle) >> LV_TRIGO_SHIFT), y =
|
||||||
|
150 + (r * lv_trigo_sin(angle) >> LV_TRIGO_SHIFT);
|
||||||
|
points[i].x = x;
|
||||||
|
points[i].y = y;
|
||||||
|
}
|
||||||
|
lv_draw_polygon(draw_ctx, &draw_dsc, points, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrate event bubbling
|
||||||
|
*/
|
||||||
|
void lv_example_event_4(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
lv_obj_t * cont = lv_obj_create(lv_scr_act());
|
||||||
|
lv_obj_remove_style_all(cont);
|
||||||
|
lv_obj_set_size(cont, 300, 300);
|
||||||
|
label = lv_label_create(cont);
|
||||||
|
lv_label_set_text_fmt(label, "%d sides", n);
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
lv_obj_add_event_cb(cont, event_cb, LV_EVENT_DRAW_MAIN, NULL);
|
||||||
|
lv_timer_create(timer_cb, 17, cont);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -41,6 +41,9 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_fade(lv_opa_t * mas
|
|||||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||||
lv_coord_t abs_y, lv_coord_t len,
|
lv_coord_t abs_y, lv_coord_t len,
|
||||||
lv_draw_mask_map_param_t * param);
|
lv_draw_mask_map_param_t * param);
|
||||||
|
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_polygon(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||||
|
lv_coord_t abs_y, lv_coord_t len,
|
||||||
|
lv_draw_mask_polygon_param_t * param);
|
||||||
|
|
||||||
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t line_mask_flat(lv_opa_t * mask_buf, lv_coord_t abs_x, lv_coord_t abs_y,
|
||||||
lv_coord_t len,
|
lv_coord_t len,
|
||||||
@@ -219,6 +222,10 @@ void lv_draw_mask_free_param(void * p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(pdsc->type == LV_DRAW_MASK_TYPE_POLYGON) {
|
||||||
|
lv_draw_mask_polygon_param_t * poly_p = (lv_draw_mask_polygon_param_t *) p;
|
||||||
|
lv_mem_free(poly_p->cfg.points);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _lv_draw_mask_cleanup(void)
|
void _lv_draw_mask_cleanup(void)
|
||||||
@@ -560,6 +567,31 @@ void lv_draw_mask_map_init(lv_draw_mask_map_param_t * param, const lv_area_t * c
|
|||||||
param->dsc.type = LV_DRAW_MASK_TYPE_MAP;
|
param->dsc.type = LV_DRAW_MASK_TYPE_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv_draw_mask_polygon_init(lv_draw_mask_polygon_param_t * param, const lv_point_t * points, uint16_t point_cnt)
|
||||||
|
{
|
||||||
|
/*Join adjacent points if they are on the same coordinate*/
|
||||||
|
lv_point_t * p = lv_mem_alloc(point_cnt * sizeof(lv_point_t));
|
||||||
|
if(p == NULL) return;
|
||||||
|
uint16_t i;
|
||||||
|
uint16_t pcnt = 0;
|
||||||
|
p[0] = points[0];
|
||||||
|
for(i = 0; i < point_cnt - 1; i++) {
|
||||||
|
if(points[i].x != points[i + 1].x || points[i].y != points[i + 1].y) {
|
||||||
|
p[pcnt] = points[i];
|
||||||
|
pcnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*The first and the last points are also adjacent*/
|
||||||
|
if(points[0].x != points[point_cnt - 1].x || points[0].y != points[point_cnt - 1].y) {
|
||||||
|
p[pcnt] = points[point_cnt - 1];
|
||||||
|
pcnt++;
|
||||||
|
}
|
||||||
|
param->cfg.points = p;
|
||||||
|
param->cfg.point_cnt = pcnt;
|
||||||
|
param->dsc.cb = (lv_draw_mask_xcb_t)lv_draw_mask_polygon;
|
||||||
|
param->dsc.type = LV_DRAW_MASK_TYPE_POLYGON;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
@@ -1218,6 +1250,79 @@ LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_map(lv_opa_t * mask
|
|||||||
return LV_DRAW_MASK_RES_CHANGED;
|
return LV_DRAW_MASK_RES_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LV_ATTRIBUTE_FAST_MEM static lv_draw_mask_res_t lv_draw_mask_polygon(lv_opa_t * mask_buf, lv_coord_t abs_x,
|
||||||
|
lv_coord_t abs_y, lv_coord_t len,
|
||||||
|
lv_draw_mask_polygon_param_t * param)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
struct {
|
||||||
|
lv_point_t p1;
|
||||||
|
lv_point_t p2;
|
||||||
|
} lines[2], tmp;
|
||||||
|
uint16_t line_cnt = 0;
|
||||||
|
lv_memset_00(&lines, sizeof(lines));
|
||||||
|
int psign_prev = 0;
|
||||||
|
for(i = 0; i < param->cfg.point_cnt; i++) {
|
||||||
|
lv_point_t p1 = param->cfg.points[i];
|
||||||
|
lv_point_t p2 = param->cfg.points[i + 1 < param->cfg.point_cnt ? i + 1 : 0];
|
||||||
|
int pdiff = p1.y - p2.y, psign = pdiff / LV_ABS(pdiff);
|
||||||
|
if(pdiff > 0) {
|
||||||
|
if(abs_y > p1.y || abs_y < p2.y) continue;
|
||||||
|
lines[line_cnt].p1 = p2;
|
||||||
|
lines[line_cnt].p2 = p1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(abs_y < p1.y || abs_y > p2.y) continue;
|
||||||
|
lines[line_cnt].p1 = p1;
|
||||||
|
lines[line_cnt].p2 = p2;
|
||||||
|
}
|
||||||
|
if(psign_prev && psign_prev == psign) continue;
|
||||||
|
psign_prev = psign;
|
||||||
|
line_cnt++;
|
||||||
|
if(line_cnt == 2) break;
|
||||||
|
}
|
||||||
|
if(line_cnt != 2) return LV_DRAW_MASK_RES_TRANSP;
|
||||||
|
if(lines[0].p1.x > lines[1].p1.x || lines[0].p2.x > lines[1].p2.x) {
|
||||||
|
tmp = lines[0];
|
||||||
|
lines[0] = lines[1];
|
||||||
|
lines[1] = tmp;
|
||||||
|
}
|
||||||
|
lv_draw_mask_line_param_t line_p;
|
||||||
|
lv_draw_mask_line_points_init(&line_p, lines[0].p1.x, lines[0].p1.y, lines[0].p2.x, lines[0].p2.y,
|
||||||
|
LV_DRAW_MASK_LINE_SIDE_RIGHT);
|
||||||
|
if(line_p.steep == 0 && line_p.flat) {
|
||||||
|
lv_coord_t x1 = LV_MIN(lines[0].p1.x, lines[0].p2.x);
|
||||||
|
lv_coord_t x2 = LV_MAX(lines[0].p1.x, lines[0].p2.x);
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
mask_buf[i] = mask_mix(mask_buf[i], (abs_x + i >= x1 && abs_x + i <= x2) * 0xFF);
|
||||||
|
}
|
||||||
|
lv_draw_mask_free_param(&line_p);
|
||||||
|
return LV_DRAW_MASK_RES_CHANGED;
|
||||||
|
}
|
||||||
|
lv_draw_mask_res_t res1 = lv_draw_mask_line(mask_buf, abs_x, abs_y, len, &line_p);
|
||||||
|
lv_draw_mask_free_param(&line_p);
|
||||||
|
if(res1 == LV_DRAW_MASK_RES_TRANSP) {
|
||||||
|
return LV_DRAW_MASK_RES_TRANSP;
|
||||||
|
}
|
||||||
|
lv_draw_mask_line_points_init(&line_p, lines[1].p1.x, lines[1].p1.y, lines[1].p2.x, lines[1].p2.y,
|
||||||
|
LV_DRAW_MASK_LINE_SIDE_LEFT);
|
||||||
|
if(line_p.steep == 0 && line_p.flat) {
|
||||||
|
lv_coord_t x1 = LV_MIN(lines[1].p1.x, lines[1].p2.x);
|
||||||
|
lv_coord_t x2 = LV_MAX(lines[1].p1.x, lines[1].p2.x);
|
||||||
|
for(i = 0; i < len; i++) {
|
||||||
|
mask_buf[i] = mask_mix(mask_buf[i], (abs_x + i >= x1 && abs_x + i <= x2) * 0xFF);
|
||||||
|
}
|
||||||
|
lv_draw_mask_free_param(&line_p);
|
||||||
|
return LV_DRAW_MASK_RES_CHANGED;
|
||||||
|
}
|
||||||
|
lv_draw_mask_res_t res2 = lv_draw_mask_line(mask_buf, abs_x, abs_y, len, &line_p);
|
||||||
|
lv_draw_mask_free_param(&line_p);
|
||||||
|
if(res2 == LV_DRAW_MASK_RES_TRANSP) {
|
||||||
|
return LV_DRAW_MASK_RES_TRANSP;
|
||||||
|
}
|
||||||
|
if(res1 == LV_DRAW_MASK_RES_CHANGED || res2 == LV_DRAW_MASK_RES_CHANGED) return LV_DRAW_MASK_RES_CHANGED;
|
||||||
|
return res1;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Initialize the circle drawing
|
* Initialize the circle drawing
|
||||||
* @param c pointer to a point. The coordinates will be calculated here
|
* @param c pointer to a point. The coordinates will be calculated here
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ enum {
|
|||||||
LV_DRAW_MASK_TYPE_RADIUS,
|
LV_DRAW_MASK_TYPE_RADIUS,
|
||||||
LV_DRAW_MASK_TYPE_FADE,
|
LV_DRAW_MASK_TYPE_FADE,
|
||||||
LV_DRAW_MASK_TYPE_MAP,
|
LV_DRAW_MASK_TYPE_MAP,
|
||||||
|
LV_DRAW_MASK_TYPE_POLYGON,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint8_t lv_draw_mask_type_t;
|
typedef uint8_t lv_draw_mask_type_t;
|
||||||
@@ -204,6 +205,16 @@ typedef struct _lv_draw_mask_map_param_t {
|
|||||||
} cfg;
|
} cfg;
|
||||||
} lv_draw_mask_map_param_t;
|
} lv_draw_mask_map_param_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*The first element must be the common descriptor*/
|
||||||
|
_lv_draw_mask_common_dsc_t dsc;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
lv_point_t * points;
|
||||||
|
uint16_t point_cnt;
|
||||||
|
} cfg;
|
||||||
|
} lv_draw_mask_polygon_param_t;
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
@@ -368,6 +379,8 @@ void lv_draw_mask_fade_init(lv_draw_mask_fade_param_t * param, const lv_area_t *
|
|||||||
*/
|
*/
|
||||||
void lv_draw_mask_map_init(lv_draw_mask_map_param_t * param, const lv_area_t * coords, const lv_opa_t * map);
|
void lv_draw_mask_map_init(lv_draw_mask_map_param_t * param, const lv_area_t * coords, const lv_opa_t * map);
|
||||||
|
|
||||||
|
void lv_draw_mask_polygon_init(lv_draw_mask_polygon_param_t * param, const lv_point_t * points, uint16_t point_cnt);
|
||||||
|
|
||||||
#endif /*LV_DRAW_COMPLEX*/
|
#endif /*LV_DRAW_COMPLEX*/
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t *
|
|||||||
void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * dsc, const lv_point_t * center,
|
||||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle);
|
uint16_t radius, uint16_t start_angle, uint16_t end_angle);
|
||||||
|
|
||||||
void lv_draw_sdl_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * draw_dsc, const lv_point_t * points,
|
||||||
|
uint16_t point_cnt);
|
||||||
|
|
||||||
void lv_draw_sdl_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
void lv_draw_sdl_draw_bg(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * dsc, const lv_area_t * coords);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
@@ -61,16 +62,15 @@ void lv_draw_sdl_init_ctx(lv_disp_drv_t * disp_drv, lv_draw_ctx_t * draw_ctx)
|
|||||||
{
|
{
|
||||||
_lv_draw_sdl_utils_init();
|
_lv_draw_sdl_utils_init();
|
||||||
lv_memset_00(draw_ctx, sizeof(lv_draw_sdl_ctx_t));
|
lv_memset_00(draw_ctx, sizeof(lv_draw_sdl_ctx_t));
|
||||||
lv_draw_sw_init_ctx(disp_drv, draw_ctx);
|
|
||||||
draw_ctx->draw_rect = lv_draw_sdl_draw_rect;
|
draw_ctx->draw_rect = lv_draw_sdl_draw_rect;
|
||||||
draw_ctx->draw_img = lv_draw_sdl_img_core;
|
draw_ctx->draw_img = lv_draw_sdl_img_core;
|
||||||
draw_ctx->draw_letter = lv_draw_sdl_draw_letter;
|
draw_ctx->draw_letter = lv_draw_sdl_draw_letter;
|
||||||
draw_ctx->draw_line = lv_draw_sdl_draw_line;
|
draw_ctx->draw_line = lv_draw_sdl_draw_line;
|
||||||
draw_ctx->draw_arc = lv_draw_sdl_draw_arc;
|
draw_ctx->draw_arc = lv_draw_sdl_draw_arc;
|
||||||
|
draw_ctx->draw_polygon = lv_draw_sdl_polygon;
|
||||||
draw_ctx->draw_bg = lv_draw_sdl_draw_bg;
|
draw_ctx->draw_bg = lv_draw_sdl_draw_bg;
|
||||||
lv_draw_sdl_ctx_t * draw_ctx_sdl = (lv_draw_sdl_ctx_t *) draw_ctx;
|
lv_draw_sdl_ctx_t * draw_ctx_sdl = (lv_draw_sdl_ctx_t *) draw_ctx;
|
||||||
draw_ctx_sdl->renderer = ((lv_draw_sdl_drv_param_t *) disp_drv->user_data)->renderer;
|
draw_ctx_sdl->renderer = ((lv_draw_sdl_drv_param_t *) disp_drv->user_data)->renderer;
|
||||||
draw_ctx_sdl->base_draw.blend = lv_draw_sdl_blend;
|
|
||||||
draw_ctx_sdl->internals = lv_mem_alloc(sizeof(lv_draw_sdl_context_internals_t));
|
draw_ctx_sdl->internals = lv_mem_alloc(sizeof(lv_draw_sdl_context_internals_t));
|
||||||
lv_memset_00(draw_ctx_sdl->internals, sizeof(lv_draw_sdl_context_internals_t));
|
lv_memset_00(draw_ctx_sdl->internals, sizeof(lv_draw_sdl_context_internals_t));
|
||||||
lv_draw_sdl_texture_cache_init(draw_ctx_sdl);
|
lv_draw_sdl_texture_cache_init(draw_ctx_sdl);
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ extern "C" {
|
|||||||
|
|
||||||
#include LV_GPU_SDL_INCLUDE_PATH
|
#include LV_GPU_SDL_INCLUDE_PATH
|
||||||
|
|
||||||
#include "../sw/lv_draw_sw.h"
|
#include "../lv_draw.h"
|
||||||
|
#include "../../core/lv_disp.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -46,7 +47,7 @@ typedef struct {
|
|||||||
} lv_draw_sdl_drv_param_t;
|
} lv_draw_sdl_drv_param_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
lv_draw_sw_ctx_t base_draw;
|
lv_draw_ctx_t base_draw;
|
||||||
SDL_Renderer * renderer;
|
SDL_Renderer * renderer;
|
||||||
struct lv_draw_sdl_context_internals_t * internals;
|
struct lv_draw_sdl_context_internals_t * internals;
|
||||||
} lv_draw_sdl_ctx_t;
|
} lv_draw_sdl_ctx_t;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
CSRCS += lv_draw_sdl.c
|
CSRCS += lv_draw_sdl.c
|
||||||
CSRCS += lv_draw_sdl_arc.c
|
CSRCS += lv_draw_sdl_arc.c
|
||||||
CSRCS += lv_draw_sdl_bg.c
|
CSRCS += lv_draw_sdl_bg.c
|
||||||
CSRCS += lv_draw_sdl_blend.c
|
|
||||||
CSRCS += lv_draw_sdl_composite.c
|
CSRCS += lv_draw_sdl_composite.c
|
||||||
CSRCS += lv_draw_sdl_img.c
|
CSRCS += lv_draw_sdl_img.c
|
||||||
CSRCS += lv_draw_sdl_label.c
|
CSRCS += lv_draw_sdl_label.c
|
||||||
CSRCS += lv_draw_sdl_line.c
|
CSRCS += lv_draw_sdl_line.c
|
||||||
CSRCS += lv_draw_sdl_mask.c
|
CSRCS += lv_draw_sdl_mask.c
|
||||||
|
CSRCS += lv_draw_sdl_polygon.c
|
||||||
CSRCS += lv_draw_sdl_rect.c
|
CSRCS += lv_draw_sdl_rect.c
|
||||||
CSRCS += lv_draw_sdl_stack_blur.c
|
CSRCS += lv_draw_sdl_stack_blur.c
|
||||||
CSRCS += lv_draw_sdl_texture_cache.c
|
CSRCS += lv_draw_sdl_texture_cache.c
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @file lv_templ.c
|
* @file lv_draw_sdl_arc.c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
#include "lv_draw_sdl_utils.h"
|
#include "lv_draw_sdl_utils.h"
|
||||||
#include "lv_draw_sdl_texture_cache.h"
|
#include "lv_draw_sdl_texture_cache.h"
|
||||||
#include "lv_draw_sdl_composite.h"
|
#include "lv_draw_sdl_composite.h"
|
||||||
#include "lv_draw_sdl_mask.h"
|
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@@ -24,14 +23,6 @@
|
|||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
lv_sdl_cache_key_magic_t magic;
|
|
||||||
uint16_t radius;
|
|
||||||
uint16_t angle;
|
|
||||||
lv_coord_t width;
|
|
||||||
uint8_t rounded;
|
|
||||||
} lv_draw_arc_key_t;
|
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
@@ -44,9 +35,6 @@ typedef struct {
|
|||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static lv_draw_arc_key_t arc_key_create(const lv_draw_arc_dsc_t * dsc, uint16_t radius, uint16_t start_angle,
|
|
||||||
uint16_t end_angle);
|
|
||||||
|
|
||||||
static void dump_masks(SDL_Texture * texture, const lv_area_t * coords, const int16_t * ids, int16_t ids_count,
|
static void dump_masks(SDL_Texture * texture, const lv_area_t * coords, const int16_t * ids, int16_t ids_count,
|
||||||
const int16_t * caps);
|
const int16_t * caps);
|
||||||
|
|
||||||
@@ -60,7 +48,6 @@ void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * ds
|
|||||||
uint16_t radius, uint16_t start_angle, uint16_t end_angle)
|
uint16_t radius, uint16_t start_angle, uint16_t end_angle)
|
||||||
{
|
{
|
||||||
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
||||||
SDL_Renderer * renderer = ctx->renderer;
|
|
||||||
|
|
||||||
lv_area_t area_out;
|
lv_area_t area_out;
|
||||||
area_out.x1 = center->x - radius;
|
area_out.x1 = center->x - radius;
|
||||||
@@ -154,19 +141,6 @@ void lv_draw_sdl_draw_arc(lv_draw_ctx_t * draw_ctx, const lv_draw_arc_dsc_t * ds
|
|||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static lv_draw_arc_key_t arc_key_create(const lv_draw_arc_dsc_t * dsc, uint16_t radius, uint16_t start_angle,
|
|
||||||
uint16_t end_angle)
|
|
||||||
{
|
|
||||||
lv_draw_arc_key_t key;
|
|
||||||
lv_memset_00(&key, sizeof(lv_draw_arc_key_t));
|
|
||||||
key.magic = LV_GPU_CACHE_KEY_MAGIC_ARC;
|
|
||||||
key.radius = radius;
|
|
||||||
key.angle = ((end_angle - start_angle) % 360 + 360) % 360;
|
|
||||||
key.width = dsc->width;
|
|
||||||
key.rounded = dsc->rounded;
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dump_masks(SDL_Texture * texture, const lv_area_t * coords, const int16_t * ids, int16_t ids_count,
|
static void dump_masks(SDL_Texture * texture, const lv_area_t * coords, const int16_t * ids, int16_t ids_count,
|
||||||
const int16_t * caps)
|
const int16_t * caps)
|
||||||
{
|
{
|
||||||
@@ -233,7 +207,7 @@ static void get_cap_area(int16_t angle, lv_coord_t thickness, uint16_t radius, c
|
|||||||
int32_t cir_x;
|
int32_t cir_x;
|
||||||
int32_t cir_y;
|
int32_t cir_y;
|
||||||
|
|
||||||
cir_x = ((radius - thick_half) * lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps);
|
cir_x = ((radius - thick_half) * lv_trigo_sin((int16_t)(90 - angle))) >> (LV_TRIGO_SHIFT - ps);
|
||||||
cir_y = ((radius - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps);
|
cir_y = ((radius - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps);
|
||||||
|
|
||||||
/*Actually the center of the pixel need to be calculated so apply 1/2 px offset*/
|
/*Actually the center of the pixel need to be calculated so apply 1/2 px offset*/
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file lv_draw_sdl_blend.c
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* INCLUDES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
#include "../../lv_conf_internal.h"
|
|
||||||
|
|
||||||
#if LV_USE_GPU_SDL
|
|
||||||
|
|
||||||
#include "lv_draw_sdl_texture_cache.h"
|
|
||||||
#include "lv_draw_sdl_utils.h"
|
|
||||||
#include "lv_draw_sdl_composite.h"
|
|
||||||
|
|
||||||
#include LV_GPU_SDL_INCLUDE_PATH
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* DEFINES
|
|
||||||
*********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* TYPEDEFS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC PROTOTYPES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
static void blend_fill(lv_draw_sdl_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
|
||||||
|
|
||||||
static void blend_map(lv_draw_sdl_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc);
|
|
||||||
/**********************
|
|
||||||
* STATIC VARIABLES
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* MACROS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* GLOBAL FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void lv_draw_sdl_blend(lv_draw_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
if(dsc->src_buf) {
|
|
||||||
blend_map((lv_draw_sdl_ctx_t *) draw_ctx, dsc);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
blend_fill((lv_draw_sdl_ctx_t *) draw_ctx, dsc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* STATIC FUNCTIONS
|
|
||||||
**********************/
|
|
||||||
|
|
||||||
void blend_fill(lv_draw_sdl_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
const lv_opa_t opa = dsc->opa;
|
|
||||||
const lv_color_t color = dsc->color;
|
|
||||||
/*Do not draw transparent things*/
|
|
||||||
if(opa < LV_OPA_MIN) return;
|
|
||||||
|
|
||||||
SDL_Renderer * renderer = draw_ctx->renderer;
|
|
||||||
|
|
||||||
lv_area_t fill_area;
|
|
||||||
_lv_area_intersect(&fill_area, draw_ctx->base_draw.base_draw.clip_area, dsc->blend_area);
|
|
||||||
SDL_Rect fill_rect;
|
|
||||||
lv_area_to_sdl_rect(&fill_area, &fill_rect);
|
|
||||||
|
|
||||||
if(dsc->mask) {
|
|
||||||
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(draw_ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM0,
|
|
||||||
lv_area_get_height(&fill_area),
|
|
||||||
lv_area_get_width(&fill_area));
|
|
||||||
SDL_Rect rect = {0, 0, lv_area_get_width(&fill_area), lv_area_get_height(&fill_area)};
|
|
||||||
uint8_t * pixels = NULL;
|
|
||||||
int pitch;
|
|
||||||
SDL_LockTexture(texture, &rect, (void **) &pixels, &pitch);
|
|
||||||
SDL_assert(pixels && pitch);
|
|
||||||
for(int y = 0; y < rect.h; y++) {
|
|
||||||
SDL_memset(&pixels[y * pitch], 0xFF, 4 * rect.w);
|
|
||||||
for(int x = 0; x < rect.w; x++) {
|
|
||||||
pixels[y * pitch + x * 4] = dsc->mask[y * rect.w + x];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDL_UnlockTexture(texture);
|
|
||||||
|
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_SetTextureAlphaMod(texture, opa);
|
|
||||||
SDL_SetTextureColorMod(texture, color.ch.red, color.ch.green, color.ch.blue);
|
|
||||||
SDL_RenderCopy(renderer, texture, &rect, &fill_rect);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_SetRenderDrawColor(renderer, color.ch.red, color.ch.green, color.ch.blue, opa);
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_RenderFillRect(renderer, &fill_rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void blend_map(lv_draw_sdl_ctx_t * draw_ctx, const lv_draw_sw_blend_dsc_t * dsc)
|
|
||||||
{
|
|
||||||
const lv_opa_t opa = dsc->opa;
|
|
||||||
/*Do not draw transparent things*/
|
|
||||||
if(opa < LV_OPA_MIN) return;
|
|
||||||
lv_coord_t sw = lv_area_get_width(dsc->blend_area), sh = lv_area_get_height(dsc->blend_area);
|
|
||||||
|
|
||||||
SDL_Renderer * renderer = draw_ctx->renderer;
|
|
||||||
|
|
||||||
SDL_Rect draw_area_rect;
|
|
||||||
lv_area_to_sdl_rect(draw_ctx->base_draw.base_draw.clip_area, &draw_area_rect);
|
|
||||||
|
|
||||||
Uint32 rmask = 0x00FF0000;
|
|
||||||
Uint32 gmask = 0x0000FF00;
|
|
||||||
Uint32 bmask = 0x000000FF;
|
|
||||||
Uint32 amask = 0x00000000;
|
|
||||||
SDL_Surface * surface = SDL_CreateRGBSurfaceFrom((void *) dsc->src_buf, sw, sh, LV_COLOR_DEPTH,
|
|
||||||
sw * LV_COLOR_DEPTH / 8, rmask, gmask, bmask, amask);
|
|
||||||
if(dsc->mask) {
|
|
||||||
SDL_Texture * masked = SDL_CreateTexture(renderer, LV_DRAW_SDL_TEXTURE_FORMAT, SDL_TEXTUREACCESS_TARGET,
|
|
||||||
sw, sh);
|
|
||||||
SDL_Texture * mask_texture = lv_sdl_create_opa_texture(renderer, dsc->mask, sw, sh, sw);
|
|
||||||
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
||||||
SDL_SetRenderTarget(renderer, masked);
|
|
||||||
|
|
||||||
SDL_SetTextureAlphaMod(mask_texture, opa);
|
|
||||||
SDL_SetTextureBlendMode(mask_texture, SDL_BLENDMODE_NONE);
|
|
||||||
SDL_RenderCopy(renderer, mask_texture, NULL, NULL);
|
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_MOD);
|
|
||||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
|
||||||
|
|
||||||
SDL_SetRenderTarget(renderer, draw_ctx->base_draw.base_draw.buf);
|
|
||||||
SDL_SetTextureBlendMode(masked, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_SetTextureAlphaMod(masked, 0xFF);
|
|
||||||
SDL_SetTextureColorMod(masked, 0xFF, 0xFF, 0xFF);
|
|
||||||
SDL_RenderCopy(renderer, masked, NULL, &draw_area_rect);
|
|
||||||
SDL_DestroyTexture(texture);
|
|
||||||
SDL_DestroyTexture(mask_texture);
|
|
||||||
SDL_DestroyTexture(masked);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
||||||
SDL_SetTextureAlphaMod(texture, opa);
|
|
||||||
SDL_SetRenderTarget(renderer, draw_ctx->base_draw.base_draw.buf);
|
|
||||||
SDL_RenderCopy(renderer, texture, NULL, &draw_area_rect);
|
|
||||||
SDL_DestroyTexture(texture);
|
|
||||||
}
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*LV_USE_GPU_SDL*/
|
|
||||||
@@ -141,7 +141,7 @@ void lv_draw_sdl_composite_end(lv_draw_sdl_ctx_t * ctx, const lv_area_t * apply_
|
|||||||
SDL_Rect dst_rect;
|
SDL_Rect dst_rect;
|
||||||
lv_area_to_sdl_rect(apply_area, &dst_rect);
|
lv_area_to_sdl_rect(apply_area, &dst_rect);
|
||||||
|
|
||||||
SDL_SetRenderTarget(ctx->renderer, ctx->base_draw.base_draw.buf);
|
SDL_SetRenderTarget(ctx->renderer, ctx->base_draw.buf);
|
||||||
switch(blend_mode) {
|
switch(blend_mode) {
|
||||||
case LV_BLEND_MODE_NORMAL:
|
case LV_BLEND_MODE_NORMAL:
|
||||||
SDL_SetTextureBlendMode(internals->composition, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(internals->composition, SDL_BLENDMODE_BLEND);
|
||||||
|
|||||||
@@ -26,7 +26,10 @@
|
|||||||
/**********************
|
/**********************
|
||||||
* TYPEDEFS
|
* TYPEDEFS
|
||||||
**********************/
|
**********************/
|
||||||
|
typedef struct sdl_img_header_t {
|
||||||
|
lv_img_header_t base;
|
||||||
|
SDL_Rect rect;
|
||||||
|
} sdl_img_header_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC PROTOTYPES
|
* STATIC PROTOTYPES
|
||||||
@@ -58,15 +61,20 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
size_t key_size;
|
size_t key_size;
|
||||||
lv_draw_sdl_cache_key_head_img_t * key = lv_draw_sdl_texture_img_key_create(src, draw_dsc->frame_id, &key_size);
|
lv_draw_sdl_cache_key_head_img_t * key = lv_draw_sdl_texture_img_key_create(src, draw_dsc->frame_id, &key_size);
|
||||||
bool texture_found = false;
|
bool texture_found = false;
|
||||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(ctx, key, key_size, &texture_found);
|
sdl_img_header_t * header = NULL;
|
||||||
|
SDL_Texture * texture = lv_draw_sdl_texture_cache_get_with_userdata(ctx, key, key_size, &texture_found,
|
||||||
|
(void **) &header);
|
||||||
if(!texture_found) {
|
if(!texture_found) {
|
||||||
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor, draw_dsc->frame_id);
|
_lv_img_cache_entry_t * cdsc = _lv_img_cache_open(src, draw_dsc->recolor, draw_dsc->frame_id);
|
||||||
lv_draw_sdl_cache_flag_t tex_flags = 0;
|
lv_draw_sdl_cache_flag_t tex_flags = 0;
|
||||||
|
SDL_Rect rect;
|
||||||
|
SDL_memset(&rect, 0, sizeof(SDL_Rect));
|
||||||
if(cdsc) {
|
if(cdsc) {
|
||||||
lv_img_decoder_dsc_t * dsc = &cdsc->dec_dsc;
|
lv_img_decoder_dsc_t * dsc = &cdsc->dec_dsc;
|
||||||
if(dsc->user_data && SDL_memcmp(dsc->user_data, LV_DRAW_SDL_DEC_DSC_TEXTURE_HEAD, 8) == 0) {
|
if(dsc->user_data && SDL_memcmp(dsc->user_data, LV_DRAW_SDL_DEC_DSC_TEXTURE_HEAD, 8) == 0) {
|
||||||
lv_draw_sdl_dec_dsc_userdata_t * ptr = (lv_draw_sdl_dec_dsc_userdata_t *) dsc->user_data;
|
lv_draw_sdl_dec_dsc_userdata_t * ptr = (lv_draw_sdl_dec_dsc_userdata_t *) dsc->user_data;
|
||||||
texture = ptr->texture;
|
texture = ptr->texture;
|
||||||
|
rect = ptr->rect;
|
||||||
if(ptr->texture_managed) {
|
if(ptr->texture_managed) {
|
||||||
tex_flags |= LV_DRAW_SDL_CACHE_FLAG_MANAGED;
|
tex_flags |= LV_DRAW_SDL_CACHE_FLAG_MANAGED;
|
||||||
}
|
}
|
||||||
@@ -80,8 +88,9 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if(texture && cdsc) {
|
if(texture && cdsc) {
|
||||||
lv_img_header_t * header = SDL_malloc(sizeof(lv_img_header_t));
|
header = SDL_malloc(sizeof(sdl_img_header_t));
|
||||||
SDL_memcpy(header, &cdsc->dec_dsc.header, sizeof(lv_img_header_t));
|
SDL_memcpy(&header->base, &cdsc->dec_dsc.header, sizeof(lv_img_header_t));
|
||||||
|
header->rect = rect;
|
||||||
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, texture, header, SDL_free, tex_flags);
|
lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_size, texture, header, SDL_free, tex_flags);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -100,7 +109,35 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
|
|
||||||
SDL_Point pivot = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
|
SDL_Point pivot = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
SDL_RenderSetClipRect(renderer, &clip_rect);
|
SDL_Rect clipped_src = {0, 0, 0, 0}, clipped_dst = coords_rect;
|
||||||
|
const SDL_Rect * src_rect = NULL, *dst_rect = &clipped_dst;
|
||||||
|
|
||||||
|
if(_lv_area_is_in(coords, clip, 0)) {
|
||||||
|
/*Image needs to be fully drawn*/
|
||||||
|
src_rect = SDL_RectEmpty(&header->rect) ? NULL : &header->rect;
|
||||||
|
}
|
||||||
|
else if(draw_dsc->angle == 0) {
|
||||||
|
/*Image needs to be partly drawn, and we calculate the area to draw manually*/
|
||||||
|
Uint32 format = 0;
|
||||||
|
int access = 0, w, h;
|
||||||
|
if(SDL_RectEmpty(&header->rect)) {
|
||||||
|
SDL_QueryTexture(texture, &format, &access, &w, &h);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = header->rect.w;
|
||||||
|
h = header->rect.h;
|
||||||
|
}
|
||||||
|
SDL_IntersectRect(&clip_rect, &coords_rect, &clipped_dst);
|
||||||
|
clipped_src.x = header->rect.x + (clipped_dst.x - coords_rect.x) * w / coords_rect.x;
|
||||||
|
clipped_src.y = header->rect.y + (clipped_dst.y - coords_rect.y) * h / coords_rect.h;
|
||||||
|
clipped_src.w = w - (coords_rect.w - clipped_dst.w) * w / coords_rect.w;
|
||||||
|
clipped_src.h = h - (coords_rect.h - clipped_dst.h) * h / coords_rect.h;
|
||||||
|
src_rect = &clipped_src;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*Image needs to be rotated, so we have to use clip rect which is slower*/
|
||||||
|
SDL_RenderSetClipRect(renderer, &clip_rect);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Color recolor;
|
SDL_Color recolor;
|
||||||
lv_color_to_sdl_color(&draw_dsc->recolor, &recolor);
|
lv_color_to_sdl_color(&draw_dsc->recolor, &recolor);
|
||||||
@@ -108,22 +145,22 @@ lv_res_t lv_draw_sdl_img_core(lv_draw_ctx_t * draw_ctx, const lv_draw_img_dsc_t
|
|||||||
/* Draw fully recolored image*/
|
/* Draw fully recolored image*/
|
||||||
SDL_SetTextureColorMod(texture, draw_dsc->recolor.ch.red, recolor.g, recolor.b);
|
SDL_SetTextureColorMod(texture, draw_dsc->recolor.ch.red, recolor.g, recolor.b);
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
||||||
SDL_RenderCopyEx(renderer, texture, NULL, &coords_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
||||||
}
|
}
|
||||||
else if(draw_dsc->recolor_opa > LV_OPA_TRANSP) {
|
else if(draw_dsc->recolor_opa > LV_OPA_TRANSP) {
|
||||||
/* Draw blended. src: origA, dst: origA * recolorA */
|
/* Draw blended. src: origA, dst: origA * recolorA */
|
||||||
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
||||||
SDL_RenderCopyEx(renderer, texture, NULL, &coords_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
||||||
SDL_SetTextureColorMod(texture, recolor.r, recolor.g, recolor.b);
|
SDL_SetTextureColorMod(texture, recolor.r, recolor.g, recolor.b);
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa * draw_dsc->recolor_opa / 255);
|
SDL_SetTextureAlphaMod(texture, draw_dsc->opa * draw_dsc->recolor_opa / 255);
|
||||||
SDL_RenderCopyEx(renderer, texture, NULL, &coords_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Draw with no recolor */
|
/* Draw with no recolor */
|
||||||
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
SDL_SetTextureColorMod(texture, 0xFF, 0xFF, 0xFF);
|
||||||
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
SDL_SetTextureAlphaMod(texture, draw_dsc->opa);
|
||||||
SDL_RenderCopyEx(renderer, texture, NULL, &coords_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
SDL_RenderCopyEx(renderer, texture, src_rect, dst_rect, draw_dsc->angle, &pivot, SDL_FLIP_NONE);
|
||||||
}
|
}
|
||||||
SDL_RenderSetClipRect(renderer, NULL);
|
SDL_RenderSetClipRect(renderer, NULL);
|
||||||
return LV_RES_OK;
|
return LV_RES_OK;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @file lv_templ.c
|
* @file lv_draw_sdl_line.c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -64,10 +64,10 @@ void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
double angle = SDL_atan2(y2 - y1, x2 - x1) * 180 / M_PI;
|
double angle = SDL_atan2(y2 - y1, x2 - x1) * 180 / M_PI;
|
||||||
lv_draw_line_key_t key = line_key_create(dsc, length);
|
lv_draw_line_key_t key = line_key_create(dsc, (lv_coord_t) length);
|
||||||
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(sdl_ctx, &key, sizeof(key), NULL);
|
SDL_Texture * texture = lv_draw_sdl_texture_cache_get(sdl_ctx, &key, sizeof(key), NULL);
|
||||||
if(!texture) {
|
if(!texture) {
|
||||||
texture = line_texture_create(sdl_ctx, dsc, length);
|
texture = line_texture_create(sdl_ctx, dsc, (lv_coord_t) length);
|
||||||
lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture);
|
lv_draw_sdl_texture_cache_put(sdl_ctx, &key, sizeof(key), texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,20 +80,23 @@ void lv_draw_sdl_draw_line(lv_draw_ctx_t * draw_ctx, const lv_draw_line_dsc_t *
|
|||||||
|
|
||||||
lv_area_t t_coords = coords, t_clip = *clip, apply_area;
|
lv_area_t t_coords = coords, t_clip = *clip, apply_area;
|
||||||
lv_area_t extension = {dsc->width / 2, dsc->width / 2, dsc->width / 2, dsc->width / 2};
|
lv_area_t extension = {dsc->width / 2, dsc->width / 2, dsc->width / 2, dsc->width / 2};
|
||||||
bool has_mask = lv_draw_sdl_composite_begin(sdl_ctx, &coords, clip, &extension, dsc->blend_mode, &t_coords, &t_clip,
|
lv_draw_sdl_composite_begin(sdl_ctx, &coords, clip, &extension, dsc->blend_mode, &t_coords, &t_clip,
|
||||||
&apply_area);
|
&apply_area);
|
||||||
|
|
||||||
SDL_Color color;
|
SDL_Color color;
|
||||||
lv_color_to_sdl_color(&dsc->color, &color);
|
lv_color_to_sdl_color(&dsc->color, &color);
|
||||||
|
|
||||||
SDL_Rect clip_rect;
|
|
||||||
lv_area_to_sdl_rect(&t_clip, &clip_rect);
|
|
||||||
SDL_RenderSetClipRect(renderer, &clip_rect);
|
|
||||||
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
|
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
|
||||||
SDL_SetTextureAlphaMod(texture, dsc->opa);
|
SDL_SetTextureAlphaMod(texture, dsc->opa);
|
||||||
SDL_Rect srcrect = {0, 0, length + dsc->width + 2, dsc->width + 2},
|
SDL_Rect srcrect = {0, 0, (int) length + dsc->width + 2, dsc->width + 2},
|
||||||
dstrect = {t_coords.x1 - 1 - dsc->width / 2, t_coords.y1 - 1, srcrect.w, srcrect.h};
|
dstrect = {t_coords.x1 - 1 - dsc->width / 2, t_coords.y1 - 1, srcrect.w, srcrect.h};
|
||||||
SDL_Point center = {1 + dsc->width / 2, 1 + dsc->width / 2};
|
SDL_Point center = {1 + dsc->width / 2, 1 + dsc->width / 2};
|
||||||
|
|
||||||
|
SDL_Rect clip_rect;
|
||||||
|
lv_area_to_sdl_rect(&t_clip, &clip_rect);
|
||||||
|
if(!SDL_RectEquals(&clip_rect, &dstrect) || angle != 0) {
|
||||||
|
SDL_RenderSetClipRect(renderer, &clip_rect);
|
||||||
|
}
|
||||||
SDL_RenderCopyEx(renderer, texture, &srcrect, &dstrect, angle, ¢er, 0);
|
SDL_RenderCopyEx(renderer, texture, &srcrect, &dstrect, angle, ¢er, 0);
|
||||||
SDL_RenderSetClipRect(renderer, NULL);
|
SDL_RenderSetClipRect(renderer, NULL);
|
||||||
|
|
||||||
|
|||||||
133
src/draw/sdl/lv_draw_sdl_polygon.c
Normal file
133
src/draw/sdl/lv_draw_sdl_polygon.c
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
* @file lv_draw_sdl_polygon.c
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* INCLUDES
|
||||||
|
*********************/
|
||||||
|
#include "../../lv_conf_internal.h"
|
||||||
|
|
||||||
|
#if LV_USE_GPU_SDL
|
||||||
|
|
||||||
|
#include "lv_draw_sdl.h"
|
||||||
|
#include "lv_draw_sdl_utils.h"
|
||||||
|
#include "lv_draw_sdl_texture_cache.h"
|
||||||
|
#include "lv_draw_sdl_composite.h"
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* DEFINES
|
||||||
|
*********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* TYPEDEFS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC PROTOTYPES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC VARIABLES
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* MACROS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
static void dump_masks(SDL_Texture * texture, const lv_area_t * coords);
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* GLOBAL FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
void lv_draw_sdl_polygon(lv_draw_ctx_t * draw_ctx, const lv_draw_rect_dsc_t * draw_dsc, const lv_point_t * points,
|
||||||
|
uint16_t point_cnt)
|
||||||
|
{
|
||||||
|
if(point_cnt < 3) return;
|
||||||
|
if(points == NULL) return;
|
||||||
|
|
||||||
|
lv_draw_mask_polygon_param_t polygon_param;
|
||||||
|
lv_draw_mask_polygon_init(&polygon_param, points, point_cnt);
|
||||||
|
|
||||||
|
if(polygon_param.cfg.point_cnt < 3) {
|
||||||
|
lv_draw_mask_free_param(&polygon_param);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_area_t poly_coords = {.x1 = LV_COORD_MAX, .y1 = LV_COORD_MAX, .x2 = LV_COORD_MIN, .y2 = LV_COORD_MIN};
|
||||||
|
|
||||||
|
uint16_t i;
|
||||||
|
for(i = 0; i < point_cnt; i++) {
|
||||||
|
poly_coords.x1 = LV_MIN(poly_coords.x1, polygon_param.cfg.points[i].x);
|
||||||
|
poly_coords.y1 = LV_MIN(poly_coords.y1, polygon_param.cfg.points[i].y);
|
||||||
|
poly_coords.x2 = LV_MAX(poly_coords.x2, polygon_param.cfg.points[i].x);
|
||||||
|
poly_coords.y2 = LV_MAX(poly_coords.y2, polygon_param.cfg.points[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_common;
|
||||||
|
lv_area_t draw_area;
|
||||||
|
is_common = _lv_area_intersect(&draw_area, &poly_coords, draw_ctx->clip_area);
|
||||||
|
if(!is_common) {
|
||||||
|
lv_draw_mask_free_param(&polygon_param);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
|
||||||
|
|
||||||
|
int16_t mask_id = lv_draw_mask_add(&polygon_param, NULL);
|
||||||
|
|
||||||
|
lv_coord_t w = lv_area_get_width(&draw_area), h = lv_area_get_height(&draw_area);
|
||||||
|
SDL_Texture * texture = lv_draw_sdl_composite_texture_obtain(ctx, LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_STREAM1, w, h);
|
||||||
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
|
dump_masks(texture, &draw_area);
|
||||||
|
|
||||||
|
lv_draw_mask_remove_id(mask_id);
|
||||||
|
lv_draw_mask_free_param(&polygon_param);
|
||||||
|
|
||||||
|
SDL_Rect srcrect = {0, 0, w, h}, dstrect;
|
||||||
|
lv_area_to_sdl_rect(&draw_area, &dstrect);
|
||||||
|
SDL_Color color;
|
||||||
|
lv_color_to_sdl_color(&draw_dsc->bg_color, &color);
|
||||||
|
SDL_SetTextureColorMod(texture, color.r, color.g, color.b);
|
||||||
|
SDL_SetTextureAlphaMod(texture, draw_dsc->bg_opa);
|
||||||
|
SDL_RenderCopy(ctx->renderer, texture, &srcrect, &dstrect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* STATIC FUNCTIONS
|
||||||
|
**********************/
|
||||||
|
|
||||||
|
static void dump_masks(SDL_Texture * texture, const lv_area_t * coords)
|
||||||
|
{
|
||||||
|
lv_coord_t w = lv_area_get_width(coords), h = lv_area_get_height(coords);
|
||||||
|
SDL_assert(w > 0 && h > 0);
|
||||||
|
SDL_Rect rect = {0, 0, w, h};
|
||||||
|
uint8_t * pixels;
|
||||||
|
int pitch;
|
||||||
|
if(SDL_LockTexture(texture, &rect, (void **) &pixels, &pitch) != 0) return;
|
||||||
|
|
||||||
|
lv_opa_t * line_buf = lv_mem_buf_get(rect.w);
|
||||||
|
for(lv_coord_t y = 0; y < rect.h; y++) {
|
||||||
|
lv_memset_ff(line_buf, rect.w);
|
||||||
|
lv_coord_t abs_x = (lv_coord_t) coords->x1, abs_y = (lv_coord_t)(y + coords->y1), len = (lv_coord_t) rect.w;
|
||||||
|
lv_draw_mask_res_t res;
|
||||||
|
res = lv_draw_mask_apply(line_buf, abs_x, abs_y, len);
|
||||||
|
if(res == LV_DRAW_MASK_RES_TRANSP) {
|
||||||
|
lv_memset_00(&pixels[y * pitch], 4 * rect.w);
|
||||||
|
}
|
||||||
|
else if(res == LV_DRAW_MASK_RES_FULL_COVER) {
|
||||||
|
lv_memset_ff(&pixels[y * pitch], 4 * rect.w);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(int x = 0; x < rect.w; x++) {
|
||||||
|
uint8_t * pixel = &pixels[y * pitch + x * 4];
|
||||||
|
*pixel = line_buf[x];
|
||||||
|
pixel[1] = pixel[2] = pixel[3] = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lv_mem_buf_release(line_buf);
|
||||||
|
SDL_UnlockTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*LV_USE_GPU_SDL*/
|
||||||
@@ -37,6 +37,7 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char head[8];
|
char head[8];
|
||||||
SDL_Texture * texture;
|
SDL_Texture * texture;
|
||||||
|
SDL_Rect rect;
|
||||||
bool texture_managed;
|
bool texture_managed;
|
||||||
bool texture_referenced;
|
bool texture_referenced;
|
||||||
} lv_draw_sdl_dec_dsc_userdata_t;
|
} lv_draw_sdl_dec_dsc_userdata_t;
|
||||||
|
|||||||
Reference in New Issue
Block a user