1 #include "evas_gl_private.h"
4 evas_gl_common_image_all_unload(Evas_Engine_GL_Context *gc)
9 EINA_LIST_FOREACH(gc->shared->images, l, im)
11 if (im->im) evas_cache_image_unload_data(&im->im->cache_entry);
14 if (!im->tex->pt->dyn.img)
16 evas_gl_common_texture_free(im->tex);
24 _evas_gl_image_cache_trim(Evas_Engine_GL_Context *gc)
26 int size = evas_common_image_get_cache();
28 while (gc->shared->images_size > size)
33 EINA_LIST_REVERSE_FOREACH(gc->shared->images, l, im2)
35 if (im2->references == 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);
46 if ((gc->shared->images_size > size) && (l))
48 printf("EEK %i > %i, no 0 ref imgs\n",
49 gc->shared->images_size, size);
52 if (!gc->shared->images)
54 printf("EEK %i > %i, no imgs\n",
55 gc->shared->images_size, size);
62 _evas_gl_image_cache_add(Evas_GL_Image *im)
64 if (im->references == 0)
66 im->csize = im->w * im->h * 4;
67 im->gc->shared->images_size += im->csize;
68 _evas_gl_image_cache_trim(im->gc);
73 im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
80 evas_gl_common_image_ref(Evas_GL_Image *im)
82 if (im->references == 0)
84 im->gc->shared->images_size -= (im->csize);
90 evas_gl_common_image_unref(Evas_GL_Image *im)
93 if (im->references == 0)
95 _evas_gl_image_cache_add(im);
100 evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
106 im_im = evas_common_load_image_from_file(file, key, lo, error);
107 if (!im_im) return NULL;
109 // FIXME: keep unreffed shared images around
110 EINA_LIST_FOREACH(gc->shared->images, l, im)
114 // why did i put this here? i think to free the rgba pixel data once a texture
116 // evas_cache_image_drop(&im_im->cache_entry);
117 gc->shared->images = eina_list_remove_list(gc->shared->images, l);
118 gc->shared->images = eina_list_prepend(gc->shared->images, im);
119 evas_gl_common_image_ref(im);
120 *error = EVAS_LOAD_ERROR_NONE;
125 im = calloc(1, sizeof(Evas_GL_Image));
128 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
135 im->cs.space = EVAS_COLORSPACE_ARGB8888;
136 im->alpha = im->im->cache_entry.flags.alpha;
137 im->w = im->im->cache_entry.w;
138 im->h = im->im->cache_entry.h;
139 if (lo) im->load_opts = *lo;
140 gc->shared->images = eina_list_prepend(gc->shared->images, im);
145 evas_gl_common_image_new_from_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, int cspace)
152 EINA_LIST_FOREACH(gc->shared->images, l, im)
154 if (((void *)(im->im->image.data) == (void *)data) &&
155 (im->im->cache_entry.w == w) &&
156 (im->im->cache_entry.h == h))
158 gc->shared->images = eina_list_remove_list(gc->shared->images, l);
159 gc->shared->images = eina_list_prepend(gc->shared->images, im);
160 evas_gl_common_image_ref(im);
165 im = calloc(1, sizeof(Evas_GL_Image));
166 if (!im) return NULL;
168 im->im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
169 w, h, data, alpha, cspace);
176 im->cs.space = cspace;
177 im->alpha = im->im->cache_entry.flags.alpha;
178 im->w = im->im->cache_entry.w;
179 im->h = im->im->cache_entry.h;
182 case EVAS_COLORSPACE_ARGB8888:
184 case EVAS_COLORSPACE_YCBCR422P601_PL:
185 case EVAS_COLORSPACE_YCBCR422P709_PL:
186 if (im->tex) evas_gl_common_texture_free(im->tex);
199 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)
203 im = calloc(1, sizeof(Evas_GL_Image));
204 if (!im) return NULL;
206 im->im = (RGBA_Image *) evas_cache_image_copied_data(evas_common_image_cache_get(),
207 w, h, data, alpha, cspace);
214 im->cs.space = cspace;
215 im->alpha = im->im->cache_entry.flags.alpha;
216 im->w = im->im->cache_entry.w;
217 im->h = im->im->cache_entry.h;
220 case EVAS_COLORSPACE_ARGB8888:
222 case EVAS_COLORSPACE_YCBCR422P601_PL:
223 case EVAS_COLORSPACE_YCBCR422P709_PL:
224 if (im->tex) evas_gl_common_texture_free(im->tex);
227 if (im->im->cache_entry.h > 0)
228 im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
229 if ((data) && (im->cs.data))
230 memcpy(im->cs.data, data, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
240 evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, int cspace)
244 im = calloc(1, sizeof(Evas_GL_Image));
245 if (!im) return NULL;
247 im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
254 im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
255 im->cs.space = cspace;
256 im->alpha = im->im->cache_entry.flags.alpha;
257 im->im->cache_entry.w = w;
258 im->im->cache_entry.h = h;
259 im->w = im->im->cache_entry.w;
260 im->h = im->im->cache_entry.h;
261 evas_cache_image_colorspace(&im->im->cache_entry, cspace);
262 im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, w, h);
265 case EVAS_COLORSPACE_ARGB8888:
267 case EVAS_COLORSPACE_YCBCR422P601_PL:
268 case EVAS_COLORSPACE_YCBCR422P709_PL:
269 // if (im->tex) evas_gl_common_texture_free(im->tex);
272 if (im->im->cache_entry.h > 0)
273 im->cs.data = calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
283 evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha)
285 if (!im) return NULL;
286 if (im->alpha == alpha) return im;
288 if (!im->im) return im;
289 im->im->cache_entry.flags.alpha = alpha ? 1 : 0;
292 evas_gl_common_texture_free(im->tex);
296 im->tex = evas_gl_common_texture_new(im->gc, im->im);
301 evas_gl_common_image_native_enable(Evas_GL_Image *im)
305 if (!im->cs.no_free) free(im->cs.data);
311 if (im->references == 0)
312 im->gc->shared->images_size -= (im->csize);
313 im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
318 evas_cache_image_drop(&im->im->cache_entry);
323 evas_gl_common_texture_free(im->tex);
327 im->cs.space = EVAS_COLORSPACE_ARGB8888;
328 im->tex = evas_gl_common_texture_native_new(im->gc, im->w, im->h, im->alpha, im);
333 evas_gl_common_image_native_disable(Evas_GL_Image *im)
337 evas_cache_image_drop(&im->im->cache_entry);
342 evas_gl_common_texture_free(im->tex);
347 im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
348 im->im->cache_entry.flags.alpha = im->alpha;
349 im->cs.space = EVAS_COLORSPACE_ARGB8888;
350 evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
351 im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
353 im->tex = evas_gl_common_texture_new(im->gc, im->im);
357 evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint)
359 im->scale_hint = hint;
360 // FIXME: take advantage of this even in gl (eg if image is
361 // 1600x1200 but we always use it at 800x600 or even less - drop
362 // the texture res down for "non dynamic" stuff to save memory)
366 evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint)
368 if (im->content_hint == hint) return;
369 im->content_hint = hint;
371 if (!im->gc->shared->info.sec_image_map) return;
372 if (!im->gc->shared->info.bgra) return;
373 // does not handle yuv yet.
374 if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return;
375 if (im->content_hint == EVAS_IMAGE_CONTENT_HINT_DYNAMIC)
379 if (!im->cs.no_free) free(im->cs.data);
385 if (im->references == 0)
386 im->gc->shared->images_size -= im->csize;
387 im->gc->shared->images = eina_list_remove(im->gc->shared->images, im);
392 evas_cache_image_drop(&im->im->cache_entry);
397 evas_gl_common_texture_free(im->tex);
400 im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
407 evas_cache_image_drop(&im->im->cache_entry);
412 evas_gl_common_texture_free(im->tex);
417 im->im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
418 im->im->cache_entry.flags.alpha = im->alpha;
419 im->cs.space = EVAS_COLORSPACE_ARGB8888;
420 evas_cache_image_colorspace(&im->im->cache_entry, im->cs.space);
421 im->im = (RGBA_Image *)evas_cache_image_size_set(&im->im->cache_entry, im->w, im->h);
423 im->tex = evas_gl_common_texture_new(im->gc, im->im);
428 evas_gl_common_image_cache_flush(Evas_Engine_GL_Context *gc)
430 _evas_gl_image_cache_trim(gc);
434 evas_gl_common_image_free(Evas_GL_Image *im)
436 #if 0 // filtering disabled
440 evas_gl_common_context_flush(im->gc);
442 if (im->references > 0) return;
444 if (im->native.func.free)
445 im->native.func.free(im->native.func.data, im);
449 if (!im->cs.no_free) free(im->cs.data);
453 if (_evas_gl_image_cache_add(im)) return;
455 if (im->im) evas_cache_image_drop(&im->im->cache_entry);
456 if (im->tex) evas_gl_common_texture_free(im->tex);
458 #if 0 // filtering disabled
459 EINA_LIST_FREE(im->filtered, fi)
462 evas_gl_common_image_free((Evas_GL_Image *)fi->image);
471 evas_gl_common_image_surface_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha)
475 im = calloc(1, sizeof(Evas_GL_Image));
476 if (!im) return NULL;
479 im->cs.space = EVAS_COLORSPACE_ARGB8888;
483 im->tex = evas_gl_common_texture_render_new(gc, w, h, alpha);
489 evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
491 if ((w == 0) && (h == 0) && (x == 0) && (y == 0))
498 im->im = (RGBA_Image *)evas_cache_image_dirty(&im->im->cache_entry, x, y, w, h);
504 evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
508 if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
509 (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
511 // SOFTWARE convert. do multi texture later
512 if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
514 if (im->dirty || !im->im->image.data)
516 free(im->im->image.data);
517 im->im->image.data = malloc(im->im->cache_entry.w * im->im->cache_entry.h * sizeof(DATA32));
518 if (im->im->image.data)
519 evas_common_convert_yuv_420p_601_rgba(im->cs.data,
520 (void *)im->im->image.data,
521 im->im->cache_entry.w, im->im->cache_entry.h);
524 space = EVAS_COLORSPACE_ARGB8888;
528 switch (im->cs.space)
530 case EVAS_COLORSPACE_ARGB8888:
531 if ((im->tex) && (im->dirty))
533 evas_cache_image_load_data(&im->im->cache_entry);
534 evas_gl_common_texture_update(im->tex, im->im);
535 evas_cache_image_unload_data(&im->im->cache_entry);
539 evas_cache_image_load_data(&im->im->cache_entry);
540 im->tex = evas_gl_common_texture_new(gc, im->im);
541 evas_cache_image_unload_data(&im->im->cache_entry);
544 if (!im->tex) return;
546 case EVAS_COLORSPACE_YCBCR422P601_PL:
547 case EVAS_COLORSPACE_YCBCR422P709_PL:
548 if ((im->tex) && (im->dirty))
550 evas_gl_common_texture_yuv_update(im->tex, im->cs.data,
551 im->im->cache_entry.w,
552 im->im->cache_entry.h);
555 if ((!im->tex) && (im->cs.data) && (*((unsigned char **)im->cs.data)))
557 im->tex = evas_gl_common_texture_yuv_new(gc, im->cs.data,
558 im->im->cache_entry.w,
559 im->im->cache_entry.h);
562 if (!im->tex) return;
565 ERR("unhandled img format colorspace=%d", im->cs.space);
571 evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
572 int npoints, RGBA_Map_Point *p, int smooth, int level __UNUSED__)
574 RGBA_Draw_Context *dc;
576 int c, cx, cy, cw, ch;
582 a = (dc->mul.col >> 24) & 0xff;
583 r = (dc->mul.col >> 16) & 0xff;
584 g = (dc->mul.col >> 8 ) & 0xff;
585 b = (dc->mul.col ) & 0xff;
592 evas_gl_common_image_update(gc, im);
594 c = gc->dc->clip.use;
595 cx = gc->dc->clip.x; cy = gc->dc->clip.y;
596 cw = gc->dc->clip.w; ch = gc->dc->clip.h;
598 if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
599 (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
601 evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
603 r, g, b, a, smooth, im->tex_only,
608 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)
610 RGBA_Draw_Context *dc;
613 double ssx, ssy, ssw, ssh;
614 double mssx, mssy, mssw, mssh;
617 int c, cx, cy, cw, ch;
624 imm = (Evas_GL_Image *)dc->mask.mask;
627 a = (dc->mul.col >> 24) & 0xff;
628 r = (dc->mul.col >> 16) & 0xff;
629 g = (dc->mul.col >> 8 ) & 0xff;
630 b = (dc->mul.col ) & 0xff;
637 evas_gl_common_image_update(gc, im);
640 evas_gl_common_rect_draw(gc, dx, dy, dw, dh);
645 evas_gl_common_image_update(gc, imm);
646 if (!imm->tex) imm = NULL; /* Turn of mask on error */
649 if ((im->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
650 (im->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
654 if (imm) imm->tex->im = imm;
655 if ((!gc->dc->cutout.rects) ||
656 ((gc->shared->info.tune.cutout.max > 0) &&
657 (gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
659 if (gc->dc->clip.use)
662 double scalex,scaley;
664 nx = dx; ny = dy; nw = dw; nh = dh;
665 RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
666 gc->dc->clip.x, gc->dc->clip.y,
667 gc->dc->clip.w, gc->dc->clip.h);
668 if ((nw < 1) || (nh < 1)) return;
669 if ((!imm) && (nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
672 evas_gl_common_context_yuv_push(gc,
679 evas_gl_common_context_image_push(gc,
684 smooth, im->tex_only);
688 ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
689 ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
690 ssw = ((double)sw * (double)(nw)) / (double)(dw);
691 ssh = ((double)sh * (double)(nh)) / (double)(dh);
694 /* Correct ones here */
695 scalex = imm->w / (double)dc->mask.w;
696 scaley = imm->h / (double)dc->mask.h;
697 mssx = scalex * (nx - dc->mask.x);
698 mssy = scaley * (ny - dc->mask.y);
702 /* No yuv + imm I'm afraid */
703 evas_gl_common_context_image_mask_push(gc,
707 mssx, mssy, mssw, mssh,
708 //dc->mask.x, dc->mask.y, dc->mask.w, dc->mask.h,
714 evas_gl_common_context_yuv_push(gc,
721 evas_gl_common_context_image_push(gc,
726 smooth, im->tex_only);
731 evas_gl_common_context_yuv_push(gc,
738 evas_gl_common_context_image_push(gc,
743 smooth, im->tex_only);
748 /* save out clip info */
749 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;
750 evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h);
751 evas_common_draw_context_clip_clip(gc->dc, dx, dy, dw, dh);
752 /* our clip is 0 size.. abort */
753 if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0))
755 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;
758 rects = evas_common_draw_context_apply_cutouts(dc);
759 for (i = 0; i < rects->active; ++i)
763 rct = rects->rects + i;
764 nx = dx; ny = dy; nw = dw; nh = dh;
765 RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h);
766 if ((nw < 1) || (nh < 1)) continue;
767 if ((nx == dx) && (ny == dy) && (nw == dw) && (nh == dh))
770 evas_gl_common_context_yuv_push(gc,
777 evas_gl_common_context_image_push(gc,
782 smooth, im->tex_only);
785 ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
786 ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
787 ssw = ((double)sw * (double)(nw)) / (double)(dw);
788 ssh = ((double)sh * (double)(nh)) / (double)(dh);
790 evas_gl_common_context_yuv_push(gc,
797 evas_gl_common_context_image_push(gc,
802 smooth, im->tex_only);
804 evas_common_draw_context_apply_clear_cutouts(rects);
805 /* restore clip info */
806 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;