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, ¢er, 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