allow max cutout rects to be tunable. and change3 default for gl?
[profile/ivi/evas.git] / src / modules / engines / gl_common / evas_gl_context.c
1 #include "evas_gl_private.h"
2
3 static int sym_done = 0;
4
5 void (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b) = NULL;
6 void (*glsym_glBindFramebuffer)      (GLenum a, GLuint b) = NULL;
7 void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e) = NULL;
8 void (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b) = NULL;
9
10 static void
11 sym_missing(void)
12 {
13    printf("EVAS ERROR - GL symbols missing!\n");
14 }
15
16 static void
17 gl_symbols(void)
18 {
19    if (sym_done) return;
20    sym_done = 1;
21
22 #ifdef _EVAS_ENGINE_SDL_H
23 # define FINDSYM(dst, sym) if (!dst) dst = SDL_GL_GetProcAddress(sym)
24 #else
25 # define FINDSYM(dst, sym) if (!dst) dst = dlsym(RTLD_DEFAULT, sym)
26 #endif
27 #define FALLBAK(dst) if (!dst) dst = (void *)sym_missing;
28    
29    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers");
30    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersEXT");
31    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersARB");
32    FALLBAK(glsym_glGenFramebuffers);
33    
34    FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer");
35    FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferEXT");
36    FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferARB");
37    FALLBAK(glsym_glBindFramebuffer);
38    
39    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2D");
40    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DEXT");
41    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DARB");
42    FALLBAK(glsym_glFramebufferTexture2D);
43
44    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffers");
45    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersEXT");
46    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersARB");
47    FALLBAK(glsym_glDeleteFramebuffers);
48 }
49
50 static void shader_array_flush(Evas_GL_Context *gc);
51
52 static Evas_GL_Context *_evas_gl_common_context = NULL;
53 static Evas_GL_Shared *shared = NULL;
54
55 void
56 glerr(int err, const char *file, const char *func, int line, const char *op)
57 {
58    fprintf(stderr, "GLERR: %s:%i %s(), %s: ", file, line, func, op);
59    switch (err)
60      {
61      case GL_INVALID_ENUM:
62         fprintf(stderr, "GL_INVALID_ENUM\n");
63         break;
64      case GL_INVALID_VALUE:
65         fprintf(stderr, "GL_INVALID_VALUE\n");
66         break;
67      case GL_INVALID_OPERATION:
68         fprintf(stderr, "GL_INVALID_OPERATION\n");
69         break;
70      case GL_OUT_OF_MEMORY:
71         fprintf(stderr, "GL_OUT_OF_MEMORY\n");
72         break;
73      default:
74         fprintf(stderr, "0x%x\n", err);
75      }
76 }
77
78 static void
79 matrix_ident(GLfloat *m)
80 {
81    memset(m, 0, 16 * sizeof(GLfloat));
82    m[0] = m[5] = m[10] = m[15] = 1.0;
83    //------------------------
84    // 1 0 0 0
85    // 0 1 0 0
86    // 0 0 1 0
87    // 0 0 0 1
88 }
89
90 static void
91 matrix_ortho(GLfloat *m, 
92              GLfloat l, GLfloat r, 
93              GLfloat t, GLfloat b, 
94              GLfloat near, GLfloat far,
95              int rot, int w, int h)
96 {
97    GLfloat rotf;
98    GLfloat cosv, sinv;
99    GLfloat tx, ty;
100    
101 //   rot = 180;
102    //------------------------
103    m[0] = 2.0 / (r - l);
104    m[1] = 0.0;
105    m[2] = 0.0;
106    m[3] = 0.0;
107
108    //------------------------
109    m[4] = 0.0;
110    m[5] = 2.0 / (t - b);
111    m[6] = 0.0;
112    m[7] = 0.0;
113    
114    //------------------------
115    m[8] = 0.0;
116    m[9] = 0.0;
117    m[10] = -(2.0 / (far - near));
118    m[11] = 0.0;
119    
120    //------------------------
121    m[12] = -((r + l) / (r - l));
122    m[13] = -((t + b) / (t - b));
123    m[14] = -((near + far) / (far - near));
124    m[15] = 1.0;
125
126    // rot
127    rotf = (((rot / 90) & 0x3) * M_PI) / 2.0;
128
129    tx = 0.0;
130    ty = 0.0;
131    if (rot == 90)
132      {
133         tx = -(w * 1.0);
134         ty = -(h * 0.0);
135      }
136    if (rot == 180)
137      {
138         tx = -(w * 1.0);
139         ty = -(h * 1.0);
140      }
141    if (rot == 270)
142      {
143         tx = -(w * 0.0);
144         ty = -(h * 1.0);
145      }
146    
147    cosv = cos(rotf);
148    sinv = sin(rotf);
149    
150    m[0] = (2.0 / (r - l)) * ( cosv);
151    m[1] = (2.0 / (r - l)) * ( sinv);
152    
153    m[4] = (2.0 / (t - b)) * (-sinv);
154    m[5] = (2.0 / (t - b)) * ( cosv);
155    
156    m[12] += (m[0] * tx) + (m[4] * ty);
157    m[13] += (m[1] * tx) + (m[5] * ty);
158    m[14] += (m[2] * tx) + (m[6] * ty);
159    m[15] += (m[3] * tx) + (m[7] * ty);
160 }
161
162 static int
163 _evas_gl_common_version_check()
164 {
165    char *version;
166    char *tmp;
167    char *tmp2;
168    int major;
169    int minor;
170
171   /*
172    * glGetString returns a string describing the current GL connection.
173    * GL_VERSION is used to get the version of the connection
174    */
175
176    version = (char *)glGetString(GL_VERSION);
177
178   /*
179    * OpengL ES
180    *
181    * 1.* : The form is:
182    *
183    * OpenGL ES-<profile> <major>.<minor>
184    *
185    * where <profile> is either "CM" or "CL". The minor can be followed by the vendor
186    * specific information
187    *
188    * 2.0 : The form is:
189    *
190    * OpenGL<space>ES<space><version number><space><vendor-specific information>
191    */
192
193    /* OpenGL ES 1.* ? */
194
195    if ((tmp = strstr(version, "OpenGL ES-CM ")) || (tmp = strstr(version, "OpenGL ES-CL ")))
196      {
197         /* Not supported */
198         return 0;
199      }
200
201    /* OpenGL ES 2.* ? */
202
203    if ((tmp = strstr(version, "OpenGL ES ")))
204      {
205         /* Supported */
206         return 1;
207      }
208
209   /*
210    * OpenGL
211    *
212    * The GL_VERSION and GL_SHADING_LANGUAGE_VERSION strings begin with a
213    * version number. The version number uses one of these forms:
214    *
215    * major_number.minor_number
216    * major_number.minor_number.release_number
217    *
218    * Vendor-specific information may follow the version number. Its format
219    * depends on the implementation, but a space always separates the
220    * version number and the vendor-specific information.
221    */
222
223    /* glGetString() returns a static string, and we are going to */
224    /* modify it, so we get a copy first */
225    version = strdup(version);
226    if (!version)
227      return 0;
228
229    tmp = strchr(version, '.');
230    /* the first '.' always exists */
231    *tmp = '\0';
232    major = atoi(version);
233    /* FIXME: maybe we can assume that minor in only a cipher */
234    tmp2 = ++tmp;
235    while ((*tmp != '.') && (*tmp != ' ') && (*tmp != '\0'))
236      tmp++;
237    /* *tmp is '\0' : version is major_number.minor_number */
238    /* *tmp is '.'  : version is major_number.minor_number.release_number */
239    /* *tmp is ' '  : version is major_number.minor_number followed by vendor */
240    *tmp = '\0';
241    minor = atoi(tmp2);
242    free(version);
243
244    if (((major == 1) && (minor >= 4)) || (major >= 2))
245      return 1;
246
247    return 0;
248 }
249
250 static void
251 _evas_gl_common_viewport_set(Evas_GL_Context *gc)
252 {
253    GLfloat proj[16];
254    int w = 1, h = 1, m = 1, rot = 1;
255
256    if ((gc->shader.surface == gc->def_surface) ||
257        (!gc->shader.surface))
258      {
259         w = gc->w;
260         h = gc->h;
261         rot = gc->rot;
262      }
263    else
264      {
265         w = gc->shader.surface->w;
266         h = gc->shader.surface->h;
267         rot = 0;
268         m = -1;
269      }
270
271    if ((!gc->change.size) || 
272        ((gc->shared->w == w) && (gc->shared->h == h) && (gc->shared->rot == rot)))
273      return;
274    
275    gc->shared->w = w;
276    gc->shared->h = h;
277    gc->shared->rot = rot;
278    gc->change.size = 0;
279
280    if ((rot == 0) || (rot == 180))
281      glViewport(0, 0, w, h);
282    else
283      glViewport(0, 0, h, w);
284    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
285    
286    matrix_ident(proj);
287    if (m == 1) matrix_ortho(proj, 0, w, 0, h, -1.0, 1.0, rot, w, h);
288    else matrix_ortho(proj, 0, w, h, 0, -1.0, 1.0, rot, w, h);
289    
290    glUseProgram(gc->shared->shader.rect.prog);
291    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
292    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.rect.prog, "mvp"), 1,
293                       GL_FALSE, proj);
294    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
295    glUseProgram(gc->shared->shader.font.prog);
296    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
297    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.font.prog, "mvp"), 1,
298                       GL_FALSE, proj);
299    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
300    
301    glUseProgram(gc->shared->shader.yuv.prog);
302    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
303    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.yuv.prog, "mvp"), 1,
304                       GL_FALSE, proj);
305    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
306    glUseProgram(gc->shared->shader.yuv_nomul.prog);
307    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
308    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.yuv_nomul.prog, "mvp"), 1,
309                       GL_FALSE, proj);
310    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
311    
312    glUseProgram(gc->shared->shader.tex.prog);
313    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
314    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex.prog, "mvp"), 1,
315                       GL_FALSE, proj);
316    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
317    glUseProgram(gc->shared->shader.tex_nomul.prog);
318    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
319    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex_nomul.prog, "mvp"), 1,
320                       GL_FALSE, proj);
321    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
322    
323    glUseProgram(gc->shared->shader.img.prog);
324    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
325    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img.prog, "mvp"), 1,
326                       GL_FALSE, proj);
327    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
328    glUseProgram(gc->shared->shader.img_nomul.prog);
329    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
330    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_nomul.prog, "mvp"), 1,
331                       GL_FALSE, proj);
332    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
333
334    glUseProgram(gc->shared->shader.img_bgra.prog);
335    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
336    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra.prog, "mvp"), 1,
337                       GL_FALSE, proj);
338    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
339    glUseProgram(gc->shared->shader.img_bgra_nomul.prog);
340    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
341    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra_nomul.prog, "mvp"), 1,
342                       GL_FALSE, proj);
343    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
344
345    glUseProgram(gc->shader.cur_prog);
346    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
347 }
348
349 Evas_GL_Context *
350 evas_gl_common_context_new(void)
351 {
352    Evas_GL_Context *gc;
353
354 #if 1
355    if (_evas_gl_common_context)
356      {
357         _evas_gl_common_context->references++;
358         return _evas_gl_common_context;
359      }
360 #endif
361    if (!_evas_gl_common_version_check())
362      return NULL;
363    gc = calloc(1, sizeof(Evas_GL_Context));
364    if (!gc) return NULL;
365
366    gl_symbols();
367    
368    gc->references = 1;
369    
370    _evas_gl_common_context = gc;
371
372    gc->shader.render_op = EVAS_RENDER_BLEND;
373    
374    if (!shared)
375      {
376         GLint linked;
377         unsigned int pixel = 0xffffffff;
378         const GLubyte *ext;
379
380         shared = calloc(1, sizeof(Evas_GL_Shared));
381         ext = glGetString(GL_EXTENSIONS);
382         if (ext)
383           {
384              fprintf(stderr, "EXT:\n%s\n", ext);
385              if ((strstr((char*) ext, "GL_ARB_texture_non_power_of_two")) ||
386                  (strstr((char*) ext, "OES_texture_npot")) ||
387                  (strstr((char*) ext, "GL_IMG_texture_npot")))
388                shared->info.tex_npo2 = 1;
389              if ((strstr((char*) ext, "GL_NV_texture_rectangle")) ||
390                  (strstr((char*) ext, "GL_EXT_texture_rectangle")) ||
391                  (strstr((char*) ext, "GL_ARB_texture_rectangle")))
392                shared->info.tex_rect = 1;
393 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
394              if ((strstr((char*) ext, "GL_EXT_texture_filter_anisotropic")))
395                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, 
396                            &(shared->info.anisotropic));
397 #endif
398 #ifdef GL_BGRA
399              if ((strstr((char*) ext, "GL_EXT_bgra")) ||
400                  (strstr((char*) ext, "GL_EXT_texture_format_BGRA8888")))
401                shared->info.bgra = 1;
402 #endif
403           }
404         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
405                       &(shared->info.max_texture_units));
406         glGetIntegerv(GL_MAX_TEXTURE_SIZE,
407                       &(shared->info.max_texture_size));
408         
409         shared->info.cutout_max = 512; // hmmm is this good?
410         if (getenv("EVAS_GL_CUTOUT_MAX"))
411            shared->info.cutout_max = atoi(getenv("EVAS_GL_CUTOUT_MAX"));
412         
413         fprintf(stderr, "max tex size %ix%i\n"
414                 "max units %i\n"
415                 "non-power-2 tex %i\n"
416                 "rect tex %i\n"
417                 "bgra : %i\n"
418                 "max ansiotropic filtering: %3.3f\n"
419                 "\n"
420                 "cutout max: %i\n"
421                 , 
422                 shared->info.max_texture_size, shared->info.max_texture_size,
423                 shared->info.max_texture_units,
424                 (int)shared->info.tex_npo2,
425                 (int)shared->info.tex_rect,
426                 (int)shared->info.bgra,
427                 (double)shared->info.anisotropic,
428                 
429                 shared->info.cutout_max
430                 );
431         
432         glDisable(GL_DEPTH_TEST);
433         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
434         glEnable(GL_DITHER);
435         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
436         glDisable(GL_BLEND);
437         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
438         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
439         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
440         // no dest alpha
441 //        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // dest alpha
442 //        glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ???
443         glDepthMask(GL_FALSE);
444         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
445         
446         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
447         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
448         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
449         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
450         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
451         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
452         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
453         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
454 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
455         if (shared->info.anisotropic > 0.0)
456           {
457              glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
458              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
459           }
460 #endif
461         
462         glEnableVertexAttribArray(SHAD_VERTEX);
463         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
464         glEnableVertexAttribArray(SHAD_COLOR);
465         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
466
467         if (!evas_gl_common_shader_program_init(&(shared->shader.rect), 
468                                                 &(shader_rect_vert_src), 
469                                                 &(shader_rect_frag_src),
470                                                 "rect")) goto error;
471         if (!evas_gl_common_shader_program_init(&(shared->shader.font),
472                                                 &(shader_font_vert_src), 
473                                                 &(shader_font_frag_src),
474                                                 "font")) goto error;
475         if (!evas_gl_common_shader_program_init(&(shared->shader.img),
476                                                 &(shader_img_vert_src),
477                                                 &(shader_img_frag_src),
478                                                 "img")) goto error;
479         if (!evas_gl_common_shader_program_init(&(shared->shader.img_nomul),
480                                                 &(shader_img_nomul_vert_src),
481                                                 &(shader_img_nomul_frag_src),
482                                                 "img_nomul")) goto error;
483         if (!evas_gl_common_shader_program_init(&(shared->shader.img_bgra),
484                                                 &(shader_img_bgra_vert_src),
485                                                 &(shader_img_bgra_frag_src),
486                                                 "img_bgra")) goto error;
487         if (!evas_gl_common_shader_program_init(&(shared->shader.img_bgra_nomul),
488                                                 &(shader_img_bgra_nomul_vert_src),
489                                                 &(shader_img_bgra_nomul_frag_src),
490                                                 "img_bgra_nomul")) goto error;
491         if (!evas_gl_common_shader_program_init(&(shared->shader.tex),
492                                                 &(shader_tex_vert_src), 
493                                                 &(shader_tex_frag_src),
494                                                 "tex")) goto error;
495         if (!evas_gl_common_shader_program_init(&(shared->shader.tex_nomul),
496                                                 &(shader_tex_nomul_vert_src), 
497                                                 &(shader_tex_nomul_frag_src),
498                                                 "tex_nomul")) goto error;
499         if (!evas_gl_common_shader_program_init(&(shared->shader.yuv),
500                                                 &(shader_yuv_vert_src), 
501                                                 &(shader_yuv_frag_src),
502                                                 "yuv")) goto error;
503         if (!evas_gl_common_shader_program_init(&(shared->shader.yuv_nomul),
504                                                 &(shader_yuv_nomul_vert_src), 
505                                                 &(shader_yuv_nomul_frag_src),
506                                                 "yuv_nomul")) goto error;
507         
508         glUseProgram(shared->shader.yuv.prog);
509         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
510         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "tex"), 0);
511         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
512         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texu"), 1);
513         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
514         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texv"), 2);
515         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
516         
517         glUseProgram(shared->shader.yuv_nomul.prog);
518         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
519         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "tex"), 0);
520         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
521         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texu"), 1);
522         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
523         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texv"), 2);
524         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
525         
526         glUseProgram(gc->shader.cur_prog);
527         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
528         // in shader:
529         // uniform sampler2D tex[8];
530         // 
531         // in code:
532         // GLuint texes[8];
533         // GLint loc = glGetUniformLocation(prog, "tex");
534         // glUniform1iv(loc, 8, texes);
535      }
536    gc->shared = shared;
537    gc->shared->references++;
538    _evas_gl_common_viewport_set(gc);
539    
540    gc->def_surface = evas_gl_common_image_surface_new(gc, 1, 1, 1);
541    
542    return gc;
543    error:
544    evas_gl_common_context_free(gc);
545    return NULL;
546 }
547
548 void
549 evas_gl_common_context_free(Evas_GL_Context *gc)
550 {
551    int i, j;
552    
553    gc->references--;
554    if (gc->references > 0) return;
555    if (gc->shared) gc->shared->references--;
556    
557    if (gc->def_surface) evas_gl_common_image_free(gc->def_surface);
558    
559    if ((gc->shared) && (gc->shared->references == 0))
560      {
561         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.rect));
562         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.font));
563         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img));
564         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_nomul));
565         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra));
566         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra_nomul));
567         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv));
568         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv_nomul));
569         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex));
570         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex_nomul));
571         
572         while (gc->shared->images)
573           {
574              evas_gl_common_image_free(gc->shared->images->data);
575           }
576         while (gc->shared->tex.whole)
577           {
578              evas_gl_common_texture_free(gc->shared->tex.whole->data);
579           }
580         for (i = 0; i < 33; i++)
581           {
582              for (j = 0; j < 3; j++)
583                {
584                   while (gc->shared->tex.atlas[i][j])
585                     {
586                        evas_gl_common_texture_free
587                          ((Evas_GL_Texture *)gc->shared->tex.atlas[i][j]);
588                        gc->shared->tex.atlas[i][j] = NULL;
589                     }
590                }
591           }
592         free(gc->shared);
593         shared = NULL;
594      }
595    
596
597    if (gc->array.vertex) free(gc->array.vertex);
598    if (gc->array.color) free(gc->array.color);
599    if (gc->array.texuv) free(gc->array.texuv);
600    if (gc->array.texuv2) free(gc->array.texuv2);
601    if (gc->array.texuv3) free(gc->array.texuv3);
602    
603    if (gc == _evas_gl_common_context) _evas_gl_common_context = NULL;
604    free(gc);
605 }
606
607 void
608 evas_gl_common_context_use(Evas_GL_Context *gc)
609 {
610    if (_evas_gl_common_context == gc) return;
611    _evas_gl_common_context = gc;
612    _evas_gl_common_viewport_set(gc);
613 }
614
615 void
616 evas_gl_common_context_newframe(Evas_GL_Context *gc)
617 {
618    gc->clip.x = 0;
619    gc->clip.y = 0;
620    gc->clip.w = 0;
621    gc->clip.h = 0;
622    gc->clip.active = 0;
623    gc->shader.surface = NULL;
624    gc->shader.cur_prog = 0;
625    gc->shader.cur_tex = 0;
626    gc->shader.cur_texu = 0;
627    gc->shader.cur_texv = 0;
628    gc->shader.render_op = EVAS_RENDER_BLEND;
629    gc->shader.cx = 0;
630    gc->shader.cy = 0;
631    gc->shader.cw = 0;
632    gc->shader.ch = 0;
633    gc->shader.smooth = 0;
634    gc->shader.blend = 0;
635    gc->shader.clip = 0;
636    gc->shader.current.cur_prog = 0;
637    gc->shader.current.cur_tex = 0;
638    gc->shader.current.cur_texu = 0;
639    gc->shader.current.cur_texv = 0;
640    gc->shader.current.render_op = 0;
641    gc->shader.current.cx = 0;
642    gc->shader.current.cy = 0;
643    gc->shader.current.cw = 0;
644    gc->shader.current.ch = 0;
645    gc->shader.current.smooth = 0;
646    gc->shader.current.blend = 0;
647    gc->shader.current.clip = 0;
648    gc->change.size = 1;
649    
650    glDisable(GL_SCISSOR_TEST);
651    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
652    glScissor(0, 0, 0, 0);
653    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
654    
655    glDisable(GL_DEPTH_TEST);
656    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
657    glEnable(GL_DITHER);
658    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
659    glDisable(GL_BLEND);
660    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
661    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
662    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
663    // no dest alpha
664 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // dest alpha
665 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ???
666    glDepthMask(GL_FALSE);
667    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
668         
669    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
670    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
671    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
672    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
673    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
674    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
675    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
676    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
677 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
678    if (shared->info.anisotropic > 0.0)
679      {
680         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
681         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
682      }
683 #endif
684    
685    glEnableVertexAttribArray(SHAD_VERTEX);
686    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
687    glEnableVertexAttribArray(SHAD_COLOR);
688    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
689    glUseProgram(gc->shader.cur_prog);
690    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
691    
692    glActiveTexture(GL_TEXTURE0);
693    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
694    glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex);
695    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
696
697    _evas_gl_common_viewport_set(gc);
698 }
699
700 void
701 evas_gl_common_context_resize(Evas_GL_Context *gc, int w, int h, int rot)
702 {
703    if ((gc->w == w) && (gc->h == h) && (gc->rot == rot)) return;
704    gc->change.size = 1;
705    gc->rot = rot;
706    gc->w = w;
707    gc->h = h;
708    if (_evas_gl_common_context == gc) _evas_gl_common_viewport_set(gc);
709 }
710
711 void
712 evas_gl_common_context_target_surface_set(Evas_GL_Context *gc,
713                                           Evas_GL_Image *surface)
714 {
715    if (surface == gc->shader.surface) return;
716    
717    evas_gl_common_context_flush(gc);
718
719    gc->shader.surface = surface;
720    gc->change.size = 1;
721 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
722 # ifndef GL_FRAMEBUFFER
723 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
724 # endif   
725 #else
726 # ifndef GL_FRAMEBUFFER
727 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
728 # endif   
729 #endif   
730    if (gc->shader.surface == gc->def_surface)
731      {
732         glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
733         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
734      }
735    else
736      {
737         glsym_glBindFramebuffer(GL_FRAMEBUFFER, surface->tex->pt->fb);
738         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
739      }
740    _evas_gl_common_viewport_set(gc);
741 }
742
743 #define PUSH_VERTEX(x, y, z) \
744    gc->array.vertex[nv++] = x; \
745    gc->array.vertex[nv++] = y; \
746    gc->array.vertex[nv++] = z
747 #define PUSH_COLOR(r, g, b, a) \
748    gc->array.color[nc++] = r; \
749    gc->array.color[nc++] = g; \
750    gc->array.color[nc++] = b; \
751    gc->array.color[nc++] = a
752 #define PUSH_TEXUV(u, v) \
753    gc->array.texuv[nu++] = u; \
754    gc->array.texuv[nu++] = v
755 #define PUSH_TEXUV2(u, v) \
756    gc->array.texuv2[nu2++] = u; \
757    gc->array.texuv2[nu2++] = v
758 #define PUSH_TEXUV3(u, v) \
759    gc->array.texuv3[nu3++] = u; \
760    gc->array.texuv3[nu3++] = v
761
762 static inline void
763 _evas_gl_common_context_array_alloc(Evas_GL_Context *gc)
764 {
765    if (gc->array.num <= gc->array.alloc) return;
766    gc->array.alloc += 6 * 1024;
767    if (gc->array.use_vertex)
768      gc->array.vertex = realloc(gc->array.vertex,
769                                 gc->array.alloc * sizeof(GLshort) * 3);
770    if (gc->array.use_color)
771      gc->array.color  = realloc(gc->array.color,
772                                 gc->array.alloc * sizeof(GLubyte) * 4);
773    if (gc->array.use_texuv)
774      gc->array.texuv  = realloc(gc->array.texuv,
775                                 gc->array.alloc * sizeof(GLfloat) * 2);
776    if (gc->array.use_texuv2)
777      gc->array.texuv2  = realloc(gc->array.texuv2,
778                                gc->array.alloc * sizeof(GLfloat) * 2);
779    if (gc->array.use_texuv3)
780      gc->array.texuv3  = realloc(gc->array.texuv3,
781                                  gc->array.alloc * sizeof(GLfloat) * 2);
782 }
783
784 void
785 evas_gl_common_context_line_push(Evas_GL_Context *gc, 
786                                  int x1, int y1, int x2, int y2,
787                                  int clip, int cx, int cy, int cw, int ch,
788                                  int r, int g, int b, int a)
789 {
790    int pnum, nv, nc, nu, nt, i;
791    Eina_Bool blend = 0;
792    GLuint prog = gc->shared->shader.rect.prog;
793    
794    shader_array_flush(gc);
795    
796    if (a < 255) blend = 1;
797    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
798    gc->shader.cur_tex = 0;
799    gc->shader.cur_prog = prog;
800    gc->shader.blend = blend;
801    gc->shader.render_op = gc->dc->render_op;
802    gc->shader.clip = clip;
803    gc->shader.cx = cx;
804    gc->shader.cy = cy;
805    gc->shader.cw = cw;
806    gc->shader.ch = ch;
807    
808    gc->array.line = 1;
809    gc->array.use_vertex = 1;
810    gc->array.use_color = 1;
811    gc->array.use_texuv = 0;
812    gc->array.use_texuv2 = 0;
813    gc->array.use_texuv3 = 0;
814    
815    pnum = gc->array.num;
816    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
817    gc->array.num += 1;
818    _evas_gl_common_context_array_alloc(gc);
819   
820    PUSH_VERTEX(x1, y1, 0);
821    PUSH_VERTEX(x2, y2, 0);
822    
823    for (i = 0; i < 2; i++)
824      {
825         PUSH_COLOR(r, g, b, a);
826      }
827    
828    shader_array_flush(gc);
829    gc->array.line = 0;
830    gc->array.use_vertex = 0;
831    gc->array.use_color = 0;
832    gc->array.use_texuv = 0;
833    gc->array.use_texuv2 = 0;
834    gc->array.use_texuv3 = 0;
835 }
836
837 void
838 evas_gl_common_context_rectangle_push(Evas_GL_Context *gc, 
839                                       int x, int y, int w, int h,
840                                       int r, int g, int b, int a)
841 {
842    int pnum, nv, nc, nu, nt, i;
843    Eina_Bool blend = 0;
844    GLuint prog = gc->shared->shader.rect.prog;
845    
846    if (a < 255) blend = 1;
847    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
848    
849    if ((gc->shader.cur_tex != 0)
850        || (gc->shader.cur_prog != prog)
851        || (gc->shader.blend != blend)
852        || (gc->shader.render_op != gc->dc->render_op)
853        || (gc->shader.clip != 0)
854        )
855      {
856         shader_array_flush(gc);
857         gc->shader.cur_tex = 0;
858         gc->shader.cur_prog = prog;
859         gc->shader.blend = blend;
860         gc->shader.render_op = gc->dc->render_op;
861         gc->shader.clip = 0;
862
863      }
864    gc->array.line = 0;
865    gc->array.use_vertex = 1;
866    gc->array.use_color = 1;
867    gc->array.use_texuv = 0;
868    gc->array.use_texuv2 = 0;
869    gc->array.use_texuv3 = 0;
870    
871    pnum = gc->array.num;
872    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
873    gc->array.num += 6;
874    _evas_gl_common_context_array_alloc(gc);
875   
876    PUSH_VERTEX(x    , y    , 0);
877    PUSH_VERTEX(x + w, y    , 0);
878    PUSH_VERTEX(x    , y + h, 0);
879    
880    PUSH_VERTEX(x + w, y    , 0);
881    PUSH_VERTEX(x + w, y + h, 0);
882    PUSH_VERTEX(x    , y + h, 0);
883    
884    for (i = 0; i < 6; i++)
885      {
886         PUSH_COLOR(r, g, b, a);
887      }
888 }
889
890 void
891 evas_gl_common_context_image_push(Evas_GL_Context *gc,
892                                   Evas_GL_Texture *tex,
893                                   double sx, double sy, double sw, double sh,
894                                   int x, int y, int w, int h,
895                                   int r, int g, int b, int a,
896                                   Eina_Bool smooth, Eina_Bool tex_only)
897 {
898    int pnum, nv, nc, nu, nu2, nt, i;
899    GLfloat tx1, tx2, ty1, ty2;
900    Eina_Bool blend = 1;
901    GLuint prog = gc->shared->shader.img.prog;
902
903    if (!tex->alpha) blend = 0;
904    if (a < 255) blend = 1;
905    
906    if (tex_only)
907      {
908         if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
909           prog = gc->shared->shader.tex_nomul.prog;
910         else
911           prog = gc->shared->shader.tex.prog;
912      }
913    else
914      {
915         if (tex->gc->shared->info.bgra)
916           {
917              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
918                prog = gc->shared->shader.img_bgra_nomul.prog;
919              else
920                prog = gc->shared->shader.img_bgra.prog;
921           }
922         else
923           {
924              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
925                prog = gc->shared->shader.img_nomul.prog;
926              else
927                prog = gc->shared->shader.img.prog;
928           }
929      }
930
931    if ((gc->shader.cur_tex != tex->pt->texture)
932        || (gc->shader.cur_prog != prog)
933        || (gc->shader.smooth != smooth)
934        || (gc->shader.blend != blend)
935        || (gc->shader.render_op != gc->dc->render_op)
936        || (gc->shader.clip != 0)
937        )
938      {
939         shader_array_flush(gc);
940         gc->shader.cur_tex = tex->pt->texture;
941         gc->shader.cur_prog = prog;
942         gc->shader.smooth = smooth;
943         gc->shader.blend = blend;
944         gc->shader.render_op = gc->dc->render_op;
945         gc->shader.clip = 0;
946      } 
947    if ((tex->im) && (tex->im->native.data))
948      {
949         if (gc->array.im != tex->im)
950           {
951              shader_array_flush(gc);
952              gc->array.im = tex->im;
953           }
954      }
955    
956    gc->array.line = 0;
957    gc->array.use_vertex = 1;
958    // if nomul... dont need this
959    gc->array.use_color = 1;
960    gc->array.use_texuv = 1;
961    gc->array.use_texuv2 = 0;
962    gc->array.use_texuv3 = 0;
963   
964    pnum = gc->array.num;
965    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
966    nt = pnum * 4;
967    gc->array.num += 6;
968    _evas_gl_common_context_array_alloc(gc);
969
970    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
971      {
972         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
973         ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
974         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
975         ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
976      }
977    else
978      {
979         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
980         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
981         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
982         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
983      }
984
985    PUSH_VERTEX(x    , y    , 0);
986    PUSH_VERTEX(x + w, y    , 0);
987    PUSH_VERTEX(x    , y + h, 0);
988    
989    PUSH_TEXUV(tx1, ty1);
990    PUSH_TEXUV(tx2, ty1);
991    PUSH_TEXUV(tx1, ty2);
992    
993    PUSH_VERTEX(x + w, y    , 0);
994    PUSH_VERTEX(x + w, y + h, 0);
995    PUSH_VERTEX(x    , y + h, 0);
996    
997    PUSH_TEXUV(tx2, ty1);
998    PUSH_TEXUV(tx2, ty2);
999    PUSH_TEXUV(tx1, ty2);
1000
1001    // if nomul... dont need this
1002    for (i = 0; i < 6; i++)
1003      {
1004         PUSH_COLOR(r, g, b, a);
1005      }
1006 }
1007
1008 void
1009 evas_gl_common_context_font_push(Evas_GL_Context *gc,
1010                                  Evas_GL_Texture *tex,
1011                                  double sx, double sy, double sw, double sh,
1012                                  int x, int y, int w, int h,
1013                                  int r, int g, int b, int a)
1014 {
1015    int pnum, nv, nc, nu, nt, i;
1016    GLfloat tx1, tx2, ty1, ty2;
1017
1018    if ((gc->shader.cur_tex != tex->pt->texture)
1019        || (gc->shader.cur_prog != gc->shared->shader.font.prog)
1020        || (gc->shader.smooth != 0)
1021        || (gc->shader.blend != 1)
1022        || (gc->shader.render_op != gc->dc->render_op)
1023        || (gc->shader.clip != 0)
1024        )
1025      {
1026         shader_array_flush(gc);
1027         gc->shader.cur_tex = tex->pt->texture;
1028         gc->shader.cur_prog = gc->shared->shader.font.prog;
1029         gc->shader.smooth = 0;
1030         gc->shader.blend = 1;
1031         gc->shader.render_op = gc->dc->render_op;
1032         gc->shader.clip = 0;
1033      }
1034    gc->array.line = 0;
1035    gc->array.use_vertex = 1;
1036    gc->array.use_color = 1;
1037    gc->array.use_texuv = 1;
1038    gc->array.use_texuv2 = 0;
1039    gc->array.use_texuv3 = 0;
1040    
1041    pnum = gc->array.num;
1042    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
1043    gc->array.num += 6;
1044    _evas_gl_common_context_array_alloc(gc);
1045
1046    if (sw == 0.0)
1047      {
1048         tx1 = tex->sx1;
1049         ty1 = tex->sy1;
1050         tx2 = tex->sx2;
1051         ty2 = tex->sy2;
1052      }
1053    else
1054      {
1055         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1056         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1057         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1058         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1059      }
1060    
1061    PUSH_VERTEX(x    , y    , 0);
1062    PUSH_VERTEX(x + w, y    , 0);
1063    PUSH_VERTEX(x    , y + h, 0);
1064    
1065    PUSH_TEXUV(tx1, ty1);
1066    PUSH_TEXUV(tx2, ty1);
1067    PUSH_TEXUV(tx1, ty2);
1068    
1069    PUSH_VERTEX(x + w, y    , 0);
1070    PUSH_VERTEX(x + w, y + h, 0);
1071    PUSH_VERTEX(x    , y + h, 0);
1072    
1073    PUSH_TEXUV(tx2, ty1);
1074    PUSH_TEXUV(tx2, ty2);
1075    PUSH_TEXUV(tx1, ty2);
1076
1077    for (i = 0; i < 6; i++)
1078      {
1079         PUSH_COLOR(r, g, b, a);
1080      }
1081 }
1082
1083 void
1084 evas_gl_common_context_yuv_push(Evas_GL_Context *gc,
1085                                 Evas_GL_Texture *tex, 
1086                                 double sx, double sy, double sw, double sh,
1087                                 int x, int y, int w, int h,
1088                                 int r, int g, int b, int a,
1089                                 Eina_Bool smooth)
1090 {
1091    int pnum, nv, nc, nu, nu2, nu3, nt, i;
1092    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
1093    Eina_Bool blend = 0;
1094    GLuint prog = gc->shared->shader.yuv.prog;
1095
1096    if (a < 255) blend = 1;
1097    
1098    if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1099      prog = gc->shared->shader.yuv_nomul.prog;
1100    else
1101      prog = gc->shared->shader.yuv.prog;
1102    
1103    if ((gc->shader.cur_tex != tex->pt->texture)
1104        || (gc->shader.cur_prog != prog)
1105        || (gc->shader.smooth != smooth)
1106        || (gc->shader.blend != blend)
1107        || (gc->shader.render_op != gc->dc->render_op)
1108        || (gc->shader.clip != 0)
1109        )
1110      {
1111         shader_array_flush(gc);
1112         gc->shader.cur_tex = tex->pt->texture;
1113         gc->shader.cur_texu = tex->ptu->texture;
1114         gc->shader.cur_texv = tex->ptv->texture;
1115         gc->shader.cur_prog = prog;
1116         gc->shader.smooth = smooth;
1117         gc->shader.blend = blend;
1118         gc->shader.render_op = gc->dc->render_op;
1119         gc->shader.clip = 0;
1120      }
1121    gc->array.line = 0;
1122    gc->array.use_vertex = 1;
1123    gc->array.use_color = 1;
1124    gc->array.use_texuv = 1;
1125    gc->array.use_texuv2 = 1;
1126    gc->array.use_texuv3 = 1;
1127    
1128    pnum = gc->array.num;
1129    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; 
1130    nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
1131    gc->array.num += 6;
1132    _evas_gl_common_context_array_alloc(gc);
1133
1134    tx1 = (sx) / (double)tex->pt->w;
1135    ty1 = (sy) / (double)tex->pt->h;
1136    tx2 = (sx + sw) / (double)tex->pt->w;
1137    ty2 = (sy + sh) / (double)tex->pt->h;
1138    
1139    t2x1 = ((sx) / 2) / (double)tex->ptu->w;
1140    t2y1 = ((sy) / 2) / (double)tex->ptu->h;
1141    t2x2 = ((sx + sw) / 2) / (double)tex->ptu->w;
1142    t2y2 = ((sy + sh) / 2) / (double)tex->ptu->h;
1143    
1144    PUSH_VERTEX(x    , y    , 0);
1145    PUSH_VERTEX(x + w, y    , 0);
1146    PUSH_VERTEX(x    , y + h, 0);
1147    
1148    PUSH_TEXUV(tx1, ty1);
1149    PUSH_TEXUV(tx2, ty1);
1150    PUSH_TEXUV(tx1, ty2);
1151    
1152    PUSH_TEXUV2(t2x1, t2y1);
1153    PUSH_TEXUV2(t2x2, t2y1);
1154    PUSH_TEXUV2(t2x1, t2y2);
1155    
1156    PUSH_TEXUV3(t2x1, t2y1);
1157    PUSH_TEXUV3(t2x2, t2y1);
1158    PUSH_TEXUV3(t2x1, t2y2);
1159    
1160    PUSH_VERTEX(x + w, y    , 0);
1161    PUSH_VERTEX(x + w, y + h, 0);
1162    PUSH_VERTEX(x    , y + h, 0);
1163    
1164    PUSH_TEXUV(tx2, ty1);
1165    PUSH_TEXUV(tx2, ty2);
1166    PUSH_TEXUV(tx1, ty2);
1167
1168    PUSH_TEXUV2(t2x2, t2y1);
1169    PUSH_TEXUV2(t2x2, t2y2);
1170    PUSH_TEXUV2(t2x1, t2y2);
1171
1172    PUSH_TEXUV3(t2x2, t2y1);
1173    PUSH_TEXUV3(t2x2, t2y2);
1174    PUSH_TEXUV3(t2x1, t2y2);
1175
1176    for (i = 0; i < 6; i++)
1177      {
1178         PUSH_COLOR(r, g, b, a);
1179      }
1180 }
1181
1182 void
1183 evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
1184                                        Evas_GL_Texture *tex,
1185                                        RGBA_Map_Point *p,
1186                                        int clip, int cx, int cy, int cw, int ch,
1187                                        int r, int g, int b, int a,
1188                                        Eina_Bool smooth, Eina_Bool tex_only)
1189 {
1190    int pnum, nv, nc, nu, nu2, nt, i;
1191    const int points[6] = { 0, 1, 2, 0, 2, 3 };
1192    GLfloat tx[4], ty[4];
1193    Eina_Bool blend = 1;
1194    RGBA_Map_Point *pt;
1195    DATA32 cmul;
1196    GLuint prog = gc->shared->shader.img.prog;
1197
1198    if (!tex->alpha) blend = 0;
1199    if (a < 255) blend = 1;
1200    if ((A_VAL(&(p[0].col)) < 0xff) || (A_VAL(&(p[1].col)) < 0xff) ||
1201        (A_VAL(&(p[2].col)) < 0xff) || (A_VAL(&(p[3].col)) < 0xff))
1202      blend = 1;
1203    
1204    if (tex_only)
1205      {
1206         if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1207           {
1208              if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
1209                  (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
1210                prog = gc->shared->shader.tex_nomul.prog;
1211              else
1212                prog = gc->shared->shader.tex.prog;
1213           }
1214         else
1215           prog = gc->shared->shader.tex.prog;
1216      }
1217    else
1218      {
1219         if (tex->gc->shared->info.bgra)
1220           {
1221              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1222                {
1223                   if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
1224                       (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
1225                     prog = gc->shared->shader.img_bgra_nomul.prog;
1226                   else
1227                     prog = gc->shared->shader.img_bgra.prog;
1228                }
1229              else
1230                prog = gc->shared->shader.img_bgra.prog;
1231           }
1232         else
1233           {
1234              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1235                {
1236                   if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
1237                       (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
1238                     prog = gc->shared->shader.img_nomul.prog;
1239                   else
1240                     prog = gc->shared->shader.img.prog;
1241                }
1242              else
1243                prog = gc->shared->shader.img.prog;
1244           }
1245      }
1246    
1247    if ((gc->shader.cur_tex != tex->pt->texture)
1248        || (gc->shader.cur_prog != prog)
1249        || (gc->shader.smooth != smooth)
1250        || (gc->shader.blend != blend)
1251        || (gc->shader.render_op != gc->dc->render_op)
1252        || (gc->shader.clip != clip)
1253        || (gc->shader.cx != cx)
1254        || (gc->shader.cy != cy)
1255        || (gc->shader.cw != cw)
1256        || (gc->shader.ch != ch)
1257        )
1258      {
1259         shader_array_flush(gc);
1260         gc->shader.cur_tex = tex->pt->texture;
1261         gc->shader.cur_prog = prog;
1262         gc->shader.smooth = smooth;
1263         gc->shader.blend = blend;
1264         gc->shader.render_op = gc->dc->render_op;
1265         gc->shader.clip = clip;
1266         gc->shader.cx = cx;
1267         gc->shader.cy = cy;
1268         gc->shader.cw = cw;
1269         gc->shader.ch = ch;
1270      }
1271    if ((tex->im) && (tex->im->native.data))
1272      {
1273         if (gc->array.im != tex->im)
1274           {
1275              shader_array_flush(gc);
1276              gc->array.im = tex->im;
1277           }
1278      }
1279    gc->array.line = 0;
1280    gc->array.use_vertex = 1;
1281    gc->array.use_color = 1;
1282    gc->array.use_texuv = 1;
1283    gc->array.use_texuv2 = 1;
1284    gc->array.use_texuv3 = 0;
1285    
1286    pnum = gc->array.num;
1287    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
1288    nt = pnum * 4;
1289    gc->array.num += 6;
1290    _evas_gl_common_context_array_alloc(gc);
1291
1292    for (i = 0; i < 4; i++)
1293      {
1294         tx[i] = ((double)(tex->x) + (((double)p[i].u) / FP1)) /
1295           (double)tex->pt->w;
1296         ty[i] = ((double)(tex->y) + (((double)p[i].v) / FP1)) / 
1297           (double)tex->pt->h;
1298      }
1299    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
1300      {
1301         // FIXME: handle yinvert
1302      }
1303    
1304    cmul = ARGB_JOIN(a, r, g, b);
1305    for (i = 0; i < 6; i++)
1306      {
1307         DATA32 cl = MUL4_SYM(cmul, p[points[i]].col);
1308         PUSH_VERTEX((p[points[i]].x >> FP), 
1309                     (p[points[i]].y >> FP),
1310                     0);
1311         PUSH_TEXUV(tx[points[i]],
1312                    ty[points[i]]);
1313         
1314         PUSH_COLOR(R_VAL(&cl),
1315                    G_VAL(&cl),
1316                    B_VAL(&cl),
1317                    A_VAL(&cl));
1318      }
1319 }
1320
1321 void
1322 evas_gl_common_context_flush(Evas_GL_Context *gc)
1323 {
1324    shader_array_flush(gc);
1325 //   fprintf(stderr, "------------FRAME: done\n");
1326 }
1327
1328 static void
1329 shader_array_flush(Evas_GL_Context *gc)
1330 {
1331    if (gc->array.num <= 0) return;
1332
1333 //   fprintf(stderr, "  flush array %i\n", gc->array.num);
1334    GLERR(__FUNCTION__, __FILE__, __LINE__, "<flush err>");
1335    if (gc->shader.cur_prog != gc->shader.current.cur_prog)
1336      {
1337         glUseProgram(gc->shader.cur_prog);
1338         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1339      }
1340
1341    if (gc->shader.cur_tex != gc->shader.current.cur_tex)
1342      {
1343 #if 0
1344         if (gc->shader.cur_tex)
1345           {
1346              glEnable(GL_TEXTURE_2D);
1347              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1348           }
1349         else
1350           {
1351              glDisable(GL_TEXTURE_2D);
1352              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1353           }
1354 #endif
1355         glActiveTexture(GL_TEXTURE0);
1356         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1357         glBindTexture(GL_TEXTURE_2D, gc->shader.cur_tex);
1358         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1359      }
1360    if (gc->array.im)
1361      {
1362         if (!gc->array.im->native.loose)
1363           {
1364              if (gc->array.im->native.func.bind)
1365                gc->array.im->native.func.bind(gc->array.im->native.func.data, 
1366                                               gc->array.im);
1367           }
1368      }
1369    if (gc->shader.render_op != gc->shader.current.render_op)
1370      {
1371         switch (gc->shader.render_op)
1372           {
1373           case EVAS_RENDER_BLEND: /**< default op: d = d*(1-sa) + s */
1374              glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1375              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1376              break;
1377           case EVAS_RENDER_COPY: /**< d = s */
1378              gc->shader.blend = 0;
1379              glBlendFunc(GL_ONE, GL_ONE);
1380              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1381              break;
1382              // FIXME: fix blend funcs below!
1383           case EVAS_RENDER_BLEND_REL: /**< d = d*(1 - sa) + s*da */
1384           case EVAS_RENDER_COPY_REL: /**< d = s*da */
1385           case EVAS_RENDER_ADD: /**< d = d + s */
1386           case EVAS_RENDER_ADD_REL: /**< d = d + s*da */
1387           case EVAS_RENDER_SUB: /**< d = d - s */
1388           case EVAS_RENDER_SUB_REL: /**< d = d - s*da */
1389           case EVAS_RENDER_TINT: /**< d = d*s + d*(1 - sa) + s*(1 - da) */
1390           case EVAS_RENDER_TINT_REL: /**< d = d*(1 - sa + s) */
1391           case EVAS_RENDER_MASK: /**< d = d*sa */
1392           case EVAS_RENDER_MUL: /**< d = d*s */
1393           default:
1394              glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1395              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1396              break;
1397           }
1398      }
1399    if (gc->shader.blend != gc->shader.current.blend)
1400      {
1401         if (gc->shader.blend)
1402           {
1403              glEnable(GL_BLEND);
1404              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1405           }
1406         else
1407           {
1408              glDisable(GL_BLEND);
1409              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1410           }
1411      }
1412    if (gc->shader.smooth != gc->shader.current.smooth)
1413      {
1414         if (gc->shader.smooth)
1415           {
1416 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1417              if (shared->info.anisotropic > 0.0)
1418                {
1419                   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, shared->info.anisotropic);
1420                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1421                }
1422 #endif
1423              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1424              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1425              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1426              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1427              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1428              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1429              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1430              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1431           }
1432         else
1433           {
1434 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1435              if (shared->info.anisotropic > 0.0)
1436                {
1437                   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
1438                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1439                }
1440 #endif
1441              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1442              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1443              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1444              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1445              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1446              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1447              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1448              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1449           }
1450      }
1451 /* hmmm this breaks things. must find out why!   
1452    if (gc->shader.clip != gc->shader.current.clip)
1453      {
1454         if (gc->shader.clip)
1455           glEnable(GL_SCISSOR_TEST);
1456         else
1457           {
1458              glDisable(GL_SCISSOR_TEST);
1459 //             glScissor(0, 0, 0, 0);
1460           }
1461      }
1462    if (gc->shader.clip)
1463      {
1464         if ((gc->shader.cx != gc->shader.current.cx) ||
1465             (gc->shader.cx != gc->shader.current.cx) ||
1466             (gc->shader.cx != gc->shader.current.cx) ||
1467             (gc->shader.cx != gc->shader.current.cx))
1468           {
1469              glScissor(gc->shader.cx, 
1470                        gc->h - gc->shader.cy - gc->shader.ch,
1471                        gc->shader.cw,
1472                        gc->shader.ch);
1473           }
1474 //                    gc->clip.x,
1475 //                    gc->h - gc->clip.y - gc->clip.h,
1476 //                    gc->clip.w,
1477 //                    gc->clip.h);
1478         
1479      }
1480  */
1481    glVertexAttribPointer(SHAD_VERTEX, 3, GL_SHORT, GL_FALSE, 0, gc->array.vertex);
1482    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1483    glVertexAttribPointer(SHAD_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, gc->array.color);
1484    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1485    if (gc->array.use_texuv)
1486      {
1487         glEnableVertexAttribArray(SHAD_TEXUV);
1488         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1489         glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv);
1490         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1491      }
1492    else
1493      {
1494         glDisableVertexAttribArray(SHAD_TEXUV);
1495         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1496      }
1497
1498    if (gc->array.line)
1499      {
1500         glDisableVertexAttribArray(SHAD_TEXUV);
1501         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1502         glDisableVertexAttribArray(SHAD_TEXUV2); 
1503         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1504         glDisableVertexAttribArray(SHAD_TEXUV3);
1505         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1506         glDrawArrays(GL_LINES, 0, gc->array.num);
1507         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1508      }
1509    else
1510      {
1511         if ((gc->array.use_texuv2) && (gc->array.use_texuv3))
1512           {
1513              glEnableVertexAttribArray(SHAD_TEXUV2);
1514              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1515              glEnableVertexAttribArray(SHAD_TEXUV3);
1516              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1517              glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv2);
1518              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1519              glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv3);
1520              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1521              glActiveTexture(GL_TEXTURE1);
1522              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1523              glBindTexture(GL_TEXTURE_2D, gc->shader.cur_texu);
1524              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1525              glActiveTexture(GL_TEXTURE2);
1526              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1527              glBindTexture(GL_TEXTURE_2D, gc->shader.cur_texv);
1528              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1529              glActiveTexture(GL_TEXTURE0);
1530              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1531           }
1532         else if (gc->array.use_texuv2)
1533           {
1534              glEnableVertexAttribArray(SHAD_TEXUV2);
1535              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1536              glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->array.texuv2);
1537              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1538           }
1539         else
1540           {
1541              glDisableVertexAttribArray(SHAD_TEXUV2);
1542              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1543              glDisableVertexAttribArray(SHAD_TEXUV3);
1544              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1545           }
1546    
1547         glDrawArrays(GL_TRIANGLES, 0, gc->array.num);
1548         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1549      }
1550    if (gc->array.im)
1551      {
1552         if (!gc->array.im->native.loose)
1553           {
1554              if (gc->array.im->native.func.unbind)
1555                gc->array.im->native.func.unbind(gc->array.im->native.func.data, 
1556                                                 gc->array.im);
1557           }
1558         gc->array.im = NULL;
1559      }
1560
1561    gc->shader.current.cur_prog = gc->shader.cur_prog;
1562    gc->shader.current.cur_tex = gc->shader.cur_tex;
1563    gc->shader.current.blend = gc->shader.blend;
1564    gc->shader.current.smooth = gc->shader.smooth;
1565    gc->shader.current.render_op = gc->shader.render_op;
1566    gc->shader.current.clip = gc->shader.clip;
1567    gc->shader.current.cx = gc->shader.cx;
1568    gc->shader.current.cy = gc->shader.cy;
1569    gc->shader.current.cw = gc->shader.cw;
1570    gc->shader.current.ch = gc->shader.ch;
1571    
1572    if (gc->array.vertex) free(gc->array.vertex);
1573    if (gc->array.color) free(gc->array.color);
1574    if (gc->array.texuv) free(gc->array.texuv);
1575    if (gc->array.texuv2) free(gc->array.texuv2);
1576    if (gc->array.texuv3) free(gc->array.texuv3);
1577    
1578    gc->array.vertex = NULL;
1579    gc->array.color = NULL;
1580    gc->array.texuv = NULL;
1581    gc->array.texuv2 = NULL;
1582    gc->array.texuv3 = NULL;
1583    
1584    gc->array.num = 0;
1585    gc->array.alloc = 0;
1586 }