1 /**
2  * @file lv_draw_sdl_refr.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "../../lv_conf_internal.h"
10 
11 #if LV_USE_GPU_SDL
12 
13 #include "../../core/lv_refr.h"
14 
15 #include "lv_draw_sdl.h"
16 #include "lv_draw_sdl_priv.h"
17 #include "lv_draw_sdl_composite.h"
18 #include "lv_draw_sdl_utils.h"
19 #include "lv_draw_sdl_layer.h"
20 
21 /*********************
22  *      DEFINES
23  *********************/
24 
25 /**********************
26  *      TYPEDEFS
27  **********************/
28 
29 /**********************
30  *  STATIC PROTOTYPES
31  **********************/
32 
33 /**********************
34  *  STATIC VARIABLES
35  **********************/
36 
37 /**********************
38  *      MACROS
39  **********************/
40 
41 /**********************
42  *   GLOBAL FUNCTIONS
43  **********************/
44 
lv_draw_sdl_layer_init(lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx,lv_draw_layer_flags_t flags)45 lv_draw_layer_ctx_t * lv_draw_sdl_layer_init(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx,
46                                              lv_draw_layer_flags_t flags)
47 {
48     lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
49     SDL_Renderer * renderer = ctx->renderer;
50 
51     lv_draw_sdl_layer_ctx_t * transform_ctx = (lv_draw_sdl_layer_ctx_t *) layer_ctx;
52 
53     transform_ctx->flags = flags;
54     transform_ctx->orig_target = SDL_GetRenderTarget(renderer);
55 
56     lv_coord_t target_w = lv_area_get_width(&layer_ctx->area_full);
57     lv_coord_t target_h = lv_area_get_height(&layer_ctx->area_full);
58 
59     enum lv_draw_sdl_composite_texture_id_t texture_id = LV_DRAW_SDL_COMPOSITE_TEXTURE_ID_TRANSFORM0 +
60                                                          ctx->internals->transform_count;
61     transform_ctx->target = lv_draw_sdl_composite_texture_obtain(ctx, texture_id, target_w, target_h,
62                                                                  &transform_ctx->target_in_cache);
63     transform_ctx->target_rect.x = 0;
64     transform_ctx->target_rect.y = 0;
65     transform_ctx->target_rect.w = target_w;
66     transform_ctx->target_rect.h = target_h;
67 
68     layer_ctx->max_row_with_alpha = target_h;
69     layer_ctx->max_row_with_no_alpha = target_h;
70 
71     SDL_SetTextureBlendMode(transform_ctx->target, SDL_BLENDMODE_BLEND);
72     SDL_SetRenderTarget(renderer, transform_ctx->target);
73 
74     /* SDL_RenderClear is not working properly, so we overwrite the target with solid color */
75     SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
76     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
77     SDL_RenderFillRect(renderer, NULL);
78     SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
79 
80     /* Set proper drawing context for transform layer */
81     ctx->internals->transform_count += 1;
82     draw_ctx->buf_area = &layer_ctx->area_full;
83     draw_ctx->clip_area = &layer_ctx->area_full;
84 
85     return layer_ctx;
86 }
87 
lv_draw_sdl_layer_blend(lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx,const lv_draw_img_dsc_t * draw_dsc)88 void lv_draw_sdl_layer_blend(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx,
89                              const lv_draw_img_dsc_t * draw_dsc)
90 {
91     lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
92     lv_draw_sdl_layer_ctx_t * transform_ctx = (lv_draw_sdl_layer_ctx_t *) layer_ctx;
93 
94     SDL_Renderer * renderer = ctx->renderer;
95 
96     SDL_Rect trans_rect;
97 
98     if(transform_ctx->flags & LV_DRAW_LAYER_FLAG_CAN_SUBDIVIDE) {
99         lv_area_zoom_to_sdl_rect(&layer_ctx->area_act, &trans_rect, draw_dsc->zoom, &draw_dsc->pivot);
100     }
101     else {
102         lv_area_zoom_to_sdl_rect(&layer_ctx->area_full, &trans_rect, draw_dsc->zoom, &draw_dsc->pivot);
103     }
104 
105     SDL_SetRenderTarget(renderer, transform_ctx->orig_target);
106 
107     /*Render off-screen texture, transformed*/
108     SDL_Rect clip_rect;
109     lv_area_to_sdl_rect(layer_ctx->original.clip_area, &clip_rect);
110     SDL_Point center = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
111     SDL_RenderSetClipRect(renderer, &clip_rect);
112     SDL_SetTextureAlphaMod(transform_ctx->target, draw_dsc->opa);
113     SDL_RenderCopyEx(renderer, transform_ctx->target, &transform_ctx->target_rect, &trans_rect,
114                      draw_dsc->angle, &center, SDL_FLIP_NONE);
115     SDL_RenderSetClipRect(renderer, NULL);
116 }
117 
lv_draw_sdl_layer_destroy(lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx)118 void lv_draw_sdl_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
119 {
120     lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
121     lv_draw_sdl_layer_ctx_t * transform_ctx = (lv_draw_sdl_layer_ctx_t *) layer_ctx;
122     if(!transform_ctx->target_in_cache && transform_ctx->target != NULL) {
123         LV_LOG_WARN("Texture is not cached, this will impact performance.");
124         SDL_DestroyTexture(transform_ctx->target);
125     }
126     ctx->internals->transform_count -= 1;
127 }
128 
lv_draw_sdl_transform_areas_offset(lv_draw_sdl_ctx_t * ctx,bool has_composite,lv_area_t * apply_area,lv_area_t * coords,lv_area_t * clip)129 void lv_draw_sdl_transform_areas_offset(lv_draw_sdl_ctx_t * ctx, bool has_composite, lv_area_t * apply_area,
130                                         lv_area_t * coords, lv_area_t * clip)
131 {
132     if(ctx->internals->transform_count == 0) {
133         return;
134     }
135     lv_area_t * area = ctx->base_draw.buf_area;
136     lv_area_move(coords, -area->x1, -area->y1);
137     lv_area_move(clip, -area->x1, -area->y1);
138     if(has_composite) {
139         lv_area_move(apply_area, -area->x1, -area->y1);
140     }
141 }
142 
143 /**********************
144  *   STATIC FUNCTIONS
145  **********************/
146 
147 #endif /*LV_USE_GPU_SDL*/
148