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_rect.x = 0;
63     transform_ctx->target_rect.y = 0;
64     transform_ctx->target_rect.w = target_w;
65     transform_ctx->target_rect.h = target_h;
66 
67     layer_ctx->max_row_with_alpha = target_h;
68     layer_ctx->max_row_with_no_alpha = target_h;
69 
70     SDL_SetTextureBlendMode(transform_ctx->target, SDL_BLENDMODE_BLEND);
71     SDL_SetRenderTarget(renderer, transform_ctx->target);
72 
73     /* SDL_RenderClear is not working properly, so we overwrite the target with solid color */
74     SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
75     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
76     SDL_RenderFillRect(renderer, NULL);
77     SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
78 
79     /* Set proper drawing context for transform layer */
80     ctx->internals->transform_count += 1;
81     draw_ctx->buf_area = &layer_ctx->area_full;
82     draw_ctx->clip_area = &layer_ctx->area_full;
83 
84     return layer_ctx;
85 }
86 
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)87 void lv_draw_sdl_layer_blend(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx,
88                              const lv_draw_img_dsc_t * draw_dsc)
89 {
90     lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
91     lv_draw_sdl_layer_ctx_t * transform_ctx = (lv_draw_sdl_layer_ctx_t *) layer_ctx;
92 
93     SDL_Renderer * renderer = ctx->renderer;
94 
95     SDL_Rect trans_rect;
96 
97     if(transform_ctx->flags & LV_DRAW_LAYER_FLAG_CAN_SUBDIVIDE) {
98         lv_area_zoom_to_sdl_rect(&layer_ctx->area_act, &trans_rect, draw_dsc->zoom, &draw_dsc->pivot);
99     }
100     else {
101         lv_area_zoom_to_sdl_rect(&layer_ctx->area_full, &trans_rect, draw_dsc->zoom, &draw_dsc->pivot);
102     }
103 
104     SDL_SetRenderTarget(renderer, transform_ctx->orig_target);
105 
106     /*Render off-screen texture, transformed*/
107     SDL_Rect clip_rect;
108     lv_area_to_sdl_rect(layer_ctx->original.clip_area, &clip_rect);
109     SDL_Point center = {.x = draw_dsc->pivot.x, .y = draw_dsc->pivot.y};
110     SDL_RenderSetClipRect(renderer, &clip_rect);
111     SDL_SetTextureAlphaMod(transform_ctx->target, draw_dsc->opa);
112     SDL_RenderCopyEx(renderer, transform_ctx->target, &transform_ctx->target_rect, &trans_rect,
113                      draw_dsc->angle, &center, SDL_FLIP_NONE);
114     SDL_RenderSetClipRect(renderer, NULL);
115 }
116 
lv_draw_sdl_layer_destroy(lv_draw_ctx_t * draw_ctx,lv_draw_layer_ctx_t * layer_ctx)117 void lv_draw_sdl_layer_destroy(lv_draw_ctx_t * draw_ctx, lv_draw_layer_ctx_t * layer_ctx)
118 {
119     lv_draw_sdl_ctx_t * ctx = (lv_draw_sdl_ctx_t *) draw_ctx;
120     ctx->internals->transform_count -= 1;
121 }
122 
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)123 void lv_draw_sdl_transform_areas_offset(lv_draw_sdl_ctx_t * ctx, bool has_composite, lv_area_t * apply_area,
124                                         lv_area_t * coords, lv_area_t * clip)
125 {
126     if(ctx->internals->transform_count == 0) {
127         return;
128     }
129     lv_area_t * area = ctx->base_draw.buf_area;
130     lv_area_move(coords, -area->x1, -area->y1);
131     lv_area_move(clip, -area->x1, -area->y1);
132     if(has_composite) {
133         lv_area_move(apply_area, -area->x1, -area->y1);
134     }
135 }
136 
137 /**********************
138  *   STATIC FUNCTIONS
139  **********************/
140 
141 #endif /*LV_USE_GPU_SDL*/
142