aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_16_sdl/evas_engine.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/software_16_sdl/evas_engine.c')
-rw-r--r--libraries/evas/src/modules/engines/software_16_sdl/evas_engine.c1337
1 files changed, 1337 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/software_16_sdl/evas_engine.c b/libraries/evas/src/modules/engines/software_16_sdl/evas_engine.c
new file mode 100644
index 0000000..02f9341
--- /dev/null
+++ b/libraries/evas/src/modules/engines/software_16_sdl/evas_engine.c
@@ -0,0 +1,1337 @@
1#include <assert.h>
2#include <math.h>
3#include <string.h>
4#include <sys/time.h>
5#include <time.h>
6#include <SDL/SDL.h>
7
8#include "evas_common.h"/* Also includes international specific stuff */
9#include "evas_engine.h"
10int _evas_engine_soft16_sdl_log_dom = -1;
11
12/* function tables - filled in later (func and parent func) */
13static Evas_Func func, pfunc;
14
15static Engine_Image_Entry *_sdl16_image_alloc (void);
16static void _sdl16_image_delete (Engine_Image_Entry *eim);
17
18static int _sdl16_image_constructor (Engine_Image_Entry *ie, void* data);
19static void _sdl16_image_destructor (Engine_Image_Entry *eim);
20
21static void _sdl16_image_dirty_region(Engine_Image_Entry *eim, unsigned int x, unsigned int y, unsigned int w, unsigned int h);
22
23static int _sdl16_image_dirty (Engine_Image_Entry *dst, const Engine_Image_Entry *src);
24
25static int _sdl16_image_size_set (Engine_Image_Entry *dst, const Engine_Image_Entry *src);
26
27static int _sdl16_image_update_data (Engine_Image_Entry* dst, void* engine_data);
28
29static void _sdl16_image_load (Engine_Image_Entry *eim, const Image_Entry* im);
30static int _sdl16_image_mem_size_get(Engine_Image_Entry *eim);
31
32#ifdef DEBUG_SDL
33static void _sdl16_image_debug (const char* context, Engine_Image_Entry* im);
34#endif
35
36static const Evas_Cache_Engine_Image_Func _sdl16_cache_engine_image_cb = {
37 NULL /* key */,
38 _sdl16_image_alloc /* alloc */,
39 _sdl16_image_delete /* dealloc */,
40 _sdl16_image_constructor /* constructor */,
41 _sdl16_image_destructor /* destructor */,
42 _sdl16_image_dirty_region /* dirty_region */,
43 _sdl16_image_dirty /* dirty */,
44 _sdl16_image_size_set /* size_set */,
45 _sdl16_image_update_data /* update_data */,
46 _sdl16_image_load /* load */,
47 _sdl16_image_mem_size_get /* mem_size_get */,
48#ifdef DEBUG_SDL /* debug */
49 _sdl16_image_debug
50#else
51 NULL
52#endif
53};
54
55#define _SDL_UPDATE_PIXELS(EIM) \
56 ((Soft16_Image *) EIM->cache_entry.src)->pixels = EIM->surface->pixels;
57
58#define RMASK565 0xf800
59#define GMASK565 0x07e0
60#define BMASK565 0x001f
61#define AMASK565 0x0000
62
63/* engine api this module provides */
64static void *
65evas_engine_sdl16_info(Evas *e __UNUSED__)
66{
67 Evas_Engine_Info_SDL_16 *info;
68 info = calloc(1, sizeof(Evas_Engine_Info_SDL_16));
69 if (!info) return NULL;
70 info->magic.magic = rand();
71 return info;
72}
73
74static void
75evas_engine_sdl16_info_free(Evas *e __UNUSED__, void *info)
76{
77 Evas_Engine_Info_SDL_16 *in;
78 in = (Evas_Engine_Info_SDL_16 *)info;
79 free(in);
80}
81
82static void
83_tmp_out_alloc(Render_Engine *re)
84{
85 Tilebuf_Rect *r;
86 unsigned int w = 0, h = 0;
87
88 EINA_INLIST_FOREACH(re->rects, r)
89 {
90 if (r->w > (int)w) w = r->w;
91 if (r->h > (int)h) h = r->h;
92 }
93
94 if (re->tmp_out)
95 {
96 if ((re->tmp_out->cache_entry.w < w) || (re->tmp_out->cache_entry.h < h))
97 {
98 evas_cache_image_drop(&re->tmp_out->cache_entry);
99 re->tmp_out = NULL;
100 }
101 }
102
103 if (!re->tmp_out)
104 {
105 Soft16_Image *im;
106
107 im = (Soft16_Image *) evas_cache_image_empty(evas_common_soft16_image_cache_get());
108 im->cache_entry.flags.alpha = 0;
109 evas_cache_image_surface_alloc(&im->cache_entry, w, h);
110
111 re->tmp_out = im;
112 }
113}
114
115static void*
116_sdl16_output_setup(int w, int h, int rotation, int fullscreen, int noframe, int hwsurface)
117{
118 Render_Engine *re;
119 SDL_Surface *surface;
120
121 re = calloc(1, sizeof(Render_Engine));
122 if (!re)
123 return NULL;
124 /* if we haven't initialized - init (automatic abort if already done) */
125 evas_common_cpu_init();
126 evas_common_blend_init();
127 evas_common_image_init();
128 evas_common_convert_init();
129 evas_common_scale_init();
130 evas_common_rectangle_init();
131 evas_common_polygon_init();
132 evas_common_line_init();
133 evas_common_font_init();
134 evas_common_draw_init();
135 evas_common_tilebuf_init();
136 evas_common_soft16_image_init();
137
138 if (w <= 0) w = 640;
139 if (h <= 0) h = 480;
140
141 re->cache = evas_cache_engine_image_init(&_sdl16_cache_engine_image_cb, evas_common_soft16_image_cache_get());
142 if (!re->cache)
143 {
144 ERR("Evas_Cache_Engine_Image allocation failed!");
145 free(re);
146 return NULL;
147 }
148
149 re->tb = evas_common_tilebuf_new(w, h);
150 /* in preliminary tests 16x16 gave highest framerates */
151 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
152 re->w = w;
153 re->h = h;
154 re->rot = rotation;
155 re->flags.hwsurface = hwsurface;
156 re->flags.fullscreen = fullscreen;
157 re->flags.noframe = noframe;
158 re->flags.end = 0;
159
160 re->update_rects_count = 0;
161 re->update_rects_limit = 0;
162 re->update_rects = NULL;
163
164 surface = SDL_SetVideoMode(w, h, 16,
165 (hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE)
166 | (fullscreen ? SDL_FULLSCREEN : 0)
167 | (noframe ? SDL_NOFRAME : 0));
168 if (!surface)
169 {
170 ERR("SDL_SetVideoMode [ %i x %i x 16 ] failed", w, h);
171 evas_cache_engine_image_shutdown(re->cache);
172 free(re);
173 return NULL;
174 }
175
176 SDL_SetAlpha(surface, SDL_RLEACCEL, 0);
177 SDL_FillRect(surface, NULL, 0);
178
179 re->soft16_engine_image = (SDL_Engine_Image_Entry *) evas_cache_engine_image_engine(re->cache, surface);
180 if (!re->soft16_engine_image)
181 {
182 ERR("Soft16_Image allocation from SDL failed");
183 evas_cache_engine_image_shutdown(re->cache);
184 free(re);
185 return NULL;
186 }
187
188 return re;
189}
190
191
192static int
193evas_engine_sdl16_setup(Evas *e, void *in)
194{
195 Evas_Engine_Info_SDL_16 *info = (Evas_Engine_Info_SDL_16 *) in;
196
197 if (evas_output_method_get(e) != evas_render_method_lookup("software_16_sdl"))
198 return 0;
199
200 SDL_Init(SDL_INIT_NOPARACHUTE);
201
202 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
203 {
204 ERR("SDL_Init failed with %s", SDL_GetError());
205 SDL_Quit();
206 return 0;
207 }
208
209 e->engine.data.output = _sdl16_output_setup(e->output.w, e->output.h,
210 info->info.rotation,
211 info->info.fullscreen,
212 info->info.noframe,
213 info->info.hwsurface);
214 if (!e->engine.data.output)
215 return 0;
216
217 e->engine.func = &func;
218 e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
219
220 return 1;
221}
222
223static void
224evas_engine_sdl16_output_free(void *data)
225{
226 Render_Engine *re;
227
228 re = (Render_Engine *)data;
229 if (re->tb) evas_common_tilebuf_free(re->tb);
230 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
231 if (re->tmp_out) evas_cache_image_drop(&re->tmp_out->cache_entry);
232 if (re->soft16_engine_image)
233 evas_cache_engine_image_drop(&re->soft16_engine_image->cache_entry);
234 if (re->cache) evas_cache_engine_image_shutdown(re->cache);
235
236 if (re->update_rects)
237 free(re->update_rects);
238 free(re);
239
240 evas_common_font_shutdown();
241 evas_common_image_shutdown();
242 evas_common_soft16_image_shutdown();
243
244 SDL_QuitSubSystem(SDL_INIT_VIDEO);
245}
246
247static void
248evas_engine_sdl16_output_resize(void *data, int w, int h)
249{
250 Render_Engine *re = data;
251 SDL_Surface *surface;
252
253 if ((re->tb->outbuf_w == w) && (re->tb->outbuf_h == h)) return;
254
255 evas_cache_engine_image_drop(&re->soft16_engine_image->cache_entry);
256
257 evas_common_tilebuf_free(re->tb);
258 re->w = w;
259 re->h = h;
260 re->tb = evas_common_tilebuf_new(w, h);
261 if (re->tb)
262 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
263
264 surface = SDL_SetVideoMode(w, h, 16,
265 (re->flags.hwsurface ? SDL_HWSURFACE : SDL_SWSURFACE)
266 | (re->flags.fullscreen ? SDL_FULLSCREEN : 0)
267 | (re->flags.noframe ? SDL_NOFRAME : 0));
268 if (!surface)
269 {
270 ERR("Unable to change the resolution to : %ix%i", w, h);
271 exit(-1);
272 }
273 re->soft16_engine_image = (SDL_Engine_Image_Entry *) evas_cache_engine_image_engine(re->cache, surface);
274 if (!re->soft16_engine_image)
275 {
276 ERR("RGBA_Image allocation from SDL failed");
277 exit(-1);
278 }
279
280 SDL_FillRect(surface, NULL, 0);
281
282 if (re->tmp_out)
283 {
284 evas_cache_image_drop(&re->tmp_out->cache_entry);
285 re->tmp_out = NULL;
286 }
287}
288
289static void
290evas_engine_sdl16_output_tile_size_set(void *data, int w, int h)
291{
292 Render_Engine *re;
293
294 re = (Render_Engine *)data;
295 evas_common_tilebuf_set_tile_size(re->tb, w, h);
296}
297
298static void
299evas_engine_sdl16_output_redraws_rect_add(void *data, int x, int y, int w, int h)
300{
301 Render_Engine *re;
302
303 re = (Render_Engine *)data;
304 evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
305}
306
307static void
308evas_engine_sdl16_output_redraws_rect_del(void *data, int x, int y, int w, int h)
309{
310 Render_Engine *re;
311
312 re = (Render_Engine *)data;
313 evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
314}
315
316static void
317evas_engine_sdl16_output_redraws_clear(void *data)
318{
319 Render_Engine *re;
320
321 re = (Render_Engine *)data;
322 evas_common_tilebuf_clear(re->tb);
323}
324
325static void *
326evas_engine_sdl16_output_redraws_next_update_get(void *data,
327 int *x, int *y, int *w, int *h,
328 int *cx, int *cy, int *cw, int *ch)
329{
330 Render_Engine *re = data;
331 Tilebuf_Rect *tb_rect;
332 SDL_Rect rect;
333
334 if (re->flags.end)
335 {
336 re->flags.end = 0;
337 return NULL;
338 }
339 if (!re->rects)
340 {
341 re->rects = evas_common_tilebuf_get_render_rects(re->tb);
342 re->cur_rect = re->rects;
343 if (re->rot != 0) _tmp_out_alloc(re); /* grows if required */
344 }
345
346 if (!re->cur_rect)
347 {
348 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
349 re->rects = NULL;
350 return NULL;
351 }
352
353 tb_rect = re->cur_rect;
354 *cx = *x = tb_rect->x;
355 *cy = *y = tb_rect->y;
356 *cw = *w = tb_rect->w;
357 *ch = *h = tb_rect->h;
358 re->cur_rect = (Tilebuf_Rect *)((EINA_INLIST_GET(re->cur_rect))->next);
359 if (!re->cur_rect)
360 {
361 evas_common_tilebuf_free_render_rects(re->rects);
362 re->rects = NULL;
363 re->flags.end = 1;
364 }
365
366 if (re->rot != 0)
367 {
368 *cx = 0;
369 *cy = 0;
370 }
371
372 rect.x = *x;
373 rect.y = *y;
374 rect.w = *w;
375 rect.h = *h;
376
377 /* Return the "fake" surface so it is passed to the drawing routines. */
378 return re->soft16_engine_image;
379}
380
381static void
382_blit_rot_90(Soft16_Image *dst, const Soft16_Image *src,
383 int out_x, int out_y, int w, int h)
384{
385 DATA16 *dp, *sp;
386 int x, y;
387
388 sp = src->pixels;
389 dp = dst->pixels + (out_x +
390 (w + out_y - 1) * dst->stride);
391
392 for (y = 0; y < h; y++)
393 {
394 DATA16 *dp_itr, *sp_itr;
395
396 sp_itr = sp;
397 dp_itr = dp;
398
399 for (x = 0; x < w; x++)
400 {
401 *dp_itr = *sp_itr;
402
403 sp_itr++;
404 dp_itr -= dst->stride;
405 }
406 sp += src->stride;
407 dp++;
408 }
409}
410
411static void
412_blit_rot_180(Soft16_Image *dst, const Soft16_Image *src,
413 int out_x, int out_y, int w, int h)
414{
415 DATA16 *dp, *sp;
416 int x, y;
417
418 sp = src->pixels;
419 dp = dst->pixels + ((w + out_x - 1) +
420 (h + out_y - 1) * dst->stride);
421
422 for (y = 0; y < h; y++)
423 {
424 DATA16 *dp_itr, *sp_itr;
425
426 sp_itr = sp;
427 dp_itr = dp;
428
429 for (x = 0; x < w; x++)
430 {
431 *dp_itr = *sp_itr;
432
433 sp_itr++;
434 dp_itr--;
435 }
436 sp += src->stride;
437 dp -= dst->stride;
438 }
439}
440
441static void
442_blit_rot_270(Soft16_Image *dst, const Soft16_Image *src,
443 int out_x, int out_y, int w, int h)
444{
445 DATA16 *dp, *sp;
446 int x, y;
447
448 sp = src->pixels;
449 dp = dst->pixels + ((h + out_x - 1) +
450 out_y * dst->stride);
451
452 for (y = 0; y < h; y++)
453 {
454 DATA16 *dp_itr, *sp_itr;
455
456 sp_itr = sp;
457 dp_itr = dp;
458
459 for (x = 0; x < w; x++)
460 {
461 *dp_itr = *sp_itr;
462
463 sp_itr++;
464 dp_itr += dst->stride;
465 }
466 sp += src->stride;
467 dp--;
468 }
469}
470
471static void
472_tmp_out_process(Render_Engine *re, int out_x, int out_y, int w, int h)
473{
474 Soft16_Image *d, *s;
475
476 d = (Soft16_Image *) re->soft16_engine_image->cache_entry.src;
477 s = re->tmp_out;
478
479 if ((w < 1) || (h < 1) ||
480 (out_x >= (int)d->cache_entry.w) || (out_y >= (int)d->cache_entry.h))
481 return;
482
483 if (re->rot == 90)
484 _blit_rot_90(d, s, out_x, out_y, w, h);
485 else if (re->rot == 180)
486 _blit_rot_180(d, s, out_x, out_y, w, h);
487 else if (re->rot == 270)
488 _blit_rot_270(d, s, out_x, out_y, w, h);
489}
490
491static void
492evas_engine_sdl16_output_redraws_next_update_push(void *data, void *surface __UNUSED__,
493 int x, int y, int w, int h)
494{
495 Render_Engine *re = data;
496 SDL_Rect rect;
497
498 if (re->update_rects_count + 1 > re->update_rects_limit)
499 {
500 re->update_rects_limit += 8;
501 re->update_rects = realloc(re->update_rects, sizeof (SDL_Rect) * re->update_rects_limit);
502 }
503
504 rect.x = x;
505 rect.y = y;
506 rect.w = w;
507 rect.h = h;
508
509 switch (re->rot)
510 {
511 case 0:
512 break;
513 case 90:
514 rect.x = y;
515 rect.y = re->w - w - x;
516 rect.w = h;
517 rect.h = w;
518 break;
519 case 180:
520 rect.x = re->w - w - x;
521 rect.y = re->h - h - y;
522 break;
523 case 270:
524 rect.x = re->h - h - y;
525 rect.y = x;
526 rect.w = h;
527 rect.h = w;
528 break;
529 default:
530 abort();
531 }
532
533 re->update_rects[re->update_rects_count] = rect;
534
535 if (re->rot != 0)
536 _tmp_out_process(re, rect.x, rect.y, w, h);
537
538 ++re->update_rects_count;
539
540 evas_common_cpu_end_opt();
541}
542
543static void
544evas_engine_sdl16_output_flush(void *data)
545{
546 Render_Engine *re = data;
547
548 if (re->update_rects_count > 0)
549 SDL_UpdateRects(re->soft16_engine_image->surface, re->update_rects_count, re->update_rects);
550
551 re->update_rects_count = 0;
552}
553
554static void
555evas_engine_sdl16_output_idle_flush(void *data)
556{
557 Render_Engine *re;
558
559 re = (Render_Engine *)data;
560 if (re->tmp_out)
561 {
562 evas_cache_image_drop(&re->tmp_out->cache_entry);
563 re->tmp_out = NULL;
564 }
565}
566
567static void*
568evas_engine_sdl16_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
569{
570 Render_Engine* re = (Render_Engine*) data;;
571
572 *error = 0;
573 return evas_cache_engine_image_request(re->cache, file, key, lo, NULL, error);
574}
575
576static int
577evas_engine_sdl16_image_alpha_get(void *data __UNUSED__, void *image)
578{
579 SDL_Engine_Image_Entry *eim = image;
580 Soft16_Image *im;
581
582 if (!eim) return 1;
583 im = (Soft16_Image *) eim->cache_entry.src;
584 switch (eim->cache_entry.src->space)
585 {
586 case EVAS_COLORSPACE_ARGB8888:
587 if (im->cache_entry.flags.alpha) return 1;
588 default:
589 break;
590 }
591 return 0;
592}
593
594static void
595evas_engine_sdl16_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
596{
597 SDL_Engine_Image_Entry *eim;
598
599 eim = image;
600 if (w) *w = eim->cache_entry.src->w;
601 if (h) *h = eim->cache_entry.src->h;
602}
603
604static int
605evas_engine_sdl16_image_colorspace_get(void *data __UNUSED__, void *image __UNUSED__)
606{
607 SDL_Engine_Image_Entry *eim = image;
608
609 if (!eim) return EVAS_COLORSPACE_RGB565_A5P;
610 return eim->cache_entry.src->space;
611}
612
613static void
614evas_engine_sdl16_image_colorspace_set(void *data __UNUSED__, void *image __UNUSED__, int cspace __UNUSED__)
615{
616 SDL_Engine_Image_Entry *eim = image;
617
618 if (!eim) return;
619 if (eim->cache_entry.src->space == cspace) return;
620
621 evas_cache_engine_image_colorspace(&eim->cache_entry, cspace, NULL);
622}
623
624static void*
625evas_engine_sdl16_image_new_from_copied_data(void *data,
626 int w, int h,
627 DATA32* image_data,
628 int alpha, int cspace)
629{
630 Render_Engine *re = data;
631
632 if (cspace != EVAS_COLORSPACE_RGB565_A5P)
633 {
634 WRN("Unsupported colorspace %d in %s() (%s:%d)",
635 cspace, __FUNCTION__, __FILE__, __LINE__);
636 return NULL;
637 }
638
639 WRN("s image_data: %p", image_data);
640
641 return evas_cache_engine_image_copied_data(re->cache,
642 w, h,
643 image_data,
644 alpha, cspace, NULL);
645}
646
647static void*
648evas_engine_sdl16_image_new_from_data(void *data, int w, int h, DATA32* image_data, int alpha, int cspace)
649{
650 Render_Engine *re = data;
651
652 if (cspace != EVAS_COLORSPACE_RGB565_A5P)
653 {
654 WRN("Unsupported colorspace %d in %s() (%s:%d)",
655 cspace, __FUNCTION__, __FILE__, __LINE__);
656 return NULL;
657 }
658
659 return evas_cache_engine_image_data(re->cache,
660 w, h,
661 image_data,
662 alpha, cspace, NULL);
663}
664
665static void
666evas_engine_sdl16_image_free(void *data __UNUSED__, void *image)
667{
668 SDL_Engine_Image_Entry *eim = image;
669
670 evas_cache_engine_image_drop(&eim->cache_entry);
671}
672
673static void*
674evas_engine_sdl16_image_size_set(void *data __UNUSED__, void *image, int w, int h)
675{
676 SDL_Engine_Image_Entry *eim = image;
677
678 return evas_cache_engine_image_size_set(&eim->cache_entry, w, h);
679}
680
681static void*
682evas_engine_sdl16_image_dirty_region(void *data __UNUSED__,
683 void *image,
684 int x, int y, int w, int h)
685{
686 SDL_Engine_Image_Entry *eim = image;
687
688 return evas_cache_engine_image_dirty(&eim->cache_entry, x, y, w, h);
689}
690
691static void*
692evas_engine_sdl16_image_data_get(void *data __UNUSED__, void *image,
693 int to_write, DATA32** image_data, int *err)
694{
695 SDL_Engine_Image_Entry *eim = image;
696 Soft16_Image *im;
697 int error;
698
699 if (!eim)
700 {
701 *image_data = NULL;
702 if (err) *err = EVAS_LOAD_ERROR_GENERIC;
703 return NULL;
704 }
705 im = (Soft16_Image *) eim->cache_entry.src;
706
707 if (to_write)
708 eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_dirty(&eim->cache_entry,
709 0, 0, eim->cache_entry.src->w, eim->cache_entry.src->h);
710
711 error = evas_cache_image_load_data(&im->cache_entry);
712 /* FIXME: Handle colorspace conversion correctly. */
713 if (image_data) *image_data = (DATA32 *) im->pixels;
714
715 if (err) *err = error;
716 return eim;
717}
718
719static void*
720evas_engine_sdl16_image_data_put(void *data, void *image, DATA32* image_data)
721{
722 SDL_Engine_Image_Entry *eim = image;
723 SDL_Engine_Image_Entry *eim_new;
724 Render_Engine *re = data;
725 Soft16_Image *im;
726
727 if (!eim) return NULL;
728 im = (Soft16_Image *) eim->cache_entry.src;
729
730 /* FIXME: Handle colorspace conversion correctly. */
731 if ((DATA16 *) image_data == im->pixels) return eim;
732
733 eim_new = (SDL_Engine_Image_Entry *) evas_cache_engine_image_data(re->cache,
734 eim->cache_entry.w, eim->cache_entry.h,
735 image_data,
736 func.image_alpha_get(data, eim),
737 func.image_colorspace_get(data, eim),
738 NULL);
739 evas_cache_engine_image_drop(&eim->cache_entry);
740
741 return eim_new;
742}
743
744static void
745evas_engine_sdl16_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
746{
747 SDL_Engine_Image_Entry *eim = image;
748 Soft16_Image *im;
749
750 if (!eim) return ;
751 im = (Soft16_Image *) eim->cache_entry.src;
752 if (!im) return ;
753 evas_cache_image_preload_data(&im->cache_entry, target);
754}
755
756static void
757evas_engine_sdl16_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
758{
759 SDL_Engine_Image_Entry *eim = image;
760 Soft16_Image *im;
761
762 if (!eim) return ;
763 im = (Soft16_Image *) eim->cache_entry.src;
764 if (!im) return ;
765 evas_cache_image_preload_cancel(&im->cache_entry, target);
766}
767
768static void*
769evas_engine_sdl16_image_alpha_set(void *data __UNUSED__, void *image, int has_alpha)
770{
771 SDL_Engine_Image_Entry *eim = image;
772 Soft16_Image *im;
773
774 if (!eim) return NULL;
775
776 im = (Soft16_Image *) eim->cache_entry.src;
777
778 if (im->cache_entry.flags.alpha == has_alpha) return eim;
779
780 //eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_alone(&eim->cache_entry, NULL);
781 //im = (Soft16_Image *) eim->cache_entry.src;
782
783 im->cache_entry.flags.alpha = has_alpha;
784 eim = (SDL_Engine_Image_Entry *) evas_cache_engine_image_dirty(&eim->cache_entry, 0, 0, eim->cache_entry.w, eim->cache_entry.h);
785
786 return eim;
787}
788
789static void*
790evas_engine_sdl16_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
791{
792 return image;
793}
794
795static void
796evas_engine_sdl16_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
797{
798 /* FIXME: need to know what evas expect from this call */
799}
800
801static void
802evas_engine_sdl16_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
803 int src_region_x, int src_region_y, int src_region_w, int src_region_h,
804 int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h,
805 int smooth)
806{
807 SDL_Engine_Image_Entry *eim = image;
808 SDL_Engine_Image_Entry *dst = surface;
809 int mustlock_im = 0;
810 int mustlock_dst = 0;
811
812 evas_cache_engine_image_load_data(&eim->cache_entry);
813
814 /* Fallback to software method */
815 if (SDL_MUSTLOCK(dst->surface))
816 {
817 mustlock_dst = 1;
818 SDL_LockSurface(dst->surface);
819 _SDL_UPDATE_PIXELS(dst);
820 }
821
822 if (eim->surface && SDL_MUSTLOCK(eim->surface))
823 {
824 mustlock_im = 1;
825 SDL_LockSurface(eim->surface);
826 _SDL_UPDATE_PIXELS(eim);
827 }
828
829 evas_common_soft16_image_draw((Soft16_Image *) eim->cache_entry.src,
830 (Soft16_Image *) dst->cache_entry.src,
831 context,
832 src_region_x, src_region_y, src_region_w, src_region_h,
833 dst_region_x, dst_region_y, dst_region_w, dst_region_h,
834 smooth);
835
836 evas_common_cpu_end_opt ();
837 if (mustlock_im)
838 SDL_UnlockSurface(eim->surface);
839
840 if (mustlock_dst)
841 SDL_UnlockSurface(dst->surface);
842}
843
844static void
845evas_engine_sdl16_image_map_draw(void *data __UNUSED__, void *context __UNUSED__, void *surface __UNUSED__, void *image __UNUSED__, int npoints __UNUSED__, RGBA_Map_Point *p __UNUSED__, int smooth __UNUSED__, int level __UNUSED__)
846{
847}
848
849static void
850evas_engine_sdl16_image_scale_hint_set(void *data __UNUSED__, void *image __UNUSED__, int hint __UNUSED__)
851{
852}
853
854static int
855evas_engine_sdl16_image_scale_hint_get(void *data __UNUSED__, void *image __UNUSED__)
856{
857 return EVAS_IMAGE_SCALE_HINT_NONE;
858}
859
860
861static void
862evas_engine_sdl16_image_cache_flush(void *data)
863{
864 Render_Engine *re = (Render_Engine*) data;
865 int size;
866
867 size = evas_cache_engine_image_get(re->cache);
868 evas_cache_engine_image_set(re->cache, 0);
869 evas_cache_engine_image_set(re->cache, size);
870}
871
872static void
873evas_engine_sdl16_image_cache_set(void *data, int bytes)
874{
875 Render_Engine *re = (Render_Engine*) data;
876
877 evas_cache_engine_image_set(re->cache, bytes);
878}
879
880static int
881evas_engine_sdl16_image_cache_get(void *data)
882{
883 Render_Engine *re = (Render_Engine*) data;
884
885 return evas_cache_engine_image_get(re->cache);
886}
887
888static char*
889evas_engine_sdl16_image_comment_get(void *data __UNUSED__, void *image __UNUSED__, char *key __UNUSED__)
890{
891 return NULL;
892}
893
894static char*
895evas_engine_sdl16_image_format_get(void *data __UNUSED__, void *image __UNUSED__)
896{
897 /* FIXME: need to know what evas expect from this call */
898 return NULL;
899}
900
901static void
902evas_engine_sdl16_font_draw(void *data __UNUSED__, void *context, void *surface, void *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
903{
904 static RGBA_Image *im = NULL;
905 SDL_Engine_Image_Entry *eim = surface;
906 Soft16_Image *dst = (Soft16_Image *) eim->cache_entry.src;
907 int mustlock_im = 0;
908
909 if (eim->surface && SDL_MUSTLOCK(eim->surface))
910 {
911 mustlock_im = 1;
912 SDL_LockSurface(eim->surface);
913 _SDL_UPDATE_PIXELS(eim);
914 }
915 evas_common_draw_context_font_ext_set(context,
916 dst,
917 evas_common_soft16_font_glyph_new,
918 evas_common_soft16_font_glyph_free,
919 evas_common_soft16_font_glyph_draw);
920 evas_common_font_draw((RGBA_Image *) eim->cache_entry.src, context, font, x, y, intl_props);
921 evas_common_draw_context_font_ext_set(context,
922 NULL,
923 NULL,
924 NULL,
925 NULL);
926
927 if (mustlock_im)
928 SDL_UnlockSurface(eim->surface);
929}
930
931static void
932evas_engine_sdl16_line_draw(void *data __UNUSED__, void *context, void *surface, int x1, int y1, int x2, int y2)
933{
934 SDL_Engine_Image_Entry *eim = surface;
935 int mustlock_im = 0;
936
937 if (eim->surface && SDL_MUSTLOCK(eim->surface))
938 {
939 mustlock_im = 1;
940 SDL_LockSurface(eim->surface);
941 _SDL_UPDATE_PIXELS(eim);
942 }
943
944 evas_common_soft16_line_draw((Soft16_Image *) eim->cache_entry.src,
945 context,
946 x1, y1, x2, y2);
947 evas_common_cpu_end_opt();
948
949 if (mustlock_im)
950 SDL_UnlockSurface(eim->surface);
951}
952
953static void
954evas_engine_sdl16_rectangle_draw(void *data __UNUSED__, void *context, void *surface, int x, int y, int w, int h)
955{
956 SDL_Engine_Image_Entry *eim = surface;
957#if ENGINE_SDL_PRIMITIVE
958 RGBA_Draw_Context *dc = context;
959#endif
960 Soft16_Image *im;
961 int mustlock_im = 0;
962
963#if ENGINE_SDL_PRIMITIVE
964 if (A_VAL(&dc->col.col) != 0x00)
965 {
966 if (A_VAL(&dc->col.col) != 0xFF)
967 {
968#endif
969 if (eim->surface && SDL_MUSTLOCK(eim->surface))
970 {
971 mustlock_im = 1;
972 SDL_LockSurface(eim->surface);
973 _SDL_UPDATE_PIXELS(eim);
974 }
975
976 im = (Soft16_Image *) eim->cache_entry.src;
977
978 evas_common_soft16_rectangle_draw(im, context, x, y, w, h);
979 evas_common_cpu_end_opt();
980
981 if (mustlock_im)
982 SDL_UnlockSurface(eim->surface);
983#if ENGINE_SDL_PRIMITIVE
984 }
985 else
986 {
987 SDL_Rect dstrect;
988
989 if (dc->clip.use)
990 {
991 SDL_Rect cliprect;
992
993 cliprect.x = dc->clip.x;
994 cliprect.y = dc->clip.y;
995 cliprect.w = dc->clip.w;
996 cliprect.h = dc->clip.h;
997
998 SDL_SetClipRect(eim->surface, &cliprect);
999 }
1000
1001 dstrect.x = x;
1002 dstrect.y = y;
1003 dstrect.w = w;
1004 dstrect.h = h;
1005
1006 SDL_FillRect(eim->surface, &dstrect, SDL_MapRGBA(eim->surface->format, R_VAL(&dc->col.col), G_VAL(&dc->col.col), B_VAL(&dc->col.col), 0xFF));
1007
1008 if (dc->clip.use)
1009 SDL_SetClipRect(eim->surface, NULL);
1010 }
1011 }
1012#endif
1013}
1014
1015static void
1016evas_engine_sdl16_polygon_draw(void *data __UNUSED__, void *context, void *surface, void *polygon, int x, int y)
1017{
1018 SDL_Engine_Image_Entry *eim = surface;
1019 int mustlock_im = 0;
1020
1021 if (eim->surface && SDL_MUSTLOCK(eim->surface))
1022 {
1023 mustlock_im = 1;
1024 SDL_LockSurface(eim->surface);
1025 _SDL_UPDATE_PIXELS(eim);
1026 }
1027
1028 evas_common_soft16_polygon_draw((Soft16_Image *) eim->cache_entry.src, context, polygon, x, y);
1029 evas_common_cpu_end_opt();
1030
1031 if (mustlock_im)
1032 SDL_UnlockSurface(eim->surface);
1033}
1034
1035static void
1036evas_engine_sdl16_image_stride_get(void *data __UNUSED__, void *image, int *stride)
1037{
1038 SDL_Engine_Image_Entry *eim = image;
1039
1040 if (stride) *stride = 0;
1041 if (!image) return;
1042 if (stride) *stride = ((Soft16_Image*) eim->cache_entry.src)->stride;
1043}
1044
1045static Eina_Bool
1046evas_engine_sdl16_canvas_alpha_get(void *data __UNUSED__, void *context __UNUSED__)
1047{
1048 return EINA_FALSE;
1049}
1050
1051/* module advertising code */
1052static int
1053module_open(Evas_Module *em)
1054{
1055 if (!em) return 0;
1056 /* get whatever engine module we inherit from */
1057 if (!_evas_module_engine_inherit(&pfunc, "software_16")) return 0;
1058 _evas_engine_soft16_sdl_log_dom = eina_log_domain_register
1059 ("evas-software_16_sdl", EVAS_DEFAULT_LOG_COLOR);
1060 if (_evas_engine_soft16_sdl_log_dom < 0)
1061 {
1062 EINA_LOG_ERR("Can not create a module log domain.");
1063 return 0;
1064 }
1065
1066 /* store it for later use */
1067 func = pfunc;
1068 /* now to override methods */
1069#define ORD(f) EVAS_API_OVERRIDE(f, &func, evas_engine_sdl16_)
1070 ORD(info);
1071 ORD(info_free);
1072 ORD(setup);
1073 ORD(canvas_alpha_get);
1074 ORD(output_free);
1075 ORD(output_resize);
1076 ORD(output_tile_size_set);
1077 ORD(output_redraws_rect_add);
1078 ORD(output_redraws_rect_del);
1079 ORD(output_redraws_clear);
1080 ORD(output_redraws_next_update_get);
1081 ORD(output_redraws_next_update_push);
1082 ORD(output_flush);
1083 ORD(output_idle_flush);
1084 ORD(image_load);
1085 ORD(image_alpha_get);
1086 ORD(image_size_get);
1087 ORD(image_colorspace_get);
1088 ORD(image_colorspace_set);
1089 ORD(image_new_from_copied_data);
1090 ORD(image_new_from_data);
1091 ORD(image_free);
1092 ORD(image_size_set);
1093 ORD(image_dirty_region);
1094 ORD(image_data_get);
1095 ORD(image_data_put);
1096 ORD(image_data_preload_request);
1097 ORD(image_data_preload_cancel);
1098 ORD(image_alpha_set);
1099 ORD(image_border_set);
1100 ORD(image_border_get);
1101 ORD(image_draw);
1102 ORD(image_map_draw);
1103 ORD(image_cache_flush);
1104 ORD(image_cache_set);
1105 ORD(image_cache_get);
1106 ORD(image_comment_get);
1107 ORD(image_format_get);
1108 ORD(image_stride_get);
1109 ORD(font_draw);
1110 ORD(line_draw);
1111 ORD(rectangle_draw);
1112 ORD(polygon_draw);
1113
1114 ORD(image_scale_hint_set);
1115 ORD(image_scale_hint_get);
1116
1117 /* now advertise out own api */
1118 em->functions = (void *)(&func);
1119 return 1;
1120}
1121
1122static void
1123module_close(Evas_Module *em __UNUSED__)
1124{
1125 eina_log_domain_unregister(_evas_engine_soft16_sdl_log_dom);
1126}
1127
1128static Evas_Module_Api evas_modapi =
1129{
1130 EVAS_MODULE_API_VERSION,
1131 "software_16_sdl",
1132 "none",
1133 {
1134 module_open,
1135 module_close
1136 }
1137};
1138
1139EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_16_sdl);
1140
1141#ifndef EVAS_STATIC_BUILD_SOFTWARE_SDL
1142EVAS_EINA_MODULE_DEFINE(engine, software_16_sdl);
1143#endif
1144
1145static Engine_Image_Entry*
1146_sdl16_image_alloc(void)
1147{
1148 SDL_Engine_Image_Entry *new;
1149
1150 new = calloc(1, sizeof (SDL_Engine_Image_Entry));
1151
1152 return (Engine_Image_Entry *) new;
1153}
1154
1155static void
1156_sdl16_image_delete(Engine_Image_Entry *eim)
1157{
1158 free(eim);
1159}
1160
1161static int
1162_sdl16_image_constructor(Engine_Image_Entry *ie, void* data __UNUSED__)
1163{
1164 SDL_Surface *sdl = NULL;
1165 SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) ie;
1166 Soft16_Image *im;
1167
1168 im = (Soft16_Image *) ie->src;
1169
1170 if (im)
1171 {
1172 evas_cache_image_load_data(&im->cache_entry);
1173
1174 if (im->pixels)
1175 {
1176 /* FIXME: Take care of CSPACE */
1177 sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
1178 ie->w, ie->h,
1179 16, ie->w * 2,
1180 RMASK565, GMASK565, BMASK565, AMASK565);
1181 eim->surface = sdl;
1182 eim->flags.engine_surface = 0;
1183 }
1184 }
1185
1186 return EVAS_LOAD_ERROR_NONE;
1187}
1188
1189static void
1190_sdl16_image_destructor(Engine_Image_Entry *eim)
1191{
1192 SDL_Engine_Image_Entry *seie = (SDL_Engine_Image_Entry *) eim;
1193
1194 if (seie->surface && !seie->flags.engine_surface)
1195 SDL_FreeSurface(seie->surface);
1196 seie->surface = NULL;
1197}
1198
1199static void
1200_sdl16_image_dirty_region(Engine_Image_Entry *eim, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
1201{
1202 SDL_Engine_Image_Entry *dst;
1203 RGBA_Image *im;
1204
1205 dst = (SDL_Engine_Image_Entry *) eim;
1206
1207 SDL_UpdateRect(dst->surface, x, y, w, h);
1208
1209 im = (RGBA_Image *)eim->src;
1210 im->flags |= RGBA_IMAGE_IS_DIRTY;
1211}
1212
1213static int
1214_sdl16_image_dirty(Engine_Image_Entry *dst, const Engine_Image_Entry *src __UNUSED__)
1215{
1216 SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) dst;
1217 SDL_Surface *sdl = NULL;
1218 Soft16_Image *im;
1219
1220 im = (Soft16_Image *) dst->src;
1221
1222 /* FIXME: Take care of CSPACE */
1223 sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
1224 dst->w, dst->h,
1225 16, dst->w * 2,
1226 RMASK565, GMASK565, BMASK565, AMASK565);
1227 eim->surface = sdl;
1228 eim->flags.engine_surface = 0;
1229
1230 return 0;
1231}
1232
1233static int
1234_sdl16_image_size_set(Engine_Image_Entry *dst, const Engine_Image_Entry *src __UNUSED__)
1235{
1236 SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) dst;
1237 SDL_Surface *sdl;
1238 Soft16_Image *im;
1239
1240 im = (Soft16_Image *) dst->src;
1241
1242 /* FIXME: handle im == NULL */
1243 sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
1244 dst->w, dst->h,
1245 16, dst->w * 2,
1246 RMASK565, GMASK565, BMASK565, AMASK565);
1247
1248 eim->surface = sdl;
1249
1250 return 0;
1251}
1252
1253static int
1254_sdl16_image_update_data(Engine_Image_Entry* dst, void* engine_data)
1255{
1256 SDL_Engine_Image_Entry *eim = (SDL_Engine_Image_Entry *) dst;
1257 SDL_Surface *sdl = NULL;
1258 Soft16_Image *im;
1259
1260 im = (Soft16_Image *) dst->src;
1261
1262 if (engine_data)
1263 {
1264 sdl = engine_data;
1265
1266 if (im)
1267 {
1268 im->pixels = sdl->pixels;
1269 im->stride = sdl->pitch / 2;
1270 im->flags.free_pixels = 0;
1271/* im->alpha = calloc(1, sizeof (DATA8) * _calc_stride(sdl->w) * sdl->h); */
1272/* im->flags.free_alpha = 0; */
1273/* im->flags.have_alpha = 1; */
1274 im->alpha = NULL;
1275 im->flags.free_alpha = 0;
1276 im->cache_entry.flags.alpha = 0;
1277
1278 dst->src->w = sdl->w;
1279 dst->src->h = sdl->h;
1280 }
1281 dst->w = sdl->w;
1282 dst->h = sdl->h;
1283 }
1284 else
1285 {
1286 SDL_FreeSurface(eim->surface);
1287 /* FIXME: Take care of CSPACE */
1288 sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
1289 dst->w, dst->h,
1290 16, dst->w * 2,
1291 RMASK565, GMASK565, BMASK565, AMASK565);
1292 }
1293
1294 eim->surface = sdl;
1295
1296 return 0;
1297}
1298
1299static void
1300_sdl16_image_load(Engine_Image_Entry *eim, const Image_Entry* ie_im)
1301{
1302 SDL_Engine_Image_Entry *load = (SDL_Engine_Image_Entry *) eim;
1303 SDL_Surface *sdl;
1304
1305 if (!load->surface)
1306 {
1307 Soft16_Image *im;
1308
1309 im = (Soft16_Image *) ie_im;
1310
1311 sdl = SDL_CreateRGBSurfaceFrom(im->pixels,
1312 eim->w, eim->h,
1313 16, eim->w * 2,
1314 RMASK565, GMASK565, BMASK565, AMASK565);
1315 load->surface = sdl;
1316 }
1317}
1318
1319static int
1320_sdl16_image_mem_size_get(Engine_Image_Entry *eim)
1321{
1322 SDL_Engine_Image_Entry *seie = (SDL_Engine_Image_Entry *) eim;
1323 int size = 0;
1324
1325 /* FIXME: Count surface size. */
1326 if (seie->surface)
1327 size = sizeof (SDL_Surface) + sizeof (SDL_PixelFormat);
1328
1329 return size;
1330}
1331
1332#ifdef DEBUG_SDL
1333static void
1334_sdl16_image_debug(const char* context, Engine_Image_Entry* im)
1335{
1336}
1337#endif