aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/gl_cocoa/evas_engine.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/gl_cocoa/evas_engine.c')
-rw-r--r--libraries/evas/src/modules/engines/gl_cocoa/evas_engine.c1462
1 files changed, 1462 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/gl_cocoa/evas_engine.c b/libraries/evas/src/modules/engines/gl_cocoa/evas_engine.c
new file mode 100644
index 0000000..fd95688
--- /dev/null
+++ b/libraries/evas/src/modules/engines/gl_cocoa/evas_engine.c
@@ -0,0 +1,1462 @@
1#include "evas_common.h" /* Also includes international specific stuff */
2#include "evas_engine.h"
3
4#include "evas_private.h"
5
6#include <dlfcn.h> /* dlopen,dlclose,etc */
7#define EVAS_GL_NO_GL_H_CHECK 1
8#include "Evas_GL.h"
9
10
11
12typedef struct _Render_Engine Render_Engine;
13typedef struct _Render_Engine_GL_Surface Render_Engine_GL_Surface;
14typedef struct _Render_Engine_GL_Context Render_Engine_GL_Context;
15
16struct _Render_Engine
17{
18 Evas_GL_Cocoa_Window *win;
19 int end;
20};
21
22
23struct _Render_Engine_GL_Surface
24{
25 int initialized;
26 int fbo_attached;
27 int w, h;
28 int depth_bits;
29 int stencil_bits;
30
31 // Render target texture/buffers
32 GLuint rt_tex;
33 GLint rt_internal_fmt;
34 GLenum rt_fmt;
35 GLuint rb_depth;
36 GLenum rb_depth_fmt;
37 GLuint rb_stencil;
38 GLenum rb_stencil_fmt;
39
40 Render_Engine_GL_Context *current_ctx;
41};
42
43struct _Render_Engine_GL_Context
44{
45 int initialized;
46 // EGLContext context;
47
48 GLuint fbo;
49
50 Render_Engine_GL_Surface *current_sfc;
51};
52
53
54int _evas_engine_gl_cocoa_log_dom = -1;
55/* function tables - filled in later (func and parent func) */
56static Evas_Func func, pfunc;
57
58/* Function table for GL APIs */
59static Evas_GL_API gl_funcs;
60
61
62
63static void *
64eng_info(Evas *e __UNUSED__)
65{
66 Evas_Engine_Info_GL_Cocoa *info;
67 info = calloc(1, sizeof(Evas_Engine_Info_GL_Cocoa));
68 DBG("Info %p", info);
69 if (!info) return NULL;
70 info->magic.magic = rand();
71 return info;
72}
73
74static void
75eng_info_free(Evas *e __UNUSED__, void *info)
76{
77 Evas_Engine_Info_GL_Cocoa *in;
78
79 DBG("Info %p", info);
80 eina_log_domain_unregister(_evas_engine_gl_cocoa_log_dom);
81 in = (Evas_Engine_Info_GL_Cocoa *)info;
82 free(in);
83}
84
85static int
86eng_setup(Evas *e, void *in)
87{
88 Render_Engine *re;
89 Evas_Engine_Info_GL_Cocoa *info;
90
91 DBG("Engine Setup");
92
93 info = (Evas_Engine_Info_GL_Cocoa *)in;
94 if (!e->engine.data.output)
95 {
96 re = calloc(1, sizeof(Render_Engine));
97 if (!re) return 0;
98
99 e->engine.data.output = re;
100 re->win = eng_window_new(info->window,
101 e->output.w,
102 e->output.h);
103 info->view = re->win->view;
104 if (!re->win)
105 {
106 free(re);
107 e->engine.data.output = NULL;
108 return 0;
109 }
110
111 evas_common_cpu_init();
112
113 evas_common_blend_init();
114 evas_common_image_init();
115 evas_common_convert_init();
116 evas_common_scale_init();
117 evas_common_rectangle_init();
118 evas_common_polygon_init();
119 evas_common_line_init();
120 evas_common_font_init();
121 evas_common_draw_init();
122 evas_common_tilebuf_init();
123 }
124 else
125 {
126 re = e->engine.data.output;
127 eng_window_free(re->win);
128 re->win = eng_window_new(info->window,
129 e->output.w,
130 e->output.h);
131 info->view = re->win->view;
132 }
133 if (!e->engine.data.output) return 0;
134
135 if (!e->engine.data.context)
136 e->engine.data.context =
137 e->engine.func->context_new(e->engine.data.output);
138 eng_window_use(re->win);
139
140 return 1;
141}
142
143static void
144eng_output_free(void *data)
145{
146 Render_Engine *re;
147
148 DBG("Output free");
149 re = (Render_Engine *)data;
150 eng_window_free(re->win);
151 free(re);
152
153 evas_common_font_shutdown();
154 evas_common_image_shutdown();
155}
156
157static void
158eng_output_resize(void *data, int w, int h)
159{
160 Render_Engine *re;
161
162 DBG("Output Resize %d %d", w, h);
163
164 re = (Render_Engine *)data;
165 re->win->width = w;
166 re->win->height = h;
167
168 eng_window_resize(re->win, w, h);
169 evas_gl_common_context_resize(re->win->gl_context, w, h, 0);
170}
171
172static void
173eng_output_tile_size_set(void *data __UNUSED__, int w __UNUSED__, int h __UNUSED__)
174{
175 DBG("tile size set");
176}
177
178static void
179eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
180{
181 Render_Engine *re;
182
183 DBG("Redraw rect %d %d %d %d", x, y, w, h);
184 re = (Render_Engine *)data;
185 evas_gl_common_context_resize(re->win->gl_context, re->win->width, re->win->height, 0);
186 /* simple bounding box */
187 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->width, re->win->height);
188 if ((w <= 0) || (h <= 0)) return;
189 if (!re->win->draw.redraw)
190 {
191#if 0
192 re->win->draw.x1 = x;
193 re->win->draw.y1 = y;
194 re->win->draw.x2 = x + w - 1;
195 re->win->draw.y2 = y + h - 1;
196#else
197 re->win->draw.x1 = 0;
198 re->win->draw.y1 = 0;
199 re->win->draw.x2 = re->win->width - 1;
200 re->win->draw.y2 = re->win->height - 1;
201#endif
202 }
203 else
204 {
205 if (x < re->win->draw.x1) re->win->draw.x1 = x;
206 if (y < re->win->draw.y1) re->win->draw.y1 = y;
207 if ((x + w - 1) > re->win->draw.x2) re->win->draw.x2 = x + w - 1;
208 if ((y + h - 1) > re->win->draw.y2) re->win->draw.y2 = y + h - 1;
209 }
210 re->win->draw.redraw = 1;
211}
212
213static void
214eng_output_redraws_rect_del(void *data __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
215{
216}
217
218static void
219eng_output_redraws_clear(void *data)
220{
221 Render_Engine *re;
222
223 re = (Render_Engine *)data;
224 re->win->draw.redraw = 0;
225}
226
227//#define SLOW_GL_COPY_RECT 1
228/* vsync games - not for now though */
229#define VSYNC_TO_SCREEN 1
230
231static void *
232eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
233{
234 Render_Engine *re;
235
236 re = (Render_Engine *)data;
237 evas_gl_common_context_flush(re->win->gl_context);
238 /* get the upate rect surface - return engine data as dummy */
239 if (!re->win->draw.redraw)
240 {
241// printf("GL: NO updates!\n");
242 return NULL;
243 }
244// printf("GL: update....!\n");
245#ifdef SLOW_GL_COPY_RECT
246 /* if any update - just return the whole canvas - works with swap
247 * buffers then */
248 if (x) *x = 0;
249 if (y) *y = 0;
250 if (w) *w = re->win->width;
251 if (h) *h = re->win->height;
252 if (cx) *cx = 0;
253 if (cy) *cy = 0;
254 if (cw) *cw = re->win->width;
255 if (ch) *ch = re->win->height;
256#else
257 /* 1 update - INCREDIBLY SLOW if combined with swap_rect in flush. a gl
258 * problem where there just is no hardware path for somethnig that
259 * obviously SHOULD be there */
260 /* only 1 update to minimise gl context games and rendering multiple update
261 * regions as evas does with other engines
262 */
263 if (x) *x = re->win->draw.x1;
264 if (y) *y = re->win->draw.y1;
265 if (w) *w = re->win->draw.x2 - re->win->draw.x1 + 1;
266 if (h) *h = re->win->draw.y2 - re->win->draw.y1 + 1;
267 if (cx) *cx = re->win->draw.x1;
268 if (cy) *cy = re->win->draw.y1;
269 if (cw) *cw = re->win->draw.x2 - re->win->draw.x1 + 1;
270 if (ch) *ch = re->win->draw.y2 - re->win->draw.y1 + 1;
271#endif
272// clear buffer. only needed for dest alpha
273// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
274// glClear(GL_COLOR_BUFFER_BIT);
275//x// printf("frame -> new\n");
276 return re->win->gl_context->def_surface;
277}
278
279static void
280eng_output_redraws_next_update_push(void *data, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
281{
282 Render_Engine *re;
283
284 re = (Render_Engine *)data;
285 /* put back update surface.. in this case just unflag redraw */
286 re->win->draw.redraw = 0;
287 re->win->draw.drew = 1;
288 evas_gl_common_context_flush(re->win->gl_context);
289}
290
291static void
292eng_output_flush(void *data)
293{
294 Render_Engine *re;
295
296 re = (Render_Engine *)data;
297 if (!re->win->draw.drew) return;
298
299 re->win->draw.drew = 0;
300 eng_window_use(re->win);
301
302#ifdef VSYNC_TO_SCREEN
303 eng_window_vsync_set(1);
304#endif
305
306 eng_window_swap_buffers(re->win);
307
308}
309
310static void
311eng_output_idle_flush(void *data __UNUSED__)
312{
313}
314
315static void
316eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
317{
318 evas_common_draw_context_add_cutout(context, x, y, w, h);
319}
320
321static void
322eng_context_cutout_clear(void *data __UNUSED__, void *context)
323{
324 evas_common_draw_context_clear_cutouts(context);
325}
326
327static void
328eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
329{
330 Render_Engine *re;
331
332 re = (Render_Engine *)data;
333 eng_window_use(re->win);
334 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
335 re->win->gl_context->dc = context;
336 evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h);
337}
338
339static void
340eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
341{
342 Render_Engine *re;
343
344 re = (Render_Engine *)data;
345 eng_window_use(re->win);
346 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
347 re->win->gl_context->dc = context;
348 evas_gl_common_line_draw(re->win->gl_context, x1, y1, x2, y2);
349}
350
351static void *
352eng_polygon_point_add(void *data, void *context __UNUSED__, void *polygon, int x, int y)
353{
354 Render_Engine *re;
355
356 re = (Render_Engine *)data;
357 return evas_gl_common_poly_point_add(polygon, x, y);
358}
359
360static void *
361eng_polygon_points_clear(void *data, void *context __UNUSED__, void *polygon)
362{
363 Render_Engine *re;
364
365 re = (Render_Engine *)data;
366 return evas_gl_common_poly_points_clear(polygon);
367}
368
369static void
370eng_polygon_draw(void *data, void *context, void *surface __UNUSED__, void *polygon, int x, int y)
371{
372 Render_Engine *re;
373
374 re = (Render_Engine *)data;
375 eng_window_use(re->win);
376 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
377 re->win->gl_context->dc = context;
378 evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y);
379}
380
381static int
382eng_image_alpha_get(void *data __UNUSED__, void *image)
383{
384// Render_Engine *re;
385 Evas_GL_Image *im;
386
387// re = (Render_Engine *)data;
388 if (!image) return 1;
389 im = image;
390 return im->alpha;
391}
392
393static int
394eng_image_colorspace_get(void *data __UNUSED__, void *image)
395{
396// Render_Engine *re;
397 Evas_GL_Image *im;
398
399// re = (Render_Engine *)data;
400 if (!image) return EVAS_COLORSPACE_ARGB8888;
401 im = image;
402 return im->cs.space;
403}
404
405static void
406eng_image_mask_create(void *data __UNUSED__, void *image)
407{
408 Evas_GL_Image *im;
409
410 if (!image) return;
411 im = image;
412 if (!im->im->image.data)
413 evas_cache_image_load_data(&im->im->cache_entry);
414 if (!im->tex)
415 im->tex = evas_gl_common_texture_new(im->gc, im->im);
416}
417
418
419static void *
420eng_image_alpha_set(void *data, void *image, int has_alpha)
421{
422 Render_Engine *re;
423 Evas_GL_Image *im;
424
425 re = (Render_Engine *)data;
426 if (!image) return NULL;
427 im = image;
428 if (im->alpha == has_alpha) return image;
429 if (im->native.data)
430 {
431 im->alpha = has_alpha;
432 return image;
433 }
434 eng_window_use(re->win);
435 if ((im->tex) && (im->tex->pt->dyn.img))
436 {
437 im->alpha = has_alpha;
438 im->tex->alpha = im->alpha;
439 return image;
440 }
441 /* FIXME: can move to gl_common */
442 if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
443 if ((has_alpha) && (im->im->cache_entry.flags.alpha)) return image;
444 else if ((!has_alpha) && (!im->im->cache_entry.flags.alpha)) return image;
445 if (im->references > 1)
446 {
447 Evas_GL_Image *im_new;
448
449 im_new = evas_gl_common_image_new_from_copied_data
450 (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
451 im->im->image.data,
452 eng_image_alpha_get(data, image),
453 eng_image_colorspace_get(data, image));
454 if (!im_new) return im;
455 evas_gl_common_image_free(im);
456 im = im_new;
457 }
458 else
459 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
460 return evas_gl_common_image_alpha_set(im, has_alpha ? 1 : 0);
461// im->im->cache_entry.flags.alpha = has_alpha ? 1 : 0;
462// return image;
463}
464
465static void *
466eng_image_border_set(void *data __UNUSED__, void *image, int l __UNUSED__, int r __UNUSED__, int t __UNUSED__, int b __UNUSED__)
467{
468// Render_Engine *re;
469//
470// re = (Render_Engine *)data;
471 return image;
472}
473
474static void
475eng_image_border_get(void *data __UNUSED__, void *image __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
476{
477// Render_Engine *re;
478//
479// re = (Render_Engine *)data;
480}
481
482static char *
483eng_image_comment_get(void *data __UNUSED__, void *image, char *key __UNUSED__)
484{
485// Render_Engine *re;
486 Evas_GL_Image *im;
487
488// re = (Render_Engine *)data;
489 if (!image) return NULL;
490 im = image;
491 if (!im->im) return NULL;
492 return im->im->info.comment;
493}
494
495static char *
496eng_image_format_get(void *data __UNUSED__, void *image)
497{
498// Render_Engine *re;
499 Evas_GL_Image *im;
500
501// re = (Render_Engine *)data;
502 im = image;
503 return NULL;
504}
505
506static void
507eng_image_colorspace_set(void *data, void *image, int cspace)
508{
509 Render_Engine *re;
510 Evas_GL_Image *im;
511
512 re = (Render_Engine *)data;
513 if (!image) return;
514 im = image;
515 if (im->native.data) return;
516 /* FIXME: can move to gl_common */
517 if (im->cs.space == cspace) return;
518 eng_window_use(re->win);
519 evas_cache_image_colorspace(&im->im->cache_entry, cspace);
520 switch (cspace)
521 {
522 case EVAS_COLORSPACE_ARGB8888:
523 if (im->cs.data)
524 {
525 if (!im->cs.no_free) free(im->cs.data);
526 im->cs.data = NULL;
527 im->cs.no_free = 0;
528 }
529 break;
530 case EVAS_COLORSPACE_YCBCR422P601_PL:
531 case EVAS_COLORSPACE_YCBCR422P709_PL:
532 if (im->tex) evas_gl_common_texture_free(im->tex);
533 im->tex = NULL;
534 if (im->cs.data)
535 {
536 if (!im->cs.no_free) free(im->cs.data);
537 }
538 if (im->im->cache_entry.h > 0)
539 im->cs.data =
540 calloc(1, im->im->cache_entry.h * sizeof(unsigned char *) * 2);
541 else
542 im->cs.data = NULL;
543 im->cs.no_free = 0;
544 break;
545 default:
546 abort();
547 break;
548 }
549 im->cs.space = cspace;
550}
551
552/////////////////////////////////////////////////////////////////////////
553//
554//
555
556// FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
557// (i am sure this is the reason) not to mention seemingly superfluous. but
558// i need to enable it for it to work on fglrx at least. havent tried nvidia.
559//
560// why is this the case? does anyone know? has anyone tried it on other gfx
561// drivers?
562//
563//#define GLX_TEX_PIXMAP_RECREATE 1
564#if 0
565static void
566eng_image_draw_filtered(void *data, void *context, void *surface,
567 void *image, Evas_Filter_Info *filter)
568{
569 Render_Engine *re = data;
570
571 if (!image) return;
572 eng_window_use(re->win);
573 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
574 re->win->gl_context->dc = context;
575
576 evas_gl_common_filter_draw(re->win->gl_context, image, filter);
577}
578
579static Filtered_Image *
580eng_image_filtered_get(void *im, uint8_t *key, size_t keylen)
581{
582 return evas_gl_common_image_filtered_get(im, key, keylen);
583}
584
585static Filtered_Image *
586eng_image_filtered_save(void *im, void *fim, uint8_t *key, size_t keylen)
587{
588 return evas_gl_common_image_filtered_save(im, fim, key, keylen);
589}
590
591static void
592eng_image_filtered_free(void *im, Filtered_Image *fim)
593{
594 evas_gl_common_image_filtered_free(im, fim);
595}
596
597#endif
598
599//
600//
601/////////////////////////////////////////////////////////////////////////
602
603static void *
604eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
605{
606 Render_Engine *re;
607
608 re = (Render_Engine *)data;
609 *error = EVAS_LOAD_ERROR_NONE;
610 eng_window_use(re->win);
611 return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error);
612}
613
614static void *
615eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
616{
617 Render_Engine *re;
618
619 re = (Render_Engine *)data;
620 eng_window_use(re->win);
621 return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace);
622}
623
624static void *
625eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
626{
627 Render_Engine *re;
628
629 re = (Render_Engine *)data;
630 eng_window_use(re->win);
631 return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace);
632}
633
634static void
635eng_image_free(void *data, void *image)
636{
637 Render_Engine *re;
638
639 re = (Render_Engine *)data;
640 if (!image) return;
641 eng_window_use(re->win);
642 evas_gl_common_image_free(image);
643}
644
645static void
646eng_image_size_get(void *data __UNUSED__, void *image, int *w, int *h)
647{
648 if (!image)
649 {
650 *w = 0;
651 *h = 0;
652 return;
653 }
654 if (w) *w = ((Evas_GL_Image *)image)->w;
655 if (h) *h = ((Evas_GL_Image *)image)->h;
656}
657
658static void *
659eng_image_size_set(void *data, void *image, int w, int h)
660{
661 Render_Engine *re;
662 Evas_GL_Image *im = image;
663 Evas_GL_Image *im_old;
664
665 re = (Render_Engine *)data;
666 if (!im) return NULL;
667 if (im->native.data)
668 {
669 im->w = w;
670 im->h = h;
671 return image;
672 }
673 eng_window_use(re->win);
674 if ((im->tex) && (im->tex->pt->dyn.img))
675 {
676 evas_gl_common_texture_free(im->tex);
677 im->tex = NULL;
678 im->w = w;
679 im->h = h;
680 im->tex = evas_gl_common_texture_dynamic_new(im->gc, im);
681 return image;
682 }
683 im_old = image;
684 if ((eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P601_PL) ||
685 (eng_image_colorspace_get(data, image) == EVAS_COLORSPACE_YCBCR422P709_PL))
686 w &= ~0x1;
687 if ((im_old) &&
688 ((int)im_old->im->cache_entry.w == w) &&
689 ((int)im_old->im->cache_entry.h == h))
690 return image;
691 if (im_old)
692 {
693 im = evas_gl_common_image_new(re->win->gl_context, w, h,
694 eng_image_alpha_get(data, image),
695 eng_image_colorspace_get(data, image));
696/*
697 evas_common_load_image_data_from_file(im_old->im);
698 if (im_old->im->image->data)
699 {
700 evas_common_blit_rectangle(im_old->im, im->im, 0, 0, w, h, 0, 0);
701 evas_common_cpu_end_opt();
702 }
703 */
704 evas_gl_common_image_free(im_old);
705 }
706 else
707 im = evas_gl_common_image_new(re->win->gl_context, w, h, 1, EVAS_COLORSPACE_ARGB8888);
708 return im;
709}
710
711static void *
712eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
713{
714 Render_Engine *re;
715 Evas_GL_Image *im = image;
716
717 re = (Render_Engine *)data;
718 if (!image) return NULL;
719 if (im->native.data) return image;
720 eng_window_use(re->win);
721 evas_gl_common_image_dirty(image, x, y, w, h);
722 return image;
723}
724
725static void *
726eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, int *err)
727{
728 Render_Engine *re;
729 Evas_GL_Image *im;
730 int error;
731
732 re = (Render_Engine *)data;
733 if (!image)
734 {
735 *image_data = NULL;
736 if (err) *err = EVAS_LOAD_ERROR_GENERIC;
737 return NULL;
738 }
739 im = image;
740 if (im->native.data)
741 {
742 *image_data = NULL;
743 if (err) *err = EVAS_LOAD_ERROR_NONE;
744 return im;
745 }
746 if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
747 {
748 *image_data = im->tex->pt->dyn.data;
749 if (err) *err = EVAS_LOAD_ERROR_NONE;
750 return im;
751 }
752 eng_window_use(re->win);
753 error = evas_cache_image_load_data(&im->im->cache_entry);
754 switch (im->cs.space)
755 {
756 case EVAS_COLORSPACE_ARGB8888:
757 if (to_write)
758 {
759 if (im->references > 1)
760 {
761 Evas_GL_Image *im_new;
762
763 im_new = evas_gl_common_image_new_from_copied_data
764 (im->gc, im->im->cache_entry.w, im->im->cache_entry.h,
765 im->im->image.data,
766 eng_image_alpha_get(data, image),
767 eng_image_colorspace_get(data, image));
768 if (!im_new)
769 {
770 *image_data = NULL;
771 if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
772 return im;
773 }
774 evas_gl_common_image_free(im);
775 im = im_new;
776 }
777 else
778 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
779 }
780 *image_data = im->im->image.data;
781 break;
782 case EVAS_COLORSPACE_YCBCR422P601_PL:
783 case EVAS_COLORSPACE_YCBCR422P709_PL:
784 *image_data = im->cs.data;
785 break;
786 default:
787 abort();
788 break;
789 }
790 if (err) *err = error;
791 return im;
792}
793
794static void *
795eng_image_data_put(void *data, void *image, DATA32 *image_data)
796{
797 Render_Engine *re;
798 Evas_GL_Image *im, *im2;
799
800 re = (Render_Engine *)data;
801 if (!image) return NULL;
802 im = image;
803 if (im->native.data) return image;
804 eng_window_use(re->win);
805 if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data))
806 {
807 if (im->tex->pt->dyn.data == image_data)
808 {
809 return image;
810 }
811 else
812 {
813 int w, h;
814
815 w = im->im->cache_entry.w;
816 h = im->im->cache_entry.h;
817 im2 = eng_image_new_from_data(data, w, h, image_data,
818 eng_image_alpha_get(data, image),
819 eng_image_colorspace_get(data, image));
820 if (!im2) return im;
821 evas_gl_common_image_free(im);
822 im = im2;
823 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
824 return im;
825 }
826 }
827 switch (im->cs.space)
828 {
829 case EVAS_COLORSPACE_ARGB8888:
830 if (image_data != im->im->image.data)
831 {
832 int w, h;
833
834 w = im->im->cache_entry.w;
835 h = im->im->cache_entry.h;
836 im2 = eng_image_new_from_data(data, w, h, image_data,
837 eng_image_alpha_get(data, image),
838 eng_image_colorspace_get(data, image));
839 if (!im2) return im;
840 evas_gl_common_image_free(im);
841 im = im2;
842 }
843 break;
844 case EVAS_COLORSPACE_YCBCR422P601_PL:
845 case EVAS_COLORSPACE_YCBCR422P709_PL:
846 if (image_data != im->cs.data)
847 {
848 if (im->cs.data)
849 {
850 if (!im->cs.no_free) free(im->cs.data);
851 }
852 im->cs.data = image_data;
853 }
854 break;
855 default:
856 abort();
857 break;
858 }
859 /* hmmm - but if we wrote... why bother? */
860 evas_gl_common_image_dirty(im, 0, 0, 0, 0);
861 return im;
862}
863
864static void
865eng_image_data_preload_request(void *data __UNUSED__, void *image, const void *target)
866{
867 Evas_GL_Image *gim = image;
868 RGBA_Image *im;
869
870 if (!gim) return;
871 if (gim->native.data) return;
872 im = (RGBA_Image *)gim->im;
873 if (!im) return;
874 evas_cache_image_preload_data(&im->cache_entry, target);
875}
876
877static void
878eng_image_data_preload_cancel(void *data __UNUSED__, void *image, const void *target)
879{
880 Evas_GL_Image *gim = image;
881 RGBA_Image *im;
882
883 if (!gim) return;
884 if (gim->native.data) return;
885 im = (RGBA_Image *)gim->im;
886 if (!im) return;
887 evas_cache_image_preload_cancel(&im->cache_entry, target);
888}
889
890static void
891eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
892{
893 Render_Engine *re;
894
895 re = (Render_Engine *)data;
896 if (!image) return;
897 eng_window_use(re->win);
898 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
899 re->win->gl_context->dc = context;
900 evas_gl_common_image_draw(re->win->gl_context, image,
901 src_x, src_y, src_w, src_h,
902 dst_x, dst_y, dst_w, dst_h,
903 smooth);
904}
905
906static void
907eng_image_scale_hint_set(void *data __UNUSED__, void *image, int hint)
908{
909 if (image) evas_gl_common_image_scale_hint_set(image, hint);
910}
911
912static int
913eng_image_scale_hint_get(void *data __UNUSED__, void *image)
914{
915 Evas_GL_Image *gim = image;
916 if (!gim) return EVAS_IMAGE_SCALE_HINT_NONE;
917 return gim->scale_hint;
918}
919
920static void
921eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
922{
923 Evas_GL_Image *gim = image;
924 Render_Engine *re;
925
926 re = (Render_Engine *)data;
927 if (!image) return;
928 eng_window_use(re->win);
929 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
930 re->win->gl_context->dc = context;
931 if (npoints != 4)
932 {
933 // FIXME: nash - you didnt fix this
934 abort();
935 }
936 if ((p[0].x == p[3].x) &&
937 (p[1].x == p[2].x) &&
938 (p[0].y == p[1].y) &&
939 (p[3].y == p[2].y) &&
940 (p[0].x <= p[1].x) &&
941 (p[0].y <= p[2].y) &&
942 (p[0].u == 0) &&
943 (p[0].v == 0) &&
944 (p[1].u == (gim->w << FP)) &&
945 (p[1].v == 0) &&
946 (p[2].u == (gim->w << FP)) &&
947 (p[2].v == (gim->h << FP)) &&
948 (p[3].u == 0) &&
949 (p[3].v == (gim->h << FP)) &&
950 (p[0].col == 0xffffffff) &&
951 (p[1].col == 0xffffffff) &&
952 (p[2].col == 0xffffffff) &&
953 (p[3].col == 0xffffffff))
954 {
955 int dx, dy, dw, dh;
956
957 dx = p[0].x >> FP;
958 dy = p[0].y >> FP;
959 dw = (p[2].x >> FP) - dx;
960 dh = (p[2].y >> FP) - dy;
961 eng_image_draw(data, context, surface, image,
962 0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
963 }
964 else
965 {
966 evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
967 smooth, level);
968 }
969}
970
971static void *
972eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha)
973{
974 Render_Engine *re;
975
976 re = (Render_Engine *)data;
977 return evas_gl_common_image_surface_new(re->win->gl_context, w, h, alpha);
978}
979
980static void
981eng_image_map_surface_free(void *data __UNUSED__, void *surface)
982{
983 evas_gl_common_image_free(surface);
984}
985
986static void
987eng_image_content_hint_set(void *data __UNUSED__, void *image, int hint)
988{
989 if (image) evas_gl_common_image_content_hint_set(image, hint);
990}
991
992static int
993eng_image_content_hint_get(void *data __UNUSED__, void *image)
994{
995 Evas_GL_Image *gim = image;
996 if (!gim) return EVAS_IMAGE_CONTENT_HINT_NONE;
997 return gim->content_hint;
998}
999
1000static void
1001eng_image_cache_flush(void *data __UNUSED__)
1002{
1003 Render_Engine *re;
1004 int tmp_size;
1005
1006 re = (Render_Engine *)data;
1007
1008 tmp_size = evas_common_image_get_cache();
1009 evas_common_image_set_cache(0);
1010 evas_common_rgba_image_scalecache_flush();
1011 evas_gl_common_image_cache_flush(re->win->gl_context);
1012 evas_common_image_set_cache(tmp_size);
1013}
1014
1015static void
1016eng_image_cache_set(void *data __UNUSED__, int bytes)
1017{
1018 Render_Engine *re;
1019
1020 re = (Render_Engine *)data;
1021 evas_common_image_set_cache(bytes);
1022 evas_common_rgba_image_scalecache_size_set(bytes);
1023 evas_gl_common_image_cache_flush(re->win->gl_context);
1024}
1025
1026static int
1027eng_image_cache_get(void *data __UNUSED__)
1028{
1029 Render_Engine *re;
1030
1031 re = (Render_Engine *)data;
1032 return evas_common_image_get_cache();
1033}
1034
1035
1036static void
1037eng_image_stride_get(void *data __UNUSED__, void *image, int *stride)
1038{
1039 Evas_GL_Image *im = image;
1040 *stride = im->w * 4;
1041 if ((im->tex) && (im->tex->pt->dyn.img))
1042 {
1043 *stride = im->tex->pt->dyn.w * 4;
1044 // FIXME: for other image formats (yuv etc.) different stride needed
1045 }
1046}
1047
1048static void
1049eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w __UNUSED__, int h __UNUSED__, int ow __UNUSED__, int oh __UNUSED__, const Evas_Text_Props *intl_props)
1050{
1051 Render_Engine *re;
1052
1053 re = (Render_Engine *)data;
1054 eng_window_use(re->win);
1055 evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
1056 re->win->gl_context->dc = context;
1057 {
1058 // FIXME: put im into context so we can free it
1059 static RGBA_Image *im = NULL;
1060
1061 if (!im)
1062 im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
1063 im->cache_entry.w = re->win->width;
1064 im->cache_entry.h = re->win->height;
1065 evas_common_draw_context_font_ext_set(context,
1066 re->win->gl_context,
1067 evas_gl_font_texture_new,
1068 evas_gl_font_texture_free,
1069 evas_gl_font_texture_draw);
1070 evas_common_font_draw(im, context, (RGBA_Font *) font, x, y,
1071 intl_props);
1072 evas_common_draw_context_font_ext_set(context,
1073 NULL,
1074 NULL,
1075 NULL,
1076 NULL);
1077 }
1078}
1079
1080
1081static Eina_Bool
1082eng_canvas_alpha_get(void *data __UNUSED__, void *info __UNUSED__)
1083{
1084 // FIXME: support ARGB gl targets!!!
1085 return EINA_FALSE;
1086}
1087
1088
1089#if 1
1090static void
1091evgl_glBindFramebuffer(GLenum target, GLuint framebuffer)
1092{
1093 // Add logic to take care when framebuffer=0
1094 glBindFramebuffer(target, framebuffer);
1095}
1096
1097static void
1098evgl_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
1099{
1100 // Add logic to take care when renderbuffer=0
1101 glBindRenderbuffer(target, renderbuffer);
1102}
1103
1104static void
1105evgl_glClearDepthf(GLclampf depth)
1106{
1107#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1108 glClearDepthf(depth);
1109#else
1110 glClearDepth(depth);
1111#endif
1112}
1113
1114static void
1115evgl_glDepthRangef(GLclampf zNear, GLclampf zFar)
1116{
1117#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1118 glDepthRangef(zNear, zFar);
1119#else
1120 glDepthRange(zNear, zFar);
1121#endif
1122}
1123
1124static void
1125evgl_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
1126{
1127#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1128 glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1129#else
1130 if (range)
1131 {
1132 range[0] = -126; // floor(log2(FLT_MIN))
1133 range[1] = 127; // floor(log2(FLT_MAX))
1134 }
1135 if (precision)
1136 {
1137 precision[0] = 24; // floor(-log2((1.0/16777218.0)));
1138 }
1139 return;
1140 shadertype = precisiontype = 0;
1141#endif
1142}
1143
1144static void
1145evgl_glReleaseShaderCompiler(void)
1146{
1147#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1148 glReleaseShaderCompiler();
1149#else
1150#endif
1151}
1152
1153static void
1154evgl_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
1155{
1156#if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1157 glShaderBinary(n, shaders, binaryformat, binary, length);
1158#else
1159// FIXME: need to dlsym/getprocaddress for this
1160 return;
1161 n = binaryformat = length = 0;
1162 shaders = binary = 0;
1163#endif
1164}
1165
1166#endif
1167
1168static void *
1169eng_gl_api_get(void *data)
1170{
1171 Render_Engine *re;
1172
1173 re = (Render_Engine *)data;
1174
1175 gl_funcs.version = EVAS_GL_API_VERSION;
1176#if 1
1177#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, )
1178 ORD(glActiveTexture);
1179 ORD(glAttachShader);
1180 ORD(glBindAttribLocation);
1181 ORD(glBindBuffer);
1182 ORD(glBindTexture);
1183 ORD(glBlendColor);
1184 ORD(glBlendEquation);
1185 ORD(glBlendEquationSeparate);
1186 ORD(glBlendFunc);
1187 ORD(glBlendFuncSeparate);
1188 ORD(glBufferData);
1189 ORD(glBufferSubData);
1190 ORD(glCheckFramebufferStatus);
1191 ORD(glClear);
1192 ORD(glClearColor);
1193// ORD(glClearDepthf);
1194 ORD(glClearStencil);
1195 ORD(glColorMask);
1196 ORD(glCompileShader);
1197 ORD(glCompressedTexImage2D);
1198 ORD(glCompressedTexSubImage2D);
1199 ORD(glCopyTexImage2D);
1200 ORD(glCopyTexSubImage2D);
1201 ORD(glCreateProgram);
1202 ORD(glCreateShader);
1203 ORD(glCullFace);
1204 ORD(glDeleteBuffers);
1205 ORD(glDeleteFramebuffers);
1206 ORD(glDeleteProgram);
1207 ORD(glDeleteRenderbuffers);
1208 ORD(glDeleteShader);
1209 ORD(glDeleteTextures);
1210 ORD(glDepthFunc);
1211 ORD(glDepthMask);
1212// ORD(glDepthRangef);
1213 ORD(glDetachShader);
1214 ORD(glDisable);
1215 ORD(glDisableVertexAttribArray);
1216 ORD(glDrawArrays);
1217 ORD(glDrawElements);
1218 ORD(glEnable);
1219 ORD(glEnableVertexAttribArray);
1220 ORD(glFinish);
1221 ORD(glFlush);
1222 ORD(glFramebufferRenderbuffer);
1223 ORD(glFramebufferTexture2D);
1224 ORD(glFrontFace);
1225 ORD(glGenBuffers);
1226 ORD(glGenerateMipmap);
1227 ORD(glGenFramebuffers);
1228 ORD(glGenRenderbuffers);
1229 ORD(glGenTextures);
1230 ORD(glGetActiveAttrib);
1231 ORD(glGetActiveUniform);
1232 ORD(glGetAttachedShaders);
1233 ORD(glGetAttribLocation);
1234 ORD(glGetBooleanv);
1235 ORD(glGetBufferParameteriv);
1236 ORD(glGetError);
1237 ORD(glGetFloatv);
1238 ORD(glGetFramebufferAttachmentParameteriv);
1239 ORD(glGetIntegerv);
1240 ORD(glGetProgramiv);
1241 ORD(glGetProgramInfoLog);
1242 ORD(glGetRenderbufferParameteriv);
1243 ORD(glGetShaderiv);
1244 ORD(glGetShaderInfoLog);
1245// ORD(glGetShaderPrecisionFormat);
1246 ORD(glGetShaderSource);
1247 ORD(glGetString);
1248 ORD(glGetTexParameterfv);
1249 ORD(glGetTexParameteriv);
1250 ORD(glGetUniformfv);
1251 ORD(glGetUniformiv);
1252 ORD(glGetUniformLocation);
1253 ORD(glGetVertexAttribfv);
1254 ORD(glGetVertexAttribiv);
1255 ORD(glGetVertexAttribPointerv);
1256 ORD(glHint);
1257 ORD(glIsBuffer);
1258 ORD(glIsEnabled);
1259 ORD(glIsFramebuffer);
1260 ORD(glIsProgram);
1261 ORD(glIsRenderbuffer);
1262 ORD(glIsShader);
1263 ORD(glIsTexture);
1264 ORD(glLineWidth);
1265 ORD(glLinkProgram);
1266 ORD(glPixelStorei);
1267 ORD(glPolygonOffset);
1268 ORD(glReadPixels);
1269// ORD(glReleaseShaderCompiler);
1270 ORD(glRenderbufferStorage);
1271 ORD(glSampleCoverage);
1272 ORD(glScissor);
1273// ORD(glShaderBinary);
1274 ORD(glShaderSource);
1275 ORD(glStencilFunc);
1276 ORD(glStencilFuncSeparate);
1277 ORD(glStencilMask);
1278 ORD(glStencilMaskSeparate);
1279 ORD(glStencilOp);
1280 ORD(glStencilOpSeparate);
1281 ORD(glTexImage2D);
1282 ORD(glTexParameterf);
1283 ORD(glTexParameterfv);
1284 ORD(glTexParameteri);
1285 ORD(glTexParameteriv);
1286 ORD(glTexSubImage2D);
1287 ORD(glUniform1f);
1288 ORD(glUniform1fv);
1289 ORD(glUniform1i);
1290 ORD(glUniform1iv);
1291 ORD(glUniform2f);
1292 ORD(glUniform2fv);
1293 ORD(glUniform2i);
1294 ORD(glUniform2iv);
1295 ORD(glUniform3f);
1296 ORD(glUniform3fv);
1297 ORD(glUniform3i);
1298 ORD(glUniform3iv);
1299 ORD(glUniform4f);
1300 ORD(glUniform4fv);
1301 ORD(glUniform4i);
1302 ORD(glUniform4iv);
1303 ORD(glUniformMatrix2fv);
1304 ORD(glUniformMatrix3fv);
1305 ORD(glUniformMatrix4fv);
1306 ORD(glUseProgram);
1307 ORD(glValidateProgram);
1308 ORD(glVertexAttrib1f);
1309 ORD(glVertexAttrib1fv);
1310 ORD(glVertexAttrib2f);
1311 ORD(glVertexAttrib2fv);
1312 ORD(glVertexAttrib3f);
1313 ORD(glVertexAttrib3fv);
1314 ORD(glVertexAttrib4f);
1315 ORD(glVertexAttrib4fv);
1316 ORD(glVertexAttribPointer);
1317 ORD(glViewport);
1318#undef ORD
1319
1320// Override functions wrapped by Evas_GL
1321#define ORD(f) EVAS_API_OVERRIDE(f, &gl_funcs, evgl_)
1322 ORD(glBindFramebuffer);
1323 ORD(glBindRenderbuffer);
1324
1325// GLES2.0 API compat on top of desktop gl
1326 ORD(glClearDepthf);
1327 ORD(glDepthRangef);
1328 ORD(glGetShaderPrecisionFormat);
1329 ORD(glReleaseShaderCompiler);
1330 ORD(glShaderBinary);
1331#undef ORD
1332
1333#endif
1334
1335 return &gl_funcs;
1336}
1337
1338static int
1339eng_image_load_error_get(void *data __UNUSED__, void *image)
1340{
1341 Evas_GL_Image *im;
1342
1343 if (!image) return EVAS_LOAD_ERROR_NONE;
1344 im = image;
1345 return im->im->cache_entry.load_error;
1346}
1347
1348static int
1349module_open(Evas_Module *em)
1350{
1351 if (!em) return 0;
1352 /* get whatever engine module we inherit from */
1353 if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
1354 _evas_engine_gl_cocoa_log_dom = eina_log_domain_register("EvasGLCocoa", EVAS_DEFAULT_LOG_COLOR);
1355 if(_evas_engine_gl_cocoa_log_dom < 0)
1356 {
1357 EINA_LOG_ERR("Impossible to create a log domain for GL (Cocoa) engine.");
1358 return 0;
1359 }
1360 /* store it for later use */
1361 func = pfunc;
1362 /* now to override methods */
1363 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
1364 ORD(info);
1365 ORD(info_free);
1366 ORD(setup);
1367 ORD(canvas_alpha_get);
1368 ORD(output_free);
1369 ORD(output_resize);
1370 ORD(output_tile_size_set);
1371 ORD(output_redraws_rect_add);
1372 ORD(output_redraws_rect_del);
1373 ORD(output_redraws_clear);
1374 ORD(output_redraws_next_update_get);
1375 ORD(output_redraws_next_update_push);
1376 ORD(context_cutout_add);
1377 ORD(context_cutout_clear);
1378 ORD(output_flush);
1379 ORD(output_idle_flush);
1380 // ORD(output_dump);
1381 ORD(rectangle_draw);
1382 ORD(line_draw);
1383 ORD(polygon_point_add);
1384 ORD(polygon_points_clear);
1385 ORD(polygon_draw);
1386
1387 ORD(image_load);
1388 ORD(image_new_from_data);
1389 ORD(image_new_from_copied_data);
1390 ORD(image_free);
1391 ORD(image_size_get);
1392 ORD(image_size_set);
1393 ORD(image_dirty_region);
1394 ORD(image_data_get);
1395 ORD(image_data_put);
1396 ORD(image_data_preload_request);
1397 ORD(image_data_preload_cancel);
1398 ORD(image_alpha_set);
1399 ORD(image_alpha_get);
1400 ORD(image_border_set);
1401 ORD(image_border_get);
1402 ORD(image_draw);
1403 ORD(image_comment_get);
1404 ORD(image_format_get);
1405 ORD(image_colorspace_set);
1406 ORD(image_colorspace_get);
1407 ORD(image_mask_create);
1408 // ORD(image_native_set);
1409 // ORD(image_native_get);
1410 // ORD(image_draw_filtered);
1411 // ORD(image_filtered_get);
1412 // ORD(image_filtered_save);
1413 // ORD(image_filtered_free);
1414
1415 ORD(font_draw);
1416
1417 ORD(image_scale_hint_set);
1418 ORD(image_scale_hint_get);
1419 ORD(image_stride_get);
1420
1421 ORD(image_map_draw);
1422 ORD(image_map_surface_new);
1423 ORD(image_map_surface_free);
1424
1425 ORD(image_content_hint_set);
1426 ORD(image_content_hint_get);
1427
1428 ORD(image_cache_flush);
1429 ORD(image_cache_set);
1430 ORD(image_cache_get);
1431
1432 ORD(gl_api_get);
1433
1434 ORD(image_load_error_get);
1435
1436 /* now advertise out own api */
1437 em->functions = (void *)(&func);
1438 return 1;
1439}
1440
1441static void
1442module_close(Evas_Module *em)
1443{
1444 eina_log_domain_unregister(_evas_engine_gl_cocoa_log_dom);
1445}
1446
1447static Evas_Module_Api evas_modapi =
1448{
1449 EVAS_MODULE_API_VERSION,
1450 "gl_cocoa",
1451 "none",
1452 {
1453 module_open,
1454 module_close
1455 }
1456};
1457
1458EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_cocoa);
1459
1460#ifndef EVAS_STATIC_BUILD_GL_COCOA
1461EVAS_EINA_MODULE_DEFINE(engine, gl_cocoa);
1462#endif