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