merged evas image masking code from brett
[framework/uifw/evas.git] / src / modules / engines / gl_common / evas_gl_context.c
1 #include "evas_gl_private.h"
2
3 #define GLPIPES 1
4
5 static int sym_done = 0;
6 int _evas_engine_GL_common_log_dom = -1;
7
8 typedef void    (*glsym_func_void) ();
9
10 void (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b) = NULL;
11 void (*glsym_glBindFramebuffer)      (GLenum a, GLuint b) = NULL;
12 void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e) = NULL;
13 void (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b) = NULL;
14
15 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
16 // just used for finding symbols :)
17 typedef void (*_eng_fn) (void);
18
19 typedef _eng_fn       (*secsym_func_eng_fn) ();
20 typedef unsigned int  (*secsym_func_uint) ();
21 typedef void         *(*secsym_func_void_ptr) ();
22
23 static _eng_fn  (*secsym_eglGetProcAddress)          (const char *a) = NULL;
24
25 void          *(*secsym_eglCreateImage)               (void *a, void *b, GLenum c, void *d, const int *e) = NULL;
26 unsigned int   (*secsym_eglDestroyImage)              (void *a, void *b) = NULL;
27 void           (*secsym_glEGLImageTargetTexture2DOES) (int a, void *b) = NULL;
28 void          *(*secsym_eglMapImageSEC)               (void *a, void *b) = NULL;
29 unsigned int   (*secsym_eglUnmapImageSEC)             (void *a, void *b) = NULL;
30 unsigned int   (*secsym_eglGetImageAttribSEC)         (void *a, void *b, int c, int *d) = NULL;
31 #endif
32
33 static int dbgflushnum = -1;
34
35 static void
36 sym_missing(void)
37 {
38    ERR("GL symbols missing!");
39 }
40
41 static void
42 gl_symbols(void)
43 {
44    if (sym_done) return;
45    sym_done = 1;
46
47 #ifdef _EVAS_ENGINE_SDL_H
48 # define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)SDL_GL_GetProcAddress(sym)
49 #else
50 # define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
51 #endif
52 #define FALLBAK(dst, typ) if (!dst) dst = (typ)sym_missing;
53    
54    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void);
55    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersEXT", glsym_func_void);
56    FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffersARB", glsym_func_void);
57    FALLBAK(glsym_glGenFramebuffers, glsym_func_void);
58    
59    FINDSYM(glsym_glBindFramebuffer, "glBindFramebuffer", glsym_func_void);
60    FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferEXT", glsym_func_void);
61    FINDSYM(glsym_glBindFramebuffer, "glBindFramebufferARB", glsym_func_void);
62    FALLBAK(glsym_glBindFramebuffer, glsym_func_void);
63    
64    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2D", glsym_func_void);
65    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DEXT", glsym_func_void);
66    FINDSYM(glsym_glFramebufferTexture2D, "glFramebufferTexture2DARB", glsym_func_void);
67    FALLBAK(glsym_glFramebufferTexture2D, glsym_func_void);
68
69    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffers", glsym_func_void);
70    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersEXT", glsym_func_void);
71    FINDSYM(glsym_glDeleteFramebuffers, "glDeleteFramebuffersARB", glsym_func_void);
72    FALLBAK(glsym_glDeleteFramebuffers, glsym_func_void);
73
74 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
75 #undef FINDSYM
76 #define FINDSYM(dst, sym, typ) \
77    if ((!dst) && (secsym_eglGetProcAddress)) dst = (typ)secsym_eglGetProcAddress(sym); \
78    if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym)
79 // yes - gl core looking for egl stuff. i know it's odd. a reverse-layer thing
80 // but it will work as the egl/glx layer calls gl core common stuff and thus
81 // these symbols will work. making the glx/egl + x11 layer do this kind-of is
82 // wrong as this is not x11 (output) layer specific like the native surface
83 // stuff. this is generic zero-copy textures for gl
84
85    FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddress", secsym_func_eng_fn);
86    FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddressEXT", secsym_func_eng_fn);
87    FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddressARB", secsym_func_eng_fn);
88    FINDSYM(secsym_eglGetProcAddress, "eglGetProcAddressKHR", secsym_func_eng_fn);
89    
90    FINDSYM(secsym_eglCreateImage, "eglCreateImage", secsym_func_void_ptr);
91    FINDSYM(secsym_eglCreateImage, "eglCreateImageEXT", secsym_func_void_ptr);
92    FINDSYM(secsym_eglCreateImage, "eglCreateImageARB", secsym_func_void_ptr);
93    FINDSYM(secsym_eglCreateImage, "eglCreateImageKHR", secsym_func_void_ptr);
94    
95    FINDSYM(secsym_eglDestroyImage, "eglDestroyImage", secsym_func_uint);
96    FINDSYM(secsym_eglDestroyImage, "eglDestroyImageEXT", secsym_func_uint);
97    FINDSYM(secsym_eglDestroyImage, "eglDestroyImageARB", secsym_func_uint);
98    FINDSYM(secsym_eglDestroyImage, "eglDestroyImageKHR", secsym_func_uint);
99    
100    FINDSYM(secsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", glsym_func_void);
101    
102    FINDSYM(secsym_eglMapImageSEC, "eglMapImageSEC", secsym_func_void_ptr);
103    
104    FINDSYM(secsym_eglUnmapImageSEC, "eglUnmapImageSEC", secsym_func_uint);
105    
106    FINDSYM(secsym_eglGetImageAttribSEC, "eglGetImageAttribSEC", secsym_func_uint);
107 #endif   
108 }
109
110 static void shader_array_flush(Evas_GL_Context *gc);
111
112 static Evas_GL_Context *_evas_gl_common_context = NULL;
113 static Evas_GL_Shared *shared = NULL;
114
115 void
116 glerr(int err, const char *file, const char *func, int line, const char *op)
117 {
118    const char *errmsg;
119    char buf[32];
120
121    switch (err)
122      {
123      case GL_INVALID_ENUM:
124         errmsg = "GL_INVALID_ENUM";
125         break;
126      case GL_INVALID_VALUE:
127         errmsg = "GL_INVALID_VALUE";
128         break;
129      case GL_INVALID_OPERATION:
130         errmsg = "GL_INVALID_OPERATION";
131         break;
132      case GL_OUT_OF_MEMORY:
133         errmsg = "GL_OUT_OF_MEMORY";
134         break;
135      default:
136         snprintf(buf, sizeof(buf), "%#x", err);
137         errmsg = buf;
138      }
139
140    eina_log_print(_evas_engine_GL_common_log_dom, EINA_LOG_LEVEL_ERR,
141                   file, func, line, "%s: %s", op, errmsg);
142 }
143
144 static void
145 matrix_ortho(GLfloat *m,
146              GLfloat l, GLfloat r,
147              GLfloat t, GLfloat b,
148              GLfloat near, GLfloat far,
149              int rot, int vw, int vh,
150              int foc, GLfloat orth)
151 {
152    GLfloat rotf;
153    GLfloat cosv, sinv;
154    GLfloat tx, ty;
155    
156    rotf = (((rot / 90) & 0x3) * M_PI) / 2.0;
157    
158    tx = -0.5 * (1.0 - orth);
159    ty = -0.5 * (1.0 - orth);
160    
161    if (rot == 90)
162      {
163         tx += -(vw * 1.0);
164         ty += -(vh * 0.0);
165      }
166    if (rot == 180)
167      {
168         tx += -(vw * 1.0);
169         ty += -(vh * 1.0);
170      }
171    if (rot == 270)
172      {
173         tx += -(vw * 0.0);
174         ty += -(vh * 1.0);
175      }
176    
177    cosv = cos(rotf);
178    sinv = sin(rotf);
179    
180    m[0] = (2.0 / (r - l)) * ( cosv);
181    m[1] = (2.0 / (r - l)) * ( sinv);
182    m[2] = 0.0;
183    m[3] = 0.0;
184    
185    m[4] = (2.0 / (t - b)) * (-sinv);
186    m[5] = (2.0 / (t - b)) * ( cosv);
187    m[6] = 0.0;
188    m[7] = 0.0;
189    
190    m[8] = 0.0;
191    m[9] = 0.0;
192    m[10] = -(2.0 / (far - near));
193    m[11] = 1.0 / (GLfloat)foc;
194    
195    m[12] = (m[0] * tx) + (m[4] * ty) - ((r + l) / (r - l));
196    m[13] = (m[1] * tx) + (m[5] * ty) - ((t + b) / (t - b));
197    m[14] = (m[2] * tx) + (m[6] * ty) - ((near + far) / (far - near));
198    m[15] = (m[3] * tx) + (m[7] * ty) + orth;
199 }
200
201 static int
202 _evas_gl_common_version_check()
203 {
204    char *version;
205    char *tmp;
206    char *tmp2;
207    int major;
208    int minor;
209
210   /*
211    * glGetString returns a string describing the current GL connection.
212    * GL_VERSION is used to get the version of the connection
213    */
214
215    version = (char *)glGetString(GL_VERSION);
216
217   /*
218    * OpengL ES
219    *
220    * 1.* : The form is:
221    *
222    * OpenGL ES-<profile> <major>.<minor>
223    *
224    * where <profile> is either "CM" or "CL". The minor can be followed by the vendor
225    * specific information
226    *
227    * 2.0 : The form is:
228    *
229    * OpenGL<space>ES<space><version number><space><vendor-specific information>
230    */
231
232    /* OpenGL ES 1.* ? */
233
234    if ((tmp = strstr(version, "OpenGL ES-CM ")) || (tmp = strstr(version, "OpenGL ES-CL ")))
235      {
236         /* Not supported */
237         return 0;
238      }
239
240    /* OpenGL ES 2.* ? */
241
242    if ((tmp = strstr(version, "OpenGL ES ")))
243      {
244         /* Supported */
245         return 1;
246      }
247
248   /*
249    * OpenGL
250    *
251    * The GL_VERSION and GL_SHADING_LANGUAGE_VERSION strings begin with a
252    * version number. The version number uses one of these forms:
253    *
254    * major_number.minor_number
255    * major_number.minor_number.release_number
256    *
257    * Vendor-specific information may follow the version number. Its format
258    * depends on the implementation, but a space always separates the
259    * version number and the vendor-specific information.
260    */
261
262    /* glGetString() returns a static string, and we are going to */
263    /* modify it, so we get a copy first */
264    version = strdup(version);
265    if (!version)
266      return 0;
267
268    tmp = strchr(version, '.');
269    /* the first '.' always exists */
270    *tmp = '\0';
271    major = atoi(version);
272    /* FIXME: maybe we can assume that minor in only a cipher */
273    tmp2 = ++tmp;
274    while ((*tmp != '.') && (*tmp != ' ') && (*tmp != '\0'))
275      tmp++;
276    /* *tmp is '\0' : version is major_number.minor_number */
277    /* *tmp is '.'  : version is major_number.minor_number.release_number */
278    /* *tmp is ' '  : version is major_number.minor_number followed by vendor */
279    *tmp = '\0';
280    minor = atoi(tmp2);
281    free(version);
282
283    if (((major == 1) && (minor >= 4)) || (major >= 2))
284      return 1;
285
286    return 0;
287 }
288
289 static void
290 _evas_gl_common_viewport_set(Evas_GL_Context *gc)
291 {
292    GLfloat proj[16];
293    int w = 1, h = 1, m = 1, rot = 1, foc = 0;
294
295    foc = gc->foc;
296    // surface in pipe 0 will be the same as all pipes
297    if ((gc->pipe[0].shader.surface == gc->def_surface) ||
298        (!gc->pipe[0].shader.surface))
299      {
300         w = gc->w;
301         h = gc->h;
302         rot = gc->rot;
303      }
304    else
305      {
306         w = gc->pipe[0].shader.surface->w;
307         h = gc->pipe[0].shader.surface->h;
308         rot = 0;
309         m = -1;
310      }
311    
312    if ((!gc->change.size) || 
313        ((gc->shared->w == w) && (gc->shared->h == h) &&
314            (gc->shared->rot == rot) && (gc->shared->foc == gc->foc) &&
315            (gc->shared->mflip == m)))
316       return;
317    
318    gc->shared->w = w;
319    gc->shared->h = h;
320    gc->shared->rot = rot;
321    gc->shared->mflip = m;
322    gc->shared->foc = foc;
323    gc->shared->z0 = gc->z0;
324    gc->shared->px = gc->px;
325    gc->shared->py = gc->py;
326    gc->change.size = 0;
327
328    if (foc == 0)
329      {
330         if ((rot == 0) || (rot == 180))
331            glViewport(0, 0, w, h);
332         else
333            glViewport(0, 0, h, w);
334         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
335         // std matrix
336         if (m == 1)
337            matrix_ortho(proj, 
338                         0, w, 0, h, 
339                         -1000000.0, 1000000.0,
340                         rot, w, h,
341                         1, 1.0);
342         // v flipped matrix for render-to-texture
343         else
344            matrix_ortho(proj, 
345                         0, w, h, 0, 
346                         -1000000.0, 1000000.0,
347                         rot, w, h,
348                         1, 1.0);
349      }
350    else
351      {
352         int px, py, vx, vy, vw = 0, vh = 0, ax = 0, ay = 0, ppx = 0, ppy = 0;
353         
354         px = gc->shared->px;
355         py = gc->shared->py;
356         
357         if      ((rot == 0  ) || (rot == 90 )) ppx = px;
358         else if ((rot == 180) || (rot == 270)) ppx = w - px;
359         if      ((rot == 0  ) || (rot == 270)) ppy = py;
360         else if ((rot == 90 ) || (rot == 180)) ppy = h - py;
361         
362         vx = ((w / 2) - ppx);
363         if (vx >= 0)
364           {
365              vw = w + (2 * vx);
366              if      ((rot == 0  ) || (rot == 90 )) ax = 2 * vx;
367              else if ((rot == 180) || (rot == 270)) ax = 0;
368           }
369         else
370           {
371              vw = w - (2 * vx);
372              if      ((rot == 0  ) || (rot == 90 )) ax = 0;
373              else if ((rot == 180) || (rot == 270)) ax = ppx - px;
374              vx = 0;
375           }
376         
377         vy = ((h / 2) - ppy);
378         if (vy < 0)
379           {
380              vh = h - (2 * vy);
381              if      ((rot == 0  ))                                 ay = 0;
382              else if ((rot == 90 ) || (rot == 180) || (rot == 270)) ay = ppy - py;
383              vy = -vy;
384           }
385         else
386           {
387              vh = h + (2 * vy);
388              if      ((rot == 0  ) || (rot == 270)) ay = 2 * vy;
389              else if ((rot == 90 ) || (rot == 180)) ay = 0;
390              vy = 0;
391           }
392         
393         if (m == -1) ay = vy * 2;
394         
395         if ((rot == 0) || (rot == 180))
396            glViewport(-2 * vx, -2 * vy, vw, vh);
397         else
398            glViewport(-2 * vy, -2 * vx, vh, vw);
399         if (m == 1)
400            matrix_ortho(proj, 0, vw, 0, vh,
401                         -1000000.0, 1000000.0,
402                         rot, vw, vh,
403                         foc, 0.0);
404         else
405            matrix_ortho(proj, 0, vw, vh, 0,
406                         -1000000.0, 1000000.0,
407                         rot, vw, vh,
408                         foc, 0.0);
409         gc->shared->ax = ax;
410         gc->shared->ay = ay;
411      }
412    
413    glUseProgram(gc->shared->shader.rect.prog);
414    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
415    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.rect.prog, "mvp"), 1,
416                       GL_FALSE, proj);
417    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
418    glUseProgram(gc->shared->shader.font.prog);
419    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
420    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.font.prog, "mvp"), 1,
421                       GL_FALSE, proj);
422    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
423    
424    glUseProgram(gc->shared->shader.yuv.prog);
425    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
426    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.yuv.prog, "mvp"), 1,
427                       GL_FALSE, proj);
428    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
429    glUseProgram(gc->shared->shader.yuv_nomul.prog);
430    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
431    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.yuv_nomul.prog, "mvp"), 1,
432                       GL_FALSE, proj);
433    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
434    
435    glUseProgram(gc->shared->shader.tex.prog);
436    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
437    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex.prog, "mvp"), 1,
438                       GL_FALSE, proj);
439    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
440    glUseProgram(gc->shared->shader.tex_nomul.prog);
441    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
442    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex_nomul.prog, "mvp"), 1,
443                       GL_FALSE, proj);
444    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
445    
446    glUseProgram(gc->shared->shader.img.prog);
447    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
448    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img.prog, "mvp"), 1,
449                       GL_FALSE, proj);
450    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
451    glUseProgram(gc->shared->shader.img_nomul.prog);
452    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
453    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_nomul.prog, "mvp"), 1,
454                       GL_FALSE, proj);
455    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
456
457    glUseProgram(gc->shared->shader.img_bgra.prog);
458    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
459    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra.prog, "mvp"), 1,
460                       GL_FALSE, proj);
461    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
462    glUseProgram(gc->shared->shader.img_bgra_nomul.prog);
463    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
464    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra_nomul.prog, "mvp"), 1,
465                       GL_FALSE, proj);
466    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
467    glUseProgram(gc->shared->shader.img_mask.prog);
468    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
469    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_mask.prog, "mvp"), 1,
470                       GL_FALSE, proj);
471    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
472
473
474
475    glUseProgram(gc->pipe[0].shader.cur_prog);
476    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
477 }
478
479 Evas_GL_Context *
480 evas_gl_common_context_new(void)
481 {
482    Evas_GL_Context *gc;
483    const char *s;
484    int i;
485
486 #if 1
487    if (_evas_gl_common_context)
488      {
489         _evas_gl_common_context->references++;
490         return _evas_gl_common_context;
491      }
492 #endif
493    if (!_evas_gl_common_version_check())
494      return NULL;
495    gc = calloc(1, sizeof(Evas_GL_Context));
496    if (!gc) return NULL;
497
498    gl_symbols();
499    
500    gc->references = 1;
501    
502    _evas_gl_common_context = gc;
503    
504    for (i = 0; i < MAX_PIPES; i++)
505       gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
506    
507    if (!shared)
508      {
509         const GLubyte *ext;
510
511         shared = calloc(1, sizeof(Evas_GL_Shared));
512         ext = glGetString(GL_EXTENSIONS);
513         if (ext)
514           {
515              if (getenv("EVAS_GL_INFO"))
516                 fprintf(stderr, "EXT:\n%s\n", ext);
517              if ((strstr((char *)ext, "GL_ARB_texture_non_power_of_two")) ||
518                  (strstr((char *)ext, "OES_texture_npot")) ||
519                  (strstr((char *)ext, "GL_IMG_texture_npot")))
520                shared->info.tex_npo2 = 1;
521              if ((strstr((char *)ext, "GL_NV_texture_rectangle")) ||
522                  (strstr((char *)ext, "GL_EXT_texture_rectangle")) ||
523                  (strstr((char *)ext, "GL_ARB_texture_rectangle")))
524                shared->info.tex_rect = 1;
525 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
526              if ((strstr((char *)ext, "GL_EXT_texture_filter_anisotropic")))
527                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, 
528                            &(shared->info.anisotropic));
529 #endif
530 #ifdef GL_BGRA
531              if ((strstr((char *)ext, "GL_EXT_bgra")) ||
532                  (strstr((char *)ext, "GL_EXT_texture_format_BGRA8888")))
533                shared->info.bgra = 1;
534 #endif
535 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
536              // FIXME: there should be an extension name/string to check for
537              // not just symbols in the lib
538              i = 0;
539              s = getenv("EVAS_GL_NO_MAP_IMAGE_SEC");
540              if (s) i = atoi(s);
541              if (!i)
542                {
543                   // test for all needed symbols - be "conservative" and
544                   // need all of it
545                   if ((secsym_eglCreateImage) &&
546                       (secsym_eglDestroyImage) &&
547                       (secsym_glEGLImageTargetTexture2DOES) &&
548                       (secsym_eglMapImageSEC) &&
549                       (secsym_eglUnmapImageSEC) &&
550                       (secsym_eglGetImageAttribSEC))
551                      shared->info.sec_image_map = 1;
552                }
553 #endif             
554           }
555         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
556                       &(shared->info.max_texture_units));
557         glGetIntegerv(GL_MAX_TEXTURE_SIZE,
558                       &(shared->info.max_texture_size));
559         shared->info.max_vertex_elements = 6 * 10000;
560 #ifdef GL_MAX_ELEMENTS_VERTICES
561         glGetIntegerv(GL_MAX_ELEMENTS_VERTICES,
562                       &(shared->info.max_vertex_elements));
563 #endif
564         s = getenv("EVAS_GL_VERTEX_MAX");
565         if (s) shared->info.max_vertex_elements = atoi(s);
566         if (shared->info.max_vertex_elements < 6)
567            shared->info.max_vertex_elements = 6;
568         
569         // magic numbers that are a result of imperical testing and getting
570         // "best case" performance across a range of systems
571         shared->info.tune.cutout.max                 = DEF_CUTOUT;
572         shared->info.tune.pipes.max                  = DEF_PIPES;
573         shared->info.tune.atlas.max_alloc_size       = DEF_ATLAS_ALLOC;
574         shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
575         shared->info.tune.atlas.max_w                = DEF_ATLAS_W;
576         shared->info.tune.atlas.max_h                = DEF_ATLAS_H;
577         shared->info.tune.atlas.slot_size            = DEF_ATLAS_SLOT;
578         
579         // per gpu hacks. based on impirical measurement of some known gpu's
580         s = (const char *)glGetString(GL_RENDERER);
581         if (s)
582           {
583              if      (strstr(s, "PowerVR SGX 540"))
584                 shared->info.tune.pipes.max = DEF_PIPES_SGX_540;
585              else if (strstr(s, "NVIDIA Tegra"))
586                 shared->info.tune.pipes.max = DEF_PIPES_TEGRA_2;
587           }
588         
589 #define GETENVOPT(name, tune_param, min, max) \
590         do { \
591            const char *__v = getenv(name); \
592            if (__v) { \
593               shared->info.tune.tune_param = atoi(__v); \
594               if (shared->info.tune.tune_param > max) \
595                  shared->info.tune.tune_param = max; \
596               else if (shared->info.tune.tune_param < min) \
597                  shared->info.tune.tune_param = min; \
598            } \
599         } while (0)
600
601         GETENVOPT("EVAS_GL_CUTOUT_MAX", cutout.max, -1, 0x7fffffff);
602         GETENVOPT("EVAS_GL_PIPES_MAX", pipes.max, 1, MAX_PIPES);
603         GETENVOPT("EVAS_GL_ATLAS_ALLOC_SIZE", atlas.max_alloc_size, MIN_ATLAS_ALLOC, MAX_ATLAS_ALLOC);
604         GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
605         GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
606         GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
607         GETENVOPT("EVAS_GL_ATLAS_SLOT_SIZE", atlas.slot_size, MIN_ATLAS_SLOT, MAX_ATLAS_SLOT);
608
609         if (getenv("EVAS_GL_INFO"))
610            fprintf(stderr,
611                    "max tex size %ix%i\n"
612                    "max units %i\n"
613                    "non-power-2 tex %i\n"
614                    "rect tex %i\n"
615                    "bgra : %i\n"
616                    "max ansiotropic filtering: %3.3f\n"
617                    "egl sec map image: %i\n"
618                    "max vertex count: %i\n"
619                    "\n"
620                    "(can set EVAS_GL_VERTEX_MAX  EVAS_GL_NO_MAP_IMAGE_SEC  EVAS_GL_INFO  EVAS_GL_MEMINFO )\n"
621                    "\n"
622                    "EVAS_GL_CUTOUT_MAX: %i\n"
623                    "EVAS_GL_PIPES_MAX: %i\n"
624                    "EVAS_GL_ATLAS_ALLOC_SIZE: %i\n"
625                    "EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE: %i\n"
626                    "EVAS_GL_ATLAS_MAX_W x EVAS_GL_ATLAS_MAX_H: %i x %i\n"
627                    "EVAS_GL_ATLAS_SLOT_SIZE: %i\n"
628                    , 
629                    (int)shared->info.max_texture_size, (int)shared->info.max_texture_size,
630                    (int)shared->info.max_texture_units,
631                    (int)shared->info.tex_npo2,
632                    (int)shared->info.tex_rect,
633                    (int)shared->info.bgra,
634                    (double)shared->info.anisotropic,
635                    (int)shared->info.sec_image_map,
636                    (int)shared->info.max_vertex_elements,
637                    
638                    (int)shared->info.tune.cutout.max,
639                    (int)shared->info.tune.pipes.max,
640                    (int)shared->info.tune.atlas.max_alloc_size,
641                    (int)shared->info.tune.atlas.max_alloc_alpha_size,
642                    (int)shared->info.tune.atlas.max_w, (int)shared->info.tune.atlas.max_h,
643                    (int)shared->info.tune.atlas.slot_size
644                   );
645         
646         glDisable(GL_DEPTH_TEST);
647         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
648         glEnable(GL_DITHER);
649         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
650         glDisable(GL_BLEND);
651         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
652         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
653         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
654         // no dest alpha
655 //        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // dest alpha
656 //        glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ???
657         glDepthMask(GL_FALSE);
658         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
659         
660         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
661         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
662         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
663         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
664         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
665         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
666         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
667         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
668 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
669         if (shared->info.anisotropic > 0.0)
670           {
671              glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
672              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
673           }
674 #endif
675         
676         glEnableVertexAttribArray(SHAD_VERTEX);
677         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
678         glEnableVertexAttribArray(SHAD_COLOR);
679         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
680
681         if (!evas_gl_common_shader_program_init(&(shared->shader.rect), 
682                                                 &(shader_rect_vert_src), 
683                                                 &(shader_rect_frag_src),
684                                                 "rect")) goto error;
685         if (!evas_gl_common_shader_program_init(&(shared->shader.font),
686                                                 &(shader_font_vert_src), 
687                                                 &(shader_font_frag_src),
688                                                 "font")) goto error;
689         if (!evas_gl_common_shader_program_init(&(shared->shader.img),
690                                                 &(shader_img_vert_src),
691                                                 &(shader_img_frag_src),
692                                                 "img")) goto error;
693         if (!evas_gl_common_shader_program_init(&(shared->shader.img_nomul),
694                                                 &(shader_img_nomul_vert_src),
695                                                 &(shader_img_nomul_frag_src),
696                                                 "img_nomul")) goto error;
697         if (!evas_gl_common_shader_program_init(&(shared->shader.img_bgra),
698                                                 &(shader_img_bgra_vert_src),
699                                                 &(shader_img_bgra_frag_src),
700                                                 "img_bgra")) goto error;
701         if (!evas_gl_common_shader_program_init(&(shared->shader.img_bgra_nomul),
702                                                 &(shader_img_bgra_nomul_vert_src),
703                                                 &(shader_img_bgra_nomul_frag_src),
704                                                 "img_bgra_nomul")) goto error;
705         if (!evas_gl_common_shader_program_init(&(shared->shader.img_mask),
706                                                 &(shader_img_mask_vert_src),
707                                                 &(shader_img_mask_frag_src),
708                                                 "img_mask")) goto error;
709         if (!evas_gl_common_shader_program_init(&(shared->shader.tex),
710                                                 &(shader_tex_vert_src), 
711                                                 &(shader_tex_frag_src),
712                                                 "tex")) goto error;
713         if (!evas_gl_common_shader_program_init(&(shared->shader.tex_nomul),
714                                                 &(shader_tex_nomul_vert_src), 
715                                                 &(shader_tex_nomul_frag_src),
716                                                 "tex_nomul")) goto error;
717         if (!evas_gl_common_shader_program_init(&(shared->shader.yuv),
718                                                 &(shader_yuv_vert_src), 
719                                                 &(shader_yuv_frag_src),
720                                                 "yuv")) goto error;
721         if (!evas_gl_common_shader_program_init(&(shared->shader.yuv_nomul),
722                                                 &(shader_yuv_nomul_vert_src), 
723                                                 &(shader_yuv_nomul_frag_src),
724                                                 "yuv_nomul")) goto error;
725         
726         glUseProgram(shared->shader.yuv.prog);
727         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
728         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "tex"), 0);
729         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
730         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texu"), 1);
731         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
732         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texv"), 2);
733         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
734         
735         glUseProgram(shared->shader.yuv_nomul.prog);
736         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
737         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "tex"), 0);
738         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
739         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texu"), 1);
740         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
741         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texv"), 2);
742         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
743
744         glUseProgram(shared->shader.img_mask.prog);
745         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
746         glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "tex"), 0);
747         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
748         glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "texm"), 1);
749         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
750
751
752
753         
754         glUseProgram(gc->pipe[0].shader.cur_prog);
755         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
756         // in shader:
757         // uniform sampler2D tex[8];
758         // 
759         // in code:
760         // GLuint texes[8];
761         // GLint loc = glGetUniformLocation(prog, "tex");
762         // glUniform1iv(loc, 8, texes);
763
764         shared->native_hash = eina_hash_int32_new(NULL);
765      }
766    gc->shared = shared;
767    gc->shared->references++;
768    _evas_gl_common_viewport_set(gc);
769    
770    gc->def_surface = evas_gl_common_image_surface_new(gc, 1, 1, 1);
771    
772    return gc;
773    error:
774    evas_gl_common_context_free(gc);
775    return NULL;
776 }
777
778 void
779 evas_gl_common_context_free(Evas_GL_Context *gc)
780 {
781    int i, j;
782    
783    gc->references--;
784    if (gc->references > 0) return;
785    if (gc->shared) gc->shared->references--;
786    
787    if (gc->def_surface) evas_gl_common_image_free(gc->def_surface);
788
789    if (gc->shared)
790      {
791         for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
792           {
793              if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
794              if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);
795              if (gc->pipe[i].array.texuv) free(gc->pipe[i].array.texuv);
796              if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
797              if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
798              if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
799           }
800      }
801    
802    if ((gc->shared) && (gc->shared->references == 0))
803      {
804         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.rect));
805         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.font));
806         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img));
807         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_nomul));
808         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra));
809         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra_nomul));
810         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_mask));
811         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv));
812         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv_nomul));
813         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex));
814         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex_nomul));
815         
816         while (gc->shared->images)
817           {
818              evas_gl_common_image_free(gc->shared->images->data);
819           }
820         while (gc->shared->tex.whole)
821           {
822              evas_gl_common_texture_free(gc->shared->tex.whole->data);
823           }
824         for (i = 0; i < 33; i++)
825           {
826              for (j = 0; j < 3; j++)
827                {
828                   while (gc->shared->tex.atlas[i][j])
829                     {
830                        evas_gl_common_texture_free
831                          ((Evas_GL_Texture *)gc->shared->tex.atlas[i][j]);
832                        gc->shared->tex.atlas[i][j] = NULL;
833                     }
834                }
835           }
836         eina_hash_free(gc->shared->native_hash);
837         free(gc->shared);
838         shared = NULL;
839      }
840    if (gc == _evas_gl_common_context) _evas_gl_common_context = NULL;
841    free(gc);
842 }
843
844 void
845 evas_gl_common_context_use(Evas_GL_Context *gc)
846 {
847    if (_evas_gl_common_context == gc) return;
848    _evas_gl_common_context = gc;
849    _evas_gl_common_viewport_set(gc);
850 }
851
852 void
853 evas_gl_common_context_newframe(Evas_GL_Context *gc)
854 {
855    int i;
856
857    if (dbgflushnum < 0)
858      {
859         dbgflushnum = 0;
860         if (getenv("EVAS_GL_DBG")) dbgflushnum = 1;
861      }
862    if (dbgflushnum) printf("----prev-flushnum: %i -----------------------------------\n", gc->flushnum);
863    
864    gc->flushnum = 0;
865    gc->state.current.cur_prog = 0;
866    gc->state.current.cur_tex = 0;
867    gc->state.current.cur_texu = 0;
868    gc->state.current.cur_texv = 0;
869    gc->state.current.cur_texm = 0;
870    gc->state.current.cur_texmu = 0;
871    gc->state.current.cur_texmv = 0;
872    gc->state.current.render_op = 0;
873    gc->state.current.smooth = 0;
874    gc->state.current.blend = 0;
875    gc->state.current.clip = 0;
876    gc->state.current.cx = 0;
877    gc->state.current.cy = 0;
878    gc->state.current.cw = 0;
879    gc->state.current.ch = 0;
880    
881    for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
882      {
883         gc->pipe[i].region.x = 0;
884         gc->pipe[i].region.y = 0;
885         gc->pipe[i].region.w = 0;
886         gc->pipe[i].region.h = 0;
887         gc->pipe[i].region.type = 0;
888         gc->pipe[i].clip.active = 0;
889         gc->pipe[i].clip.x = 0;
890         gc->pipe[i].clip.y = 0;
891         gc->pipe[i].clip.w = 0;
892         gc->pipe[i].clip.h = 0;
893         gc->pipe[i].shader.surface = NULL;
894         gc->pipe[i].shader.cur_prog = 0;
895         gc->pipe[i].shader.cur_tex = 0;
896         gc->pipe[i].shader.cur_texu = 0;
897         gc->pipe[i].shader.cur_texv = 0;
898         gc->pipe[i].shader.cur_texm = 0;
899         gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
900         gc->pipe[i].shader.smooth = 0;
901         gc->pipe[i].shader.blend = 0;
902         gc->pipe[i].shader.clip = 0;
903         gc->pipe[i].shader.cx = 0;
904         gc->pipe[i].shader.cy = 0;
905         gc->pipe[i].shader.cw = 0;
906         gc->pipe[i].shader.ch = 0;
907      }
908    gc->change.size = 1;
909    
910    glDisable(GL_SCISSOR_TEST);
911    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
912    glScissor(0, 0, 0, 0);
913    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
914    
915    glDisable(GL_DEPTH_TEST);
916    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
917    glEnable(GL_DITHER);
918    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
919    glDisable(GL_BLEND);
920    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
921    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
922    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
923    // no dest alpha
924 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // dest alpha
925 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ???
926    glDepthMask(GL_FALSE);
927    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
928         
929    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
930    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
931    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
932    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
933    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
934    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
935    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
936    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
937 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
938    if (shared->info.anisotropic > 0.0)
939      {
940         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
941         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
942      }
943 #endif
944    
945    glEnableVertexAttribArray(SHAD_VERTEX);
946    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
947    glEnableVertexAttribArray(SHAD_COLOR);
948    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
949    glUseProgram(gc->pipe[0].shader.cur_prog);
950    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
951
952
953
954    glActiveTexture(GL_TEXTURE0);
955    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
956    glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
957    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
958
959
960    _evas_gl_common_viewport_set(gc);
961 }
962
963 void
964 evas_gl_common_context_resize(Evas_GL_Context *gc, int w, int h, int rot)
965 {
966    if ((gc->w == w) && (gc->h == h) && (gc->rot == rot)) return;
967    evas_gl_common_context_flush(gc);
968    gc->change.size = 1;
969    gc->rot = rot;
970    gc->w = w;
971    gc->h = h;
972    if (_evas_gl_common_context == gc) _evas_gl_common_viewport_set(gc);
973 }
974
975 void
976 evas_gl_common_context_target_surface_set(Evas_GL_Context *gc,
977                                           Evas_GL_Image *surface)
978 {
979    if (surface == gc->pipe[0].shader.surface) return;
980    
981    evas_gl_common_context_flush(gc);
982    
983    gc->state.current.cur_prog = -1;
984    gc->state.current.cur_tex = -1;
985    gc->state.current.cur_texu = -1;
986    gc->state.current.cur_texv = -1;
987    gc->state.current.render_op = -1;
988    gc->state.current.smooth = -1;
989    gc->state.current.blend = -1;
990    gc->state.current.clip = -1;
991    gc->state.current.cx = -1;
992    gc->state.current.cy = -1;
993    gc->state.current.cw = -1;
994    gc->state.current.ch = -1;
995
996    gc->pipe[0].shader.surface = surface;
997    gc->change.size = 1;
998 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
999 # ifndef GL_FRAMEBUFFER
1000 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
1001 # endif   
1002 #else
1003 # ifndef GL_FRAMEBUFFER
1004 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
1005 # endif   
1006 #endif   
1007    if (gc->pipe[0].shader.surface == gc->def_surface)
1008      {
1009         glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
1010         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1011      }
1012    else
1013      {
1014         glsym_glBindFramebuffer(GL_FRAMEBUFFER, surface->tex->pt->fb);
1015         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1016      }
1017    _evas_gl_common_viewport_set(gc);
1018 }
1019
1020 #define PUSH_VERTEX(n, x, y, z) \
1021    gc->pipe[n].array.vertex[nv++] = x; \
1022    gc->pipe[n].array.vertex[nv++] = y; \
1023    gc->pipe[n].array.vertex[nv++] = z
1024 #define PUSH_COLOR(n, r, g, b, a) \
1025    gc->pipe[n].array.color[nc++] = r; \
1026    gc->pipe[n].array.color[nc++] = g; \
1027    gc->pipe[n].array.color[nc++] = b; \
1028    gc->pipe[n].array.color[nc++] = a
1029 #define PUSH_TEXUV(n, u, v) \
1030    gc->pipe[n].array.texuv[nu++] = u; \
1031    gc->pipe[n].array.texuv[nu++] = v
1032 #define PUSH_TEXUV2(n, u, v) \
1033    gc->pipe[n].array.texuv2[nu2++] = u; \
1034    gc->pipe[n].array.texuv2[nu2++] = v
1035 #define PUSH_TEXUV3(n, u, v) \
1036    gc->pipe[n].array.texuv3[nu3++] = u; \
1037    gc->pipe[n].array.texuv3[nu3++] = v
1038 #define PUSH_TEXM(n, u, v) \
1039    gc->pipe[n].array.texm[nm++] = u; \
1040    gc->pipe[n].array.texm[nm++] = v
1041
1042
1043 static inline void
1044 array_alloc(Evas_GL_Context *gc, int n)
1045 {
1046    if (gc->pipe[n].array.num <= gc->pipe[n].array.alloc) return;
1047    gc->pipe[n].array.alloc += 6 * 1024;
1048    if (gc->pipe[n].array.use_vertex)
1049      gc->pipe[n].array.vertex = realloc(gc->pipe[n].array.vertex,
1050                                 gc->pipe[n].array.alloc * sizeof(GLshort) * 3);
1051    if (gc->pipe[n].array.use_color)
1052      gc->pipe[n].array.color  = realloc(gc->pipe[n].array.color,
1053                                 gc->pipe[n].array.alloc * sizeof(GLubyte) * 4);
1054    if (gc->pipe[n].array.use_texuv)
1055      gc->pipe[n].array.texuv  = realloc(gc->pipe[n].array.texuv,
1056                                 gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1057    if (gc->pipe[n].array.use_texm)
1058      gc->pipe[n].array.texm  = realloc(gc->pipe[n].array.texm,
1059                                 gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1060    if (gc->pipe[n].array.use_texuv2)
1061      gc->pipe[n].array.texuv2  = realloc(gc->pipe[n].array.texuv2,
1062                                gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1063    if (gc->pipe[n].array.use_texuv3)
1064      gc->pipe[n].array.texuv3  = realloc(gc->pipe[n].array.texuv3,
1065                                  gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1066 }
1067
1068 static int
1069 pipe_region_intersects(Evas_GL_Context *gc, int n,
1070                        int x, int y, int w, int h)
1071 {
1072    int i, rx, ry, rw, rh, ii;
1073    
1074    rx = gc->pipe[n].region.x;
1075    ry = gc->pipe[n].region.y;
1076    rw = gc->pipe[n].region.w;
1077    rh = gc->pipe[n].region.h;
1078    if (!RECTS_INTERSECT(x, y, w, h, rx, ry, rw, rh))
1079       return 0;
1080    
1081    // a hack for now. map pipes use their whole bounding box for intersects
1082    // which at worst case reduces to old pipeline flushes, but cheaper than
1083    // full quad region or triangle intersects right now
1084    if (gc->pipe[n].region.type == RTYPE_MAP) return 1;
1085    
1086    for (i = 0, 
1087         ii = 0; 
1088         
1089         i < gc->pipe[n].array.num; 
1090         
1091         i += (3 * 2), 
1092         ii += (3 * 3 * 2))
1093      {  // tri 1...
1094         // 0, 1, 2 < top left
1095         // 3, 4, 5 < top right
1096         // 6. 7, 8 < bottom left
1097         rx = gc->pipe[n].array.vertex[ii + 0];
1098         ry = gc->pipe[n].array.vertex[ii + 1];
1099         rw = gc->pipe[n].array.vertex[ii + 3] - rx;
1100         rh = gc->pipe[n].array.vertex[ii + 7] - ry;
1101         if (RECTS_INTERSECT(x, y, w, h, rx, ry, rw, rh))
1102            return 1;
1103      }
1104    return 0;
1105 }
1106
1107 static void
1108 pipe_region_expand(Evas_GL_Context *gc, int n,
1109                    int x, int y, int w, int h)
1110 {
1111    int x1, y1, x2, y2;
1112    
1113    if (gc->pipe[n].region.w <= 0)
1114      {
1115         gc->pipe[n].region.x = x;
1116         gc->pipe[n].region.y = y;
1117         gc->pipe[n].region.w = w;
1118         gc->pipe[n].region.h = h;
1119         return;
1120      }
1121    x1 = gc->pipe[n].region.x;
1122    y1 = gc->pipe[n].region.y;
1123    x2 = gc->pipe[n].region.x + gc->pipe[n].region.w;
1124    y2 = gc->pipe[n].region.y + gc->pipe[n].region.h;
1125    if (x < x1) x1 = x;
1126    if (y < y1) y1 = y;
1127    if ((x + w) > x2) x2 = x + w;
1128    if ((y + h) > y2) y2 = y + h;
1129    gc->pipe[n].region.x = x1;
1130    gc->pipe[n].region.y = y1;
1131    gc->pipe[n].region.w = x2 - x1;
1132    gc->pipe[n].region.h = y2 - y1;
1133 }
1134
1135 static Eina_Bool
1136 vertex_array_size_check(Evas_GL_Context *gc, int pn, int n)
1137 {
1138    return 1;
1139 // this fixup breaks for expedite test 32. why?
1140    if ((gc->pipe[pn].array.num + n) > gc->shared->info.max_vertex_elements)
1141      {
1142         shader_array_flush(gc);
1143         return 0;
1144      }
1145    return 1;
1146 }
1147
1148 void
1149 evas_gl_common_context_line_push(Evas_GL_Context *gc, 
1150                                  int x1, int y1, int x2, int y2,
1151                                  int clip, int cx, int cy, int cw, int ch,
1152                                  int r, int g, int b, int a)
1153 {
1154    int pnum, nv, nc, nu, nt, i;
1155    Eina_Bool blend = 0;
1156    GLuint prog = gc->shared->shader.rect.prog;
1157    int pn = 0;
1158    
1159    if (a < 255) blend = 1;
1160    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
1161    
1162    shader_array_flush(gc);
1163    vertex_array_size_check(gc, gc->state.top_pipe, 2);
1164    pn = gc->state.top_pipe;
1165    gc->pipe[pn].shader.cur_tex = 0;
1166    gc->pipe[pn].shader.cur_prog = prog;
1167    gc->pipe[pn].shader.blend = blend;
1168    gc->pipe[pn].shader.render_op = gc->dc->render_op;
1169    gc->pipe[pn].shader.clip = clip;
1170    gc->pipe[pn].shader.cx = cx;
1171    gc->pipe[pn].shader.cy = cy;
1172    gc->pipe[pn].shader.cw = cw;
1173    gc->pipe[pn].shader.ch = ch;
1174    
1175    gc->pipe[pn].array.line = 1;
1176    gc->pipe[pn].array.use_vertex = 1;
1177    gc->pipe[pn].array.use_color = 1;
1178    gc->pipe[pn].array.use_texuv = 0;
1179    gc->pipe[pn].array.use_texuv2 = 0;
1180    gc->pipe[pn].array.use_texuv3 = 0;
1181    
1182    pnum = gc->pipe[pn].array.num;
1183    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
1184    gc->pipe[pn].array.num += 2;
1185    array_alloc(gc, pn);
1186   
1187    PUSH_VERTEX(pn, x1, y1, 0);
1188    PUSH_VERTEX(pn, x2, y2, 0);
1189    
1190    for (i = 0; i < 2; i++)
1191      {
1192         PUSH_COLOR(pn, r, g, b, a);
1193      }
1194    
1195    shader_array_flush(gc);
1196    gc->pipe[pn].array.line = 0;
1197    gc->pipe[pn].array.use_vertex = 0;
1198    gc->pipe[pn].array.use_color = 0;
1199    gc->pipe[pn].array.use_texuv = 0;
1200    gc->pipe[pn].array.use_texuv2 = 0;
1201    gc->pipe[pn].array.use_texuv3 = 0;
1202 }
1203
1204 void
1205 evas_gl_common_context_rectangle_push(Evas_GL_Context *gc,
1206                                       int x, int y, int w, int h,
1207                                       int r, int g, int b, int a)
1208 {
1209    int pnum, nv, nc, nu, nt, i;
1210    Eina_Bool blend = 0;
1211    GLuint prog = gc->shared->shader.rect.prog;
1212    int pn = 0;
1213
1214    if (gc->dc->mask.mask)
1215      {
1216         RGBA_Draw_Context *dc;
1217         dc = gc->dc;
1218         Evas_GL_Image *im;
1219         im = (void *)dc->mask.mask;
1220         evas_gl_common_context_font_push(gc, im->tex,
1221                                 x - dc->mask.x,y - dc->mask.y,
1222                                 dc->mask.w,dc->mask.h,
1223                                 x,y,w,h,r,g,b,a);
1224         return;
1225      }
1226
1227    if (a < 255) blend = 1;
1228    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
1229
1230 again:
1231    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1232    pn = gc->state.top_pipe;
1233 #ifdef GLPIPES
1234    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1235      {
1236         gc->pipe[pn].region.type = RTYPE_RECT;
1237         gc->pipe[pn].shader.cur_tex = 0;
1238         gc->pipe[pn].shader.cur_prog = prog;
1239         gc->pipe[pn].shader.blend = blend;
1240         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1241         gc->pipe[pn].shader.clip = 0;
1242         gc->pipe[pn].shader.cx = 0;
1243         gc->pipe[pn].shader.cy = 0;
1244         gc->pipe[pn].shader.cw = 0;
1245         gc->pipe[pn].shader.ch = 0;
1246         gc->pipe[pn].array.line = 0;
1247         gc->pipe[pn].array.use_vertex = 1;
1248         gc->pipe[pn].array.use_color = 1;
1249         gc->pipe[pn].array.use_texuv = 0;
1250         gc->pipe[pn].array.use_texuv2 = 0;
1251         gc->pipe[pn].array.use_texuv3 = 0;
1252      }
1253    else
1254      {
1255         int found = 0;
1256         
1257         for (i = pn; i >= 0; i--)
1258           {
1259              if ((gc->pipe[i].region.type == RTYPE_RECT)
1260                  && (gc->pipe[i].shader.cur_tex == 0)
1261                  && (gc->pipe[i].shader.cur_prog == prog)
1262                  && (gc->pipe[i].shader.blend == blend)
1263                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1264                  && (gc->pipe[i].shader.clip == 0)
1265                 )
1266                {
1267                   found = 1;
1268                   pn = i;
1269                   break;
1270                }
1271              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1272           }
1273         if (!found)
1274           {
1275              pn = gc->state.top_pipe + 1;
1276              if (pn >= gc->shared->info.tune.pipes.max)
1277                {
1278                   shader_array_flush(gc);
1279                   goto again;
1280                }
1281              gc->state.top_pipe = pn;
1282              gc->pipe[pn].region.type = RTYPE_RECT;
1283              gc->pipe[pn].shader.cur_tex = 0;
1284              gc->pipe[pn].shader.cur_prog = prog;
1285              gc->pipe[pn].shader.blend = blend;
1286              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1287              gc->pipe[pn].shader.clip = 0;
1288              gc->pipe[pn].shader.cx = 0;
1289              gc->pipe[pn].shader.cy = 0;
1290              gc->pipe[pn].shader.cw = 0;
1291              gc->pipe[pn].shader.ch = 0;
1292              gc->pipe[pn].array.line = 0;
1293              gc->pipe[pn].array.use_vertex = 1;
1294              gc->pipe[pn].array.use_color = 1;
1295              gc->pipe[pn].array.use_texuv = 0;
1296              gc->pipe[pn].array.use_texuv2 = 0;
1297              gc->pipe[pn].array.use_texuv3 = 0;
1298          }
1299      }
1300 #else   
1301    if ((gc->pipe[pn].shader.cur_tex != 0)
1302        || (gc->pipe[pn].shader.cur_prog != prog)
1303        || (gc->pipe[pn].shader.blend != blend)
1304        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1305        || (gc->pipe[pn].shader.clip != 0)
1306        )
1307      {
1308         shader_array_flush(gc);
1309         pn = gc->state.top_pipe;
1310         gc->pipe[pn].shader.cur_tex = 0;
1311         gc->pipe[pn].shader.cur_prog = prog;
1312         gc->pipe[pn].shader.blend = blend;
1313         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1314         gc->pipe[pn].shader.clip = 0;
1315         gc->pipe[pn].shader.cx = 0;
1316         gc->pipe[pn].shader.cy = 0;
1317         gc->pipe[pn].shader.cw = 0;
1318         gc->pipe[pn].shader.ch = 0;
1319      }
1320    
1321    gc->pipe[pn].region.type = RTYPE_RECT;
1322    gc->pipe[pn].array.line = 0;
1323    gc->pipe[pn].array.use_vertex = 1;
1324    gc->pipe[pn].array.use_color = 1;
1325    gc->pipe[pn].array.use_texuv = 0;
1326    gc->pipe[pn].array.use_texuv2 = 0;
1327    gc->pipe[pn].array.use_texuv3 = 0;
1328 #endif
1329    
1330    pipe_region_expand(gc, pn, x, y, w, h);
1331    
1332    pnum = gc->pipe[pn].array.num;
1333    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
1334    gc->pipe[pn].array.num += 6;
1335    array_alloc(gc, pn);
1336   
1337    PUSH_VERTEX(pn, x    , y    , 0);
1338    PUSH_VERTEX(pn, x + w, y    , 0);
1339    PUSH_VERTEX(pn, x    , y + h, 0);
1340    
1341    PUSH_VERTEX(pn, x + w, y    , 0);
1342    PUSH_VERTEX(pn, x + w, y + h, 0);
1343    PUSH_VERTEX(pn, x    , y + h, 0);
1344    
1345    for (i = 0; i < 6; i++)
1346      {
1347         PUSH_COLOR(pn, r, g, b, a);
1348      }
1349 }
1350
1351 void
1352 evas_gl_common_context_image_push(Evas_GL_Context *gc,
1353                                   Evas_GL_Texture *tex,
1354                                   double sx, double sy, double sw, double sh,
1355                                   int x, int y, int w, int h,
1356                                   int r, int g, int b, int a,
1357                                   Eina_Bool smooth, Eina_Bool tex_only)
1358 {
1359    int pnum, nv, nc, nu, nu2, nt, i;
1360    GLfloat tx1, tx2, ty1, ty2;
1361    Eina_Bool blend = 1;
1362    GLuint prog = gc->shared->shader.img.prog;
1363    int pn = 0;
1364
1365    if (!tex->alpha) blend = 0;
1366    if (a < 255) blend = 1;
1367    
1368    if (tex_only)
1369      {
1370         if (tex->pt->dyn.img)
1371           {
1372              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1373                 prog = gc->shared->shader.img_nomul.prog;
1374              else
1375                 prog = gc->shared->shader.img.prog;
1376           }
1377         else
1378           {
1379              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1380                 prog = gc->shared->shader.tex_nomul.prog;
1381              else
1382                 prog = gc->shared->shader.tex.prog;
1383           }
1384      }
1385    else
1386      {
1387         if (tex->gc->shared->info.bgra)
1388           {
1389              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1390                prog = gc->shared->shader.img_bgra_nomul.prog;
1391              else
1392                prog = gc->shared->shader.img_bgra.prog;
1393           }
1394         else
1395           {
1396              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1397                prog = gc->shared->shader.img_nomul.prog;
1398              else
1399                prog = gc->shared->shader.img.prog;
1400           }
1401      }
1402
1403 again:
1404    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1405    pn = gc->state.top_pipe;
1406 #ifdef GLPIPES
1407    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1408      {
1409         gc->pipe[pn].region.type = RTYPE_IMAGE;
1410         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1411         gc->pipe[pn].shader.cur_prog = prog;
1412         gc->pipe[pn].shader.smooth = smooth;
1413         gc->pipe[pn].shader.blend = blend;
1414         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1415         gc->pipe[pn].shader.clip = 0;
1416         gc->pipe[pn].shader.cx = 0;
1417         gc->pipe[pn].shader.cy = 0;
1418         gc->pipe[pn].shader.cw = 0;
1419         gc->pipe[pn].shader.ch = 0;
1420         gc->pipe[pn].array.line = 0;
1421         gc->pipe[pn].array.use_vertex = 1;
1422         // if nomul... dont need this
1423         gc->pipe[pn].array.use_color = 1;
1424         gc->pipe[pn].array.use_texuv = 1;
1425         gc->pipe[pn].array.use_texuv2 = 0;
1426         gc->pipe[pn].array.use_texuv3 = 0;
1427      }
1428    else
1429      {
1430         int found = 0;
1431         
1432         for (i = pn; i >= 0; i--)
1433           {
1434              if ((gc->pipe[i].region.type == RTYPE_IMAGE)
1435                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
1436                  && (gc->pipe[i].shader.cur_prog == prog)
1437                  && (gc->pipe[i].shader.smooth == smooth)
1438                  && (gc->pipe[i].shader.blend == blend)
1439                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1440                  && (gc->pipe[i].shader.clip == 0)
1441                 )
1442                {
1443                   found = 1;
1444                   pn = i;
1445                   break;
1446                }
1447              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1448           }
1449         if (!found)
1450           {
1451              pn = gc->state.top_pipe + 1;
1452              if (pn >= gc->shared->info.tune.pipes.max)
1453                {
1454                   shader_array_flush(gc);
1455                   goto again;
1456                }
1457              gc->state.top_pipe = pn;
1458              gc->pipe[pn].region.type = RTYPE_IMAGE;
1459              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1460              gc->pipe[pn].shader.cur_prog = prog;
1461              gc->pipe[pn].shader.smooth = smooth;
1462              gc->pipe[pn].shader.blend = blend;
1463              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1464              gc->pipe[pn].shader.clip = 0;
1465              gc->pipe[pn].shader.cx = 0;
1466              gc->pipe[pn].shader.cy = 0;
1467              gc->pipe[pn].shader.cw = 0;
1468              gc->pipe[pn].shader.ch = 0;
1469              gc->pipe[pn].array.line = 0;
1470              gc->pipe[pn].array.use_vertex = 1;
1471              // if nomul... dont need this
1472              gc->pipe[pn].array.use_color = 1;
1473              gc->pipe[pn].array.use_texuv = 1;
1474              gc->pipe[pn].array.use_texuv2 = 0;
1475              gc->pipe[pn].array.use_texuv3 = 0;
1476    
1477          }
1478      }
1479    if ((tex->im) && (tex->im->native.data))
1480      {
1481         if (gc->pipe[pn].array.im != tex->im)
1482           {
1483              shader_array_flush(gc);
1484              pn = gc->state.top_pipe;
1485              gc->pipe[pn].array.im = tex->im;
1486              goto again;
1487           }
1488      }
1489    if (tex->pt->dyn.img)
1490      {
1491         if (gc->pipe[pn].array.im != tex->im)
1492           {
1493              shader_array_flush(gc);
1494              pn = gc->state.top_pipe;
1495              gc->pipe[pn].array.im = tex->im;
1496              goto again;
1497           }
1498      }
1499 #else   
1500    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
1501        || (gc->pipe[pn].shader.cur_prog != prog)
1502        || (gc->pipe[pn].shader.smooth != smooth)
1503        || (gc->pipe[pn].shader.blend != blend)
1504        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1505        || (gc->pipe[pn].shader.clip != 0)
1506        )
1507      {
1508         shader_array_flush(gc);
1509         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1510         gc->pipe[pn].shader.cur_prog = prog;
1511         gc->pipe[pn].shader.smooth = smooth;
1512         gc->pipe[pn].shader.blend = blend;
1513         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1514         gc->pipe[pn].shader.clip = 0;
1515         gc->pipe[pn].shader.cx = 0;
1516         gc->pipe[pn].shader.cy = 0;
1517         gc->pipe[pn].shader.cw = 0;
1518         gc->pipe[pn].shader.ch = 0;
1519      } 
1520    if ((tex->im) && (tex->im->native.data))
1521      {
1522         if (gc->pipe[pn].array.im != tex->im)
1523           {
1524              shader_array_flush(gc);
1525              gc->pipe[pn].array.im = tex->im;
1526           }
1527      }
1528    if (tex->pt->dyn.img)
1529      {
1530         if (gc->pipe[pn].array.im != tex->im)
1531           {
1532              shader_array_flush(gc);
1533              gc->pipe[pn].array.im = tex->im;
1534           }
1535      }
1536
1537    gc->pipe[pn].array.line = 0;
1538    gc->pipe[pn].array.use_vertex = 1;
1539    // if nomul... dont need this
1540    gc->pipe[pn].array.use_color = 1;
1541    gc->pipe[pn].array.use_texuv = 1;
1542    gc->pipe[pn].array.use_texuvm = 0;
1543    gc->pipe[pn].array.use_texuv2 = 0;
1544    gc->pipe[pn].array.use_texuv3 = 0;
1545 #endif
1546
1547    pipe_region_expand(gc, pn, x, y, w, h);
1548   
1549    pnum = gc->pipe[pn].array.num;
1550    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
1551    nt = pnum * 4;
1552    gc->pipe[pn].array.num += 6;
1553    array_alloc(gc, pn);
1554
1555    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
1556      {
1557         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1558         ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1559         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1560         ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1561      }
1562    else
1563      {
1564         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1565         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1566         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1567         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1568      }
1569
1570    PUSH_VERTEX(pn, x    , y    , 0);
1571    PUSH_VERTEX(pn, x + w, y    , 0);
1572    PUSH_VERTEX(pn, x    , y + h, 0);
1573    
1574    PUSH_TEXUV(pn, tx1, ty1);
1575    PUSH_TEXUV(pn, tx2, ty1);
1576    PUSH_TEXUV(pn, tx1, ty2);
1577    
1578    PUSH_VERTEX(pn, x + w, y    , 0);
1579    PUSH_VERTEX(pn, x + w, y + h, 0);
1580    PUSH_VERTEX(pn, x    , y + h, 0);
1581    
1582    PUSH_TEXUV(pn, tx2, ty1);
1583    PUSH_TEXUV(pn, tx2, ty2);
1584    PUSH_TEXUV(pn, tx1, ty2);
1585
1586    // if nomul... dont need this
1587    for (i = 0; i < 6; i++)
1588      {
1589         PUSH_COLOR(pn, r, g, b, a);
1590      }
1591 }
1592
1593
1594 void
1595 evas_gl_common_context_image_mask_push(Evas_GL_Context *gc,
1596                                   Evas_GL_Texture *tex,
1597                                   Evas_GL_Texture *texm,
1598                                   double sx, double sy, double sw, double sh,
1599                                   double sxm, double sym, double swm,double shm,
1600                                   int x, int y, int w, int h,
1601                                   int r, int g, int b, int a,
1602                                   Eina_Bool smooth)
1603 {
1604    int pnum, nv, nc, nu, nm, nt, i;
1605    GLfloat tx1, tx2, ty1, ty2;
1606    GLfloat txm1, txm2, tym1, tym2;
1607    Eina_Bool blend = 1;
1608    GLuint prog = gc->shared->shader.img_mask.prog;
1609    int pn = 0;
1610
1611 #if 0
1612    if (tex->gc->shared->info.bgra)
1613    {
1614            prog = gc->shared->shader.img_mask.prog;
1615    }
1616    else
1617    {
1618 #warning Nash: FIXME: Need two shaders?
1619            printf("Not good: Need other texture\n");
1620            prog = gc->shared->shader.img.prog;
1621    }
1622 #endif
1623
1624 again:
1625    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1626    pn = gc->state.top_pipe;
1627 #ifdef GLPIPES
1628    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1629      {
1630         gc->pipe[pn].region.type = RTYPE_IMASK;
1631         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1632         gc->pipe[pn].shader.cur_texm = texm->pt->texture;
1633         gc->pipe[pn].shader.cur_prog = prog;
1634         gc->pipe[pn].shader.smooth = smooth;
1635         gc->pipe[pn].shader.blend = blend;
1636         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1637         gc->pipe[pn].shader.clip = 0;
1638         gc->pipe[pn].shader.cx = 0;
1639         gc->pipe[pn].shader.cy = 0;
1640         gc->pipe[pn].shader.cw = 0;
1641         gc->pipe[pn].shader.ch = 0;
1642         gc->pipe[pn].array.line = 0;
1643         gc->pipe[pn].array.use_vertex = 1;
1644         // if nomul... dont need this
1645         gc->pipe[pn].array.use_color = 1;
1646         gc->pipe[pn].array.use_texuv = 1;
1647         gc->pipe[pn].array.use_texuv2 = 0;
1648         gc->pipe[pn].array.use_texuv3 = 0;
1649         gc->pipe[pn].array.use_texm = 1;
1650      }
1651    else
1652      {
1653         int found = 0;
1654         
1655         for (i = pn; i >= 0; i--)
1656           {
1657              if ((gc->pipe[i].region.type == RTYPE_IMASK)
1658                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
1659                  && (gc->pipe[i].shader.cur_texm == texm->pt->texture)
1660                  && (gc->pipe[i].shader.cur_prog == prog)
1661                  && (gc->pipe[i].shader.smooth == smooth)
1662                  && (gc->pipe[i].shader.blend == blend)
1663                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1664                  && (gc->pipe[i].shader.clip == 0)
1665                 )
1666                {
1667                   found = 1;
1668                   pn = i;
1669                   break;
1670                }
1671              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1672           }
1673         if (!found)
1674           {
1675              pn = gc->state.top_pipe + 1;
1676              if (pn >= gc->shared->info.tune.pipes.max)
1677                {
1678                   shader_array_flush(gc);
1679                   goto again;
1680                }
1681              gc->state.top_pipe = pn;
1682              gc->pipe[pn].region.type = RTYPE_IMASK;
1683              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1684              gc->pipe[pn].shader.cur_texm = texm->pt->texture;
1685              gc->pipe[pn].shader.cur_prog = prog;
1686              gc->pipe[pn].shader.smooth = smooth;
1687              gc->pipe[pn].shader.blend = blend;
1688              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1689              gc->pipe[pn].shader.clip = 0;
1690              gc->pipe[pn].shader.cx = 0;
1691              gc->pipe[pn].shader.cy = 0;
1692              gc->pipe[pn].shader.cw = 0;
1693              gc->pipe[pn].shader.ch = 0;
1694              gc->pipe[pn].array.line = 0;
1695              gc->pipe[pn].array.use_vertex = 1;
1696              gc->pipe[pn].array.use_color = 1;
1697              gc->pipe[pn].array.use_texuv = 1;
1698              gc->pipe[pn].array.use_texuv2 = 0;
1699              gc->pipe[pn].array.use_texuv3 = 0;
1700              gc->pipe[pn].array.use_texm = 1;
1701    
1702          }
1703      }
1704    if ((tex->im) && (tex->im->native.data))
1705      {
1706         if (gc->pipe[pn].array.im != tex->im)
1707           {
1708              shader_array_flush(gc);
1709              pn = gc->state.top_pipe;
1710              gc->pipe[pn].array.im = tex->im;
1711              goto again;
1712           }
1713      }
1714    if (tex->pt->dyn.img)
1715      {
1716         if (gc->pipe[pn].array.im != tex->im)
1717           {
1718              shader_array_flush(gc);
1719              pn = gc->state.top_pipe;
1720              gc->pipe[pn].array.im = tex->im;
1721              goto again;
1722           }
1723      }
1724 #else   
1725    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
1726        || (gc->pipe[pn].shader.cur_prog != prog)
1727        || (gc->pipe[pn].shader.smooth != smooth)
1728        || (gc->pipe[pn].shader.blend != blend)
1729        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1730        || (gc->pipe[pn].shader.clip != 0)
1731        )
1732      {
1733         shader_array_flush(gc);
1734         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1735         gc->pipe[pn].shader.cur_texm = texm->pt->texture;
1736         gc->pipe[pn].shader.cur_prog = prog;
1737         gc->pipe[pn].shader.smooth = smooth;
1738         gc->pipe[pn].shader.blend = blend;
1739         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1740         gc->pipe[pn].shader.clip = 0;
1741         gc->pipe[pn].shader.cx = 0;
1742         gc->pipe[pn].shader.cy = 0;
1743         gc->pipe[pn].shader.cw = 0;
1744         gc->pipe[pn].shader.ch = 0;
1745      } 
1746    if ((tex->im) && (tex->im->native.data))
1747      {
1748         if (gc->pipe[pn].array.im != tex->im)
1749           {
1750              shader_array_flush(gc);
1751              gc->pipe[pn].array.im = tex->im;
1752           }
1753      }
1754    if (tex->pt->dyn.img)
1755      {
1756         if (gc->pipe[pn].array.im != tex->im)
1757           {
1758              shader_array_flush(gc);
1759              gc->pipe[pn].array.im = tex->im;
1760           }
1761      }
1762
1763    gc->pipe[pn].array.line = 0;
1764    gc->pipe[pn].array.use_vertex = 1;
1765    gc->pipe[pn].array.use_color = 1;
1766    gc->pipe[pn].array.use_texuv = 1;
1767    gc->pipe[pn].array.use_texuv2 = 0;
1768    gc->pipe[pn].array.use_texuv3 = 0;
1769    gc->pipe[pn].array.use_texm = 1;
1770 #endif
1771
1772    pipe_region_expand(gc, pn, x, y, w, h);
1773   
1774    pnum = gc->pipe[pn].array.num;
1775    nv = pnum * 3; nc = pnum * 4; nm = pnum * 2; nu = pnum * 2;
1776    nt = pnum * 4;
1777    gc->pipe[pn].array.num += 6;
1778    array_alloc(gc, pn);
1779
1780    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
1781      {
1782         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1783         ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1784         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1785         ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1786
1787         txm1 = ((double)(texm->x) + sxm) / (double)texm->pt->w;
1788         tym1 = ((double)(texm->y) + sym + shm) / (double)texm->pt->h;
1789         txm2 = ((double)(texm->x) + sxm + swm) / (double)texm->pt->w;
1790         tym2 = ((double)(texm->y) + sym) / (double)texm->pt->h;
1791      }
1792    else
1793      {
1794              printf("B:\n");
1795         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1796         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1797         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1798         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1799
1800         txm1 = (texm->x + sxm) / (double)texm->pt->w;
1801         tym1 = (texm->y + sy) / (double)texm->pt->h;
1802         txm2 = (texm->x + sxm + swm) / (double)texm->pt->w;
1803         tym2 = (texm->y + sy + sh) / (double)texm->pt->h;
1804      }
1805   printf(" %3.6lf %3.6lf %3.6lf %3.6lf\n",sx,sy,sw,sh);
1806   printf("m%3.6lf %3.6lf %3.6lf %3.6lf\n",sxm,sym,swm,shm);
1807   printf(" %3f %3f %3f %3f\n",tx1,ty1,tx2,ty2);
1808   printf("m%3f %3f %3f %3f\n",txm1,tym1,txm2,tym2);
1809
1810    PUSH_VERTEX(pn, x    , y    , 0);
1811    PUSH_VERTEX(pn, x + w, y    , 0);
1812    PUSH_VERTEX(pn, x    , y + h, 0);
1813    
1814    PUSH_TEXUV(pn, tx1, ty1);
1815    PUSH_TEXUV(pn, tx2, ty1);
1816    PUSH_TEXUV(pn, tx1, ty2);
1817
1818    PUSH_TEXM(pn, txm1, tym1);
1819    PUSH_TEXM(pn, txm2, tym1);
1820    PUSH_TEXM(pn, txm1, tym2);
1821
1822    PUSH_VERTEX(pn, x + w, y    , 0);
1823    PUSH_VERTEX(pn, x + w, y + h, 0);
1824    PUSH_VERTEX(pn, x    , y + h, 0);
1825    
1826    PUSH_TEXUV(pn, tx2, ty1);
1827    PUSH_TEXUV(pn, tx2, ty2);
1828    PUSH_TEXUV(pn, tx1, ty2);
1829
1830    PUSH_TEXM(pn, txm2, tym1);
1831    PUSH_TEXM(pn, txm2, tym2);
1832    PUSH_TEXM(pn, txm1, tym2);
1833
1834    // if nomul... dont need this
1835    for (i = 0; i < 6; i++)
1836      {
1837         PUSH_COLOR(pn, r, g, b, a);
1838      }
1839 }
1840
1841
1842 void
1843 evas_gl_common_context_font_push(Evas_GL_Context *gc,
1844                                  Evas_GL_Texture *tex,
1845                                  double sx, double sy, double sw, double sh,
1846                                  int x, int y, int w, int h,
1847                                  int r, int g, int b, int a)
1848 {
1849    int pnum, nv, nc, nu, nt, i;
1850    GLfloat tx1, tx2, ty1, ty2;
1851    int pn = 0;
1852
1853 again:
1854    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1855    pn = gc->state.top_pipe;
1856 #ifdef GLPIPES
1857    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1858      {
1859         gc->pipe[pn].region.type = RTYPE_FONT;
1860         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1861         gc->pipe[pn].shader.cur_prog = gc->shared->shader.font.prog;
1862         gc->pipe[pn].shader.smooth = 0;
1863         gc->pipe[pn].shader.blend = 1;
1864         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1865         gc->pipe[pn].shader.clip = 0;
1866         gc->pipe[pn].shader.cx = 0;
1867         gc->pipe[pn].shader.cy = 0;
1868         gc->pipe[pn].shader.cw = 0;
1869         gc->pipe[pn].shader.ch = 0;
1870         gc->pipe[pn].array.line = 0;
1871         gc->pipe[pn].array.use_vertex = 1;
1872         gc->pipe[pn].array.use_color = 1;
1873         gc->pipe[pn].array.use_texuv = 1;
1874         gc->pipe[pn].array.use_texuv2 = 0;
1875         gc->pipe[pn].array.use_texuv3 = 0;
1876      }
1877    else
1878      {
1879         int found = 0;
1880         
1881         for (i = pn; i >= 0; i--)
1882           {
1883              if ((gc->pipe[i].region.type == RTYPE_FONT)
1884                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
1885                  && (gc->pipe[i].shader.cur_prog == gc->shared->shader.font.prog)
1886                  && (gc->pipe[i].shader.smooth == 0)
1887                  && (gc->pipe[i].shader.blend == 1)
1888                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1889                  && (gc->pipe[i].shader.clip == 0)
1890                 )
1891                {
1892                   found = 1;
1893                   pn = i;
1894                   break;
1895                }
1896              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1897           }
1898         if (!found)
1899           {
1900              pn = gc->state.top_pipe + 1;
1901              if (pn >= gc->shared->info.tune.pipes.max)
1902                {
1903                   shader_array_flush(gc);
1904                   goto again;
1905                }
1906              gc->state.top_pipe = pn;
1907              gc->pipe[pn].region.type = RTYPE_FONT;
1908              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1909              gc->pipe[pn].shader.cur_prog = gc->shared->shader.font.prog;
1910              gc->pipe[pn].shader.smooth = 0;
1911              gc->pipe[pn].shader.blend = 1;
1912              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1913              gc->pipe[pn].shader.clip = 0;
1914              gc->pipe[pn].shader.cx = 0;
1915              gc->pipe[pn].shader.cy = 0;
1916              gc->pipe[pn].shader.cw = 0;
1917              gc->pipe[pn].shader.ch = 0;
1918              gc->pipe[pn].array.line = 0;
1919              gc->pipe[pn].array.use_vertex = 1;
1920              gc->pipe[pn].array.use_color = 1;
1921              gc->pipe[pn].array.use_texuv = 1;
1922              gc->pipe[pn].array.use_texuv2 = 0;
1923              gc->pipe[pn].array.use_texuv3 = 0;
1924          }
1925      }
1926 #else   
1927    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
1928        || (gc->pipe[pn].shader.cur_prog != gc->shared->shader.font.prog)
1929        || (gc->pipe[pn].shader.smooth != 0)
1930        || (gc->pipe[pn].shader.blend != 1)
1931        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1932        || (gc->pipe[pn].shader.clip != 0)
1933        )
1934      {
1935         shader_array_flush(gc);
1936         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1937         gc->pipe[pn].shader.cur_prog = gc->shared->shader.font.prog;
1938         gc->pipe[pn].shader.smooth = 0;
1939         gc->pipe[pn].shader.blend = 1;
1940         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1941         gc->pipe[pn].shader.clip = 0;
1942         gc->pipe[pn].shader.cx = 0;
1943         gc->pipe[pn].shader.cy = 0;
1944         gc->pipe[pn].shader.cw = 0;
1945         gc->pipe[pn].shader.ch = 0;
1946      }
1947
1948    gc->pipe[pn].region.type = RTYPE_FONT;
1949    gc->pipe[pn].array.line = 0;
1950    gc->pipe[pn].array.use_vertex = 1;
1951    gc->pipe[pn].array.use_color = 1;
1952    gc->pipe[pn].array.use_texuv = 1;
1953    gc->pipe[pn].array.use_texuv2 = 0;
1954    gc->pipe[pn].array.use_texuv3 = 0;
1955 #endif
1956    
1957    pipe_region_expand(gc, pn, x, y, w, h);
1958    
1959    pnum = gc->pipe[pn].array.num;
1960    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
1961    gc->pipe[pn].array.num += 6;
1962    array_alloc(gc, pn);
1963
1964    if (sw == 0.0)
1965      {
1966         tx1 = tex->sx1;
1967         ty1 = tex->sy1;
1968         tx2 = tex->sx2;
1969         ty2 = tex->sy2;
1970      }
1971    else
1972      {
1973         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1974         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1975         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1976         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1977      }
1978    
1979    PUSH_VERTEX(pn, x    , y    , 0);
1980    PUSH_VERTEX(pn, x + w, y    , 0);
1981    PUSH_VERTEX(pn, x    , y + h, 0);
1982    
1983    PUSH_TEXUV(pn, tx1, ty1);
1984    PUSH_TEXUV(pn, tx2, ty1);
1985    PUSH_TEXUV(pn, tx1, ty2);
1986    
1987    PUSH_VERTEX(pn, x + w, y    , 0);
1988    PUSH_VERTEX(pn, x + w, y + h, 0);
1989    PUSH_VERTEX(pn, x    , y + h, 0);
1990    
1991    PUSH_TEXUV(pn, tx2, ty1);
1992    PUSH_TEXUV(pn, tx2, ty2);
1993    PUSH_TEXUV(pn, tx1, ty2);
1994
1995    for (i = 0; i < 6; i++)
1996      {
1997         PUSH_COLOR(pn, r, g, b, a);
1998      }
1999 }
2000
2001 void
2002 evas_gl_common_context_yuv_push(Evas_GL_Context *gc,
2003                                 Evas_GL_Texture *tex, 
2004                                 double sx, double sy, double sw, double sh,
2005                                 int x, int y, int w, int h,
2006                                 int r, int g, int b, int a,
2007                                 Eina_Bool smooth)
2008 {
2009    int pnum, nv, nc, nu, nu2, nu3, nt, i;
2010    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
2011    Eina_Bool blend = 0;
2012    GLuint prog = gc->shared->shader.yuv.prog;
2013    int pn = 0;
2014
2015    if (a < 255) blend = 1;
2016    
2017    if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2018      prog = gc->shared->shader.yuv_nomul.prog;
2019    else
2020      prog = gc->shared->shader.yuv.prog;
2021    
2022 again:
2023    vertex_array_size_check(gc, gc->state.top_pipe, 6);
2024    pn = gc->state.top_pipe;
2025 #ifdef GLPIPES
2026    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
2027      {
2028         gc->pipe[pn].region.type = RTYPE_YUV;
2029         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2030         gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2031         gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2032         gc->pipe[pn].shader.cur_prog = prog;
2033         gc->pipe[pn].shader.smooth = smooth;
2034         gc->pipe[pn].shader.blend = blend;
2035         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2036         gc->pipe[pn].shader.clip = 0;
2037         gc->pipe[pn].shader.cx = 0;
2038         gc->pipe[pn].shader.cy = 0;
2039         gc->pipe[pn].shader.cw = 0;
2040         gc->pipe[pn].shader.ch = 0;
2041         gc->pipe[pn].array.line = 0;
2042         gc->pipe[pn].array.use_vertex = 1;
2043         gc->pipe[pn].array.use_color = 1;
2044         gc->pipe[pn].array.use_texuv = 1;
2045         gc->pipe[pn].array.use_texuv2 = 1;
2046         gc->pipe[pn].array.use_texuv3 = 1;
2047      }
2048    else
2049      {
2050         int found = 0;
2051         
2052         for (i = pn; i >= 0; i--)
2053           {
2054              if ((gc->pipe[i].region.type == RTYPE_YUV)
2055                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
2056                  && (gc->pipe[i].shader.cur_prog == gc->shared->shader.font.prog)
2057                  && (gc->pipe[i].shader.smooth == smooth)
2058                  && (gc->pipe[i].shader.blend == blend)
2059                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
2060                  && (gc->pipe[i].shader.clip == 0)
2061                 )
2062                {
2063                   found = 1;
2064                   pn = i;
2065                   break;
2066                }
2067              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
2068           }
2069         if (!found)
2070           {
2071              pn = gc->state.top_pipe + 1;
2072              if (pn >= gc->shared->info.tune.pipes.max)
2073                {
2074                   shader_array_flush(gc);
2075                   goto again;
2076                }
2077              gc->state.top_pipe = pn;
2078              gc->pipe[pn].region.type = RTYPE_YUV;
2079              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2080              gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2081              gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2082              gc->pipe[pn].shader.cur_prog = prog;
2083              gc->pipe[pn].shader.smooth = smooth;
2084              gc->pipe[pn].shader.blend = blend;
2085              gc->pipe[pn].shader.render_op = gc->dc->render_op;
2086              gc->pipe[pn].shader.clip = 0;
2087              gc->pipe[pn].shader.cx = 0;
2088              gc->pipe[pn].shader.cy = 0;
2089              gc->pipe[pn].shader.cw = 0;
2090              gc->pipe[pn].shader.ch = 0;
2091              gc->pipe[pn].array.line = 0;
2092              gc->pipe[pn].array.use_vertex = 1;
2093              gc->pipe[pn].array.use_color = 1;
2094              gc->pipe[pn].array.use_texuv = 1;
2095              gc->pipe[pn].array.use_texuv2 = 1;
2096              gc->pipe[pn].array.use_texuv3 = 1;
2097          }
2098      }
2099 #else   
2100    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
2101        || (gc->pipe[pn].shader.cur_prog != prog)
2102        || (gc->pipe[pn].shader.smooth != smooth)
2103        || (gc->pipe[pn].shader.blend != blend)
2104        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
2105        || (gc->pipe[pn].shader.clip != 0)
2106        )
2107      {
2108         shader_array_flush(gc);
2109         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2110         gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2111         gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2112         gc->pipe[pn].shader.cur_prog = prog;
2113         gc->pipe[pn].shader.smooth = smooth;
2114         gc->pipe[pn].shader.blend = blend;
2115         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2116         gc->pipe[pn].shader.clip = 0;
2117         gc->pipe[pn].shader.cx = 0;
2118         gc->pipe[pn].shader.cy = 0;
2119         gc->pipe[pn].shader.cw = 0;
2120         gc->pipe[pn].shader.ch = 0;
2121      }
2122    
2123    gc->pipe[pn].region.type = RTYPE_YUV;
2124    gc->pipe[pn].array.line = 0;
2125    gc->pipe[pn].array.use_vertex = 1;
2126    gc->pipe[pn].array.use_color = 1;
2127    gc->pipe[pn].array.use_texuv = 1;
2128    gc->pipe[pn].array.use_texuv2 = 1;
2129    gc->pipe[pn].array.use_texuv3 = 1;
2130 #endif
2131    
2132    pipe_region_expand(gc, pn, x, y, w, h);
2133    
2134    pnum = gc->pipe[pn].array.num;
2135    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; 
2136    nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
2137    gc->pipe[pn].array.num += 6;
2138    array_alloc(gc, pn);
2139
2140    tx1 = (sx) / (double)tex->pt->w;
2141    ty1 = (sy) / (double)tex->pt->h;
2142    tx2 = (sx + sw) / (double)tex->pt->w;
2143    ty2 = (sy + sh) / (double)tex->pt->h;
2144    
2145    t2x1 = ((sx) / 2) / (double)tex->ptu->w;
2146    t2y1 = ((sy) / 2) / (double)tex->ptu->h;
2147    t2x2 = ((sx + sw) / 2) / (double)tex->ptu->w;
2148    t2y2 = ((sy + sh) / 2) / (double)tex->ptu->h;
2149    
2150    PUSH_VERTEX(pn, x    , y    , 0);
2151    PUSH_VERTEX(pn, x + w, y    , 0);
2152    PUSH_VERTEX(pn, x    , y + h, 0);
2153    
2154    PUSH_TEXUV(pn, tx1, ty1);
2155    PUSH_TEXUV(pn, tx2, ty1);
2156    PUSH_TEXUV(pn, tx1, ty2);
2157    
2158    PUSH_TEXUV2(pn, t2x1, t2y1);
2159    PUSH_TEXUV2(pn, t2x2, t2y1);
2160    PUSH_TEXUV2(pn, t2x1, t2y2);
2161    
2162    PUSH_TEXUV3(pn, t2x1, t2y1);
2163    PUSH_TEXUV3(pn, t2x2, t2y1);
2164    PUSH_TEXUV3(pn, t2x1, t2y2);
2165    
2166    PUSH_VERTEX(pn, x + w, y    , 0);
2167    PUSH_VERTEX(pn, x + w, y + h, 0);
2168    PUSH_VERTEX(pn, x    , y + h, 0);
2169    
2170    PUSH_TEXUV(pn, tx2, ty1);
2171    PUSH_TEXUV(pn, tx2, ty2);
2172    PUSH_TEXUV(pn, tx1, ty2);
2173
2174    PUSH_TEXUV2(pn, t2x2, t2y1);
2175    PUSH_TEXUV2(pn, t2x2, t2y2);
2176    PUSH_TEXUV2(pn, t2x1, t2y2);
2177
2178    PUSH_TEXUV3(pn, t2x2, t2y1);
2179    PUSH_TEXUV3(pn, t2x2, t2y2);
2180    PUSH_TEXUV3(pn, t2x1, t2y2);
2181
2182    for (i = 0; i < 6; i++)
2183      {
2184         PUSH_COLOR(pn, r, g, b, a);
2185      }
2186 }
2187
2188 void
2189 evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
2190                                        Evas_GL_Texture *tex,
2191                                        RGBA_Map_Point *p,
2192                                        int clip, int cx, int cy, int cw, int ch,
2193                                        int r, int g, int b, int a,
2194                                        Eina_Bool smooth, Eina_Bool tex_only,
2195                                        Eina_Bool yuv)
2196 {
2197    int pnum, nv, nc, nu, nu2, nu3, nt, i;
2198    const int points[6] = { 0, 1, 2, 0, 2, 3 };
2199    int x = 0, y = 0, w = 0, h = 0, px = 0, py = 0;
2200    GLfloat tx[4], ty[4], t2x[4], t2y[4];
2201    Eina_Bool blend = 1;
2202    DATA32 cmul;
2203    GLuint prog = gc->shared->shader.img.prog;
2204    int pn = 0;
2205    int flat = 0;
2206
2207    if (!tex->alpha) blend = 0;
2208    if (a < 255) blend = 1;
2209    if ((A_VAL(&(p[0].col)) < 0xff) || (A_VAL(&(p[1].col)) < 0xff) ||
2210        (A_VAL(&(p[2].col)) < 0xff) || (A_VAL(&(p[3].col)) < 0xff))
2211      blend = 1;
2212    
2213    if ((p[0].z == p[1].z) && (p[1].z == p[2].z) && (p[2].z == p[3].z))
2214       flat = 1;
2215
2216    if (!clip) cx = cy = cw = ch = 0;
2217    
2218    if (!flat)
2219      {
2220         if (p[0].foc <= 0) flat = 1;
2221      }
2222    if (yuv)
2223      {
2224         prog = gc->shared->shader.yuv.prog;
2225         if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2226           {
2227              if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2228                  (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2229                 prog = gc->shared->shader.yuv_nomul.prog;
2230              else
2231                 prog = gc->shared->shader.yuv.prog;
2232           }
2233         else
2234            prog = gc->shared->shader.yuv.prog;
2235      }
2236    else
2237      {
2238         if (tex_only)
2239           {
2240              if (tex->pt->dyn.img)
2241                {
2242                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2243                     {
2244                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2245                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2246                           prog = gc->shared->shader.img_nomul.prog;
2247                        else
2248                           prog = gc->shared->shader.img.prog;
2249                     }
2250                   else
2251                      prog = gc->shared->shader.img.prog;
2252                }
2253              else
2254                {
2255                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2256                     {
2257                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2258                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2259                           prog = gc->shared->shader.tex_nomul.prog;
2260                        else
2261                           prog = gc->shared->shader.tex.prog;
2262                     }
2263                   else
2264                      prog = gc->shared->shader.tex.prog;
2265                }
2266           }
2267         else
2268           {
2269              if (tex->gc->shared->info.bgra)
2270                {
2271                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2272                     {
2273                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2274                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2275                           prog = gc->shared->shader.img_bgra_nomul.prog;
2276                        else
2277                           prog = gc->shared->shader.img_bgra.prog;
2278                     }
2279                   else
2280                      prog = gc->shared->shader.img_bgra.prog;
2281                }
2282              else
2283                {
2284                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2285                     {
2286                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2287                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2288                           prog = gc->shared->shader.img_nomul.prog;
2289                        else
2290                           prog = gc->shared->shader.img.prog;
2291                     }
2292                   else
2293                      prog = gc->shared->shader.img.prog;
2294                }
2295           }
2296      }
2297    
2298    if (!flat)
2299      {
2300         shader_array_flush(gc);
2301         gc->foc = p[0].foc >> FP;
2302         gc->z0 = p[0].z0 >> FP;
2303         gc->px = p[0].px >> FP;
2304         gc->py = p[0].py >> FP;
2305         gc->change.size = 1;
2306         _evas_gl_common_viewport_set(gc);
2307      }
2308 again:
2309    vertex_array_size_check(gc, gc->state.top_pipe, 6);
2310    pn = gc->state.top_pipe;
2311 #ifdef GLPIPES
2312    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
2313      {
2314         gc->pipe[pn].region.type = RTYPE_MAP;
2315         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2316         if (yuv)
2317           {
2318              gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2319              gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2320           }
2321         gc->pipe[pn].shader.cur_prog = prog;
2322         gc->pipe[pn].shader.smooth = smooth;
2323         gc->pipe[pn].shader.blend = blend;
2324         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2325         gc->pipe[pn].shader.clip = clip;
2326         gc->pipe[pn].shader.cx = cx;
2327         gc->pipe[pn].shader.cy = cy;
2328         gc->pipe[pn].shader.cw = cw;
2329         gc->pipe[pn].shader.ch = ch;
2330         gc->pipe[pn].array.line = 0;
2331         gc->pipe[pn].array.use_vertex = 1;
2332         gc->pipe[pn].array.use_color = 1;
2333         gc->pipe[pn].array.use_texuv = 1;
2334         if (yuv)
2335           {
2336              gc->pipe[pn].array.use_texuv2 = 1;
2337              gc->pipe[pn].array.use_texuv3 = 1;
2338           }
2339         else
2340           {
2341              gc->pipe[pn].array.use_texuv2 = 0;
2342              gc->pipe[pn].array.use_texuv3 = 0;
2343           }
2344      }
2345    else
2346      {
2347         int found = 0;
2348         
2349         for (i = pn; i >= 0; i--)
2350           {
2351              if ((gc->pipe[i].region.type == RTYPE_MAP)
2352                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
2353                  && (gc->pipe[i].shader.cur_prog == prog)
2354                  && (gc->pipe[i].shader.smooth == smooth)
2355                  && (gc->pipe[i].shader.blend == blend)
2356                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
2357                  && (gc->pipe[i].shader.clip == clip)
2358                  && (gc->pipe[i].shader.cx == cx)
2359                  && (gc->pipe[i].shader.cy == cy)
2360                  && (gc->pipe[i].shader.cw == cw)
2361                  && (gc->pipe[i].shader.ch == ch)
2362                 )
2363                {
2364                   found = 1;
2365                   pn = i;
2366                   break;
2367                }
2368              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
2369           }
2370         if (!found)
2371           {
2372              pn = gc->state.top_pipe + 1;
2373              if (pn >= gc->shared->info.tune.pipes.max)
2374                {
2375                   shader_array_flush(gc);
2376                   goto again;
2377                }
2378              gc->state.top_pipe = pn;
2379              gc->pipe[pn].region.type = RTYPE_MAP;
2380              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2381              if (yuv)
2382                {
2383                   gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2384                   gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2385                }
2386              gc->pipe[pn].shader.cur_prog = prog;
2387              gc->pipe[pn].shader.smooth = smooth;
2388              gc->pipe[pn].shader.blend = blend;
2389              gc->pipe[pn].shader.render_op = gc->dc->render_op;
2390              gc->pipe[pn].shader.clip = clip;
2391              gc->pipe[pn].shader.cx = cx;
2392              gc->pipe[pn].shader.cy = cy;
2393              gc->pipe[pn].shader.cw = cw;
2394              gc->pipe[pn].shader.ch = ch;
2395              gc->pipe[pn].array.line = 0;
2396              gc->pipe[pn].array.use_vertex = 1;
2397              gc->pipe[pn].array.use_color = 1;
2398              gc->pipe[pn].array.use_texuv = 1;
2399              if (yuv)
2400                {
2401                   gc->pipe[pn].array.use_texuv2 = 1;
2402                   gc->pipe[pn].array.use_texuv3 = 1;
2403                }
2404              else
2405                {
2406                   gc->pipe[pn].array.use_texuv2 = 0;
2407                   gc->pipe[pn].array.use_texuv3 = 0;
2408                }
2409          }
2410      }
2411    if ((tex->im) && (tex->im->native.data))
2412      {
2413         if (gc->pipe[pn].array.im != tex->im)
2414           {
2415              shader_array_flush(gc);
2416              pn = gc->state.top_pipe;
2417              gc->pipe[pn].array.im = tex->im;
2418              goto again;
2419           }
2420      }
2421    if (tex->pt->dyn.img)
2422      {
2423         if (gc->pipe[pn].array.im != tex->im)
2424           {
2425              shader_array_flush(gc);
2426              pn = gc->state.top_pipe;
2427              gc->pipe[pn].array.im = tex->im;
2428              goto again;
2429           }
2430      }
2431 #else   
2432    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
2433        || (gc->pipe[pn].shader.cur_prog != prog)
2434        || (gc->pipe[pn].shader.smooth != smooth)
2435        || (gc->pipe[pn].shader.blend != blend)
2436        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
2437        || (gc->pipe[pn].shader.clip != clip)
2438        || (gc->pipe[pn].shader.cx != cx)
2439        || (gc->pipe[pn].shader.cy != cy)
2440        || (gc->pipe[pn].shader.cw != cw)
2441        || (gc->pipe[pn].shader.ch != ch)
2442        )
2443      {
2444         shader_array_flush(gc);
2445         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2446         gc->pipe[pn].shader.cur_prog = prog;
2447         gc->pipe[pn].shader.smooth = smooth;
2448         gc->pipe[pn].shader.blend = blend;
2449         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2450         gc->pipe[pn].shader.clip = clip;
2451         gc->pipe[pn].shader.cx = cx;
2452         gc->pipe[pn].shader.cy = cy;
2453         gc->pipe[pn].shader.cw = cw;
2454         gc->pipe[pn].shader.ch = ch;
2455      }
2456    if ((tex->im) && (tex->im->native.data))
2457      {
2458         if (gc->pipe[pn].array.im != tex->im)
2459           {
2460              shader_array_flush(gc);
2461              gc->pipe[pn].array.im = tex->im;
2462           }
2463      }
2464    if (tex->pt->dyn.img)
2465      {
2466         if (gc->pipe[pn].array.im != tex->im)
2467           {
2468              shader_array_flush(gc);
2469              gc->pipe[pn].array.im = tex->im;
2470           }
2471      }
2472
2473    gc->pipe[pn].region.type = RTYPE_MAP;
2474    gc->pipe[pn].array.line = 0;
2475    gc->pipe[pn].array.use_vertex = 1;
2476    gc->pipe[pn].array.use_color = 1;
2477    gc->pipe[pn].array.use_texuv = 1;
2478    if (yuv)
2479      {
2480         gc->pipe[pn].array.use_texuv2 = 1;
2481         gc->pipe[pn].array.use_texuv3 = 1;
2482      }
2483    else
2484      {
2485         gc->pipe[pn].array.use_texuv2 = 0;
2486         gc->pipe[pn].array.use_texuv3 = 0;
2487      }
2488 #endif   
2489    
2490    x = w = (p[points[0]].x >> FP);
2491    y = h = (p[points[0]].y >> FP);
2492    for (i = 0; i < 4; i++)
2493      {
2494         tx[i] = ((double)(tex->x) + (((double)p[i].u) / FP1)) /
2495           (double)tex->pt->w;
2496         ty[i] = ((double)(tex->y) + (((double)p[i].v) / FP1)) / 
2497           (double)tex->pt->h;
2498         px = (p[points[i]].x >> FP);
2499         if      (px < x) x = px;
2500         else if (px > w) w = py;
2501         py = (p[points[i]].y >> FP);
2502         if      (py < y) y = py;
2503         else if (py > h) h = py;
2504         if (yuv)
2505           {
2506              t2x[i] = ((((double)p[i].u / 2) / FP1)) / (double)tex->ptu->w;
2507              t2y[i] = ((((double)p[i].v / 2) / FP1)) / (double)tex->ptu->h;
2508           }
2509      }
2510    w = w - x;
2511    h = h - y;
2512    
2513    pipe_region_expand(gc, pn, x, y, w, h);
2514    
2515    pnum = gc->pipe[pn].array.num;
2516    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
2517    nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
2518    gc->pipe[pn].array.num += 6;
2519    array_alloc(gc, pn);
2520
2521    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
2522      {
2523         // FIXME: handle yinvert
2524         ERR("not handling inverted y case for map4");
2525      }
2526    
2527    cmul = ARGB_JOIN(a, r, g, b);
2528    for (i = 0; i < 6; i++)
2529      {
2530         DATA32 cl = MUL4_SYM(cmul, p[points[i]].col);
2531         if (flat)
2532           {
2533              PUSH_VERTEX(pn,
2534                          (p[points[i]].x >> FP), 
2535                          (p[points[i]].y >> FP),
2536                          0);
2537           }
2538         else
2539           {
2540              PUSH_VERTEX(pn,
2541                          (p[points[i]].x3 >> FP) + gc->shared->ax, 
2542                          (p[points[i]].y3 >> FP) + gc->shared->ay,
2543                          (p[points[i]].z >> FP) 
2544                          + (gc->shared->foc - gc->shared->z0));
2545           }
2546         PUSH_TEXUV(pn,
2547                    tx[points[i]],
2548                    ty[points[i]]);
2549         if (yuv)
2550           {
2551              PUSH_TEXUV2(pn,
2552                          t2x[points[i]],
2553                          t2y[points[i]]);
2554              PUSH_TEXUV3(pn,
2555                          t2x[points[i]],
2556                          t2y[points[i]]);
2557           }
2558         
2559         PUSH_COLOR(pn,
2560                    R_VAL(&cl),
2561                    G_VAL(&cl),
2562                    B_VAL(&cl),
2563                    A_VAL(&cl));
2564      }
2565    if (!flat)
2566      {
2567         shader_array_flush(gc);
2568         gc->foc = 0;
2569         gc->z0 = 0;
2570         gc->px = 0;
2571         gc->py = 0;
2572         gc->change.size = 1;
2573         _evas_gl_common_viewport_set(gc);
2574      }
2575 }
2576
2577 void
2578 evas_gl_common_context_flush(Evas_GL_Context *gc)
2579 {
2580    shader_array_flush(gc);
2581 }
2582
2583 static void
2584 shader_array_flush(Evas_GL_Context *gc)
2585 {
2586    int i, gw, gh, setclip, cy, fbo = 0, done = 0;
2587    
2588    gw = gc->w;
2589    gh = gc->h;
2590    if (!((gc->pipe[0].shader.surface == gc->def_surface) ||
2591          (!gc->pipe[0].shader.surface)))
2592      {
2593         gw = gc->pipe[0].shader.surface->w;
2594         gh = gc->pipe[0].shader.surface->h;
2595         fbo = 1;
2596      }
2597    for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
2598      {
2599         if (gc->pipe[i].array.num <= 0) break;
2600         setclip = 0;
2601         done++;
2602         gc->flushnum++;
2603         GLERR(__FUNCTION__, __FILE__, __LINE__, "<flush err>");
2604         if (gc->pipe[i].shader.cur_prog != gc->state.current.cur_prog)
2605           {
2606              glUseProgram(gc->pipe[i].shader.cur_prog);
2607              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2608           }
2609         
2610         if (gc->pipe[i].shader.cur_tex != gc->state.current.cur_tex)
2611           {
2612 #if 0
2613              if (gc->pipe[i].shader.cur_tex)
2614                {
2615                   glEnable(GL_TEXTURE_2D);
2616                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2617                }
2618              else
2619                {
2620                   glDisable(GL_TEXTURE_2D);
2621                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2622                }
2623 #endif
2624
2625              glActiveTexture(GL_TEXTURE0);
2626              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2627              glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_tex);
2628              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2629           }
2630
2631         if (gc->pipe[i].array.im)
2632           {
2633 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2634              if (gc->pipe[i].array.im->tex->pt->dyn.img)
2635                {
2636                   secsym_glEGLImageTargetTexture2DOES
2637                      (GL_TEXTURE_2D, gc->pipe[i].array.im->tex->pt->dyn.img);
2638                }
2639              else
2640 #endif                
2641                {
2642                   if (!gc->pipe[i].array.im->native.loose)
2643                     {
2644                        if (gc->pipe[i].array.im->native.func.bind)
2645                           gc->pipe[i].array.im->native.func.bind(gc->pipe[i].array.im->native.func.data, 
2646                                                                  gc->pipe[i].array.im);
2647                     }
2648                }
2649           }
2650         if (gc->pipe[i].shader.render_op != gc->state.current.render_op)
2651           {
2652              switch (gc->pipe[i].shader.render_op)
2653                {
2654                case EVAS_RENDER_BLEND: /**< default op: d = d*(1-sa) + s */
2655                   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2656                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2657                   break;
2658                case EVAS_RENDER_COPY: /**< d = s */
2659                   gc->pipe[i].shader.blend = 0;
2660                   glBlendFunc(GL_ONE, GL_ONE);
2661                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2662                   break;
2663                   // FIXME: fix blend funcs below!
2664                case EVAS_RENDER_BLEND_REL: /**< d = d*(1 - sa) + s*da */
2665                case EVAS_RENDER_COPY_REL: /**< d = s*da */
2666                case EVAS_RENDER_ADD: /**< d = d + s */
2667                case EVAS_RENDER_ADD_REL: /**< d = d + s*da */
2668                case EVAS_RENDER_SUB: /**< d = d - s */
2669                case EVAS_RENDER_SUB_REL: /**< d = d - s*da */
2670                case EVAS_RENDER_TINT: /**< d = d*s + d*(1 - sa) + s*(1 - da) */
2671                case EVAS_RENDER_TINT_REL: /**< d = d*(1 - sa + s) */
2672                case EVAS_RENDER_MASK: /**< d = d*sa */
2673                case EVAS_RENDER_MUL: /**< d = d*s */
2674                default:
2675                   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2676                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2677                   break;
2678                }
2679           }
2680         if (gc->pipe[i].shader.blend != gc->state.current.blend)
2681           {
2682              if (gc->pipe[i].shader.blend)
2683                {
2684                   glEnable(GL_BLEND);
2685                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2686                }
2687              else
2688                {
2689                   glDisable(GL_BLEND);
2690                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2691                }
2692           }
2693         if ((gc->pipe[i].shader.smooth != gc->state.current.smooth) ||
2694             (gc->pipe[i].shader.cur_tex != gc->state.current.cur_tex))
2695           {
2696              if (gc->pipe[i].shader.smooth)
2697                {
2698 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2699                   if (shared->info.anisotropic > 0.0)
2700                     {
2701                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, shared->info.anisotropic);
2702                        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2703                     }
2704 #endif
2705                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2706                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2707                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2708                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2709                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2710                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2711                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2712                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2713                }
2714              else
2715                {
2716 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2717                   if (shared->info.anisotropic > 0.0)
2718                     {
2719                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
2720                        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2721                     }
2722 #endif
2723                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2724                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2725                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2726                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2727                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2728                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2729                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2730                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2731                }
2732           }
2733         if (gc->pipe[i].shader.clip != gc->state.current.clip)
2734           {
2735              
2736              if (gc->pipe[i].shader.clip)
2737                {
2738                   cy = gh - gc->pipe[i].shader.cy - gc->pipe[i].shader.ch;
2739                   if (fbo) cy = gc->pipe[i].shader.cy;
2740                   glEnable(GL_SCISSOR_TEST);
2741                   glScissor(gc->pipe[i].shader.cx, cy,
2742                             gc->pipe[i].shader.cw, gc->pipe[i].shader.ch);
2743                   setclip = 1;
2744                }
2745              else
2746                {
2747                   glDisable(GL_SCISSOR_TEST);
2748                   glScissor(0, 0, 0, 0);
2749                }
2750           }
2751         if ((gc->pipe[i].shader.clip) && (!setclip))
2752           {
2753              if ((gc->pipe[i].shader.cx != gc->state.current.cx) ||
2754                  (gc->pipe[i].shader.cy != gc->state.current.cy) ||
2755                  (gc->pipe[i].shader.cw != gc->state.current.cw) ||
2756                  (gc->pipe[i].shader.ch != gc->state.current.ch))
2757                {
2758                   cy = gh - gc->pipe[i].shader.cy - gc->pipe[i].shader.ch;
2759                   if (fbo) cy = gc->pipe[i].shader.cy;
2760                   glScissor(gc->pipe[i].shader.cx, cy,
2761                             gc->pipe[i].shader.cw, gc->pipe[i].shader.ch);
2762                }
2763           }
2764
2765         glVertexAttribPointer(SHAD_VERTEX, 3, GL_SHORT, GL_FALSE, 0, gc->pipe[i].array.vertex);
2766         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2767         glVertexAttribPointer(SHAD_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, gc->pipe[i].array.color);
2768         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2769         if (gc->pipe[i].array.use_texuv)
2770           {
2771              glEnableVertexAttribArray(SHAD_TEXUV);
2772              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2773              glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv);
2774              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2775           }
2776         else
2777           {
2778              glDisableVertexAttribArray(SHAD_TEXUV);
2779              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2780           }
2781         
2782         if (gc->pipe[i].array.line)
2783           {
2784              glDisableVertexAttribArray(SHAD_TEXUV);
2785              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2786              glDisableVertexAttribArray(SHAD_TEXUV2);
2787              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2788              glDisableVertexAttribArray(SHAD_TEXUV3);
2789              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2790              glDrawArrays(GL_LINES, 0, gc->pipe[i].array.num);
2791              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2792           }
2793         else
2794           {
2795              if (gc->pipe[i].array.use_texm)
2796                {
2797                        printf("using tex m (%d)\n",gc->pipe[i].shader.cur_texm);
2798                   glEnableVertexAttribArray(SHAD_TEXM);
2799                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2800                   glVertexAttribPointer(SHAD_TEXM, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texm);
2801                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2802                   glActiveTexture(GL_TEXTURE1);
2803                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2804                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texm);
2805                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2806                   glActiveTexture(GL_TEXTURE0);
2807                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2808                }
2809              else
2810                {
2811                   glDisableVertexAttribArray(SHAD_TEXM);
2812                }
2813              if ((gc->pipe[i].array.use_texuv2) && (gc->pipe[i].array.use_texuv3))
2814                {
2815                   glEnableVertexAttribArray(SHAD_TEXUV2);
2816                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2817                   glEnableVertexAttribArray(SHAD_TEXUV3);
2818                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2819                   glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
2820                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2821                   glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv3);
2822                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2823                   glActiveTexture(GL_TEXTURE1);
2824                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2825                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
2826                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2827                   glActiveTexture(GL_TEXTURE2);
2828                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2829                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texv);
2830                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2831                   glActiveTexture(GL_TEXTURE0);
2832                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2833                }
2834              else if (gc->pipe[i].array.use_texuv2)
2835                {
2836                   glEnableVertexAttribArray(SHAD_TEXUV2);
2837                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2838                   glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
2839                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2840                   glActiveTexture(GL_TEXTURE1);
2841                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2842                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
2843                   glActiveTexture(GL_TEXTURE0);
2844                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2845                }
2846              else
2847                {
2848                   glDisableVertexAttribArray(SHAD_TEXUV2);
2849                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2850                   glDisableVertexAttribArray(SHAD_TEXUV3);
2851                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2852                }
2853              if (dbgflushnum)
2854                {
2855                   const char *types[6] = 
2856                     {"----", "RECT", "IMAG", "FONT", "YUV-", "MAP"};
2857                   printf("  DRAW#%3i %4i -> %p[%4ix%4i] @ %4ix%4i -{ tex %4i type %s }-\n",
2858                          i,
2859                          gc->pipe[i].array.num / 6, 
2860                          gc->pipe[0].shader.surface,
2861                          gc->pipe[0].shader.surface->w,
2862                          gc->pipe[0].shader.surface->h,
2863                          gw, gh,
2864                          gc->pipe[i].shader.cur_tex,
2865                          types[gc->pipe[i].region.type]
2866                         );
2867                }
2868              glDrawArrays(GL_TRIANGLES, 0, gc->pipe[i].array.num);
2869              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2870           }
2871         if (gc->pipe[i].array.im)
2872           {
2873              if (!gc->pipe[i].array.im->native.loose)
2874                {
2875                   if (gc->pipe[i].array.im->native.func.unbind)
2876                      gc->pipe[i].array.im->native.func.unbind(gc->pipe[i].array.im->native.func.data, 
2877                                                               gc->pipe[i].array.im);
2878                }
2879              gc->pipe[i].array.im = NULL;
2880           }
2881         
2882         gc->state.current.cur_prog  = gc->pipe[i].shader.cur_prog;
2883         gc->state.current.cur_tex   = gc->pipe[i].shader.cur_tex;
2884         gc->state.current.blend     = gc->pipe[i].shader.blend;
2885         gc->state.current.smooth    = gc->pipe[i].shader.smooth;
2886         gc->state.current.render_op = gc->pipe[i].shader.render_op;
2887         gc->state.current.clip      = gc->pipe[i].shader.clip;
2888         gc->state.current.cx        = gc->pipe[i].shader.cx;
2889         gc->state.current.cy        = gc->pipe[i].shader.cy;
2890         gc->state.current.cw        = gc->pipe[i].shader.cw;
2891         gc->state.current.ch        = gc->pipe[i].shader.ch;
2892         
2893         if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
2894         if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);
2895         if (gc->pipe[i].array.texuv) free(gc->pipe[i].array.texuv);
2896         if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
2897         if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
2898         if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
2899         
2900         gc->pipe[i].array.vertex = NULL;
2901         gc->pipe[i].array.color = NULL;
2902         gc->pipe[i].array.texuv = NULL;
2903         gc->pipe[i].array.texm = NULL;
2904         gc->pipe[i].array.texuv2 = NULL;
2905         gc->pipe[i].array.texuv3 = NULL;
2906
2907         gc->pipe[i].array.num = 0;
2908         gc->pipe[i].array.alloc = 0;
2909         
2910         gc->pipe[i].region.x = 0;
2911         gc->pipe[i].region.y = 0;
2912         gc->pipe[i].region.w = 0;
2913         gc->pipe[i].region.h = 0;
2914         gc->pipe[i].region.type = 0;
2915      }
2916    gc->state.top_pipe = 0;
2917    if (dbgflushnum)
2918      {
2919         if (done > 0) printf("DONE (pipes): %i\n", done);
2920      }
2921 }
2922
2923 Eina_Bool
2924 evas_gl_common_module_open(void)
2925 {
2926    if (_evas_engine_GL_common_log_dom < 0)
2927      _evas_engine_GL_common_log_dom = eina_log_domain_register
2928        ("evas-gl_common", EVAS_DEFAULT_LOG_COLOR);
2929    if (_evas_engine_GL_common_log_dom < 0)
2930      {
2931         EINA_LOG_ERR("Can not create a module log domain.");
2932         return EINA_FALSE;
2933      }
2934    return EINA_TRUE;
2935 }
2936
2937 void
2938 evas_gl_common_module_close(void)
2939 {
2940    if (_evas_engine_GL_common_log_dom < 0) return;
2941    eina_log_domain_unregister(_evas_engine_GL_common_log_dom);
2942    _evas_engine_GL_common_log_dom = -1;
2943 }