1 /* Copyright (C) 2010-2019 The RetroArch team 2 * 3 * --------------------------------------------------------------------------------------- 4 * The following license statement only applies to this file (gfx_thumbnail.c). 5 * --------------------------------------------------------------------------------------- 6 * 7 * Permission is hereby granted, free of charge, 8 * to any person obtaining a copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation the rights to 10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 11 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 #ifndef __GFX_THUMBNAIL_H 24 #define __GFX_THUMBNAIL_H 25 26 #include <retro_common_api.h> 27 #include <libretro.h> 28 29 #include <boolean.h> 30 31 #include "gfx_animation.h" 32 #include "gfx_thumbnail_path.h" 33 34 RETRO_BEGIN_DECLS 35 36 /* Defines the current status of an entry 37 * thumbnail texture */ 38 enum gfx_thumbnail_status 39 { 40 GFX_THUMBNAIL_STATUS_UNKNOWN = 0, 41 GFX_THUMBNAIL_STATUS_PENDING, 42 GFX_THUMBNAIL_STATUS_AVAILABLE, 43 GFX_THUMBNAIL_STATUS_MISSING 44 }; 45 46 /* Defines thumbnail alignment within 47 * gfx_thumbnail_draw() bounding box */ 48 enum gfx_thumbnail_alignment 49 { 50 GFX_THUMBNAIL_ALIGN_CENTRE = 0, 51 GFX_THUMBNAIL_ALIGN_TOP, 52 GFX_THUMBNAIL_ALIGN_BOTTOM, 53 GFX_THUMBNAIL_ALIGN_LEFT, 54 GFX_THUMBNAIL_ALIGN_RIGHT 55 }; 56 57 /* Defines all possible thumbnail shadow 58 * effect types */ 59 enum gfx_thumbnail_shadow_type 60 { 61 GFX_THUMBNAIL_SHADOW_NONE = 0, 62 GFX_THUMBNAIL_SHADOW_DROP, 63 GFX_THUMBNAIL_SHADOW_OUTLINE 64 }; 65 66 /* Holds all runtime parameters associated with 67 * an entry thumbnail */ 68 typedef struct 69 { 70 uintptr_t texture; 71 unsigned width; 72 unsigned height; 73 float alpha; 74 float delay_timer; 75 enum gfx_thumbnail_status status; 76 bool fade_active; 77 } gfx_thumbnail_t; 78 79 /* Holds all configuration parameters associated 80 * with a thumbnail shadow effect */ 81 typedef struct 82 { 83 struct 84 { 85 unsigned width; 86 } outline; 87 float alpha; 88 struct 89 { 90 float x_offset; 91 float y_offset; 92 } drop; 93 enum gfx_thumbnail_shadow_type type; 94 } gfx_thumbnail_shadow_t; 95 96 /* Structure containing all gfx_thumbnail 97 * variables */ 98 struct gfx_thumbnail_state 99 { 100 /* Due to the asynchronous nature of thumbnail 101 * loading, it is quite possible to trigger a load 102 * then navigate to a different menu list before 103 * the load is complete/handled. As an additional 104 * safety check, we therefore tag the current menu 105 * list with counter value that is incremented whenever 106 * a list is cleared/set. This is sent as userdata when 107 * requesting a thumbnail, and the upload is only 108 * handled if the tag matches the most recent value 109 * at the time when the load completes */ 110 uint64_t list_id; 111 112 /* When streaming thumbnails, to minimise the processing 113 * of unnecessary images (i.e. when scrolling rapidly through 114 * playlists), we delay loading until an entry has been on screen 115 * for at least gfx_thumbnail_delay ms */ 116 float stream_delay; 117 118 /* Duration in ms of the thumbnail 'fade in' animation */ 119 float fade_duration; 120 121 /* When true, 'fade in' animation will also be 122 * triggered for missing thumbnails */ 123 bool fade_missing; 124 }; 125 126 typedef struct gfx_thumbnail_state gfx_thumbnail_state_t; 127 128 129 /* Setters */ 130 131 /* When streaming thumbnails, sets time in ms that an 132 * entry must be on screen before an image load is 133 * requested 134 * > if 'delay' is negative, default value is set */ 135 void gfx_thumbnail_set_stream_delay(float delay); 136 137 /* Sets duration in ms of the thumbnail 'fade in' 138 * animation 139 * > If 'duration' is negative, default value is set */ 140 void gfx_thumbnail_set_fade_duration(float duration); 141 142 /* Specifies whether 'fade in' animation should be 143 * triggered for missing thumbnails 144 * > When 'true', allows menu driver to animate 145 * any 'thumbnail unavailable' notifications */ 146 void gfx_thumbnail_set_fade_missing(bool fade_missing); 147 148 /* Core interface */ 149 150 /* When called, prevents the handling of any pending 151 * thumbnail load requests 152 * >> **MUST** be called before deleting any gfx_thumbnail_t 153 * objects passed to gfx_thumbnail_request() or 154 * gfx_thumbnail_process_stream(), otherwise 155 * heap-use-after-free errors *will* occur */ 156 void gfx_thumbnail_cancel_pending_requests(void); 157 158 /* Requests loading of the specified thumbnail 159 * - If operation fails, 'thumbnail->status' will be set to 160 * MUI_THUMBNAIL_STATUS_MISSING 161 * - If operation is successful, 'thumbnail->status' will be 162 * set to MUI_THUMBNAIL_STATUS_PENDING 163 * 'thumbnail' will be populated with texture info/metadata 164 * once the image load is complete 165 * NOTE 1: Must be called *after* gfx_thumbnail_set_system() 166 * and gfx_thumbnail_set_content*() 167 * NOTE 2: 'playlist' and 'idx' are only required here for 168 * on-demand thumbnail download support 169 * (an annoyance...) */ 170 void gfx_thumbnail_request( 171 gfx_thumbnail_path_data_t *path_data, enum gfx_thumbnail_id thumbnail_id, 172 playlist_t *playlist, size_t idx, gfx_thumbnail_t *thumbnail, 173 unsigned gfx_thumbnail_upscale_threshold, 174 bool network_on_demand_thumbnails 175 ); 176 177 /* Requests loading of a specific thumbnail image file 178 * (may be used, for example, to load savestate images) 179 * - If operation fails, 'thumbnail->status' will be set to 180 * MUI_THUMBNAIL_STATUS_MISSING 181 * - If operation is successful, 'thumbnail->status' will be 182 * set to MUI_THUMBNAIL_STATUS_PENDING 183 * 'thumbnail' will be populated with texture info/metadata 184 * once the image load is complete */ 185 void gfx_thumbnail_request_file( 186 const char *file_path, gfx_thumbnail_t *thumbnail, 187 unsigned gfx_thumbnail_upscale_threshold); 188 189 /* Resets (and free()s the current texture of) the 190 * specified thumbnail */ 191 void gfx_thumbnail_reset(gfx_thumbnail_t *thumbnail); 192 193 /* Stream processing */ 194 195 /* Handles streaming of the specified thumbnail as it moves 196 * on/off screen 197 * - Must be called each frame for every on-screen entry 198 * - Must be called once for each entry as it moves off-screen 199 * (or can be called each frame - overheads are small) 200 * NOTE 1: Must be called *after* gfx_thumbnail_set_system() 201 * NOTE 2: This function calls gfx_thumbnail_set_content*() 202 * NOTE 3: This function is intended for use in situations 203 * where each menu entry has a *single* thumbnail. 204 * If each entry has two thumbnails, use 205 * gfx_thumbnail_process_streams() for improved 206 * performance */ 207 void gfx_thumbnail_process_stream( 208 gfx_thumbnail_path_data_t *path_data, 209 gfx_animation_t *p_anim, 210 enum gfx_thumbnail_id thumbnail_id, 211 playlist_t *playlist, 212 size_t idx, 213 gfx_thumbnail_t *thumbnail, 214 bool on_screen, 215 unsigned gfx_thumbnail_upscale_threshold, 216 bool network_on_demand_thumbnails 217 ); 218 219 /* Handles streaming of the specified thumbnails as they move 220 * on/off screen 221 * - Must be called each frame for every on-screen entry 222 * - Must be called once for each entry as it moves off-screen 223 * (or can be called each frame - overheads are small) 224 * NOTE 1: Must be called *after* gfx_thumbnail_set_system() 225 * NOTE 2: This function calls gfx_thumbnail_set_content*() 226 * NOTE 3: This function is intended for use in situations 227 * where each menu entry has *two* thumbnails. 228 * If each entry only has a single thumbnail, use 229 * gfx_thumbnail_process_stream() for improved 230 * performance */ 231 void gfx_thumbnail_process_streams( 232 gfx_thumbnail_path_data_t *path_data, 233 gfx_animation_t *p_anim, 234 playlist_t *playlist, size_t idx, 235 gfx_thumbnail_t *right_thumbnail, 236 gfx_thumbnail_t *left_thumbnail, 237 bool on_screen, 238 unsigned gfx_thumbnail_upscale_threshold, 239 bool network_on_demand_thumbnails 240 ); 241 242 /* Thumbnail rendering */ 243 244 /* Determines the actual screen dimensions of a 245 * thumbnail when centred with aspect correct 246 * scaling within a rectangle of (width x height) */ 247 void gfx_thumbnail_get_draw_dimensions( 248 gfx_thumbnail_t *thumbnail, 249 unsigned width, unsigned height, float scale_factor, 250 float *draw_width, float *draw_height); 251 252 /* Draws specified thumbnail with specified alignment 253 * (and aspect correct scaling) within a rectangle of 254 * (width x height). 255 * 'shadow' defines an optional shadow effect (may be 256 * set to NULL if a shadow effect is not required). 257 * NOTE: Setting scale_factor > 1.0f will increase the 258 * size of the thumbnail beyond the limits of the 259 * (width x height) rectangle (alignment + aspect 260 * correct scaling is preserved). Use with caution */ 261 void gfx_thumbnail_draw( 262 void *userdata, 263 unsigned video_width, 264 unsigned video_height, 265 gfx_thumbnail_t *thumbnail, 266 float x, float y, unsigned width, unsigned height, 267 enum gfx_thumbnail_alignment alignment, 268 float alpha, float scale_factor, 269 gfx_thumbnail_shadow_t *shadow); 270 271 gfx_thumbnail_state_t *gfx_thumb_get_ptr(void); 272 273 RETRO_END_DECLS 274 275 #endif 276