aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common_8/evas_soft8_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common_8/evas_soft8_main.c')
-rw-r--r--libraries/evas/src/lib/engines/common_8/evas_soft8_main.c656
1 files changed, 656 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common_8/evas_soft8_main.c b/libraries/evas/src/lib/engines/common_8/evas_soft8_main.c
new file mode 100644
index 0000000..cc4ce25
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common_8/evas_soft8_main.c
@@ -0,0 +1,656 @@
1#include "evas_common_soft8.h"
2
3static Evas_Cache_Image *eci = NULL;
4static int reference = 0;
5
6static Image_Entry *_evas_common_soft8_image_new(void);
7static void _evas_common_soft8_image_delete(Image_Entry * ie);
8
9static int _evas_common_soft8_image_surface_alloc(Image_Entry * ie, unsigned int w, unsigned int h);
10static void _evas_common_soft8_image_surface_delete(Image_Entry * ie);
11static DATA32 *_evas_common_soft8_image_surface_pixels(Image_Entry * ie);
12
13static int _evas_common_load_soft8_image_from_file(Image_Entry * ie);
14static void _evas_common_soft8_image_unload(Image_Entry * ie);
15
16static void _evas_common_soft8_image_dirty_region(Image_Entry * im, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
17static int _evas_common_soft8_image_dirty(Image_Entry * ie_dst,
18 const Image_Entry * ie_src);
19
20static int _evas_common_soft8_image_ram_usage(Image_Entry * ie);
21
22static int _evas_common_soft8_image_size_set(Image_Entry * ie_dst,
23 const Image_Entry * ie_im, unsigned int w, unsigned int h);
24static int _evas_common_soft8_image_from_copied_data(Image_Entry * ie_dst, unsigned int w, unsigned int h, DATA32 * image_data, int alpha, int cspace);
25static int _evas_common_soft8_image_from_data(Image_Entry * ie_dst, unsigned int w, unsigned int h, DATA32 * image_data, int alpha, int cspace);
26static int _evas_common_soft8_image_colorspace_set(Image_Entry * ie_dst,
27 int cspace);
28
29static int _evas_common_load_soft8_image_data_from_file(Image_Entry * ie);
30
31/*
32static void
33_evas_common_soft8_image_debug(const char* context, Image_Entry *eim)
34{
35 DBG("[8] %p = [%s] {%s,%s} %i [%i|%i]", eim, context, eim->file, eim->key, eim->references, eim->w, eim->h);
36}
37*/
38
39static const Evas_Cache_Image_Func _evas_common_soft8_image_func = {
40 _evas_common_soft8_image_new,
41 _evas_common_soft8_image_delete,
42 _evas_common_soft8_image_surface_alloc,
43 _evas_common_soft8_image_surface_delete,
44 _evas_common_soft8_image_surface_pixels,
45 _evas_common_load_soft8_image_from_file,
46 _evas_common_soft8_image_unload,
47 _evas_common_soft8_image_dirty_region,
48 _evas_common_soft8_image_dirty,
49 _evas_common_soft8_image_size_set,
50 _evas_common_soft8_image_from_copied_data,
51 _evas_common_soft8_image_from_data,
52 _evas_common_soft8_image_colorspace_set,
53 _evas_common_load_soft8_image_data_from_file,
54 _evas_common_soft8_image_ram_usage,
55/* _evas_common_soft8_image_debug */
56 NULL
57};
58
59EAPI void
60evas_common_soft8_image_init(void)
61{
62 if (!eci)
63 eci = evas_cache_image_init(&_evas_common_soft8_image_func);
64 reference++;
65}
66
67EAPI void
68evas_common_soft8_image_shutdown(void)
69{
70 if (--reference == 0)
71 {
72// DISABLE for now - something wrong with cache shutdown freeing things
73// still in use - rage_thumb segv's now.
74//
75// actually - i think i see it. cache ref goes to 0 (and thus gets freed)
76// because in eng_setup() when a buffer changes size it is FIRST freed
77// THEN allocated again - thus brignhjing ref to 0 then back to 1 immediately
78// where it should stay at 1. - see evas_engine.c in the buffer enigne for
79// example. eng_output_free() is called BEFORE _output_setup(). although this
80// is only a SIGNE of the problem. we can patch this up with either freeing
81// after the setup (so we just pt a ref of 2 then back to 1), or just
82// evas_common_image_init() at the start and evas_common_image_shutdown()
83// after it all. really ref 0 should only be reached when no more canvases
84// with no more objects exist anywhere.
85
86// ENABLE IT AGAIN, hope it is fixed. Gustavo @ January 22nd, 2009.
87 //evas_cache_image_shutdown(eci);
88 //eci = NULL;
89 }
90}
91
92EAPI Evas_Cache_Image *
93evas_common_soft8_image_cache_get(void)
94{
95 return eci;
96}
97
98static Image_Entry *
99_evas_common_soft8_image_new(void)
100{
101 Soft8_Image *im;
102
103 im = calloc(1, sizeof(Soft8_Image));
104 if (!im)
105 return NULL;
106
107 im->stride = -1;
108
109 return (Image_Entry *) im;
110}
111
112static void
113_evas_common_soft8_image_delete(Image_Entry * ie)
114{
115 memset(ie, 0xFF, sizeof(Soft8_Image));
116 free(ie);
117}
118
119static int
120_evas_common_soft8_image_surface_alloc(Image_Entry * ie, unsigned int w, unsigned int h)
121{
122 Soft8_Image *im = (Soft8_Image *) ie;
123
124 if (im->stride < 0)
125 im->stride = _calc_stride(w);
126
127 im->pixels =
128 realloc(im->pixels, IMG_BYTE_SIZE(im->stride, h, ie->flags.alpha));
129 if (!im->pixels)
130 return -1;
131
132 if (ie->flags.alpha)
133 {
134 im->alpha = (DATA8 *) (im->pixels + (im->stride * h));
135 im->flags.free_alpha = 0;
136 }
137 im->flags.free_pixels = 1;
138
139 return 0;
140}
141
142static void
143_evas_common_soft8_image_surface_delete(Image_Entry * ie)
144{
145 Soft8_Image *im = (Soft8_Image *) ie;
146
147 if (im->flags.free_pixels)
148 free(im->pixels);
149 im->pixels = NULL;
150 im->flags.free_pixels = 0;
151
152 if (im->flags.free_alpha)
153 free(im->alpha);
154 im->alpha = NULL;
155 im->flags.free_alpha = 0;
156}
157
158static DATA32 *
159_evas_common_soft8_image_surface_pixels(Image_Entry * ie __UNUSED__)
160{
161 abort();
162
163 return NULL;
164}
165
166static int
167_evas_common_load_soft8_image_from_file(Image_Entry * ie)
168{
169 Soft8_Image *sim = (Soft8_Image *) ie;
170 RGBA_Image *im;
171 int error = 0;
172
173 im = (RGBA_Image *) evas_cache_image_request(evas_common_image_cache_get(),
174 sim->cache_entry.file,
175 sim->cache_entry.key,
176 &sim->cache_entry.load_opts,
177 &error);
178 sim->source = im;
179 if (!sim->source)
180 return -1;
181
182 sim->cache_entry.w = sim->source->cache_entry.w;
183 sim->cache_entry.h = sim->source->cache_entry.h;
184 ie->flags.alpha = im->cache_entry.flags.alpha;
185 if (sim->stride < 0)
186 sim->stride = _calc_stride(sim->cache_entry.w);
187
188 return 0;
189}
190
191static void
192_evas_common_soft8_image_unload(Image_Entry * ie __UNUSED__)
193{
194}
195
196static void
197_evas_common_soft8_image_dirty_region(Image_Entry * im __UNUSED__,
198 unsigned int x __UNUSED__,
199 unsigned int y __UNUSED__,
200 unsigned int w __UNUSED__,
201 unsigned int h __UNUSED__)
202{
203}
204
205static int
206_evas_common_soft8_image_dirty(Image_Entry * ie_dst, const Image_Entry * ie_src)
207{
208 Soft8_Image *dst = (Soft8_Image *) ie_dst;
209 Soft8_Image *src = (Soft8_Image *) ie_src;
210
211 evas_cache_image_load_data(&src->cache_entry);
212 evas_cache_image_surface_alloc(&dst->cache_entry,
213 src->cache_entry.w, src->cache_entry.h);
214
215/* evas_common_blit_rectangle(src, dst, 0, 0, src->cache_entry.w, src->cache_entry.h, 0, 0); */
216
217 return 0;
218}
219
220static int
221_evas_common_soft8_image_ram_usage(Image_Entry * ie)
222{
223 Soft8_Image *im = (Soft8_Image *) ie;
224
225 if (im->pixels && im->flags.free_pixels)
226 return IMG_BYTE_SIZE(im->stride, im->cache_entry.h, ie->flags.alpha);
227 return 0;
228}
229
230static int
231_evas_common_soft8_image_size_set(Image_Entry * ie_dst,
232 const Image_Entry * ie_im,
233 unsigned int w __UNUSED__,
234 unsigned int h __UNUSED__)
235{
236 Soft8_Image *dst = (Soft8_Image *) ie_dst;
237 Soft8_Image *im = (Soft8_Image *) ie_im;
238
239 dst->flags = im->flags;
240
241 return 0;
242}
243
244static int
245_evas_common_soft8_image_from_data(Image_Entry * ie_dst,
246 unsigned int w, unsigned int h,
247 DATA32 * image_data, int alpha,
248 int cspace __UNUSED__)
249{
250 Soft8_Image *im = (Soft8_Image *) ie_dst;
251
252 /* FIXME: handle colorspace */
253 ie_dst->w = w;
254 ie_dst->h = h;
255 ie_dst->flags.alpha = alpha;
256
257 im->flags.free_pixels = 0;
258 im->flags.free_alpha = 0;
259 if (im->stride < 0)
260 im->stride = _calc_stride(w);
261
262 /* FIXME: That's bad, the application must be aware of the engine internal. */
263 im->pixels = (DATA8 *) image_data;
264 if (ie_dst->flags.alpha)
265 im->alpha = (DATA8 *) (im->pixels + (im->stride * h));
266
267 return 0;
268}
269
270static int
271_evas_common_soft8_image_from_copied_data(Image_Entry * ie_dst,
272 unsigned int w __UNUSED__,
273 unsigned int h,
274 DATA32 * image_data,
275 int alpha __UNUSED__,
276 int cspace __UNUSED__)
277{
278 Soft8_Image *im = (Soft8_Image *) ie_dst;
279
280 /* FIXME: handle colorspace */
281 if (image_data)
282 memcpy(im->pixels, image_data,
283 IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
284 else
285 memset(im->pixels, 0, IMG_BYTE_SIZE(im->stride, h, ie_dst->flags.alpha));
286
287 return 0;
288}
289
290static int
291_evas_common_soft8_image_colorspace_set(Image_Entry * ie_dst __UNUSED__,
292 int cspace __UNUSED__)
293{
294 /* FIXME: handle colorspace */
295 return 0;
296}
297
298static int
299_evas_common_load_soft8_image_data_from_file(Image_Entry * ie)
300{
301 Soft8_Image *im = (Soft8_Image *) ie;
302
303 if (im->pixels)
304 return 0;
305 if (!im->source)
306 return -1;
307
308 evas_cache_image_load_data(&im->source->cache_entry);
309 if (im->source->image.data)
310 {
311 DATA32 *sp;
312
313 evas_cache_image_surface_alloc(&im->cache_entry,
314 im->source->cache_entry.w,
315 im->source->cache_entry.h);
316
317 sp = im->source->image.data;
318 if (im->alpha)
319 evas_common_soft8_image_convert_from_rgba(im, sp);
320 else
321 evas_common_soft8_image_convert_from_rgb(im, sp);
322 }
323 evas_cache_image_drop(&im->source->cache_entry);
324 im->source = NULL;
325
326 return 0;
327}
328
329/* Soft16_Image * */
330/* evas_common_soft16_image_new(int w, unsigned int h, unsigned int stride, int have_alpha, DATA16 *pixels, */
331/* int copy) */
332/* { */
333/* Soft16_Image *im; */
334
335/* if (stride < 0) stride = _calc_stride(w); */
336
337/* im = evas_common_soft16_image_alloc(w, h, stride, have_alpha, copy); */
338/* if (!im) return NULL; */
339
340/* if (pixels) */
341/* { */
342/* if (copy) */
343/* memcpy(im->pixels, pixels, IMG_BYTE_SIZE(stride, h, have_alpha)); */
344/* else */
345/* { */
346/* im->pixels = pixels; */
347/* if (have_alpha) im->alpha = (DATA8 *)(im->pixels + (stride * h)); */
348/* } */
349/* } */
350/* return im; */
351/* } */
352
353static inline void
354_get_clip(const RGBA_Draw_Context * dc, const Soft8_Image * im,
355 Eina_Rectangle * clip)
356{
357 if (dc->clip.use)
358 {
359 EINA_RECTANGLE_SET(clip, dc->clip.x, dc->clip.y, dc->clip.w,
360 dc->clip.h);
361 if (clip->x < 0)
362 {
363 clip->w += clip->x;
364 clip->x = 0;
365 }
366 if (clip->y < 0)
367 {
368 clip->h += clip->y;
369 clip->y = 0;
370 }
371 if ((clip->x + clip->w) > (int)im->cache_entry.w)
372 clip->w = im->cache_entry.w - clip->x;
373 if ((clip->y + clip->h) > (int)im->cache_entry.h)
374 clip->h = im->cache_entry.h - clip->y;
375 }
376 else
377 {
378 EINA_RECTANGLE_SET(clip, 0, 0, im->cache_entry.w, im->cache_entry.h);
379 }
380}
381
382static inline int
383_is_empty_rectangle(const Eina_Rectangle * r)
384{
385 return (r->w < 1) || (r->h < 1);
386}
387
388static inline void
389_shrink(int *s_pos, int *s_size, int pos, int size)
390{
391 int d;
392
393 d = (*s_pos) - pos;
394 if (d < 0)
395 {
396 (*s_size) += d;
397 (*s_pos) = pos;
398 }
399
400 d = size + pos - (*s_pos);
401 if ((*s_size) > d)
402 (*s_size) = d;
403}
404
405static int
406_soft8_adjust_areas(Eina_Rectangle * src,
407 int src_max_x, int src_max_y, Eina_Rectangle * dst,
408 int dst_max_x, int dst_max_y, Eina_Rectangle * dst_clip)
409{
410 if (_is_empty_rectangle(src) ||
411 _is_empty_rectangle(dst) || _is_empty_rectangle(dst_clip))
412 return 0;
413
414 /* shrink clip */
415 _shrink(&dst_clip->x, &dst_clip->w, dst->x, dst->w);
416 _shrink(&dst_clip->y, &dst_clip->h, dst->y, dst->h);
417 if (_is_empty_rectangle(dst_clip))
418 return 0;
419
420 /* sanitise x */
421 if (src->x < 0)
422 {
423 dst->x -= (src->x * dst->w) / src->w;
424 dst->w += (src->x * dst->w) / src->w;
425 src->w += src->x;
426 src->x = 0;
427 }
428 if (src->x >= src_max_x)
429 return 0;
430 if ((src->x + src->w) > src_max_x)
431 {
432 dst->w = (dst->w * (src_max_x - src->x)) / (src->w);
433 src->w = src_max_x - src->x;
434 }
435 if (dst->w <= 0)
436 return 0;
437 if (src->w <= 0)
438 return 0;
439 if (dst_clip->x < 0)
440 {
441 dst_clip->w += dst_clip->x;
442 dst_clip->x = 0;
443 }
444 if (dst_clip->w <= 0)
445 return 0;
446 if (dst_clip->x >= dst_max_x)
447 return 0;
448
449 _shrink(&dst_clip->x, &dst_clip->w, 0, dst_max_x);
450 if (dst_clip->w <= 0)
451 return 0;
452
453 /* sanitise y */
454 if (src->y < 0)
455 {
456 dst->y -= (src->y * dst->h) / src->h;
457 dst->h += (src->y * dst->h) / src->h;
458 src->h += src->y;
459 src->y = 0;
460 }
461 if (src->y >= src_max_y)
462 return 0;
463 if ((src->y + src->h) > src_max_y)
464 {
465 dst->h = (dst->h * (src_max_y - src->y)) / (src->h);
466 src->h = src_max_y - src->y;
467 }
468 if (dst->h <= 0)
469 return 0;
470 if (src->h <= 0)
471 return 0;
472 if (dst_clip->y < 0)
473 {
474 dst_clip->h += dst_clip->y;
475 dst_clip->y = 0;
476 }
477 if (dst_clip->h <= 0)
478 return 0;
479 if (dst_clip->y >= dst_max_y)
480 return 0;
481
482 _shrink(&dst_clip->y, &dst_clip->h, 0, dst_max_y);
483 if (dst_clip->h <= 0)
484 return 0;
485
486 return 1;
487}
488
489static void
490_soft8_image_draw_sampled_int(Soft8_Image * src, Soft8_Image * dst,
491 RGBA_Draw_Context * dc,
492 Eina_Rectangle sr, Eina_Rectangle dr)
493{
494 Eina_Rectangle cr;
495
496 if (!
497 (RECTS_INTERSECT
498 (dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
499 return;
500 if (!
501 (RECTS_INTERSECT
502 (sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
503 return;
504
505 _get_clip(dc, dst, &cr);
506 if (!_soft8_adjust_areas
507 (&sr, src->cache_entry.w, src->cache_entry.h, &dr, dst->cache_entry.w,
508 dst->cache_entry.h, &cr))
509 return;
510
511 if ((dr.w == sr.w) && (dr.h == sr.h))
512 evas_common_soft8_image_draw_unscaled(src, dst, dc, sr, dr, cr);
513 else
514 evas_common_soft8_image_draw_scaled_sampled(src, dst, dc, sr, dr, cr);
515}
516
517EAPI void
518evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst,
519 RGBA_Draw_Context * dc,
520 int src_region_x, int src_region_y,
521 int src_region_w, int src_region_h,
522 int dst_region_x, int dst_region_y,
523 int dst_region_w, int dst_region_h,
524 int smooth __UNUSED__)
525{
526 Eina_Rectangle sr, dr;
527 Cutout_Rects *rects;
528 Cutout_Rect *r;
529 struct RGBA_Draw_Context_clip clip_bkp;
530 int i;
531
532 /* handle cutouts here! */
533 EINA_RECTANGLE_SET(&dr, dst_region_x, dst_region_y, dst_region_w,
534 dst_region_h);
535
536 if (_is_empty_rectangle(&dr))
537 return;
538 if (!
539 (RECTS_INTERSECT
540 (dr.x, dr.y, dr.w, dr.h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
541 return;
542
543 EINA_RECTANGLE_SET(&sr, src_region_x, src_region_y, src_region_w,
544 src_region_h);
545
546 if (_is_empty_rectangle(&sr))
547 return;
548 if (!
549 (RECTS_INTERSECT
550 (sr.x, sr.y, sr.w, sr.h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
551 return;
552
553 /* no cutouts - cut right to the chase */
554 if (!dc->cutout.rects)
555 {
556 _soft8_image_draw_sampled_int(src, dst, dc, sr, dr);
557 return;
558 }
559
560 /* save out clip info */
561 clip_bkp = dc->clip;
562 evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w,
563 dst->cache_entry.h);
564 evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y,
565 dst_region_w, dst_region_h);
566 /* our clip is 0 size.. abort */
567 if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
568 {
569 dc->clip = clip_bkp;
570 return;
571 }
572 rects = evas_common_draw_context_apply_cutouts(dc);
573 for (i = 0; i < rects->active; i++)
574 {
575 r = rects->rects + i;
576 evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
577 _soft8_image_draw_sampled_int(src, dst, dc, sr, dr);
578 }
579 evas_common_draw_context_apply_clear_cutouts(rects);
580 dc->clip = clip_bkp;
581}
582
583EAPI Soft8_Image *
584evas_common_soft8_image_alpha_set(Soft8_Image * im, int have_alpha)
585{
586 Soft8_Image *new_im;
587
588 if (im->cache_entry.flags.alpha == have_alpha)
589 return im;
590
591 new_im = (Soft8_Image *) evas_cache_image_alone(&im->cache_entry);
592
593 new_im->cache_entry.flags.alpha = have_alpha;
594
595 if (im->cache_entry.w > 0 && im->cache_entry.h)
596 new_im =
597 (Soft8_Image *) evas_cache_image_size_set(&new_im->cache_entry,
598 im->cache_entry.w,
599 im->cache_entry.h);
600
601 return new_im;
602}
603
604/* Soft16_Image * */
605/* evas_common_soft16_image_size_set(Soft16_Image *old_im, unsigned int w, unsigned int h) */
606/* { */
607/* Soft16_Image *new_im; */
608/* DATA16 *dp, *sp; */
609/* int i, cw, ch, ew; */
610
611/* if ((old_im->cache_entry.w == w) && (old_im->cache_entry.h == h)) return old_im; */
612
613/* new_im = evas_common_soft16_image_new(w, h, -1, old_im->flags.have_alpha, NULL, 1); */
614
615/* if (old_im->cache_entry.w < new_im->cache_entry.w) */
616/* cw = old_im->cache_entry.w; */
617/* else */
618/* cw = new_im->cache_entry.w; */
619
620/* ew = new_im->cache_entry.w - cw; */
621
622/* if (old_im->cache_entry.h < new_im->cache_entry.h) */
623/* ch = old_im->cache_entry.h; */
624/* else */
625/* ch = new_im->cache_entry.h; */
626
627/* dp = new_im->pixels; */
628/* sp = old_im->pixels; */
629/* for (i = 0; i < ch; i++) */
630/* { */
631/* memcpy(dp, sp, cw * sizeof(DATA16)); */
632/* if (ew > 0) memset(dp, 0, ew * sizeof(DATA16)); */
633
634/* dp += new_im->stride; */
635/* sp += old_im->stride; */
636/* } */
637
638/* if (old_im->flags.have_alpha) */
639/* { */
640/* DATA8 *dp, *sp; */
641
642/* dp = new_im->alpha; */
643/* sp = old_im->alpha; */
644/* for (i = 0; i < ch; i++) */
645/* { */
646/* memcpy(dp, sp, cw * sizeof(DATA8)); */
647/* if (ew > 0) memset(dp, 0, ew * sizeof(DATA8)); */
648
649/* dp += new_im->stride; */
650/* sp += old_im->stride; */
651/* } */
652/* } */
653
654/* evas_cache_image_drop(&old_im->cache_entry); */
655/* return new_im; */
656/* } */