1 /****************************************************************************
2 *
3 * Copyright 2012 - 2020 Vivante Corporation, Santa Clara, California.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * 'Software'), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject
12 * to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *****************************************************************************/
27
28 #include "elm_precom.h"
29 #include "vg_lite.h"
30 #if !DDRLESS
_buffer_format_to_vglite(ELM_BUFFER_FORMAT format)31 static vg_lite_buffer_format_t _buffer_format_to_vglite(ELM_BUFFER_FORMAT format)
32 {
33 vg_lite_buffer_format_t fmt;
34 switch (format) {
35 case ELM_BUFFER_FORMAT_RGBA8888:
36 fmt = VG_LITE_RGBA8888;
37 break;
38
39 case ELM_BUFFER_FORMAT_RGBX8888:
40 fmt = VG_LITE_RGBX8888;
41 break;
42
43 case ELM_BUFFER_FORMAT_BGRA8888:
44 fmt = VG_LITE_BGRA8888;
45 break;
46
47 case ELM_BUFFER_FORMAT_BGRX8888:
48 fmt = VG_LITE_BGRX8888;
49 break;
50
51 case ELM_BUFFER_FORMAT_RGB565:
52 fmt = VG_LITE_RGB565;
53 break;
54
55 case ELM_BUFFER_FORMAT_BGR565:
56 fmt = VG_LITE_BGR565;
57 break;
58
59 case ELM_BUFFER_FORMAT_RGBA4444:
60 fmt = VG_LITE_RGBA4444;
61 break;
62
63 case ELM_BUFFER_FORMAT_BGRA4444:
64 fmt = VG_LITE_BGRA4444;
65 break;
66
67 default:
68 fmt = VG_LITE_RGBA8888;
69 break;
70 }
71
72 return fmt;
73 }
74 #endif
75 /*!
76 @abstract Create internal render buffer.
77
78 @discussion
79 This functiois is to create an internal render buffer for Elementary rendering, ussually it's not for direct display.
80 The buffer which is displayed on pannel is wrapped up by another API, whose address is managed by display controller side.
81
82 @param width
83 The buffer's width.
84
85 @param height
86 The buffer's height.
87
88 @param format
89 The buffer's format, check enumeration of ELM_BUFFER_FORMAT.
90
91 @return
92 The buffer handle.
93 */
ElmCreateBuffer(unsigned int width,unsigned int height,ELM_BUFFER_FORMAT format)94 ElmBuffer ElmCreateBuffer(unsigned int width, unsigned int height, ELM_BUFFER_FORMAT format)
95 {
96 #if !DDRLESS
97 el_Obj_Buffer *buffer_obj;
98 vg_lite_buffer_t *buffer;
99 vg_lite_error_t error;
100 ElmHandle handle = ELM_NULL_HANDLE;
101
102 do {
103 /* Allocate ebo object. */
104 buffer_obj = (el_Obj_Buffer *)calloc(1,sizeof(el_Obj_Buffer));
105 if (buffer_obj != NULL) {
106 buffer_obj->object.type = ELM_OBJECT_TYPE_BUF;
107
108 /* Allocate the buffer. */
109 buffer = &buffer_obj->buffer;
110 memset(buffer, 0, sizeof(vg_lite_buffer_t));
111 buffer->width = width;
112 buffer->height = height;
113 buffer->format = (vg_lite_buffer_format_t)format;
114 error = vg_lite_allocate(buffer);
115 if (error)
116 goto error_exit;
117
118 JUMP_IF_NON_ZERO_VALUE(add_object((el_Object *)buffer_obj), error_exit);
119 handle = buffer_obj->object.handle;
120 }
121 } while(0);
122
123 return handle;
124 error_exit:
125 vg_lite_free(buffer);
126 free(buffer_obj);
127 return ELM_NULL_HANDLE;
128 #else
129 return ELM_NULL_HANDLE;
130 #endif
131 }
132
133 /*!
134 @abstract Wrap a customized buffer.
135
136 @discussion
137 The application may wrap a user created buffer by giving the information of
138 the buffer including the size, the memory addresses and format. E.g., the
139 application can wrap a system framebuffer thus ELM can directly render onto
140 the screen.
141
142 @return
143 The buffer handle.
144 */
ElmWrapBuffer(int width,int height,int stride,void * logical,uint32_t physical,ELM_BUFFER_FORMAT format)145 ElmBuffer ElmWrapBuffer(int width, int height, int stride,
146 void *logical, uint32_t physical,
147 ELM_BUFFER_FORMAT format)
148 {
149 #if !DDRLESS
150 el_Obj_Buffer *buffer_obj;
151 vg_lite_buffer_t *buffer;
152 ElmHandle handle = ELM_NULL_HANDLE;
153
154 do {
155 /* open framebuffer. */
156 buffer_obj = (el_Obj_Buffer *)elm_alloc(1, sizeof(el_Obj_Buffer));
157 if (buffer_obj != NULL) {
158 buffer_obj->object.type = ELM_OBJECT_TYPE_BUF;
159 buffer = &buffer_obj->buffer;
160
161 buffer->width = width;
162 buffer->height = height;
163 buffer->stride = stride;
164 buffer->memory = logical;
165 buffer->handle = NULL;
166 buffer->address = physical;
167 buffer->format = _buffer_format_to_vglite(format);
168 buffer->tiled = VG_LITE_LINEAR;
169 JUMP_IF_NON_ZERO_VALUE(add_object((el_Object *)buffer_obj), error_exit);
170 handle = buffer_obj->object.handle;
171 }
172 } while(0);
173
174 return handle;
175
176 error_exit:
177 free(buffer_obj);
178 return ELM_NULL_HANDLE;
179 #else
180 return ELM_NULL_HANDLE;
181 #endif
182
183 }
184
185 /*!
186 @abstract Get buffer address.
187
188 @discussion
189 The function is to get the address of ElmBuffer.
190
191 @return
192 The buffer address.
193 */
194
ElmGetBufferAddress(ElmBuffer buffer)195 uint32_t ElmGetBufferAddress(ElmBuffer buffer)
196 {
197 #if !DDRLESS
198 el_Obj_Buffer *buff_obj;
199 buff_obj = (el_Obj_Buffer *)get_object(buffer);
200
201 if (buff_obj == NULL)
202 {
203 return 0;
204 }
205 else
206 {
207 return buff_obj->buffer.address;
208 }
209 #else
210 return 0;
211 #endif
212 }
213
214 /*!
215 @abstract Destroy a render buffer.
216
217 @discussion
218 This function is to release all internal resource inside Elementary libary belonging to this buffer.
219 Applicatoin need make sure the buffer is not being used by elmentary library any more when calling this function.
220
221 @param buffer
222 The render buffer handle
223
224 @return
225 If destroying is completed successfully.
226 */
ElmDestroyBuffer(ElmBuffer buffer)227 BOOL ElmDestroyBuffer(ElmBuffer buffer)
228 {
229 #if !DDRLESS
230 /* Find the object. */
231 el_Obj_Buffer *buff = (el_Obj_Buffer *)get_object(buffer);
232
233 /* If found, delete the vg_lite_buffer object. Otherwise, return FALSE. */
234 if (buff != NULL) {
235 if (buff->buffer.handle != NULL) {
236 /* Free the buffer memory. */
237 vg_lite_free(&buff->buffer);
238 }
239
240 remove_object((el_Object*)buff);
241 elm_free(buff);
242
243 return TRUE;
244 }
245 else {
246 return FALSE;
247 }
248 #else
249 return TRUE;
250 #endif
251 }
252
ElmSaveBuffer(ElmBuffer buffer,const char * name)253 BOOL ElmSaveBuffer(ElmBuffer buffer, const char *name)
254 {
255 #if !DDRLESS
256 el_Obj_Buffer *buff = (el_Obj_Buffer *)get_object(buffer);
257
258 /* If found, delete the vg_lite_buffer object. Otherwise, return FALSE. */
259 if (buff != NULL) {
260 #if !RTOS
261 /*
262 "vg_lite_save_png" function does not exist (anymore). Probably a left
263 over from an older driver.
264 */
265 if (buff->buffer.memory != NULL) {
266 vg_lite_save_png(name, &buff->buffer);
267 }
268 #endif
269 return TRUE;
270 }
271 else {
272 return FALSE;
273 }
274 #else
275 return TRUE;
276 #endif
277 }
278
279 /*!
280 @abstract Convert vglite format to elm format.
281 */
_buffer_format_to_Elm(vg_lite_buffer_format_t format)282 ELM_BUFFER_FORMAT _buffer_format_to_Elm(vg_lite_buffer_format_t format)
283 {
284 switch (format)
285 {
286 case VG_LITE_RGB565:
287 return ELM_BUFFER_FORMAT_RGB565;
288 break;
289 case VG_LITE_BGR565:
290 return ELM_BUFFER_FORMAT_BGR565;
291 break;
292 default:
293 return ELM_BUFFER_FORMAT_RGBA8888;
294 break;
295 }
296 }
297
298 /*!
299 @abstract Get handle of the framebuffer.
300 */
ElmGetBuffer(vg_lite_buffer_t * buffer)301 ElmBuffer ElmGetBuffer(vg_lite_buffer_t *buffer)
302 {
303 elm_tls_t* elm_tls;
304
305 elm_tls = (elm_tls_t *) elm_os_get_tls();
306 if (elm_tls == NULL)
307 return ELM_NULL_HANDLE;
308
309 for (int i = 0; i < APP_BUFFER_COUNT; i++) {
310 if (elm_tls->gContext.elmFB[i].buffer == NULL) {
311 elm_tls->gContext.elmFB[i].buffer = buffer;
312 elm_tls->gContext.elmFB[i].handle = ElmWrapBuffer(buffer->width, buffer->height, buffer->stride, buffer->memory,
313 buffer->address, _buffer_format_to_Elm(buffer->format));
314 vg_lite_clear(buffer, NULL, 0x0);
315 return elm_tls->gContext.elmFB[i].handle;
316 }
317 if (elm_tls->gContext.elmFB[i].buffer == buffer)
318 return elm_tls->gContext.elmFB[i].handle;
319 }
320 return 0;
321 }
322