diff options
Diffstat (limited to 'libraries/evas/src/modules/engines/fb/evas_outbuf.c')
-rw-r--r-- | libraries/evas/src/modules/engines/fb/evas_outbuf.c | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/fb/evas_outbuf.c b/libraries/evas/src/modules/engines/fb/evas_outbuf.c new file mode 100644 index 0000000..57cf7a6 --- /dev/null +++ b/libraries/evas/src/modules/engines/fb/evas_outbuf.c | |||
@@ -0,0 +1,397 @@ | |||
1 | #include "evas_common.h" | ||
2 | #include "evas_engine.h" | ||
3 | #include <sys/time.h> | ||
4 | #include <sys/utsname.h> | ||
5 | |||
6 | void | ||
7 | evas_fb_outbuf_fb_init(void) | ||
8 | { | ||
9 | } | ||
10 | |||
11 | void | ||
12 | evas_fb_outbuf_fb_free(Outbuf *buf) | ||
13 | { | ||
14 | /* FIXME: implement */ | ||
15 | WRN("destroying fb info.. not implemented!!!! WARNING. LEAK!"); | ||
16 | if (buf->priv.back_buf) | ||
17 | evas_cache_image_drop(&buf->priv.back_buf->cache_entry); | ||
18 | free(buf); | ||
19 | } | ||
20 | |||
21 | Outbuf * | ||
22 | evas_fb_outbuf_fb_setup_fb(int w, int h, int rot, Outbuf_Depth depth, int vt_no, int dev_no, int refresh) | ||
23 | { | ||
24 | /* create outbuf struct */ | ||
25 | /* setup window and/or fb */ | ||
26 | /* if (dithered) create backbuf */ | ||
27 | Outbuf *buf; | ||
28 | int fb_fd = -1; | ||
29 | int fb_depth; | ||
30 | |||
31 | fb_depth = -1; | ||
32 | if (depth == OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED) fb_depth = 16; | ||
33 | else if (depth == OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED) fb_depth = 15; | ||
34 | else if (depth == OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED) fb_depth = 16; | ||
35 | else if (depth == OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED) fb_depth = 12; | ||
36 | else if (depth == OUTBUF_DEPTH_RGB_32BPP_888_8888) fb_depth = 32; | ||
37 | else if (depth == OUTBUF_DEPTH_INHERIT) fb_depth = 0; | ||
38 | buf = calloc(1, sizeof(Outbuf)); | ||
39 | if (!buf) | ||
40 | return NULL; | ||
41 | |||
42 | fb_init(vt_no, dev_no); | ||
43 | if (rot == 0 || rot == 180) | ||
44 | buf->priv.fb.fb = fb_setmode(w, h, fb_depth, refresh); | ||
45 | else if (rot == 90 || rot == 270) | ||
46 | buf->priv.fb.fb = fb_setmode(h, w, fb_depth, refresh); | ||
47 | if (!buf->priv.fb.fb) buf->priv.fb.fb = fb_getmode(); | ||
48 | if (!buf->priv.fb.fb) | ||
49 | { | ||
50 | free(buf); | ||
51 | return NULL; | ||
52 | } | ||
53 | fb_fd = fb_postinit(buf->priv.fb.fb); | ||
54 | |||
55 | if (rot == 0 || rot == 180) | ||
56 | { | ||
57 | buf->w = buf->priv.fb.fb->width; | ||
58 | buf->h = buf->priv.fb.fb->height; | ||
59 | } | ||
60 | else if (rot == 90 || rot == 270) | ||
61 | { | ||
62 | buf->w = buf->priv.fb.fb->height; | ||
63 | buf->h = buf->priv.fb.fb->width; | ||
64 | } | ||
65 | |||
66 | buf->depth = depth; | ||
67 | buf->rot = rot; | ||
68 | |||
69 | { | ||
70 | Gfx_Func_Convert conv_func; | ||
71 | int i; | ||
72 | |||
73 | buf->priv.mask.r = 0; | ||
74 | for (i = 0; i < (int)buf->priv.fb.fb->fb_var.red.length; i++) | ||
75 | buf->priv.mask.r |= (1 << (buf->priv.fb.fb->fb_var.red.offset + i)); | ||
76 | buf->priv.mask.g = 0; | ||
77 | for (i = 0; i < (int)buf->priv.fb.fb->fb_var.green.length; i++) | ||
78 | buf->priv.mask.g |= (1 << (buf->priv.fb.fb->fb_var.green.offset + i)); | ||
79 | buf->priv.mask.b = 0; | ||
80 | for (i = 0; i < (int)buf->priv.fb.fb->fb_var.blue.length; i++) | ||
81 | buf->priv.mask.b |= (1 << (buf->priv.fb.fb->fb_var.blue.offset + i)); | ||
82 | |||
83 | conv_func = NULL; | ||
84 | if (buf->rot == 0 || buf->rot == 180) | ||
85 | conv_func = evas_common_convert_func_get(0, buf->w, buf->h, | ||
86 | buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
87 | buf->priv.mask.r, | ||
88 | buf->priv.mask.g, | ||
89 | buf->priv.mask.b, | ||
90 | PAL_MODE_NONE, | ||
91 | buf->rot); | ||
92 | else if (buf->rot == 90 || buf->rot == 270) | ||
93 | conv_func = evas_common_convert_func_get(0, buf->h, buf->w, | ||
94 | buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
95 | buf->priv.mask.r, | ||
96 | buf->priv.mask.g, | ||
97 | buf->priv.mask.b, | ||
98 | PAL_MODE_NONE, | ||
99 | buf->rot); | ||
100 | if (!conv_func) | ||
101 | { | ||
102 | free(buf); | ||
103 | return NULL; | ||
104 | } | ||
105 | } | ||
106 | // if (buf->priv.fb.fb->fb_var.bits_per_pixel < 24) | ||
107 | // buf->priv.back_buf = evas_common_image_create(buf->w, buf->h); | ||
108 | |||
109 | return buf; | ||
110 | } | ||
111 | |||
112 | void | ||
113 | evas_fb_outbuf_fb_blit(Outbuf *buf, int src_x, int src_y, int w, int h, int dst_x, int dst_y) | ||
114 | { | ||
115 | if (buf->priv.back_buf) | ||
116 | { | ||
117 | evas_common_blit_rectangle(buf->priv.back_buf, buf->priv.back_buf, | ||
118 | src_x, src_y, w, h, dst_x, dst_y); | ||
119 | evas_fb_outbuf_fb_update(buf, dst_x, dst_y, w, h); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | if (buf->priv.fb.fb) | ||
124 | { | ||
125 | /* FIXME: need to implement an fb call for "copy area" */ | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | void | ||
131 | evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) | ||
132 | { | ||
133 | if (!(buf->priv.back_buf)) return; | ||
134 | if (buf->priv.fb.fb) | ||
135 | { | ||
136 | Gfx_Func_Convert conv_func; | ||
137 | DATA8 *data; | ||
138 | |||
139 | data = NULL; | ||
140 | conv_func = NULL; | ||
141 | if (buf->rot == 0) | ||
142 | { | ||
143 | data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + | ||
144 | buf->priv.fb.fb->bpp * | ||
145 | (x + (y * buf->priv.fb.fb->width)); | ||
146 | conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
147 | buf->priv.mask.r, buf->priv.mask.g, | ||
148 | buf->priv.mask.b, PAL_MODE_NONE, | ||
149 | buf->rot); | ||
150 | } | ||
151 | else if (buf->rot == 180) | ||
152 | { | ||
153 | data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + | ||
154 | buf->priv.fb.fb->bpp * | ||
155 | (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width)); | ||
156 | conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
157 | buf->priv.mask.r, buf->priv.mask.g, | ||
158 | buf->priv.mask.b, PAL_MODE_NONE, | ||
159 | buf->rot); | ||
160 | } | ||
161 | else if (buf->rot == 270) | ||
162 | { | ||
163 | data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + | ||
164 | buf->priv.fb.fb->bpp * | ||
165 | (buf->h - y - h + (x * buf->priv.fb.fb->width)); | ||
166 | conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
167 | buf->priv.mask.r, buf->priv.mask.g, | ||
168 | buf->priv.mask.b, PAL_MODE_NONE, | ||
169 | buf->rot); | ||
170 | } | ||
171 | else if (buf->rot == 90) | ||
172 | { | ||
173 | data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + | ||
174 | buf->priv.fb.fb->bpp * | ||
175 | (y + ((buf->w - x - w) * buf->priv.fb.fb->width)); | ||
176 | conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
177 | buf->priv.mask.r, buf->priv.mask.g, | ||
178 | buf->priv.mask.b, PAL_MODE_NONE, | ||
179 | buf->rot); | ||
180 | } | ||
181 | if (conv_func) | ||
182 | { | ||
183 | DATA32 *src_data; | ||
184 | |||
185 | src_data = buf->priv.back_buf->image.data + (y * buf->w) + x; | ||
186 | if (buf->rot == 0 || buf->rot == 180) | ||
187 | { | ||
188 | conv_func(src_data, data, | ||
189 | buf->w - w, | ||
190 | buf->priv.fb.fb->width - w, | ||
191 | w, h, | ||
192 | x, y, NULL); | ||
193 | } | ||
194 | else if (buf->rot == 90 || buf->rot == 270) | ||
195 | { | ||
196 | conv_func(src_data, data, | ||
197 | buf->w - w, | ||
198 | buf->priv.fb.fb->width - h, | ||
199 | h, w, | ||
200 | x, y, NULL); | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | RGBA_Image * | ||
207 | evas_fb_outbuf_fb_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) | ||
208 | { | ||
209 | if (buf->priv.back_buf) | ||
210 | { | ||
211 | *cx = x; *cy = y; *cw = w; *ch = h; | ||
212 | return buf->priv.back_buf; | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | RGBA_Image *im; | ||
217 | |||
218 | *cx = 0; *cy = 0; *cw = w; *ch = h; | ||
219 | im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); | ||
220 | im->cache_entry.flags.alpha = 1; | ||
221 | im = (RGBA_Image *) evas_cache_image_size_set(&im->cache_entry, w, h); | ||
222 | |||
223 | return im; | ||
224 | } | ||
225 | return NULL; | ||
226 | } | ||
227 | |||
228 | void | ||
229 | evas_fb_outbuf_fb_free_region_for_update(Outbuf *buf, RGBA_Image *update) | ||
230 | { | ||
231 | if (update != buf->priv.back_buf) evas_cache_image_drop(&update->cache_entry); | ||
232 | } | ||
233 | |||
234 | void | ||
235 | evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h) | ||
236 | { | ||
237 | if (!buf->priv.fb.fb) return; | ||
238 | if (buf->priv.back_buf) | ||
239 | { | ||
240 | if (update != buf->priv.back_buf) | ||
241 | evas_common_blit_rectangle(update, buf->priv.back_buf, | ||
242 | 0, 0, w, h, x, y); | ||
243 | evas_fb_outbuf_fb_update(buf, x, y, w, h); | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | Gfx_Func_Convert conv_func; | ||
248 | DATA8 *data; | ||
249 | |||
250 | data = NULL; | ||
251 | conv_func = NULL; | ||
252 | if (buf->rot == 0) | ||
253 | { | ||
254 | data = (DATA8 *)buf->priv.fb.fb->mem + | ||
255 | buf->priv.fb.fb->mem_offset + | ||
256 | buf->priv.fb.fb->bpp * | ||
257 | (x + (y * buf->priv.fb.fb->width)); | ||
258 | conv_func = evas_common_convert_func_get(data, w, h, | ||
259 | buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
260 | buf->priv.mask.r, buf->priv.mask.g, | ||
261 | buf->priv.mask.b, PAL_MODE_NONE, | ||
262 | buf->rot); | ||
263 | } | ||
264 | else if (buf->rot == 180) | ||
265 | { | ||
266 | data = (DATA8 *)buf->priv.fb.fb->mem + | ||
267 | buf->priv.fb.fb->mem_offset + | ||
268 | buf->priv.fb.fb->bpp * | ||
269 | (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width)); | ||
270 | conv_func = evas_common_convert_func_get(data, w, h, | ||
271 | buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
272 | buf->priv.mask.r, buf->priv.mask.g, | ||
273 | buf->priv.mask.b, PAL_MODE_NONE, | ||
274 | buf->rot); | ||
275 | } | ||
276 | else if (buf->rot == 270) | ||
277 | { | ||
278 | data = (DATA8 *)buf->priv.fb.fb->mem + | ||
279 | buf->priv.fb.fb->mem_offset + | ||
280 | buf->priv.fb.fb->bpp * | ||
281 | (buf->h - y - h + (x * buf->priv.fb.fb->width)); | ||
282 | conv_func = evas_common_convert_func_get(data, h, w, | ||
283 | buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
284 | buf->priv.mask.r, buf->priv.mask.g, | ||
285 | buf->priv.mask.b, PAL_MODE_NONE, | ||
286 | buf->rot); | ||
287 | } | ||
288 | else if (buf->rot == 90) | ||
289 | { | ||
290 | data = (DATA8 *)buf->priv.fb.fb->mem + | ||
291 | buf->priv.fb.fb->mem_offset + | ||
292 | buf->priv.fb.fb->bpp * | ||
293 | (y + ((buf->w - x - w) * buf->priv.fb.fb->width)); | ||
294 | conv_func = evas_common_convert_func_get(data, h, w, | ||
295 | buf->priv.fb.fb->fb_var.bits_per_pixel, | ||
296 | buf->priv.mask.r, buf->priv.mask.g, | ||
297 | buf->priv.mask.b, PAL_MODE_NONE, | ||
298 | buf->rot); | ||
299 | } | ||
300 | if (conv_func) | ||
301 | { | ||
302 | DATA32 *src_data; | ||
303 | |||
304 | src_data = update->image.data; | ||
305 | if (buf->rot == 0 || buf->rot == 180) | ||
306 | { | ||
307 | conv_func(src_data, data, | ||
308 | 0, | ||
309 | buf->priv.fb.fb->width - w, | ||
310 | w, h, | ||
311 | x, y, NULL); | ||
312 | } | ||
313 | else if (buf->rot == 90 || buf->rot == 270) | ||
314 | { | ||
315 | conv_func(src_data, data, | ||
316 | 0, | ||
317 | buf->priv.fb.fb->width - h, | ||
318 | h, w, | ||
319 | x, y, NULL); | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | } | ||
324 | |||
325 | void | ||
326 | evas_fb_outbuf_fb_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth) | ||
327 | { | ||
328 | if ((w == buf->w) && (h == buf->h) && | ||
329 | (rot == buf->rot) && (depth == buf->depth)) | ||
330 | return; | ||
331 | if (buf->priv.back_buf) | ||
332 | { | ||
333 | evas_cache_image_drop(&buf->priv.back_buf->cache_entry); | ||
334 | buf->priv.back_buf = NULL; | ||
335 | } | ||
336 | if (buf->priv.fb.fb) | ||
337 | { | ||
338 | /* FIXME: implement this */ | ||
339 | } | ||
340 | /* if backbuf delet it */ | ||
341 | /* resize window or reset fb mode */ | ||
342 | /* if (dithered) create new backbuf */ | ||
343 | } | ||
344 | |||
345 | int | ||
346 | evas_fb_outbuf_fb_get_width(Outbuf *buf) | ||
347 | { | ||
348 | return buf->w; | ||
349 | } | ||
350 | |||
351 | int | ||
352 | evas_fb_outbuf_fb_get_height(Outbuf *buf) | ||
353 | { | ||
354 | return buf->h; | ||
355 | } | ||
356 | |||
357 | Outbuf_Depth | ||
358 | evas_fb_outbuf_fb_get_depth(Outbuf *buf) | ||
359 | { | ||
360 | return buf->depth; | ||
361 | } | ||
362 | |||
363 | int | ||
364 | evas_fb_outbuf_fb_get_rot(Outbuf *buf) | ||
365 | { | ||
366 | return buf->rot; | ||
367 | } | ||
368 | |||
369 | int | ||
370 | evas_fb_outbuf_fb_get_have_backbuf(Outbuf *buf) | ||
371 | { | ||
372 | if (buf->priv.back_buf) return 1; | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | void | ||
377 | evas_fb_outbuf_fb_set_have_backbuf(Outbuf *buf, int have_backbuf) | ||
378 | { | ||
379 | if (buf->priv.back_buf) | ||
380 | { | ||
381 | if (have_backbuf) return; | ||
382 | evas_cache_image_drop(&buf->priv.back_buf->cache_entry); | ||
383 | buf->priv.back_buf = NULL; | ||
384 | } | ||
385 | else | ||
386 | { | ||
387 | if (!have_backbuf) return; | ||
388 | if (buf->priv.fb.fb) | ||
389 | { | ||
390 | if (buf->priv.fb.fb->fb_var.bits_per_pixel < 24) | ||
391 | { | ||
392 | buf->priv.back_buf = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); | ||
393 | buf->priv.back_buf = (RGBA_Image *) evas_cache_image_size_set(&buf->priv.back_buf->cache_entry, buf->w, buf->h); | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | } | ||