1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(sdl_render): support all draw task types (#6437)

This commit is contained in:
Gabor Kiss-Vamosi 2024-08-26 10:46:40 +02:00 committed by GitHub
parent d028a970a0
commit 51f06c097d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 190 additions and 145 deletions

View File

@ -1502,10 +1502,16 @@ menu "LVGL configuration"
default 1 if LV_SDL_SINGLE_BUFFER default 1 if LV_SDL_SINGLE_BUFFER
default 2 if LV_SDL_DOUBLE_BUFFER default 2 if LV_SDL_DOUBLE_BUFFER
config LV_SDL_ACCELERATED
bool "Use hardware acceleration"
depends on LV_USE_SDL
default y
config LV_SDL_FULLSCREEN config LV_SDL_FULLSCREEN
bool "SDL fullscreen" bool "SDL fullscreen"
depends on LV_USE_SDL depends on LV_USE_SDL
default n default n
config LV_SDL_DIRECT_EXIT config LV_SDL_DIRECT_EXIT
bool "Exit the application when all SDL windows are closed" bool "Exit the application when all SDL windows are closed"
depends on LV_USE_SDL depends on LV_USE_SDL

View File

@ -253,7 +253,6 @@ static void profile_create(lv_obj_t * parent)
LV_IMAGE_DECLARE(img_demo_widgets_avatar); LV_IMAGE_DECLARE(img_demo_widgets_avatar);
lv_obj_t * avatar = lv_image_create(panel1); lv_obj_t * avatar = lv_image_create(panel1);
lv_image_set_src(avatar, &img_demo_widgets_avatar); lv_image_set_src(avatar, &img_demo_widgets_avatar);
// lv_image_set_src(avatar, "A:lvgl/demos/widgets/assets/avatar.png")
lv_obj_t * name = lv_label_create(panel1); lv_obj_t * name = lv_label_create(panel1);
lv_label_set_text(name, "Elena Smith"); lv_label_set_text(name, "Elena Smith");
@ -998,11 +997,11 @@ void shop_create(lv_obj_t * parent)
lv_obj_add_style(title, &style_title, 0); lv_obj_add_style(title, &style_title, 0);
LV_IMAGE_DECLARE(img_clothes); LV_IMAGE_DECLARE(img_clothes);
create_shop_item(list, &img_clothes, "Blue jeans", "Clothes", "$722"); create_shop_item(list, &img_clothes, "Blue T-shirt", "Clothes", "$722");
create_shop_item(list, &img_clothes, "Blue jeans", "Clothes", "$411"); create_shop_item(list, &img_clothes, "Blue T-shirt", "Clothes", "$411");
create_shop_item(list, &img_clothes, "Blue jeans", "Clothes", "$917"); create_shop_item(list, &img_clothes, "Blue T-shirt", "Clothes", "$917");
create_shop_item(list, &img_clothes, "Blue jeans", "Clothes", "$64"); create_shop_item(list, &img_clothes, "Blue T-shirt", "Clothes", "$64");
create_shop_item(list, &img_clothes, "Blue jeans", "Clothes", "$805"); create_shop_item(list, &img_clothes, "Blue T-shirt", "Clothes", "$805");
lv_obj_t * notifications = lv_obj_create(parent); lv_obj_t * notifications = lv_obj_create(parent);
if(disp_size == DISP_SMALL) { if(disp_size == DISP_SMALL) {

View File

@ -939,6 +939,7 @@
#define LV_SDL_INCLUDE_PATH <SDL2/SDL.h> #define LV_SDL_INCLUDE_PATH <SDL2/SDL.h>
#define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/ #define LV_SDL_RENDER_MODE LV_DISPLAY_RENDER_MODE_DIRECT /*LV_DISPLAY_RENDER_MODE_DIRECT is recommended for best performance*/
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/ #define LV_SDL_BUF_COUNT 1 /*1 or 2*/
#define LV_SDL_ACCELERATED 1 /*1: Use hardware acceleration*/
#define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/ #define LV_SDL_FULLSCREEN 0 /*1: Make the window full screen by default*/
#define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/ #define LV_SDL_DIRECT_EXIT 1 /*1: Exit the application when all SDL windows are closed*/
#define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/ #define LV_SDL_MOUSEWHEEL_MODE LV_SDL_MOUSEWHEEL_MODE_ENCODER /*LV_SDL_MOUSEWHEEL_MODE_ENCODER/CROWN*/

View File

@ -9,7 +9,7 @@ sudo dpkg --add-architecture i386
sudo apt update sudo apt update
sudo apt install gcc gcc-multilib g++-multilib ninja-build \ sudo apt install gcc gcc-multilib g++-multilib ninja-build \
libpng-dev libjpeg-turbo8-dev libfreetype6-dev \ libpng-dev libjpeg-turbo8-dev libfreetype6-dev \
libglew-dev libglfw3-dev libsdl2-dev libsdl2-image-dev \ libglew-dev libglfw3-dev libsdl2-dev \
libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 \ libpng-dev:i386 libjpeg-dev:i386 libfreetype6-dev:i386 \
ruby-full gcovr cmake python3 pngquant libinput-dev libxkbcommon-dev \ ruby-full gcovr cmake python3 pngquant libinput-dev libxkbcommon-dev \
libdrm-dev pkg-config wayland-protocols libwayland-dev libwayland-bin \ libdrm-dev pkg-config wayland-protocols libwayland-dev libwayland-bin \

View File

@ -42,6 +42,7 @@ void lv_draw_arc_dsc_init(lv_draw_arc_dsc_t * dsc)
dsc->width = 1; dsc->width = 1;
dsc->opa = LV_OPA_COVER; dsc->opa = LV_OPA_COVER;
dsc->color = lv_color_black(); dsc->color = lv_color_black();
dsc->base.dsc_size = sizeof(lv_draw_arc_dsc_t);
} }
lv_draw_arc_dsc_t * lv_draw_task_get_arc_dsc(lv_draw_task_t * task) lv_draw_arc_dsc_t * lv_draw_task_get_arc_dsc(lv_draw_task_t * task)

View File

@ -42,6 +42,7 @@ void LV_ATTRIBUTE_FAST_MEM lv_draw_line_dsc_init(lv_draw_line_dsc_t * dsc)
dsc->width = 1; dsc->width = 1;
dsc->opa = LV_OPA_COVER; dsc->opa = LV_OPA_COVER;
dsc->color = lv_color_black(); dsc->color = lv_color_black();
dsc->base.dsc_size = sizeof(lv_draw_line_dsc_t);
} }
lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task) lv_draw_line_dsc_t * lv_draw_task_get_line_dsc(lv_draw_task_t * task)

