acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

lv_draw_sdl_texture_cache.c (5594B)

      1 /**
      2  * @file lv_draw_sdl_texture_cache.c
      3  *
      4  */
      5 
      6 /*********************
      7  *      INCLUDES
      8  *********************/
      9 
     10 #include "../../lv_conf_internal.h"
     11 
     12 #if LV_USE_GPU_SDL
     13 
     14 #include "lv_draw_sdl_texture_cache.h"
     15 
     16 #include "lv_draw_sdl_utils.h"
     17 
     18 /*********************
     19  *      DEFINES
     20  *********************/
     21 
     22 /**********************
     23  *      TYPEDEFS
     24  **********************/
     25 
     26 typedef struct {
     27     SDL_Texture * texture;
     28     void * userdata;
     29     lv_lru_free_t * userdata_free;
     30     lv_draw_sdl_cache_flag_t flags;
     31 } draw_cache_value_t;
     32 
     33 typedef struct {
     34     lv_sdl_cache_key_magic_t magic;
     35 } temp_texture_key_t;
     36 
     37 typedef struct {
     38     lv_coord_t width, height;
     39 } temp_texture_userdata_t;
     40 
     41 static void draw_cache_free_value(draw_cache_value_t *);
     42 
     43 static draw_cache_value_t * draw_cache_get_entry(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
     44                                                  bool * found);
     45 /**********************
     46  *  STATIC VARIABLES
     47  **********************/
     48 
     49 /**********************
     50  *      MACROS
     51  **********************/
     52 
     53 /**********************
     54  *   GLOBAL FUNCTIONS
     55  **********************/
     56 
     57 void lv_draw_sdl_texture_cache_init(lv_draw_sdl_ctx_t * ctx)
     58 {
     59     ctx->internals->texture_cache = lv_lru_create(LV_GPU_SDL_LRU_SIZE, 65536,
     60                                                   (lv_lru_free_t *) draw_cache_free_value, NULL);
     61 }
     62 
     63 void lv_draw_sdl_texture_cache_deinit(lv_draw_sdl_ctx_t * ctx)
     64 {
     65     lv_lru_del(ctx->internals->texture_cache);
     66 }
     67 
     68 SDL_Texture * lv_draw_sdl_texture_cache_get(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, bool * found)
     69 {
     70     return lv_draw_sdl_texture_cache_get_with_userdata(ctx, key, key_length, found, NULL);
     71 }
     72 
     73 SDL_Texture * lv_draw_sdl_texture_cache_get_with_userdata(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
     74                                                           bool * found, void ** userdata)
     75 {
     76     draw_cache_value_t * value = draw_cache_get_entry(ctx, key, key_length, found);
     77     if(!value) return NULL;
     78     if(userdata) {
     79         *userdata = value->userdata;
     80     }
     81     return value->texture;
     82 }
     83 
     84 void lv_draw_sdl_texture_cache_put(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, SDL_Texture * texture)
     85 {
     86     lv_draw_sdl_texture_cache_put_advanced(ctx, key, key_length, texture, NULL, NULL, 0);
     87 }
     88 
     89 void lv_draw_sdl_texture_cache_put_advanced(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
     90                                             SDL_Texture * texture, void * userdata, void userdata_free(void *),
     91                                             lv_draw_sdl_cache_flag_t flags)
     92 {
     93     lv_lru_t * lru = ctx->internals->texture_cache;
     94     draw_cache_value_t * value = SDL_malloc(sizeof(draw_cache_value_t));
     95     value->texture = texture;
     96     value->userdata = userdata;
     97     value->userdata_free = userdata_free;
     98     value->flags = flags;
     99     if(!texture) {
    100         lv_lru_set(lru, key, key_length, value, 1);
    101         return;
    102     }
    103     if(flags & LV_DRAW_SDL_CACHE_FLAG_MANAGED) {
    104         /* Managed texture doesn't count into cache size */
    105         LV_LOG_INFO("cache texture %p", texture);
    106         lv_lru_set(lru, key, key_length, value, 1);
    107         return;
    108     }
    109     Uint32 format;
    110     int access, width, height;
    111     if(SDL_QueryTexture(texture, &format, &access, &width, &height) != 0) {
    112         return;
    113     }
    114     LV_LOG_INFO("cache texture %p, %d*%d@%dbpp", texture, width, height, SDL_BITSPERPIXEL(format));
    115     lv_lru_set(lru, key, key_length, value, width * height * SDL_BITSPERPIXEL(format) / 8);
    116 }
    117 
    118 lv_draw_sdl_cache_key_head_img_t * lv_draw_sdl_texture_img_key_create(const void * src, int32_t frame_id, size_t * size)
    119 {
    120     lv_draw_sdl_cache_key_head_img_t header;
    121     /* VERY IMPORTANT! Padding between members is uninitialized, so we have to wipe them manually */
    122     SDL_memset(&header, 0, sizeof(header));
    123     header.magic = LV_GPU_CACHE_KEY_MAGIC_IMG;
    124     header.type = lv_img_src_get_type(src);
    125     header.frame_id = frame_id;
    126     void * key;
    127     size_t key_size;
    128     if(header.type == LV_IMG_SRC_FILE || header.type == LV_IMG_SRC_SYMBOL) {
    129         size_t srclen = SDL_strlen(src);
    130         key_size = sizeof(header) + srclen;
    131         key = SDL_malloc(key_size);
    132         SDL_memcpy(key, &header, sizeof(header));
    133         /*Copy string content as key value*/
    134         SDL_memcpy(key + sizeof(header), src, srclen);
    135     }
    136     else {
    137         key_size = sizeof(header) + sizeof(void *);
    138         key = SDL_malloc(key_size);
    139         SDL_memcpy(key, &header, sizeof(header));
    140         /*Copy address number as key value*/
    141         SDL_memcpy(key + sizeof(header), &src, sizeof(void *));
    142     }
    143     *size = key_size;
    144     return (lv_draw_sdl_cache_key_head_img_t *) key;
    145 }
    146 
    147 static void draw_cache_free_value(draw_cache_value_t * value)
    148 {
    149     if(value->texture && !(value->flags & LV_DRAW_SDL_CACHE_FLAG_MANAGED)) {
    150         LV_LOG_INFO("destroy texture %p", value->texture);
    151         SDL_DestroyTexture(value->texture);
    152     }
    153     if(value->userdata_free) {
    154         value->userdata_free(value->userdata);
    155     }
    156     SDL_free(value);
    157 }
    158 
    159 static draw_cache_value_t * draw_cache_get_entry(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length,
    160                                                  bool * found)
    161 {
    162     lv_lru_t * lru = ctx->internals->texture_cache;
    163     draw_cache_value_t * value = NULL;
    164     lv_lru_get(lru, key, key_length, (void **) &value);
    165     if(!value) {
    166         if(found) {
    167             *found = false;
    168         }
    169         return NULL;
    170     }
    171     if(found) {
    172         *found = true;
    173     }
    174     return value;
    175 }
    176 
    177 #endif /*LV_USE_GPU_SDL*/
    178