diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/modules/engines/gl_common/evas_gl_image.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to '')
-rw-r--r-- | libraries/evas/src/modules/engines/gl_common/evas_gl_image.c | 968 |
1 files changed, 968 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c b/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c new file mode 100644 index 0000000..1d4b1f8 --- /dev/null +++ b/libraries/evas/src/modules/engines/gl_common/evas_gl_image.c | |||
@@ -0,0 +1,968 @@ | |||
1 | #include "evas_gl_private.h" | ||
2 | |||
3 | void | ||
4 | evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc) | ||
5 | { | ||
6 | Eina_List *l; | ||
7 | Evas_GL_Image *im; | ||
8 | |||
9 | EINA_LIST_FOREACH(gc->shared->images, l, im) | ||
10 | { | ||
11 | if (im->im) evas_cache_image_unload_data(&im->im->cache_entry); | ||
12 | if (im->tex) | ||
13 | { | ||
14 | if (!im->tex->pt->dyn.img) | ||
15 | { | ||
16 | evas_gl_common_texture_free(im->tex); | ||
17 | im->tex = NULL; | ||
18 | } | ||
19 | } | ||
20 | } | ||
21 | } | ||
22 | |||
23 | static void | ||
24 | _evas_gl_image_cache_trim(Evas_Engine_GL_Context *gc) | ||
25 | { | ||
26 | int size = evas_common_image_get_cache(); | ||
27 | |||
28 | while (gc->shared->images_size > size) | ||
29 | { | ||
30 | Evas_GL_Image *im2; | ||
31 | Eina_List *l = NULL; | ||
32 | |||
33 | EINA_LIST_REVERSE_FOREACH(gc->shared->images, l, im2) | ||
34 | { | ||
35 | if (im2->references == 0) | ||
36 | { | ||
37 | im2->cached = 0; | ||
38 | im2->gc->shared->images = | ||
39 | eina_list_remove_list(im2->gc->shared->images, l); | ||
40 | im2->gc->shared->images_size -= (im2->csize); | ||
41 | evas_gl_common_image_free(im2); | ||
42 | l = NULL; | ||
43 | break; | ||
44 | } | ||
45 | } | ||
46 | if ((gc->shared->images_size > size) && (l)) | ||
47 | { | ||
48 | // printf("EEK %i > %i, no 0 ref imgs\n", | ||
49 | // gc->shared->images_size, size); | ||
50 | break; | ||
51 | } | ||
52 | if (!gc->shared->images) | ||
53 | { | ||
54 | // printf("EEK %i > %i, no imgs\n", | ||
55 | // gc->shared->images_size, size); | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static Eina_Bool | ||
62 | _evas_gl_image_cache_add(Evas_GL_Image *im) | ||
63 | { | ||
64 | if (im->references == 0) | ||
65 | { | ||
66 | im->csize = im->w * im->h * 4; | ||
67 | im->gc->shared->images_size += im->csize; | ||
68 | _evas_gl_image_cache_trim(im->gc); | ||
69 | return EINA_TRUE; | ||
70 | } | ||
71 | else | ||
72 | { | ||
73 | im->gc->shared->images = eina_list_remove(im->gc->shared->images, im); | ||
74 | im->cached = 0; | ||
75 | } | ||
76 | return EINA_FALSE; | ||
77 | } | ||
78 | |||
79 | void | ||
80 | evas_gl_common_image_ref(Evas_GL_Image *im) | ||
81 | { | ||
82 | if (im->references == 0) | ||
83 | { | ||
84 | im->gc->shared->images_size -= (im->csize); | ||
85 | } | ||
86 | im->references++; | ||
87 | } | ||
88 | |||
89 | void | ||
90 | evas_gl_common_image_unref(Evas_GL_Image *im) | ||
91 | { | ||
92 | im->references--; | ||
93 | if (im->references == 0) | ||
94 | { | ||
95 | _evas_gl_image_cache_add(im); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | Evas_GL_Image * | ||
100 | evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error) | ||
101 | { | ||
102 | Evas_GL_Image *im; | ||
103 | RGBA_Image *im_im; | ||
104 | Eina_List *l; | ||
105 | |||
106 | im_im = evas_common_load_image_from_file(file, key, lo, error); | ||
107 | if (!im_im) return NULL; | ||
108 | |||
109 | /* i'd LOVe to do this, but we can't because we load to load header | ||
110 | * to get image size to know if its too big or not! so this disallows | ||
111 | * us to know that - photocam thus suffers | ||
112 | if (((int)im_im->cache_entry.w > gc->shared->info.max_texture_size) || | ||
113 | ((int)im_im->cache_entry.h > gc->shared->info.max_texture_size)) | ||
114 | { | ||
115 | evas_cache_image_drop(&(im_im->cache_entry)); | ||
116 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | ||
117 | return NULL; | ||
118 | } | ||
119 | */ | ||
120 | |||
121 | // FIXME: keep unreffed shared images around | ||
122 | EINA_LIST_FOREACH(gc->shared->images, l, im) | ||
123 | { | ||
124 | if (im->im == im_im) | ||
125 | { | ||
126 | // why did i put this here? i think to free the rgba pixel data once a texture | ||
127 | // exists. | ||
128 | // evas_cache_image_drop(&(im_im->cache_entry)); | ||
129 | gc->shared->images = eina_list_remove_list(gc->shared->images, l); | ||
130 | gc->shared->images = eina_list_prepend(gc->shared->images, im); | ||
131 | evas_gl_common_image_ref(im); | ||
132 | *error = EVAS_LOAD_ERROR_NONE; | ||
133 | return im; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | im = calloc(1, sizeof(Evas_GL_Image)); | ||
138 | if (!im) | ||
139 | { | ||
140 | evas_cache_image_drop(&(im_im->cache_entry)); | ||
141 | *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; | ||
142 | return NULL; | ||
143 | } | ||
144 | im->references = 1; | ||
145 | im->im = im_im; | ||
146 | im->gc = gc; | ||
147 | im->cached = 1; | ||
148 | im->cs.space = EVAS_COLORSPACE_ARGB8888; | ||
149 | im->alpha = im->im->cache_entry.flags.alpha; | ||
150 | im->w = im->im->cache_entry.w; | ||
151 | im->h = im->im->cache_entry.h; | ||
152 | if (lo) im->load_opts = *lo; | ||
153 | gc->shared->images = eina_list_prepend(gc->shared->images, im); | ||
154 | return im; | ||
155 | } | ||
156 | |||
157 | Evas_GL_Image * | ||
158 | evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace) | ||
159 | { | ||
160 | Evas_GL_Image *im; | ||
161 | Eina_List *l; | ||
162 | |||
163 | if (((int)w > gc->shared->info.max_texture_size) || | ||
164 | ((int)h > gc->shared->info.max_texture_size)) | ||
165 | return NULL; | ||
166 | |||
167 | if (data) | ||
168 | { | ||
169 | EINA_LIST_FOREACH(gc->shared->images, l, im) | ||
170 | { | ||
171 | if (((void *)(im->im->image.data) == (void *)data) && | ||
172 | (im->im->cache_entry.w == w) && | ||
173 | (im->im->cache_entry.h == h)) | ||
174 | { | ||
175 | gc->shared->images = eina_list_remove_list(gc->shared->images, l); | ||
176 | gc->shared->images = eina_list_prepend(gc->shared->images, im); | ||
177 | evas_gl_common_image_ref(im); | ||
178 | return im; | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | im = calloc(1, sizeof(Evas_GL_Image)); | ||
183 | if (!im) return NULL; | ||
184 | im->references = 1; | ||
185 | im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(), | ||
186 | w, h, data, alpha, cspace); | ||
187 | if (!im->im) | ||
188 | { | ||
189 | free(im); | ||
190 | return NULL; | ||
191 | } | ||
192 | im->gc = gc; | ||
193 | im->cs.space = cspace; | ||
194 | im->alpha = im->im->cache_entry.flags.alpha; | ||
195 | im->w = im->im->cache_entry.w; | ||
196 | im->h = im->im->cache_entry.h; | ||
197 | switch (cspace) | ||
198 | { | ||
199 | case EVAS_COLORSPACE_ARGB8888: | ||
200 | break; | ||
201 | case EVAS_COLORSPACE_YCBCR422P601_PL: | ||
202 | case EVAS_COLORSPACE_YCBCR422P709_PL: | ||
203 | if (im->tex) evas_gl_common_texture_free(im->tex); | ||
204 | im->tex = NULL; | ||
205 | im->cs.data = data; | ||
206 | im->cs.no_free = 1; | ||
207 | break; | ||
208 | default: | ||
209 | abort(); | ||
210 | break; | ||
211 | } | ||
212 | return im; | ||
213 | } | ||
214 | |||
215 | Evas_GL_Image * | ||
216 | evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace) | ||
217 | { | ||
218 | Evas_GL_Image *im; | ||
219 | |||
220 | if (((int)w > gc->shared->info.max_texture_size) || | ||
221 | ((int)h > gc->shared->info.max_texture_size)) | ||
222 | return NULL; | ||
223 | |||
224 | im = calloc(1, sizeof(Evas_GL_Image)); | ||
225 | if (!im) return NULL; | ||
226 | im->references = 1; | ||
227 | im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(), | ||
228 | w, h, data, alpha, cspace); | ||
229 | if (!im->im) | ||
230 | { | ||
231 | free(im); | ||
232 | return NULL; | ||
233 | } | ||
234 | im->gc = gc; | ||
235 | im->cs.space = cspace; | ||
236 | im->alpha = im->im->cache_entry.flags.alpha; | ||
237 | im->w = im->im->cache_entry.w; | ||
238 | im->h = im->im->cache_entry.h; | ||
239 | switch (cspace) | ||
240 | { | ||
241 | case EVAS_COLORSPACE_ARGB8888: | ||
242 | break; | ||
243 | case EVAS_COLORSPACE_YCBCR422P601_PL: | ||
244 | case EVAS_COLORSPACE_YCBCR422P709_PL: | ||
245 | if (im->tex) evas_gl_common_texture_free(im->tex); | ||
246 | im->tex = NULL; | ||
247 | im->cs.no_free = 0; | ||
248 | if (im->im->cache_entry.h > 0) | ||
249 | im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2); | ||
250 | if ((data) && (im->cs.data)) | ||
251 | memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2); | ||
252 | break; | ||
253 | default: | ||
254 | abort(); | ||
255 | break; | ||
256 | } | ||
257 | return im; | ||
258 | } | ||
259 | |||
260 | Evas_GL_Image * | ||
261 | evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace) | ||
262 | { | ||
263 | Evas_GL_Image *im; | ||
264 | |||
265 | if (((int)w > gc->shared->info.max_texture_size) || | ||
266 | ((int)h > gc->shared->info.max_texture_size)) | ||
267 | return NULL; | ||
268 | |||
269 | im = calloc(1, sizeof(Evas_GL_Image)); | ||
270 | if (!im) return NULL; | ||
271 | im->references = 1; | ||
272 | im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); | ||
273 | if (!im->im) | ||
274 | { | ||
275 | free(im); | ||
276 | return NULL; | ||
277 | } | ||
278 | im->gc = gc; | ||
279 | im->im->cache_entry.flags.alpha = alpha ? 1 : 0; | ||
280 | im->cs.space = cspace; | ||
281 | im->alpha = im->im->cache_entry.flags.alpha; | ||
282 | im->im->cache_entry.w = w; | ||
283 | im->im->cache_entry.h = h; | ||
284 | im->w = im->im->cache_entry.w; | ||
285 | im->h = im->im->cache_entry.h; | ||
286 | evas_cache_image_colorspace(&im->im->cache_entry, cspace); | ||
287 | im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, w, h); | ||
288 | switch (cspace) | ||
289 | { | ||
290 | case EVAS_COLORSPACE_ARGB8888: | ||
291 | break; | ||
292 | case EVAS_COLORSPACE_YCBCR422P601_PL: | ||
293 | case EVAS_COLORSPACE_YCBCR422P709_PL: | ||
294 | case EVAS_COLORSPACE_YCBCR422601_PL: | ||
295 | case EVAS_COLORSPACE_YCBCR420NV12601_PL: | ||
296 | case EVAS_COLORSPACE_YCBCR420TM12601_PL: | ||
297 | // if (im->tex) evas_gl_common_texture_free(im->tex); | ||
298 | im->tex = NULL; | ||
299 | im->cs.no_free = 0; | ||
300 | if (im->im->cache_entry.h > 0) | ||
301 | im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2); | ||
302 | break; | ||
303 | default: | ||
304 | abort(); | ||
305 | break; | ||
306 | } | ||
307 | return im; | ||
308 | } | ||
309 | |||
310 | Evas_GL_Image * | ||
311 | evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha) | ||
312 | { | ||
313 | if (!im) return NULL; | ||
314 | if (im->alpha == alpha) return im; | ||
315 | im->alpha = alpha; | ||
316 | if (!im->im) return im; | ||
317 | im->im->cache_entry.flags.alpha = alpha ? 1 : 0; | ||
318 | if (im->tex) | ||
319 | { | ||
320 | evas_gl_common_texture_free(im->tex); | ||
321 | im->tex = NULL; | ||
322 | } | ||
323 | if (!im->tex) | ||
324 | im->tex = evas_gl_common_texture_new(im->gc, im->im); | ||
325 | return im; | ||
326 | } | ||
327 | |||
328 | void | ||
329 | evas_gl_common_image_native_enable(Evas_GL_Image *im) | ||
330 | { | ||
331 | if (im->cs.data) | ||
332 | { | ||
333 | if (!im->cs.no_free) free(im->cs.data); | ||
334 | im->cs.data = NULL; | ||
335 | } | ||
336 | im->cs.no_free = 0; | ||
337 | if (im->cached) | ||
338 | { | ||
339 | if (im->references == 0) | ||
340 | im->gc->shared->images_size -= (im->csize); | ||
341 | im->gc->shared->images = eina_list_remove(im->gc->shared->images, im); | ||
342 | im->cached = 0; | ||
343 | } | ||
344 | if (im->im) | ||
345 | { | ||
346 | evas_cache_image_drop(&im->im->cache_entry); | ||
347 | im->im = NULL; | ||
348 | } | ||
349 | if (im->tex) | ||
350 | { | ||
351 | evas_gl_common_texture_free(im->tex); | ||
352 | im->tex = NULL; | ||
353 | } | ||
354 | |||
355 | im->cs.space = EVAS_COLORSPACE_ARGB8888; | ||
356 | im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h, im->alpha, im); | ||
357 | im->tex_only = 1; | ||
358 | } | ||
359 | |||
360 | void | ||
361 | evas_gl_common_image_native_disable(Evas_GL_Image *im) | ||
362 | { | ||
363 | if (im->im) | ||
364 | { | ||
365 | evas_cache_image_drop(&im->im->cache_entry); | ||
366 | im->im = NULL; | ||
367 | } | ||
368 | if (im->tex) | ||
369 | { | ||
370 | evas_gl_common_texture_free(im->tex); | ||
371 | im->tex = NULL; | ||
372 | } | ||
373 | im->tex_only = 0; | ||
374 | |||
375 | im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); | ||
376 | im->im->cache_entry.flags.alpha = im->alpha; | ||
377 | im->cs.space = EVAS_COLORSPACE_ARGB8888; | ||
378 | evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space); | ||
379 | im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h); | ||
380 | if (!im->tex) | ||
381 | im->tex = evas_gl_common_texture_new(im->gc, im->im); | ||
382 | } | ||
383 | |||
384 | void | ||
385 | evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint) | ||
386 | { | ||
387 | im->scale_hint = hint; | ||
388 | // FIXME: take advantage of this even in gl (eg if image is | ||
389 | // 1600x1200 but we always use it at 800x600 or even less - drop | ||
390 | // the texture res down for "non dynamic" stuff to save memory) | ||
391 | } | ||
392 | |||
393 | void | ||
394 | evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint) | ||
395 | { | ||
396 | if (im->content_hint == hint) return; | ||
397 | im->content_hint = hint; | ||
398 | if (!im->gc) return; | ||
399 | if (!im->gc->shared->info.sec_image_map) return; | ||
400 | if (!im->gc->shared->info.bgra) return; | ||
401 | // does not handle yuv yet. | ||
402 | if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return; | ||
403 | if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC) | ||
404 | { | ||
405 | if (im->cs.data) | ||
406 | { | ||
407 | if (!im->cs.no_free) free(im->cs.data); | ||
408 | im->cs.data = NULL; | ||
409 | } | ||
410 | im->cs.no_free = 0; | ||
411 | if (im->cached) | ||
412 | { | ||
413 | if (im->references == 0) | ||
414 | im->gc->shared->images_size -= im->csize; | ||
415 | im->gc->shared->images = eina_list_remove(im->gc->shared->images, im); | ||
416 | im->cached = 0; | ||
417 | } | ||
418 | if (im->im) | ||
419 | { | ||
420 | evas_cache_image_drop(&im->im->cache_entry); | ||
421 | im->im = NULL; | ||
422 | } | ||
423 | if (im->tex) | ||
424 | { | ||
425 | evas_gl_common_texture_free(im->tex); | ||
426 | im->tex = NULL; | ||
427 | } | ||
428 | im->tex = evas_gl_common_texture_dynamic_new(im->gc, im); | ||
429 | im->tex_only = 1; | ||
430 | } | ||
431 | else | ||
432 | { | ||
433 | if (im->im) | ||
434 | { | ||
435 | evas_cache_image_drop(&im->im->cache_entry); | ||
436 | im->im = NULL; | ||
437 | } | ||
438 | if (im->tex) | ||
439 | { | ||
440 | evas_gl_common_texture_free(im->tex); | ||
441 | im->tex = NULL; | ||
442 | } | ||
443 | im->tex_only = 0; | ||
444 | |||
445 | im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); | ||
446 | im->im->cache_entry.flags.alpha = im->alpha; | ||
447 | im->cs.space = EVAS_COLORSPACE_ARGB8888; | ||
448 | evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space); | ||
449 | im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h); | ||
450 | if (!im->tex) | ||
451 | im->tex = evas_gl_common_texture_new(im->gc, im->im); | ||
452 | } | ||
453 | } | ||
454 | |||
455 | void | ||
456 | evas_gl_common_image_cache_flush(Evas_Engine_GL_Context *gc) | ||
457 | { | ||
458 | _evas_gl_image_cache_trim(gc); | ||
459 | } | ||
460 | |||
461 | void | ||
462 | evas_gl_common_image_free(Evas_GL_Image *im) | ||
463 | { | ||
464 | #if 0 // filtering disabled | ||
465 | Filtered_Image *fi; | ||
466 | #endif | ||
467 | |||
468 | evas_gl_common_context_flush(im->gc); | ||
469 | im->references--; | ||
470 | if (im->references > 0) return; | ||
471 | |||
472 | if (im->native.func.free) | ||
473 | im->native.func.free(im->native.func.data, im); | ||
474 | |||
475 | if (im->cs.data) | ||
476 | { | ||
477 | if (!im->cs.no_free) free(im->cs.data); | ||
478 | } | ||
479 | if (im->cached) | ||
480 | { | ||
481 | if (_evas_gl_image_cache_add(im)) return; | ||
482 | } | ||
483 | if (im->im) evas_cache_image_drop(&im->im->cache_entry); | ||
484 | if (im->tex) evas_gl_common_texture_free(im->tex); | ||
485 | |||
486 | #if 0 // filtering disabled | ||
487 | EINA_LIST_FREE(im->filtered, fi) | ||
488 | { | ||
489 | free(fi->key); | ||
490 | evas_gl_common_image_free((Evas_GL_Image *)fi->image); | ||
491 | free(fi); | ||
492 | } | ||
493 | #endif | ||
494 | |||
495 | free(im); | ||
496 | } | ||
497 | |||
498 | Evas_GL_Image * | ||
499 | evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha) | ||
500 | { | ||
501 | Evas_GL_Image *im; | ||
502 | |||
503 | if (((int)w > gc->shared->info.max_texture_size) || | ||
504 | ((int)h > gc->shared->info.max_texture_size)) | ||
505 | return NULL; | ||
506 | |||
507 | im = calloc(1, sizeof(Evas_GL_Image)); | ||
508 | if (!im) return NULL; | ||
509 | im->references = 1; | ||
510 | im->gc = gc; | ||
511 | im->cs.space = EVAS_COLORSPACE_ARGB8888; | ||
512 | im->alpha = alpha; | ||
513 | im->w = w; | ||
514 | im->h = h; | ||
515 | im->tex = evas_gl_common_texture_render_new(gc, w, h, alpha); | ||
516 | im->tex_only = 1; | ||
517 | return im; | ||
518 | } | ||
519 | |||
520 | void | ||
521 | evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h) | ||
522 | { | ||
523 | if ((w == 0) && (h == 0) && (x == 0) && (y == 0)) | ||
524 | { | ||
525 | w = im->w; | ||
526 | h = im->h; | ||
527 | } | ||
528 | if (im->im) | ||
529 | { | ||
530 | im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h); | ||
531 | } | ||
532 | im->dirty = 1; | ||
533 | } | ||
534 | |||
535 | void | ||
536 | evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) | ||
537 | { | ||
538 | Image_Entry *ie; | ||
539 | if (!im->im) return; | ||
540 | ie = (Image_Entry *)(im->im); | ||
541 | /* | ||
542 | if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || | ||
543 | (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) | ||
544 | { | ||
545 | // SOFTWARE convert. do multi texture later | ||
546 | if ((im->cs.data) && (*((unsigned char **)im->cs.data))) | ||
547 | { | ||
548 | if (im->dirty || !im->im->image.data) | ||
549 | { | ||
550 | free(im->im->image.data); | ||
551 | im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32)); | ||
552 | if (im->im->image.data) | ||
553 | evas_common_convert_yuv_420p_601_rgba(im->cs.data, | ||
554 | (void *)im->im->image.data, | ||
555 | im->im->cache_entry.w, im->im->cache_entry.h); | ||
556 | } | ||
557 | } | ||
558 | space = EVAS_COLORSPACE_ARGB8888; | ||
559 | } | ||
560 | else | ||
561 | */ | ||
562 | switch (im->cs.space) | ||
563 | { | ||
564 | case EVAS_COLORSPACE_ARGB8888: | ||
565 | if ((im->tex) && | ||
566 | ((im->dirty) || (ie->flags.animated))) | ||
567 | { | ||
568 | evas_cache_image_load_data(&im->im->cache_entry); | ||
569 | evas_gl_common_texture_update(im->tex, im->im); | ||
570 | evas_cache_image_unload_data(&im->im->cache_entry); | ||
571 | } | ||
572 | if (!im->tex) | ||
573 | { | ||
574 | evas_cache_image_load_data(&im->im->cache_entry); | ||
575 | im->tex = evas_gl_common_texture_new(gc, im->im); | ||
576 | evas_cache_image_unload_data(&im->im->cache_entry); | ||
577 | } | ||
578 | im->dirty = 0; | ||
579 | if (!im->tex) return; | ||
580 | break; | ||
581 | case EVAS_COLORSPACE_YCBCR422P601_PL: | ||
582 | case EVAS_COLORSPACE_YCBCR422P709_PL: | ||
583 | if ((im->tex) && (im->dirty)) | ||
584 | { | ||
585 | evas_gl_common_texture_yuv_update(im->tex, im->cs.data, | ||
586 | im->im->cache_entry.w, | ||
587 | im->im->cache_entry.h); | ||
588 | im->dirty = 0; | ||
589 | } | ||
590 | if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data))) | ||
591 | { | ||
592 | im->tex = evas_gl_common_texture_yuv_new(gc, im->cs.data, | ||
593 | im->im->cache_entry.w, | ||
594 | im->im->cache_entry.h); | ||
595 | im->dirty = 0; | ||
596 | } | ||
597 | if (!im->tex) return; | ||
598 | break; | ||
599 | case EVAS_COLORSPACE_YCBCR422601_PL: | ||
600 | if ((im->tex) && (im->dirty)) | ||
601 | { | ||
602 | evas_gl_common_texture_yuy2_update(im->tex, im->cs.data, | ||
603 | im->im->cache_entry.w, | ||
604 | im->im->cache_entry.h); | ||
605 | im->dirty = 0; | ||
606 | } | ||
607 | if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data))) | ||
608 | { | ||
609 | im->tex = evas_gl_common_texture_yuy2_new(gc, im->cs.data, | ||
610 | im->im->cache_entry.w, | ||
611 | im->im->cache_entry.h); | ||
612 | im->dirty = 0; | ||
613 | } | ||
614 | if (!im->tex) return; | ||
615 | break; | ||
616 | case EVAS_COLORSPACE_YCBCR420NV12601_PL: | ||
617 | if ((im->tex) && (im->dirty)) | ||
618 | { | ||
619 | evas_gl_common_texture_nv12_update(im->tex, im->cs.data, | ||
620 | im->im->cache_entry.w, | ||
621 | im->im->cache_entry.h); | ||
622 | im->dirty = 0; | ||
623 | } | ||
624 | if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data))) | ||
625 | { | ||
626 | im->tex = evas_gl_common_texture_nv12_new(gc, im->cs.data, | ||
627 | im->im->cache_entry.w, | ||
628 | im->im->cache_entry.h); | ||
629 | im->dirty = 0; | ||
630 | } | ||
631 | if (!im->tex) return; | ||
632 | break; | ||
633 | case EVAS_COLORSPACE_YCBCR420TM12601_PL: | ||
634 | if ((im->tex) && (im->dirty)) | ||
635 | { | ||
636 | evas_gl_common_texture_nv12tiled_update(im->tex, im->cs.data, | ||
637 | im->im->cache_entry.w, | ||
638 | im->im->cache_entry.h); | ||
639 | im->dirty = 0; | ||
640 | } | ||
641 | if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data))) | ||
642 | { | ||
643 | im->tex = evas_gl_common_texture_nv12tiled_new(gc, im->cs.data, | ||
644 | im->im->cache_entry.w, | ||
645 | im->im->cache_entry.h); | ||
646 | im->dirty = 0; | ||
647 | } | ||
648 | if (!im->tex) return; | ||
649 | break; | ||
650 | default: | ||
651 | ERR("unhandled img format colorspace=%d", im->cs.space); | ||
652 | break; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | void | ||
657 | evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, | ||
658 | int npoints, RGBA_Map_Point *p, int smooth, int level __UNUSED__) | ||
659 | { | ||
660 | RGBA_Draw_Context *dc; | ||
661 | int r, g, b, a; | ||
662 | int c, cx, cy, cw, ch; | ||
663 | |||
664 | dc = gc->dc; | ||
665 | if (dc->mul.use) | ||
666 | { | ||
667 | a = (dc->mul.col >> 24) & 0xff; | ||
668 | r = (dc->mul.col >> 16) & 0xff; | ||
669 | g = (dc->mul.col >> 8 ) & 0xff; | ||
670 | b = (dc->mul.col ) & 0xff; | ||
671 | } | ||
672 | else | ||
673 | { | ||
674 | r = g = b = a = 255; | ||
675 | } | ||
676 | |||
677 | evas_gl_common_image_update(gc, im); | ||
678 | |||
679 | c = gc->dc->clip.use; | ||
680 | cx = gc->dc->clip.x; cy = gc->dc->clip.y; | ||
681 | cw = gc->dc->clip.w; ch = gc->dc->clip.h; | ||
682 | im->tex->im = im; | ||
683 | |||
684 | evas_gl_common_context_image_map_push(gc, im->tex, npoints, p, | ||
685 | c, cx, cy, cw, ch, | ||
686 | r, g, b, a, smooth, im->tex_only, | ||
687 | im->cs.space); | ||
688 | } | ||
689 | |||
690 | void | ||
691 | evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth) | ||
692 | { | ||
693 | RGBA_Draw_Context *dc; | ||
694 | Evas_GL_Image *imm; | ||
695 | int r, g, b, a; | ||
696 | double ssx, ssy, ssw, ssh; | ||
697 | double mssx, mssy, mssw, mssh; | ||
698 | Cutout_Rects *rects; | ||
699 | Cutout_Rect *rct; | ||
700 | int c, cx, cy, cw, ch; | ||
701 | int i; | ||
702 | int yuv = 0; | ||
703 | int yuy2 = 0; | ||
704 | int nv12 = 0; | ||
705 | |||
706 | if (sw < 1) sw = 1; | ||
707 | if (sh < 1) sh = 1; | ||
708 | dc = gc->dc; | ||
709 | imm = (Evas_GL_Image *)dc->mask.mask; | ||
710 | if (dc->mul.use) | ||
711 | { | ||
712 | a = (dc->mul.col >> 24) & 0xff; | ||
713 | r = (dc->mul.col >> 16) & 0xff; | ||
714 | g = (dc->mul.col >> 8 ) & 0xff; | ||
715 | b = (dc->mul.col ) & 0xff; | ||
716 | } | ||
717 | else | ||
718 | { | ||
719 | r = g = b = a = 255; | ||
720 | } | ||
721 | |||
722 | evas_gl_common_image_update(gc, im); | ||
723 | if (!im->tex) | ||
724 | { | ||
725 | evas_gl_common_rect_draw(gc, dx, dy, dw, dh); | ||
726 | return; | ||
727 | } | ||
728 | if (imm) | ||
729 | { | ||
730 | evas_gl_common_image_update(gc, imm); | ||
731 | if (!imm->tex) imm = NULL; /* Turn of mask on error */ | ||
732 | } | ||
733 | |||
734 | if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) || | ||
735 | (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL)) | ||
736 | yuv = 1; | ||
737 | if (im->cs.space == EVAS_COLORSPACE_YCBCR422601_PL) | ||
738 | yuy2 = 1; | ||
739 | if ((im->cs.space == EVAS_COLORSPACE_YCBCR420NV12601_PL) || | ||
740 | (im->cs.space == EVAS_COLORSPACE_YCBCR420TM12601_PL)) | ||
741 | nv12 = 1; | ||
742 | |||
743 | im->tex->im = im; | ||
744 | if (imm) imm->tex->im = imm; | ||
745 | if ((!gc->dc->cutout.rects) || | ||
746 | ((gc->shared->info.tune.cutout.max > 0) && | ||
747 | (gc->dc->cutout.active > gc->shared->info.tune.cutout.max))) | ||
748 | { | ||
749 | if (gc->dc->clip.use) | ||
750 | { | ||
751 | int nx, ny, nw, nh; | ||
752 | double scalex,scaley; | ||
753 | |||
754 | nx = dx; ny = dy; nw = dw; nh = dh; | ||
755 | RECTS_CLIP_TO_RECT(nx, ny, nw, nh, | ||
756 | gc->dc->clip.x, gc->dc->clip.y, | ||
757 | gc->dc->clip.w, gc->dc->clip.h); | ||
758 | if ((nw < 1) || (nh < 1)) return; | ||
759 | if ((!imm) && (nx == dx) && (ny == dy) && (nw == dw) && (nh == dh)) | ||
760 | { | ||
761 | if (yuv) | ||
762 | evas_gl_common_context_yuv_push(gc, | ||
763 | im->tex, | ||
764 | sx, sy, sw, sh, | ||
765 | dx, dy, dw, dh, | ||
766 | r, g, b, a, | ||
767 | smooth); | ||
768 | else if (yuy2) | ||
769 | evas_gl_common_context_yuy2_push(gc, | ||
770 | im->tex, | ||
771 | sx, sy, sw, sh, | ||
772 | dx, dy, dw, dh, | ||
773 | r, g, b, a, | ||
774 | smooth); | ||
775 | else if (nv12) | ||
776 | evas_gl_common_context_nv12_push(gc, | ||
777 | im->tex, | ||
778 | sx, sy, sw, sh, | ||
779 | dx, dy, dw, dh, | ||
780 | r, g, b, a, | ||
781 | smooth); | ||
782 | else | ||
783 | |||
784 | evas_gl_common_context_image_push(gc, | ||
785 | im->tex, | ||
786 | sx, sy, sw, sh, | ||
787 | dx, dy, dw, dh, | ||
788 | r, g, b, a, | ||
789 | smooth, im->tex_only); | ||
790 | return; | ||
791 | } | ||
792 | |||
793 | ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw)); | ||
794 | ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh)); | ||
795 | ssw = ((double)sw * (double)(nw)) / (double)(dw); | ||
796 | ssh = ((double)sh * (double)(nh)) / (double)(dh); | ||
797 | if (imm) | ||
798 | { | ||
799 | /* Correct ones here */ | ||
800 | scalex = imm->w / (double)dc->mask.w; | ||
801 | scaley = imm->h / (double)dc->mask.h; | ||
802 | mssx = scalex * (nx - dc->mask.x); | ||
803 | mssy = scaley * (ny - dc->mask.y); | ||
804 | mssw = scalex * nw; | ||
805 | mssh = scaley * nh; | ||
806 | |||
807 | /* No yuv + imm I'm afraid */ | ||
808 | evas_gl_common_context_image_mask_push(gc, | ||
809 | im->tex, | ||
810 | imm->tex, | ||
811 | ssx, ssy, ssw, ssh, | ||
812 | mssx, mssy, mssw, mssh, | ||
813 | //dc->mask.x, dc->mask.y, dc->mask.w, dc->mask.h, | ||
814 | nx, ny, nw, nh, | ||
815 | r, g, b, a, | ||
816 | smooth); | ||
817 | } | ||
818 | else if (yuv) | ||
819 | evas_gl_common_context_yuv_push(gc, | ||
820 | im->tex, | ||
821 | ssx, ssy, ssw, ssh, | ||
822 | nx, ny, nw, nh, | ||
823 | r, g, b, a, | ||
824 | smooth); | ||
825 | else if (yuy2) | ||
826 | evas_gl_common_context_yuy2_push(gc, | ||
827 | im->tex, | ||
828 | ssx, ssy, ssw, ssh, | ||
829 | nx, ny, nw, nh, | ||
830 | r, g, b, a, | ||
831 | smooth); | ||
832 | else if (nv12) | ||
833 | evas_gl_common_context_nv12_push(gc, | ||
834 | im->tex, | ||
835 | ssx, ssy, ssw, ssh, | ||
836 | nx, ny, nw, nh, | ||
837 | r, g, b, a, | ||
838 | smooth); | ||
839 | else | ||
840 | evas_gl_common_context_image_push(gc, | ||
841 | im->tex, | ||
842 | ssx, ssy, ssw, ssh, | ||
843 | nx, ny, nw, nh, | ||
844 | r, g, b, a, | ||
845 | smooth, im->tex_only); | ||
846 | } | ||
847 | else | ||
848 | { | ||
849 | if (yuv) | ||
850 | evas_gl_common_context_yuv_push(gc, | ||
851 | im->tex, | ||
852 | sx, sy, sw, sh, | ||
853 | dx, dy, dw, dh, | ||
854 | r, g, b, a, | ||
855 | smooth); | ||
856 | else if (yuy2) | ||
857 | evas_gl_common_context_yuy2_push(gc, | ||
858 | im->tex, | ||
859 | sx, sy, sw, sh, | ||
860 | dx, dy, dw, dh, | ||
861 | r, g, b, a, | ||
862 | smooth); | ||
863 | else if (nv12) | ||
864 | evas_gl_common_context_nv12_push(gc, | ||
865 | im->tex, | ||
866 | sx, sy, sw, sh, | ||
867 | dx, dy, dw, dh, | ||
868 | r, g, b, a, | ||
869 | smooth); | ||
870 | else | ||
871 | evas_gl_common_context_image_push(gc, | ||
872 | im->tex, | ||
873 | sx, sy, sw, sh, | ||
874 | dx, dy, dw, dh, | ||
875 | r, g, b, a, | ||
876 | smooth, im->tex_only); | ||
877 | } | ||
878 | return; | ||
879 | } | ||
880 | |||
881 | /* save out clip info */ | ||
882 | c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h; | ||
883 | evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h); | ||
884 | evas_common_draw_context_clip_clip(gc->dc, dx, dy, dw, dh); | ||
885 | /* our clip is 0 size.. abort */ | ||
886 | if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0)) | ||
887 | { | ||
888 | gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch; | ||
889 | return; | ||
890 | } | ||
891 | rects = evas_common_draw_context_apply_cutouts(dc); | ||
892 | for (i = 0; i < rects->active; ++i) | ||
893 | { | ||
894 | int nx, ny, nw, nh; | ||
895 | |||
896 | rct = rects->rects + i; | ||
897 | nx = dx; ny = dy; nw = dw; nh = dh; | ||
898 | RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h); | ||
899 | if ((nw < 1) || (nh < 1)) continue; | ||
900 | if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh)) | ||
901 | { | ||
902 | if (yuv) | ||
903 | evas_gl_common_context_yuv_push(gc, | ||
904 | im->tex, | ||
905 | sx, sy, sw, sh, | ||
906 | dx, dy, dw, dh, | ||
907 | r, g, b, a, | ||
908 | smooth); | ||
909 | else if (yuy2) | ||
910 | evas_gl_common_context_yuy2_push(gc, | ||
911 | im->tex, | ||
912 | sx, sy, sw, sh, | ||
913 | dx, dy, dw, dh, | ||
914 | r, g, b, a, | ||
915 | smooth); | ||
916 | else if (nv12) | ||
917 | evas_gl_common_context_nv12_push(gc, | ||
918 | im->tex, | ||
919 | sx, sy, sw, sh, | ||
920 | dx, dy, dw, dh, | ||
921 | r, g, b, a, | ||
922 | smooth); | ||
923 | else | ||
924 | evas_gl_common_context_image_push(gc, | ||
925 | im->tex, | ||
926 | sx, sy, sw, sh, | ||
927 | dx, dy, dw, dh, | ||
928 | r, g, b, a, | ||
929 | smooth, im->tex_only); | ||
930 | continue; | ||
931 | } | ||
932 | ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw)); | ||
933 | ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh)); | ||
934 | ssw = ((double)sw * (double)(nw)) / (double)(dw); | ||
935 | ssh = ((double)sh * (double)(nh)) / (double)(dh); | ||
936 | if (yuv) | ||
937 | evas_gl_common_context_yuv_push(gc, | ||
938 | im->tex, | ||
939 | ssx, ssy, ssw, ssh, | ||
940 | nx, ny, nw, nh, | ||
941 | r, g, b, a, | ||
942 | smooth); | ||
943 | else if (yuy2) | ||
944 | evas_gl_common_context_yuy2_push(gc, | ||
945 | im->tex, | ||
946 | ssx, ssy, ssw, ssh, | ||
947 | nx, ny, nw, nh, | ||
948 | r, g, b, a, | ||
949 | smooth); | ||
950 | else if (nv12) | ||
951 | evas_gl_common_context_nv12_push(gc, | ||
952 | im->tex, | ||
953 | ssx, ssy, ssw, ssh, | ||
954 | nx, ny, nw, nh, | ||
955 | r, g, b, a, | ||
956 | smooth); | ||
957 | else | ||
958 | evas_gl_common_context_image_push(gc, | ||
959 | im->tex, | ||
960 | ssx, ssy, ssw, ssh, | ||
961 | nx, ny, nw, nh, | ||
962 | r, g, b, a, | ||
963 | smooth, im->tex_only); | ||
964 | } | ||
965 | evas_common_draw_context_apply_clear_cutouts(rects); | ||
966 | /* restore clip info */ | ||
967 | gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch; | ||
968 | } | ||