View File

@ -48,6 +48,7 @@ void lv_draw_triangle_dsc_init(lv_draw_triangle_dsc_t * dsc)
dsc->bg_grad.stops[1].frac = 0xFF; dsc->bg_grad.stops[1].frac = 0xFF;
dsc->bg_grad.stops_count = 2; dsc->bg_grad.stops_count = 2;
dsc->bg_opa = LV_OPA_COVER; dsc->bg_opa = LV_OPA_COVER;
dsc->base.dsc_size = sizeof(lv_draw_triangle_dsc_t);
LV_PROFILER_END; LV_PROFILER_END;
} }

View File

@ -9,13 +9,13 @@
#include "../lv_draw_private.h" #include "../lv_draw_private.h"
#if LV_USE_DRAW_SDL #if LV_USE_DRAW_SDL
#include LV_SDL_INCLUDE_PATH #include LV_SDL_INCLUDE_PATH
#include <SDL2/SDL_image.h>
#include "lv_draw_sdl.h" #include "lv_draw_sdl.h"
#include "../../core/lv_refr_private.h" #include "../../core/lv_refr_private.h"
#include "../../display/lv_display_private.h" #include "../../display/lv_display_private.h"
#include "../../stdlib/lv_string.h" #include "../../stdlib/lv_string.h"
#include "../../drivers/sdl/lv_sdl_window.h" #include "../../drivers/sdl/lv_sdl_window.h"
#include "../../misc/cache/lv_cache_entry_private.h"
#include "../../misc/lv_area_private.h"
/********************* /*********************
* DEFINES * DEFINES
@ -40,7 +40,7 @@ static void execute_drawing(lv_draw_sdl_unit_t * u);
static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer); static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer);
static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task); static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task);
static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data); static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data);
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -92,7 +92,12 @@ static lv_cache_compare_res_t sdl_texture_cache_compare_cb(const cache_data_t *
return lhs_dsc_size > rhs_dsc_size ? 1 : -1; return lhs_dsc_size > rhs_dsc_size ? 1 : -1;
} }
int cmp_res = memcmp(lhs->draw_dsc, rhs->draw_dsc, lhs->draw_dsc->dsc_size); const uint8_t * left_draw_dsc = (const uint8_t *)lhs->draw_dsc;
const uint8_t * right_draw_dsc = (const uint8_t *)rhs->draw_dsc;
left_draw_dsc += sizeof(lv_draw_dsc_base_t);
right_draw_dsc += sizeof(lv_draw_dsc_base_t);
int cmp_res = lv_memcmp(left_draw_dsc, right_draw_dsc, lhs->draw_dsc->dsc_size - sizeof(lv_draw_dsc_base_t));
if(cmp_res != 0) { if(cmp_res != 0) {
return cmp_res > 0 ? 1 : -1; return cmp_res > 0 ? 1 : -1;
@ -169,25 +174,36 @@ static int32_t evaluate(lv_draw_unit_t * draw_unit, lv_draw_task_t * task)
return 0; return 0;
} }
static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data) static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * cache_data)
{ {
lv_draw_task_t * task = u->task_act; lv_draw_task_t * task = u->task_act;
lv_layer_t dest_layer; lv_layer_t dest_layer;
lv_memzero(&dest_layer, sizeof(dest_layer)); lv_memzero(&dest_layer, sizeof(dest_layer));
int32_t texture_w = lv_area_get_width(&task->_real_area);
int32_t texture_h = lv_area_get_height(&task->_real_area);
lv_draw_buf_t draw_buf; lv_draw_buf_t draw_buf;
dest_layer.draw_buf = &draw_buf; dest_layer.draw_buf = &draw_buf;
lv_draw_buf_init(dest_layer.draw_buf, lv_area_get_width(&task->area), lv_area_get_height(&task->area), lv_draw_buf_init(dest_layer.draw_buf, texture_w, texture_h,
LV_COLOR_FORMAT_ARGB8888, LV_STRIDE_AUTO, sdl_render_buf, sizeof(sdl_render_buf)); LV_COLOR_FORMAT_ARGB8888, LV_STRIDE_AUTO, sdl_render_buf, sizeof(sdl_render_buf));
dest_layer.color_format = LV_COLOR_FORMAT_ARGB8888; dest_layer.color_format = LV_COLOR_FORMAT_ARGB8888;
dest_layer.buf_area = task->area;
dest_layer._clip_area = task->area; dest_layer.buf_area = task->_real_area;
dest_layer.phy_clip_area = task->area; dest_layer._clip_area = task->_real_area;
dest_layer.phy_clip_area = task->_real_area;
lv_memzero(sdl_render_buf, lv_area_get_size(&dest_layer.buf_area) * 4 + 100); lv_memzero(sdl_render_buf, lv_area_get_size(&dest_layer.buf_area) * 4 + 100);
lv_display_t * disp = lv_refr_get_disp_refreshing(); lv_display_t * disp = lv_refr_get_disp_refreshing();
SDL_Texture * texture = NULL; lv_obj_t * obj = ((lv_draw_dsc_base_t *)task->draw_dsc)->obj;
bool original_send_draw_task_event = false;
if(obj) {
original_send_draw_task_event = lv_obj_has_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
lv_obj_remove_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
}
switch(task->type) { switch(task->type) {
case LV_DRAW_TASK_TYPE_FILL: { case LV_DRAW_TASK_TYPE_FILL: {
lv_draw_fill_dsc_t * fill_dsc = task->draw_dsc; lv_draw_fill_dsc_t * fill_dsc = task->draw_dsc;
@ -203,7 +219,7 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data)
} }
break; break;
case LV_DRAW_TASK_TYPE_BORDER: { case LV_DRAW_TASK_TYPE_BORDER: {
lv_draw_border_dsc_t * border_dsc = task->draw_dsc;; lv_draw_border_dsc_t * border_dsc = task->draw_dsc;
lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc); lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.base.user_data = lv_sdl_window_get_renderer(disp); rect_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
@ -216,56 +232,55 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data)
lv_draw_rect(&dest_layer, &rect_dsc, &task->area); lv_draw_rect(&dest_layer, &rect_dsc, &task->area);
break; break;
} }
case LV_DRAW_TASK_TYPE_BOX_SHADOW: {
lv_draw_box_shadow_dsc_t * box_shadow_dsc = task->draw_dsc;
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
rect_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
rect_dsc.bg_opa = LV_OPA_0;
rect_dsc.radius = box_shadow_dsc->radius;
rect_dsc.bg_color = box_shadow_dsc->color;
rect_dsc.shadow_opa = box_shadow_dsc->opa;
rect_dsc.shadow_width = box_shadow_dsc->width;
rect_dsc.shadow_spread = box_shadow_dsc->spread;
rect_dsc.shadow_offset_x = box_shadow_dsc->ofs_x;
rect_dsc.shadow_offset_y = box_shadow_dsc->ofs_y;
lv_draw_rect(&dest_layer, &rect_dsc, &task->area);
break;
}
case LV_DRAW_TASK_TYPE_LABEL: { case LV_DRAW_TASK_TYPE_LABEL: {
lv_draw_label_dsc_t label_dsc; lv_draw_label_dsc_t label_dsc;
lv_draw_label_dsc_init(&label_dsc);
lv_memcpy(&label_dsc, task->draw_dsc, sizeof(label_dsc)); lv_memcpy(&label_dsc, task->draw_dsc, sizeof(label_dsc));
label_dsc.base.user_data = lv_sdl_window_get_renderer(disp); label_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
lv_draw_label(&dest_layer, &label_dsc, &task->area); lv_draw_label(&dest_layer, &label_dsc, &task->area);
} }
break; break;
case LV_DRAW_TASK_TYPE_ARC: {
lv_draw_arc_dsc_t arc_dsc;
lv_memcpy(&arc_dsc, task->draw_dsc, sizeof(arc_dsc));
arc_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
lv_draw_arc(&dest_layer, &arc_dsc);
}
break;
case LV_DRAW_TASK_TYPE_LINE: {
lv_draw_line_dsc_t line_dsc;
lv_memcpy(&line_dsc, task->draw_dsc, sizeof(line_dsc));
line_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
lv_draw_line(&dest_layer, &line_dsc);
}
break;
case LV_DRAW_TASK_TYPE_TRIANGLE: {
lv_draw_triangle_dsc_t triangle_dsc;
lv_memcpy(&triangle_dsc, task->draw_dsc, sizeof(triangle_dsc));
triangle_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
lv_draw_triangle(&dest_layer, &triangle_dsc);
}
break;
case LV_DRAW_TASK_TYPE_IMAGE: { case LV_DRAW_TASK_TYPE_IMAGE: {
lv_draw_image_dsc_t * image_dsc = task->draw_dsc; lv_draw_image_dsc_t image_dsc;
lv_image_src_t type = lv_image_src_get_type(image_dsc->src); lv_memcpy(&image_dsc, task->draw_dsc, sizeof(image_dsc));
SDL_Surface * surface = NULL; image_dsc.base.user_data = lv_sdl_window_get_renderer(disp);
if(type == LV_IMAGE_SRC_FILE) { lv_draw_image(&dest_layer, &image_dsc, &task->area);
const char * path = image_dsc->src;
surface = IMG_Load(&path[2]);
if(surface == NULL) {
LV_LOG_ERROR("could not load image from file: %s", IMG_GetError());
return false;
}
}
else if(type == LV_IMAGE_SRC_VARIABLE) {
lv_image_dsc_t * lvd = (lv_image_dsc_t *)image_dsc->src;
surface = SDL_CreateRGBSurfaceFrom((void *)lvd->data,
lvd->header.w, lvd->header.h,
LV_COLOR_FORMAT_GET_BPP(lvd->header.cf),
lvd->header.stride,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
0x00FF0000,
0x0000FF00,
0x000000FF,
0xFF000000
#else
0x0000FF00,
0x00FF0000,
0xFF000000,
0x000000FF
#endif
);
if(surface == NULL) {
LV_LOG_ERROR("could not load image from variable");
return false;
}
}
else {
LV_LOG_WARN("image source type unknown");
return false;
}
SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp);
texture = SDL_CreateTextureFromSurface(renderer, surface);
break; break;
} }
default: default:
@ -279,29 +294,22 @@ static bool draw_to_texture(lv_draw_sdl_unit_t * u, cache_data_t * data)
} }
} }
SDL_Rect rect; SDL_Texture * texture = SDL_CreateTexture(lv_sdl_window_get_renderer(disp), SDL_PIXELFORMAT_ARGB8888,
rect.x = dest_layer.buf_area.x1; SDL_TEXTUREACCESS_STATIC, texture_w, texture_h);
rect.y = dest_layer.buf_area.y1;
rect.w = lv_area_get_width(&dest_layer.buf_area);
rect.h = lv_area_get_height(&dest_layer.buf_area);
if(texture == NULL) {
texture = SDL_CreateTexture(lv_sdl_window_get_renderer(disp), SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STATIC, rect.w, rect.h);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_UpdateTexture(texture, NULL, sdl_render_buf, rect.w * 4); SDL_UpdateTexture(texture, NULL, sdl_render_buf, texture_w * 4);
}
else {
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
}
lv_draw_dsc_base_t * base_dsc = task->draw_dsc; lv_draw_dsc_base_t * base_dsc = task->draw_dsc;
data->draw_dsc = lv_malloc(base_dsc->dsc_size); cache_data->draw_dsc = lv_malloc(base_dsc->dsc_size);
lv_memcpy((void *)data->draw_dsc, base_dsc, base_dsc->dsc_size); lv_memcpy((void *)cache_data->draw_dsc, base_dsc, base_dsc->dsc_size);
data->w = lv_area_get_width(&task->area); cache_data->w = texture_w;
data->h = lv_area_get_height(&task->area); cache_data->h = texture_h;
data->texture = texture; cache_data->texture = texture;
if(obj) {
lv_obj_update_flag(obj, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS, original_send_draw_task_event);
}
return true; return true;
} }
@ -318,13 +326,18 @@ static void blend_texture_layer(lv_draw_sdl_unit_t * u)
clip_rect.h = lv_area_get_height(u->base_unit.clip_area); clip_rect.h = lv_area_get_height(u->base_unit.clip_area);
lv_draw_task_t * t = u->task_act; lv_draw_task_t * t = u->task_act;
SDL_Rect rect;
rect.x = t->area.x1;
rect.y = t->area.y1;
rect.w = lv_area_get_width(&t->area);
rect.h = lv_area_get_height(&t->area);
lv_draw_image_dsc_t * draw_dsc = t->draw_dsc; lv_draw_image_dsc_t * draw_dsc = t->draw_dsc;
SDL_Rect rect;
rect.w = (lv_area_get_width(&t->area) * draw_dsc->scale_x) / 256;
rect.h = (lv_area_get_height(&t->area) * draw_dsc->scale_y) / 256;
rect.x = -draw_dsc->pivot.x;
rect.y = -draw_dsc->pivot.y;
rect.x = (rect.x * draw_dsc->scale_x) / 256;
rect.y = (rect.y * draw_dsc->scale_y) / 256;
rect.x += t->area.x1 + draw_dsc->pivot.x;
rect.y += t->area.y1 + draw_dsc->pivot.y;
lv_layer_t * src_layer = (lv_layer_t *)draw_dsc->src; lv_layer_t * src_layer = (lv_layer_t *)draw_dsc->src;
SDL_Texture * src_texture = layer_get_texture(src_layer); SDL_Texture * src_texture = layer_get_texture(src_layer);
@ -332,21 +345,24 @@ static void blend_texture_layer(lv_draw_sdl_unit_t * u)
SDL_SetTextureBlendMode(src_texture, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(src_texture, SDL_BLENDMODE_BLEND);
SDL_SetRenderTarget(renderer, layer_get_texture(u->base_unit.target_layer)); SDL_SetRenderTarget(renderer, layer_get_texture(u->base_unit.target_layer));
SDL_RenderSetClipRect(renderer, &clip_rect); SDL_RenderSetClipRect(renderer, &clip_rect);
SDL_RenderCopy(renderer, src_texture, NULL, &rect);
SDL_Point center = {draw_dsc->pivot.x, draw_dsc->pivot.y};
SDL_RenderCopyEx(renderer, src_texture, NULL, &rect, draw_dsc->rotation / 10, &center, SDL_FLIP_NONE);
// SDL_RenderCopy(renderer, src_texture, NULL, &rect);
SDL_DestroyTexture(src_texture); SDL_DestroyTexture(src_texture);
SDL_RenderSetClipRect(renderer, NULL); SDL_RenderSetClipRect(renderer, NULL);
} }
static void draw_from_cached_texture(lv_draw_sdl_unit_t * u) static void draw_from_cached_texture(lv_draw_sdl_unit_t * u)
{ {
lv_draw_task_t * t = u->task_act; lv_draw_task_t * t = u->task_act;
cache_data_t data_to_find; cache_data_t data_to_find;
data_to_find.draw_dsc = (lv_draw_dsc_base_t *)t->draw_dsc; data_to_find.draw_dsc = (lv_draw_dsc_base_t *)t->draw_dsc;
data_to_find.w = lv_area_get_width(&t->area); data_to_find.w = lv_area_get_width(&t->_real_area);
data_to_find.h = lv_area_get_height(&t->area); data_to_find.h = lv_area_get_height(&t->_real_area);
data_to_find.texture = NULL; data_to_find.texture = NULL;
/*user_data stores the renderer to differentiate it from SW rendered tasks. /*user_data stores the renderer to differentiate it from SW rendered tasks.
@ -354,11 +370,24 @@ static void draw_from_cached_texture(lv_draw_sdl_unit_t * u)
void * user_data_saved = data_to_find.draw_dsc->user_data; void * user_data_saved = data_to_find.draw_dsc->user_data;
data_to_find.draw_dsc->user_data = NULL; data_to_find.draw_dsc->user_data = NULL;
/*img_dsc->image_area is an absolute coordinate so it's different
*for the same image on a different position. So make it relative before using for cache. */
if(t->type == LV_DRAW_TASK_TYPE_IMAGE) {
lv_draw_image_dsc_t * img_dsc = (lv_draw_image_dsc_t *)data_to_find.draw_dsc;
lv_area_move(&img_dsc->image_area, -t->area.x1, -t->area.y1);
}
lv_cache_entry_t * entry_cached = lv_cache_acquire_or_create(u->texture_cache, &data_to_find, u); lv_cache_entry_t * entry_cached = lv_cache_acquire_or_create(u->texture_cache, &data_to_find, u);
if(t->type == LV_DRAW_TASK_TYPE_IMAGE) {
lv_draw_image_dsc_t * img_dsc = (lv_draw_image_dsc_t *)data_to_find.draw_dsc;
lv_area_move(&img_dsc->image_area, t->area.x1, t->area.y1);
}
if(!entry_cached) { if(!entry_cached) {
return; return;
} }
data_to_find.draw_dsc->user_data = user_data_saved; data_to_find.draw_dsc->user_data = user_data_saved;
cache_data_t * data_cached = lv_cache_entry_get_data(entry_cached); cache_data_t * data_cached = lv_cache_entry_get_data(entry_cached);
@ -377,53 +406,60 @@ static void draw_from_cached_texture(lv_draw_sdl_unit_t * u)
SDL_SetRenderTarget(renderer, layer_get_texture(dest_layer)); SDL_SetRenderTarget(renderer, layer_get_texture(dest_layer));
lv_draw_image_dsc_t * draw_dsc = lv_draw_task_get_image_dsc(t); rect.x = t->_real_area.x1 - dest_layer->buf_area.x1;
if(draw_dsc) { rect.y = t->_real_area.y1 - dest_layer->buf_area.y1;
lv_area_t image_area; rect.w = data_cached->w;
image_area.x1 = 0; rect.h = data_cached->h;
image_area.y1 = 0;
image_area.x2 = draw_dsc->header.w - 1;
image_area.y2 = draw_dsc->header.h - 1;
lv_area_move(&image_area, t->area.x1 - dest_layer->buf_area.x1, t->area.y1 - dest_layer->buf_area.y1);
rect.x = image_area.x1;
rect.y = image_area.y1;
rect.w = lv_area_get_width(&image_area);
rect.h = lv_area_get_height(&image_area);
SDL_RenderSetClipRect(renderer, &clip_rect); SDL_RenderSetClipRect(renderer, &clip_rect);
SDL_RenderCopy(renderer, texture, NULL, &rect); SDL_RenderCopy(renderer, texture, NULL, &rect);
}
else {
rect.x = t->area.x1 - dest_layer->buf_area.x1;
rect.y = t->area.y1 - dest_layer->buf_area.y1;
rect.w = lv_area_get_width(&t->area);
rect.h = lv_area_get_height(&t->area);
SDL_RenderSetClipRect(renderer, &clip_rect);
SDL_RenderCopy(renderer, texture, NULL, &rect);
}
SDL_RenderSetClipRect(renderer, NULL); SDL_RenderSetClipRect(renderer, NULL);
lv_cache_release(u->texture_cache, entry_cached, u); lv_cache_release(u->texture_cache, entry_cached, u);
/*Do not cache label's with local text as the text will be freed*/
if(t->type == LV_DRAW_TASK_TYPE_LABEL) {
lv_draw_label_dsc_t * label_dsc = t->draw_dsc;
if(label_dsc->text_local) {
lv_cache_drop(u->texture_cache, &data_to_find, NULL);
}
}
} }
static void execute_drawing(lv_draw_sdl_unit_t * u) static void execute_drawing(lv_draw_sdl_unit_t * u)
{ {
lv_draw_task_t * t = u->task_act; lv_draw_task_t * t = u->task_act;
if(t->type == LV_DRAW_TASK_TYPE_BOX_SHADOW) return; if(t->type == LV_DRAW_TASK_TYPE_FILL) {
if(t->type == LV_DRAW_TASK_TYPE_LINE) return; lv_draw_fill_dsc_t * fill_dsc = t->draw_dsc;
if(t->type == LV_DRAW_TASK_TYPE_TRIANGLE) return; if(fill_dsc->radius == 0 && fill_dsc->grad.dir == LV_GRAD_DIR_NONE) {
SDL_Rect rect;
lv_layer_t * layer = u->base_unit.target_layer;
lv_area_t fill_area = t->area;
lv_area_intersect(&fill_area, &fill_area, u->base_unit.clip_area);
rect.x = fill_area.x1 - layer->buf_area.x1;
rect.y = fill_area.y1 - layer->buf_area.y1;
rect.w = lv_area_get_width(&fill_area);
rect.h = lv_area_get_height(&fill_area);
lv_display_t * disp = lv_refr_get_disp_refreshing();
SDL_Renderer * renderer = lv_sdl_window_get_renderer(disp);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, fill_dsc->color.red, fill_dsc->color.green, fill_dsc->color.blue, fill_dsc->opa);
SDL_RenderSetClipRect(renderer, NULL);
SDL_RenderFillRect(renderer, &rect);
return;
}
}
if(t->type == LV_DRAW_TASK_TYPE_LAYER) { if(t->type == LV_DRAW_TASK_TYPE_LAYER) {
blend_texture_layer(u); blend_texture_layer(u);
return;
} }
else {
draw_from_cached_texture(u); draw_from_cached_texture(u);
} }
}
static SDL_Texture * layer_get_texture(lv_layer_t * layer) static SDL_Texture * layer_get_texture(lv_layer_t * layer)
{ {

View File

@ -14,6 +14,7 @@
#include "../../core/lv_global.h" #include "../../core/lv_global.h"
#include "../../display/lv_display_private.h" #include "../../display/lv_display_private.h"
#include "../../lv_init.h" #include "../../lv_init.h"
#include "../../draw/lv_draw_buf.h"
/* for aligned_alloc */ /* for aligned_alloc */
#ifndef __USE_ISOC11 #ifndef __USE_ISOC11
@ -24,10 +25,6 @@
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ #define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include "lv_sdl_private.h" #include "lv_sdl_private.h"
#if LV_USE_DRAW_SDL
#include <SDL2/SDL_image.h>
#endif
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
@ -91,13 +88,6 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res)
event_handler_timer = lv_timer_create(sdl_event_handler, 5, NULL); event_handler_timer = lv_timer_create(sdl_event_handler, 5, NULL);
lv_tick_set_cb(SDL_GetTicks); lv_tick_set_cb(SDL_GetTicks);
#if LV_USE_DRAW_SDL
if(!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) {
fprintf(stderr, "could not initialize sdl2_image: %s\n", IMG_GetError());
return NULL;
}
#endif
inited = true; inited = true;
} }
@ -133,15 +123,19 @@ lv_display_t * lv_sdl_window_create(int32_t hor_res, int32_t ver_res)
LV_SDL_RENDER_MODE); LV_SDL_RENDER_MODE);
} }
#else /*/*LV_USE_DRAW_SDL == 1*/ #else /*/*LV_USE_DRAW_SDL == 1*/
uint32_t stride = lv_draw_buf_width_to_stride(disp->hor_res,
lv_display_get_color_format(disp));
/*It will render directly to default Texture, so the buffer is not used, so just set something*/ /*It will render directly to default Texture, so the buffer is not used, so just set something*/
static uint8_t dummy_buf[1]; static lv_draw_buf_t draw_buf;
lv_display_set_buffers(disp, dummy_buf, NULL, stride * disp->ver_res, static uint8_t dummy_buf; /*It won't be used as it will render to the SDL textures directly*/
LV_SDL_RENDER_MODE); lv_draw_buf_init(&draw_buf, 4096, 4096, LV_COLOR_FORMAT_ARGB8888, 4096 * 4, &dummy_buf, 4096 * 4096 * 4);
lv_display_set_draw_buffers(disp, &draw_buf, NULL);
lv_display_set_render_mode(disp, LV_DISPLAY_RENDER_MODE_DIRECT);
#endif /*LV_USE_DRAW_SDL == 0*/ #endif /*LV_USE_DRAW_SDL == 0*/
lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL); lv_display_add_event_cb(disp, res_chg_event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
/*Process the initial events*/
sdl_event_handler(NULL);
return disp; return disp;
} }
@ -313,7 +307,6 @@ static void sdl_event_handler(lv_timer_t * t)
lv_display_t * disp = lv_sdl_get_disp_from_win_id(event.window.windowID); lv_display_t * disp = lv_sdl_get_disp_from_win_id(event.window.windowID);
if(disp == NULL) continue; if(disp == NULL) continue;
lv_sdl_window_t * dsc = lv_display_get_driver_data(disp); lv_sdl_window_t * dsc = lv_display_get_driver_data(disp);
switch(event.window.event) { switch(event.window.event) {
#if SDL_VERSION_ATLEAST(2, 0, 5) #if SDL_VERSION_ATLEAST(2, 0, 5)
case SDL_WINDOWEVENT_TAKE_FOCUS: case SDL_WINDOWEVENT_TAKE_FOCUS:
@ -361,7 +354,8 @@ static void window_create(lv_display_t * disp)
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
hor_res * dsc->zoom, ver_res * dsc->zoom, flag); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/ hor_res * dsc->zoom, ver_res * dsc->zoom, flag); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/
dsc->renderer = SDL_CreateRenderer(dsc->window, -1, SDL_RENDERER_SOFTWARE); dsc->renderer = SDL_CreateRenderer(dsc->window, -1,
LV_SDL_ACCELERATED ? SDL_RENDERER_ACCELERATED : SDL_RENDERER_SOFTWARE);
#if LV_USE_DRAW_SDL == 0 #if LV_USE_DRAW_SDL == 0
texture_resize(disp); texture_resize(disp);

View File

@ -3054,6 +3054,17 @@
#define LV_SDL_BUF_COUNT 1 /*1 or 2*/ #define LV_SDL_BUF_COUNT 1 /*1 or 2*/
#endif #endif
#endif #endif
#ifndef LV_SDL_ACCELERATED
#ifdef LV_KCONFIG_PRESENT
#ifdef CONFIG_LV_SDL_ACCELERATED
#define LV_SDL_ACCELERATED CONFIG_LV_SDL_ACCELERATED
#else
#define LV_SDL_ACCELERATED 0
#endif
#else
#define LV_SDL_ACCELERATED 1 /*1: Use hardware acceleration*/
#endif
#endif
#ifndef LV_SDL_FULLSCREEN #ifndef LV_SDL_FULLSCREEN
#ifdef CONFIG_LV_SDL_FULLSCREEN #ifdef CONFIG_LV_SDL_FULLSCREEN
#define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN #define LV_SDL_FULLSCREEN CONFIG_LV_SDL_FULLSCREEN

View File

@ -351,10 +351,7 @@ include_directories(${FREETYPE_INCLUDE_DIRS})
if(OPTIONS_SDL) if(OPTIONS_SDL)
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
find_library(NAME SDL2_image REQUIRED)
link_libraries(SDL2_image)
include_directories(${SDL2_INCLUDE_DIRS}) include_directories(${SDL2_INCLUDE_DIRS})
include_directories(${SDL2_IMAGE_INCLUDE_DIRS})
endif() endif()
# libinput is required for the libinput device driver test case # libinput is required for the libinput device driver test case
@ -474,9 +471,7 @@ foreach( test_case_fname ${TEST_CASE_FILES} )
${TEST_LIBS}) ${TEST_LIBS})
if(OPTIONS_SDL) if(OPTIONS_SDL)
target_link_libraries(${test_name} PRIVATE target_link_libraries(${test_name} PRIVATE ${SDL_LIBRARY})
${SDL_LIBRARY}
${SDL_IMAGE_LIBRARY})
endif() endif()
if (NOT $ENV{NON_AMD64_BUILD}) if (NOT $ENV{NON_AMD64_BUILD})