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