1 /**
2 * @file lv_opengles_texture.c
3 *
4 */
5
6 /*********************
7 * INCLUDES
8 *********************/
9
10 #include "lv_opengles_texture.h"
11 #if LV_USE_OPENGLES
12
13 #include "lv_opengles_debug.h"
14 #include "../../display/lv_display_private.h"
15 #include <stdlib.h>
16 #include <GL/glew.h>
17 #include <GLFW/glfw3.h>
18
19 /*********************
20 * DEFINES
21 *********************/
22
23 /**********************
24 * TYPEDEFS
25 **********************/
26
27 typedef struct {
28 unsigned int texture_id;
29 uint8_t * fb1;
30 } lv_opengles_texture_t;
31
32 /**********************
33 * STATIC PROTOTYPES
34 **********************/
35
36 static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
37 static void release_disp_cb(lv_event_t * e);
38
39 /**********************
40 * STATIC VARIABLES
41 **********************/
42
43 /**********************
44 * MACROS
45 **********************/
46
47 /**********************
48 * GLOBAL FUNCTIONS
49 **********************/
50
lv_opengles_texture_create(int32_t w,int32_t h)51 lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h)
52 {
53 lv_display_t * disp = lv_display_create(w, h);
54 if(disp == NULL) {
55 return NULL;
56 }
57 lv_opengles_texture_t * dsc = lv_malloc_zeroed(sizeof(lv_opengles_texture_t));
58 LV_ASSERT_MALLOC(dsc);
59 if(dsc == NULL) {
60 lv_display_delete(disp);
61 return NULL;
62 }
63 uint32_t stride = lv_draw_buf_width_to_stride(w, lv_display_get_color_format(disp));
64 uint32_t buf_size = stride * h;
65 dsc->fb1 = malloc(buf_size);
66 if(dsc->fb1 == NULL) {
67 lv_free(dsc);
68 lv_display_delete(disp);
69 return NULL;
70 }
71
72 GL_CALL(glGenTextures(1, &dsc->texture_id));
73 GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id));
74 GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
75 GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
76 GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
77 GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
78 GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
79
80 /* set the dimensions and format to complete the texture */
81 /* Color depth: 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888) */
82 #if LV_COLOR_DEPTH == 8
83 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, disp->hor_res, disp->ver_res, 0, GL_RED, GL_UNSIGNED_BYTE, NULL));
84 #elif LV_COLOR_DEPTH == 16
85 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
86 NULL));
87 #elif LV_COLOR_DEPTH == 24
88 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, disp->hor_res, disp->ver_res, 0, GL_BGR, GL_UNSIGNED_BYTE, NULL));
89 #elif LV_COLOR_DEPTH == 32
90 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
91 #else
92 #error("Unsupported color format")
93 #endif
94
95 glGenerateMipmap(GL_TEXTURE_2D);
96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 20);
97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
99
100 lv_display_set_buffers(disp, dsc->fb1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_DIRECT);
101 lv_display_set_flush_cb(disp, flush_cb);
102 lv_display_set_driver_data(disp, dsc);
103 lv_display_add_event_cb(disp, release_disp_cb, LV_EVENT_DELETE, disp);
104
105 return disp;
106 }
107
lv_opengles_texture_get_texture_id(lv_display_t * disp)108 unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp)
109 {
110 if(disp->flush_cb != flush_cb) {
111 return 0;
112 }
113 lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
114 return dsc->texture_id;
115 }
116
lv_opengles_texture_get_from_texture_id(unsigned int texture_id)117 lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id)
118 {
119 lv_display_t * disp = NULL;
120 while(NULL != (disp = lv_display_get_next(disp))) {
121 unsigned int disp_texture_id = lv_opengles_texture_get_texture_id(disp);
122 if(disp_texture_id == texture_id) {
123 return disp;
124 }
125 }
126 return NULL;
127 }
128
129 /**********************
130 * STATIC FUNCTIONS
131 **********************/
132
flush_cb(lv_display_t * disp,const lv_area_t * area,uint8_t * px_map)133 static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map)
134 {
135 LV_UNUSED(area);
136 LV_UNUSED(px_map);
137
138 #if !LV_USE_DRAW_OPENGLES
139 if(lv_display_flush_is_last(disp)) {
140
141 lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
142 lv_color_format_t cf = lv_display_get_color_format(disp);
143 uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf);
144
145 GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id));
146
147 GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
148 GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf)));
149 /*Color depth: 8 (L8), 16 (RGB565), 24 (RGB888), 32 (XRGB8888)*/
150 #if LV_COLOR_DEPTH == 8
151 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, disp->hor_res, disp->ver_res, 0, GL_RED, GL_UNSIGNED_BYTE, dsc->fb1));
152 #elif LV_COLOR_DEPTH == 16
153 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
154 dsc->fb1));
155 #elif LV_COLOR_DEPTH == 24
156 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, disp->hor_res, disp->ver_res, 0, GL_BGR, GL_UNSIGNED_BYTE, dsc->fb1));
157 #elif LV_COLOR_DEPTH == 32
158 GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE, dsc->fb1));
159 #else
160 #error("Unsupported color format")
161 #endif
162 }
163 #endif /* !LV_USE_DRAW_OPENGLES */
164
165 lv_display_flush_ready(disp);
166 }
167
release_disp_cb(lv_event_t * e)168 static void release_disp_cb(lv_event_t * e)
169 {
170 lv_display_t * disp = lv_event_get_user_data(e);
171 lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
172 free(dsc->fb1);
173 GL_CALL(glDeleteTextures(1, &dsc->texture_id));
174 lv_free(dsc);
175 }
176
177 #endif /*LV_USE_OPENGLES*/
178