221d7f293726a006f73790ff608e59e046476c73
[framework/uifw/evas.git] / src / modules / engines / gl_common / evas_gl_context.c
1 #include "evas_gl_private.h"
2
3 #define GLPIPES 1
4
5 static int sym_done = 0;
6 int _evas_engine_GL_common_log_dom = -1;
7
8 typedef void    (*glsym_func_void) ();
9
10 void (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b) = NULL;
11 void (*glsym_glBindFramebuffer)      (GLenum a, GLuint b) = NULL;
12 void (*glsym_glFramebufferTexture2D) (GLenum a, GLenum b, GLenum c, GLuint d, GLint e) = NULL;
13 void (*glsym_glDeleteFramebuffers)   (GLsizei a, const GLuint *b) = NULL;
14 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.tex.prog);
471    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
472    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex.prog, "mvp"), 1,
473                       GL_FALSE, proj);
474    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
475    glUseProgram(gc->shared->shader.tex_nomul.prog);
476    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
477    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.tex_nomul.prog, "mvp"), 1,
478                       GL_FALSE, proj);
479    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
480
481    glUseProgram(gc->shared->shader.img.prog);
482    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
483    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img.prog, "mvp"), 1,
484                       GL_FALSE, proj);
485    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
486    glUseProgram(gc->shared->shader.img_nomul.prog);
487    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
488    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_nomul.prog, "mvp"), 1,
489                       GL_FALSE, proj);
490    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
491
492    glUseProgram(gc->shared->shader.img_bgra.prog);
493    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
494    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra.prog, "mvp"), 1,
495                       GL_FALSE, proj);
496    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
497    glUseProgram(gc->shared->shader.img_bgra_nomul.prog);
498    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
499    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra_nomul.prog, "mvp"), 1,
500                       GL_FALSE, proj);
501    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
502    glUseProgram(gc->shared->shader.img_mask.prog);
503    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
504    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_mask.prog, "mvp"), 1,
505                       GL_FALSE, proj);
506    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
507    glUseProgram(gc->shared->shader.filter_invert.prog);
508    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
509    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_invert.prog, "mvp"), 1,
510                       GL_FALSE, proj);
511    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
512    glUseProgram(gc->shared->shader.filter_invert_nomul.prog);
513    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
514    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_invert_nomul.prog, "mvp"), 1,
515                       GL_FALSE, proj);
516    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
517    glUseProgram(gc->shared->shader.filter_invert_bgra.prog);
518    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
519    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_invert_bgra.prog, "mvp"), 1,
520                       GL_FALSE, proj);
521    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
522    glUseProgram(gc->shared->shader.filter_invert_bgra_nomul.prog);
523    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
524    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_invert_bgra_nomul.prog, "mvp"), 1,
525                       GL_FALSE, proj);
526    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
527
528    glUseProgram(gc->shared->shader.filter_greyscale.prog);
529    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
530    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_greyscale.prog, "mvp"), 1,
531                       GL_FALSE, proj);
532    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
533    glUseProgram(gc->shared->shader.filter_greyscale_nomul.prog);
534    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
535    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_greyscale_nomul.prog, "mvp"), 1,
536                       GL_FALSE, proj);
537    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
538    glUseProgram(gc->shared->shader.filter_greyscale_bgra.prog);
539    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
540    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_greyscale_bgra.prog, "mvp"), 1,
541                       GL_FALSE, proj);
542    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
543    glUseProgram(gc->shared->shader.filter_greyscale_bgra_nomul.prog);
544    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
545    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_greyscale_bgra_nomul.prog, "mvp"), 1,
546                       GL_FALSE, proj);
547    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
548
549    glUseProgram(gc->shared->shader.filter_sepia.prog);
550    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
551    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_sepia.prog, "mvp"), 1,
552                       GL_FALSE, proj);
553    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
554    glUseProgram(gc->shared->shader.filter_sepia_nomul.prog);
555    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
556    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_sepia_nomul.prog, "mvp"), 1,
557                       GL_FALSE, proj);
558    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
559    glUseProgram(gc->shared->shader.filter_sepia_bgra.prog);
560    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
561    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_sepia_bgra.prog, "mvp"), 1,
562                       GL_FALSE, proj);
563    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
564    glUseProgram(gc->shared->shader.filter_sepia_bgra_nomul.prog);
565    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
566    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_sepia_bgra_nomul.prog, "mvp"), 1,
567                       GL_FALSE, proj);
568    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
569
570 #if 0
571    glUseProgram(gc->shared->shader.filter_blur_bgra_nomul.prog);
572    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
573    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_blur_bgra_nomul.prog, "mvp"), 1,
574                       GL_FALSE, proj);
575    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
576    glUseProgram(gc->shared->shader.filter_blur_bgra_nomul.prog);
577    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
578    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_blur_bgra_nomul.prog, "mvp"), 1,
579                       GL_FALSE, proj);
580    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
581    glUseProgram(gc->shared->shader.filter_blur_bgra_nomul.prog);
582    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
583    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_blur_bgra_nomul.prog, "mvp"), 1,
584                       GL_FALSE, proj);
585    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
586    glUseProgram(gc->shared->shader.filter_blur_bgra_nomul.prog);
587    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
588    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.filter_blur_bgra_nomul.prog, "mvp"), 1,
589                       GL_FALSE, proj);
590    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
591 #endif
592
593
594    glUseProgram(gc->pipe[0].shader.cur_prog);
595    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
596 }
597
598 Evas_Engine_GL_Context *
599 evas_gl_common_context_new(void)
600 {
601    Evas_Engine_GL_Context *gc;
602    const char *s;
603    int i;
604
605 #if 1
606    if (_evas_gl_common_context)
607      {
608         _evas_gl_common_context->references++;
609         return _evas_gl_common_context;
610      }
611 #endif
612    if (!_evas_gl_common_version_check())
613      return NULL;
614    gc = calloc(1, sizeof(Evas_Engine_GL_Context));
615    if (!gc) return NULL;
616
617    gl_symbols();
618
619    gc->references = 1;
620
621    _evas_gl_common_context = gc;
622
623    for (i = 0; i < MAX_PIPES; i++)
624       gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
625
626    if (!shared)
627      {
628         const GLubyte *ext;
629
630         shared = calloc(1, sizeof(Evas_GL_Shared));
631         ext = glGetString(GL_EXTENSIONS);
632         if (ext)
633           {
634              if (getenv("EVAS_GL_INFO"))
635                 fprintf(stderr, "EXT:\n%s\n", ext);
636              if ((strstr((char *)ext, "GL_ARB_texture_non_power_of_two")) ||
637                  (strstr((char *)ext, "OES_texture_npot")) ||
638                  (strstr((char *)ext, "GL_IMG_texture_npot")))
639                shared->info.tex_npo2 = 1;
640              if ((strstr((char *)ext, "GL_NV_texture_rectangle")) ||
641                  (strstr((char *)ext, "GL_EXT_texture_rectangle")) ||
642                  (strstr((char *)ext, "GL_ARB_texture_rectangle")))
643                shared->info.tex_rect = 1;
644              if ((strstr((char *)ext, "GL_ARB_get_program_binary")) ||
645                  (strstr((char *)ext, "GL_OES_get_program_binary")))
646                shared->info.bin_program = 1;
647 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
648              if ((strstr((char *)ext, "GL_EXT_texture_filter_anisotropic")))
649                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
650                            &(shared->info.anisotropic));
651 #endif
652 #ifdef GL_BGRA
653              if ((strstr((char *)ext, "GL_EXT_bgra")) ||
654                  (strstr((char *)ext, "GL_EXT_texture_format_BGRA8888")))
655                shared->info.bgra = 1;
656 #endif
657 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
658              // FIXME: there should be an extension name/string to check for
659              // not just symbols in the lib
660              i = 0;
661              s = getenv("EVAS_GL_NO_MAP_IMAGE_SEC");
662              if (s) i = atoi(s);
663              if (!i)
664                {
665                   // test for all needed symbols - be "conservative" and
666                   // need all of it
667                   if ((secsym_eglCreateImage) &&
668                       (secsym_eglDestroyImage) &&
669                       (secsym_glEGLImageTargetTexture2DOES) &&
670                       (secsym_eglMapImageSEC) &&
671                       (secsym_eglUnmapImageSEC) &&
672                       (secsym_eglGetImageAttribSEC))
673                      shared->info.sec_image_map = 1;
674                }
675 #endif
676           }
677         glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,
678                       &(shared->info.max_texture_units));
679         glGetIntegerv(GL_MAX_TEXTURE_SIZE,
680                       &(shared->info.max_texture_size));
681         shared->info.max_vertex_elements = 6 * 100000;
682 #ifdef GL_MAX_ELEMENTS_VERTICES
683 /* only applies to glDrawRangeElements. don't really need to get it.
684         glGetIntegerv(GL_MAX_ELEMENTS_VERTICES,
685                       &(shared->info.max_vertex_elements));
686  */
687 #endif
688         s = getenv("EVAS_GL_VERTEX_MAX");
689         if (s) shared->info.max_vertex_elements = atoi(s);
690         if (shared->info.max_vertex_elements < 6)
691            shared->info.max_vertex_elements = 6;
692
693         // magic numbers that are a result of imperical testing and getting
694         // "best case" performance across a range of systems
695         shared->info.tune.cutout.max                 = DEF_CUTOUT;
696         shared->info.tune.pipes.max                  = DEF_PIPES;
697         shared->info.tune.atlas.max_alloc_size       = DEF_ATLAS_ALLOC;
698         shared->info.tune.atlas.max_alloc_alpha_size = DEF_ATLAS_ALLOC_ALPHA;
699         shared->info.tune.atlas.max_w                = DEF_ATLAS_W;
700         shared->info.tune.atlas.max_h                = DEF_ATLAS_H;
701         shared->info.tune.atlas.slot_size            = DEF_ATLAS_SLOT;
702
703         // per gpu hacks. based on impirical measurement of some known gpu's
704         s = (const char *)glGetString(GL_RENDERER);
705         if (s)
706           {
707              if      (strstr(s, "PowerVR SGX 540"))
708                 shared->info.tune.pipes.max = DEF_PIPES_SGX_540;
709              else if (strstr(s, "NVIDIA Tegra"))
710                 shared->info.tune.pipes.max = DEF_PIPES_TEGRA_2;
711           }
712
713 #define GETENVOPT(name, tune_param, min, max) \
714         do { \
715            const char *__v = getenv(name); \
716            if (__v) { \
717               shared->info.tune.tune_param = atoi(__v); \
718               if (shared->info.tune.tune_param > max) \
719                  shared->info.tune.tune_param = max; \
720               else if (shared->info.tune.tune_param < min) \
721                  shared->info.tune.tune_param = min; \
722            } \
723         } while (0)
724
725         GETENVOPT("EVAS_GL_CUTOUT_MAX", cutout.max, -1, 0x7fffffff);
726         GETENVOPT("EVAS_GL_PIPES_MAX", pipes.max, 1, MAX_PIPES);
727         GETENVOPT("EVAS_GL_ATLAS_ALLOC_SIZE", atlas.max_alloc_size, MIN_ATLAS_ALLOC, MAX_ATLAS_ALLOC);
728         GETENVOPT("EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE", atlas.max_alloc_alpha_size, MIN_ATLAS_ALLOC_ALPHA, MAX_ATLAS_ALLOC_ALPHA);
729         GETENVOPT("EVAS_GL_ATLAS_MAX_W", atlas.max_w, 0, MAX_ATLAS_W);
730         GETENVOPT("EVAS_GL_ATLAS_MAX_H", atlas.max_h, 0, MAX_ATLAS_H);
731         GETENVOPT("EVAS_GL_ATLAS_SLOT_SIZE", atlas.slot_size, MIN_ATLAS_SLOT, MAX_ATLAS_SLOT);
732         s = (const char *)getenv("EVAS_GL_GET_PROGRAM_BINARY");
733         if (s)
734           {
735              if (atoi(s) == 0) shared->info.bin_program = 0;
736           }
737
738         if (getenv("EVAS_GL_INFO"))
739            fprintf(stderr,
740                    "max tex size %ix%i\n"
741                    "max units %i\n"
742                    "non-power-2 tex %i\n"
743                    "rect tex %i\n"
744                    "bgra : %i\n"
745                    "max ansiotropic filtering: %3.3f\n"
746                    "egl sec map image: %i\n"
747                    "max vertex count: %i\n"
748                    "\n"
749                    "(can set EVAS_GL_VERTEX_MAX  EVAS_GL_NO_MAP_IMAGE_SEC  EVAS_GL_INFO  EVAS_GL_MEMINFO )\n"
750                    "\n"
751                    "EVAS_GL_GET_PROGRAM_BINARY: %i\n"
752                    "EVAS_GL_CUTOUT_MAX: %i\n"
753                    "EVAS_GL_PIPES_MAX: %i\n"
754                    "EVAS_GL_ATLAS_ALLOC_SIZE: %i\n"
755                    "EVAS_GL_ATLAS_ALLOC_ALPHA_SIZE: %i\n"
756                    "EVAS_GL_ATLAS_MAX_W x EVAS_GL_ATLAS_MAX_H: %i x %i\n"
757                    "EVAS_GL_ATLAS_SLOT_SIZE: %i\n"
758                    ,
759                    (int)shared->info.max_texture_size, (int)shared->info.max_texture_size,
760                    (int)shared->info.max_texture_units,
761                    (int)shared->info.tex_npo2,
762                    (int)shared->info.tex_rect,
763                    (int)shared->info.bgra,
764                    (double)shared->info.anisotropic,
765                    (int)shared->info.sec_image_map,
766                    (int)shared->info.max_vertex_elements,
767
768                    (int)shared->info.bin_program,
769                    (int)shared->info.tune.cutout.max,
770                    (int)shared->info.tune.pipes.max,
771                    (int)shared->info.tune.atlas.max_alloc_size,
772                    (int)shared->info.tune.atlas.max_alloc_alpha_size,
773                    (int)shared->info.tune.atlas.max_w, (int)shared->info.tune.atlas.max_h,
774                    (int)shared->info.tune.atlas.slot_size
775                   );
776
777         glDisable(GL_DEPTH_TEST);
778         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
779         glEnable(GL_DITHER);
780         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
781         glDisable(GL_BLEND);
782         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
783         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
784         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
785         // no dest alpha
786 //        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // dest alpha
787 //        glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ???
788         glDepthMask(GL_FALSE);
789         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
790
791         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
792         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
793         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
794         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
795         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
796         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
797         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
798         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
799 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
800         if (shared->info.anisotropic > 0.0)
801           {
802              glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
803              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
804           }
805 #endif
806
807         glEnableVertexAttribArray(SHAD_VERTEX);
808         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
809         glEnableVertexAttribArray(SHAD_COLOR);
810         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
811
812         if (!evas_gl_common_shader_program_init(shared)) goto error;
813
814         glUseProgram(shared->shader.yuv.prog);
815         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
816         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "tex"), 0);
817         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
818         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texu"), 1);
819         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
820         glUniform1i(glGetUniformLocation(shared->shader.yuv.prog, "texv"), 2);
821         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
822
823         glUseProgram(shared->shader.yuv_nomul.prog);
824         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
825         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "tex"), 0);
826         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
827         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texu"), 1);
828         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
829         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texv"), 2);
830         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
831
832         glUseProgram(shared->shader.img_mask.prog);
833         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
834         glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "tex"), 0);
835         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
836         glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "texm"), 1);
837         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
838
839
840
841         glUseProgram(gc->pipe[0].shader.cur_prog);
842         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
843
844         evas_gl_common_shader_program_init_done();
845         // in shader:
846         // uniform sampler2D tex[8];
847         //
848         // in code:
849         // GLuint texes[8];
850         // GLint loc = glGetUniformLocation(prog, "tex");
851         // glUniform1iv(loc, 8, texes);
852
853         shared->native_pm_hash  = eina_hash_int32_new(NULL);
854         shared->native_tex_hash = eina_hash_int32_new(NULL);
855      }
856    gc->shared = shared;
857    gc->shared->references++;
858    _evas_gl_common_viewport_set(gc);
859
860    gc->def_surface = evas_gl_common_image_surface_new(gc, 1, 1, 1);
861
862    return gc;
863    error:
864    evas_gl_common_context_free(gc);
865    return NULL;
866 }
867
868 void
869 evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
870 {
871    int i, j;
872    Eina_List *l;
873
874    gc->references--;
875    if (gc->references > 0) return;
876    if (gc->shared) gc->shared->references--;
877
878    if (gc->def_surface) evas_gl_common_image_free(gc->def_surface);
879
880    if (gc->shared)
881      {
882         for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
883           {
884              if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
885              if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);
886              if (gc->pipe[i].array.texuv) free(gc->pipe[i].array.texuv);
887              if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
888              if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
889              if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
890           }
891      }
892
893    if ((gc->shared) && (gc->shared->references == 0))
894      {
895         Evas_GL_Texture_Pool *pt;
896
897         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.rect));
898         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.font));
899         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img));
900         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_nomul));
901         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra));
902         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra_nomul));
903         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_mask));
904         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv));
905         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv_nomul));
906         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex));
907         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex_nomul));
908
909         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.filter_invert));
910
911         while (gc->shared->images)
912           {
913              evas_gl_common_image_free(gc->shared->images->data);
914           }
915
916         EINA_LIST_FOREACH(gc->shared->tex.whole, l, pt)
917            evas_gl_texture_pool_empty(pt);
918         for (i = 0; i < 33; i++)
919           {
920              for (j = 0; j < 3; j++)
921                {
922                   EINA_LIST_FOREACH(gc->shared->tex.atlas[i][j], l, pt)
923                      evas_gl_texture_pool_empty(pt);
924                }
925           }
926         eina_hash_free(gc->shared->native_pm_hash);
927         eina_hash_free(gc->shared->native_tex_hash);
928         free(gc->shared);
929         shared = NULL;
930      }
931    if (gc == _evas_gl_common_context) _evas_gl_common_context = NULL;
932    free(gc);
933 }
934
935 void
936 evas_gl_common_context_use(Evas_Engine_GL_Context *gc)
937 {
938    if (_evas_gl_common_context == gc) return;
939    _evas_gl_common_context = gc;
940    if (gc) _evas_gl_common_viewport_set(gc);
941 }
942
943 void
944 evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc)
945 {
946    int i;
947
948    if (dbgflushnum < 0)
949      {
950         dbgflushnum = 0;
951         if (getenv("EVAS_GL_DBG")) dbgflushnum = 1;
952      }
953    if (dbgflushnum) printf("----prev-flushnum: %i -----------------------------------\n", gc->flushnum);
954
955    gc->flushnum = 0;
956    gc->state.current.cur_prog = 0;
957    gc->state.current.cur_tex = 0;
958    gc->state.current.cur_texu = 0;
959    gc->state.current.cur_texv = 0;
960    gc->state.current.cur_texm = 0;
961    gc->state.current.cur_texmu = 0;
962    gc->state.current.cur_texmv = 0;
963    gc->state.current.render_op = 0;
964    gc->state.current.smooth = 0;
965    gc->state.current.blend = 0;
966    gc->state.current.clip = 0;
967    gc->state.current.cx = 0;
968    gc->state.current.cy = 0;
969    gc->state.current.cw = 0;
970    gc->state.current.ch = 0;
971
972    for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
973      {
974         gc->pipe[i].region.x = 0;
975         gc->pipe[i].region.y = 0;
976         gc->pipe[i].region.w = 0;
977         gc->pipe[i].region.h = 0;
978         gc->pipe[i].region.type = 0;
979         gc->pipe[i].clip.active = 0;
980         gc->pipe[i].clip.x = 0;
981         gc->pipe[i].clip.y = 0;
982         gc->pipe[i].clip.w = 0;
983         gc->pipe[i].clip.h = 0;
984         gc->pipe[i].shader.surface = NULL;
985         gc->pipe[i].shader.cur_prog = 0;
986         gc->pipe[i].shader.cur_tex = 0;
987         gc->pipe[i].shader.cur_texu = 0;
988         gc->pipe[i].shader.cur_texv = 0;
989         gc->pipe[i].shader.cur_texm = 0;
990         gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
991         gc->pipe[i].shader.smooth = 0;
992         gc->pipe[i].shader.blend = 0;
993         gc->pipe[i].shader.clip = 0;
994         gc->pipe[i].shader.cx = 0;
995         gc->pipe[i].shader.cy = 0;
996         gc->pipe[i].shader.cw = 0;
997         gc->pipe[i].shader.ch = 0;
998      }
999    gc->change.size = 1;
1000
1001    glDisable(GL_SCISSOR_TEST);
1002    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1003    glScissor(0, 0, 0, 0);
1004    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1005
1006    glDisable(GL_DEPTH_TEST);
1007    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1008    glEnable(GL_DITHER);
1009    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1010    glDisable(GL_BLEND);
1011    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1012    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1013    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1014    // no dest alpha
1015 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // dest alpha
1016 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE); // ???
1017    glDepthMask(GL_FALSE);
1018    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1019
1020    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1021    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1022    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1023    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1024    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1025    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1026    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1027    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1028 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
1029    if (shared->info.anisotropic > 0.0)
1030      {
1031         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
1032         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1033      }
1034 #endif
1035
1036    glEnableVertexAttribArray(SHAD_VERTEX);
1037    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1038    glEnableVertexAttribArray(SHAD_COLOR);
1039    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1040    glUseProgram(gc->pipe[0].shader.cur_prog);
1041    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1042
1043    glActiveTexture(GL_TEXTURE0);
1044    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1045    glBindTexture(GL_TEXTURE_2D, gc->pipe[0].shader.cur_tex);
1046    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1047
1048    _evas_gl_common_viewport_set(gc);
1049 }
1050
1051 void
1052 evas_gl_common_context_resize(Evas_Engine_GL_Context *gc, int w, int h, int rot)
1053 {
1054    if ((gc->w == w) && (gc->h == h) && (gc->rot == rot)) return;
1055    evas_gl_common_context_flush(gc);
1056    gc->change.size = 1;
1057    gc->rot = rot;
1058    gc->w = w;
1059    gc->h = h;
1060    if (_evas_gl_common_context == gc) _evas_gl_common_viewport_set(gc);
1061 }
1062
1063 void
1064 evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
1065                                           Evas_GL_Image *surface)
1066 {
1067    if (surface == gc->pipe[0].shader.surface) return;
1068
1069    evas_gl_common_context_flush(gc);
1070
1071    gc->state.current.cur_prog = -1;
1072    gc->state.current.cur_tex = -1;
1073    gc->state.current.cur_texu = -1;
1074    gc->state.current.cur_texv = -1;
1075    gc->state.current.render_op = -1;
1076    gc->state.current.smooth = -1;
1077    gc->state.current.blend = -1;
1078    gc->state.current.clip = -1;
1079    gc->state.current.cx = -1;
1080    gc->state.current.cy = -1;
1081    gc->state.current.cw = -1;
1082    gc->state.current.ch = -1;
1083
1084    gc->pipe[0].shader.surface = surface;
1085    gc->change.size = 1;
1086 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
1087 # ifndef GL_FRAMEBUFFER
1088 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
1089 # endif
1090 #else
1091 # ifndef GL_FRAMEBUFFER
1092 #  define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
1093 # endif
1094 #endif
1095    if (gc->pipe[0].shader.surface == gc->def_surface)
1096      {
1097         glsym_glBindFramebuffer(GL_FRAMEBUFFER, 0);
1098         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1099      }
1100    else
1101      {
1102         glsym_glBindFramebuffer(GL_FRAMEBUFFER, surface->tex->pt->fb);
1103         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
1104      }
1105    _evas_gl_common_viewport_set(gc);
1106 }
1107
1108 #define PUSH_VERTEX(n, x, y, z) \
1109    gc->pipe[n].array.vertex[nv++] = x; \
1110    gc->pipe[n].array.vertex[nv++] = y; \
1111    gc->pipe[n].array.vertex[nv++] = z
1112 #define PUSH_COLOR(n, r, g, b, a) \
1113    gc->pipe[n].array.color[nc++] = r; \
1114    gc->pipe[n].array.color[nc++] = g; \
1115    gc->pipe[n].array.color[nc++] = b; \
1116    gc->pipe[n].array.color[nc++] = a
1117 #define PUSH_TEXUV(n, u, v) \
1118    gc->pipe[n].array.texuv[nu++] = u; \
1119    gc->pipe[n].array.texuv[nu++] = v
1120 #define PUSH_TEXUV2(n, u, v) \
1121    gc->pipe[n].array.texuv2[nu2++] = u; \
1122    gc->pipe[n].array.texuv2[nu2++] = v
1123 #define PUSH_TEXUV3(n, u, v) \
1124    gc->pipe[n].array.texuv3[nu3++] = u; \
1125    gc->pipe[n].array.texuv3[nu3++] = v
1126 #define PUSH_TEXM(n, u, v) \
1127    gc->pipe[n].array.texm[nm++] = u; \
1128    gc->pipe[n].array.texm[nm++] = v
1129
1130
1131 static inline void
1132 array_alloc(Evas_Engine_GL_Context *gc, int n)
1133 {
1134    gc->havestuff = EINA_TRUE;
1135    if (gc->pipe[n].array.num <= gc->pipe[n].array.alloc) return;
1136    gc->pipe[n].array.alloc += 6 * 1024;
1137    if (gc->pipe[n].array.use_vertex)
1138      gc->pipe[n].array.vertex = realloc(gc->pipe[n].array.vertex,
1139                                 gc->pipe[n].array.alloc * sizeof(GLshort) * 3);
1140    if (gc->pipe[n].array.use_color)
1141      gc->pipe[n].array.color  = realloc(gc->pipe[n].array.color,
1142                                 gc->pipe[n].array.alloc * sizeof(GLubyte) * 4);
1143    if (gc->pipe[n].array.use_texuv)
1144      gc->pipe[n].array.texuv  = realloc(gc->pipe[n].array.texuv,
1145                                 gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1146    if (gc->pipe[n].array.use_texm)
1147      gc->pipe[n].array.texm  = realloc(gc->pipe[n].array.texm,
1148                                 gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1149    if (gc->pipe[n].array.use_texuv2)
1150      gc->pipe[n].array.texuv2  = realloc(gc->pipe[n].array.texuv2,
1151                                gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1152    if (gc->pipe[n].array.use_texuv3)
1153      gc->pipe[n].array.texuv3  = realloc(gc->pipe[n].array.texuv3,
1154                                  gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
1155 }
1156
1157 static int
1158 pipe_region_intersects(Evas_Engine_GL_Context *gc, int n,
1159                        int x, int y, int w, int h)
1160 {
1161    int i, rx, ry, rw, rh, ii;
1162
1163    rx = gc->pipe[n].region.x;
1164    ry = gc->pipe[n].region.y;
1165    rw = gc->pipe[n].region.w;
1166    rh = gc->pipe[n].region.h;
1167    if (!RECTS_INTERSECT(x, y, w, h, rx, ry, rw, rh))
1168       return 0;
1169
1170    // a hack for now. map pipes use their whole bounding box for intersects
1171    // which at worst case reduces to old pipeline flushes, but cheaper than
1172    // full quad region or triangle intersects right now
1173    if (gc->pipe[n].region.type == RTYPE_MAP) return 1;
1174
1175    for (i = 0,
1176         ii = 0;
1177
1178         i < gc->pipe[n].array.num;
1179
1180         i += (3 * 2),
1181         ii += (3 * 3 * 2))
1182      {  // tri 1...
1183         // 0, 1, 2 < top left
1184         // 3, 4, 5 < top right
1185         // 6. 7, 8 < bottom left
1186         rx = gc->pipe[n].array.vertex[ii + 0];
1187         ry = gc->pipe[n].array.vertex[ii + 1];
1188         rw = gc->pipe[n].array.vertex[ii + 3] - rx;
1189         rh = gc->pipe[n].array.vertex[ii + 7] - ry;
1190         if (RECTS_INTERSECT(x, y, w, h, rx, ry, rw, rh))
1191            return 1;
1192      }
1193    return 0;
1194 }
1195
1196 static void
1197 pipe_region_expand(Evas_Engine_GL_Context *gc, int n,
1198                    int x, int y, int w, int h)
1199 {
1200    int x1, y1, x2, y2;
1201
1202    if (gc->pipe[n].region.w <= 0)
1203      {
1204         gc->pipe[n].region.x = x;
1205         gc->pipe[n].region.y = y;
1206         gc->pipe[n].region.w = w;
1207         gc->pipe[n].region.h = h;
1208         return;
1209      }
1210    x1 = gc->pipe[n].region.x;
1211    y1 = gc->pipe[n].region.y;
1212    x2 = gc->pipe[n].region.x + gc->pipe[n].region.w;
1213    y2 = gc->pipe[n].region.y + gc->pipe[n].region.h;
1214    if (x < x1) x1 = x;
1215    if (y < y1) y1 = y;
1216    if ((x + w) > x2) x2 = x + w;
1217    if ((y + h) > y2) y2 = y + h;
1218    gc->pipe[n].region.x = x1;
1219    gc->pipe[n].region.y = y1;
1220    gc->pipe[n].region.w = x2 - x1;
1221    gc->pipe[n].region.h = y2 - y1;
1222 }
1223
1224 static Eina_Bool
1225 vertex_array_size_check(Evas_Engine_GL_Context *gc, int pn, int n)
1226 {
1227    return 1;
1228 // this fixup breaks for expedite test 32. why?
1229    if ((gc->pipe[pn].array.num + n) > gc->shared->info.max_vertex_elements)
1230      {
1231         shader_array_flush(gc);
1232         return 0;
1233      }
1234    return 1;
1235 }
1236
1237 void
1238 evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
1239                                  int x1, int y1, int x2, int y2,
1240                                  int clip, int cx, int cy, int cw, int ch,
1241                                  int r, int g, int b, int a)
1242 {
1243    int pnum, nv, nc, nu, nt, i;
1244    Eina_Bool blend = 0;
1245    GLuint prog = gc->shared->shader.rect.prog;
1246    int pn = 0;
1247
1248    if (a < 255) blend = 1;
1249    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
1250
1251    shader_array_flush(gc);
1252    vertex_array_size_check(gc, gc->state.top_pipe, 2);
1253    pn = gc->state.top_pipe;
1254    gc->pipe[pn].shader.cur_tex = 0;
1255    gc->pipe[pn].shader.cur_prog = prog;
1256    gc->pipe[pn].shader.blend = blend;
1257    gc->pipe[pn].shader.render_op = gc->dc->render_op;
1258    gc->pipe[pn].shader.clip = clip;
1259    gc->pipe[pn].shader.cx = cx;
1260    gc->pipe[pn].shader.cy = cy;
1261    gc->pipe[pn].shader.cw = cw;
1262    gc->pipe[pn].shader.ch = ch;
1263
1264    gc->pipe[pn].array.line = 1;
1265    gc->pipe[pn].array.use_vertex = 1;
1266    gc->pipe[pn].array.use_color = 1;
1267    gc->pipe[pn].array.use_texuv = 0;
1268    gc->pipe[pn].array.use_texuv2 = 0;
1269    gc->pipe[pn].array.use_texuv3 = 0;
1270
1271    pnum = gc->pipe[pn].array.num;
1272    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
1273    gc->pipe[pn].array.num += 2;
1274    array_alloc(gc, pn);
1275
1276    PUSH_VERTEX(pn, x1, y1, 0);
1277    PUSH_VERTEX(pn, x2, y2, 0);
1278
1279    for (i = 0; i < 2; i++)
1280      {
1281         PUSH_COLOR(pn, r, g, b, a);
1282      }
1283
1284    shader_array_flush(gc);
1285    gc->pipe[pn].array.line = 0;
1286    gc->pipe[pn].array.use_vertex = 0;
1287    gc->pipe[pn].array.use_color = 0;
1288    gc->pipe[pn].array.use_texuv = 0;
1289    gc->pipe[pn].array.use_texuv2 = 0;
1290    gc->pipe[pn].array.use_texuv3 = 0;
1291 }
1292
1293 void
1294 evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
1295                                       int x, int y, int w, int h,
1296                                       int r, int g, int b, int a)
1297 {
1298    int pnum, nv, nc, nu, nt, i;
1299    Eina_Bool blend = 0;
1300    GLuint prog = gc->shared->shader.rect.prog;
1301    int pn = 0;
1302
1303    if (gc->dc->mask.mask)
1304      {
1305         RGBA_Draw_Context *dc;
1306         dc = gc->dc;
1307         Evas_GL_Image *im;
1308         im = (void *)dc->mask.mask;
1309         evas_gl_common_context_font_push(gc, im->tex,
1310                                 x - dc->mask.x,y - dc->mask.y,
1311                                 dc->mask.w,dc->mask.h,
1312                                 x,y,w,h,r,g,b,a);
1313         return;
1314      }
1315
1316    if (a < 255) blend = 1;
1317    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
1318
1319 again:
1320    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1321    pn = gc->state.top_pipe;
1322 #ifdef GLPIPES
1323    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1324      {
1325         gc->pipe[pn].region.type = RTYPE_RECT;
1326         gc->pipe[pn].shader.cur_tex = 0;
1327         gc->pipe[pn].shader.cur_prog = prog;
1328         gc->pipe[pn].shader.blend = blend;
1329         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1330         gc->pipe[pn].shader.clip = 0;
1331         gc->pipe[pn].shader.cx = 0;
1332         gc->pipe[pn].shader.cy = 0;
1333         gc->pipe[pn].shader.cw = 0;
1334         gc->pipe[pn].shader.ch = 0;
1335         gc->pipe[pn].array.line = 0;
1336         gc->pipe[pn].array.use_vertex = 1;
1337         gc->pipe[pn].array.use_color = 1;
1338         gc->pipe[pn].array.use_texuv = 0;
1339         gc->pipe[pn].array.use_texuv2 = 0;
1340         gc->pipe[pn].array.use_texuv3 = 0;
1341      }
1342    else
1343      {
1344         int found = 0;
1345
1346         for (i = pn; i >= 0; i--)
1347           {
1348              if ((gc->pipe[i].region.type == RTYPE_RECT)
1349                  && (gc->pipe[i].shader.cur_tex == 0)
1350                  && (gc->pipe[i].shader.cur_prog == prog)
1351                  && (gc->pipe[i].shader.blend == blend)
1352                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1353                  && (gc->pipe[i].shader.clip == 0)
1354                 )
1355                {
1356                   found = 1;
1357                   pn = i;
1358                   break;
1359                }
1360              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1361           }
1362         if (!found)
1363           {
1364              pn = gc->state.top_pipe + 1;
1365              if (pn >= gc->shared->info.tune.pipes.max)
1366                {
1367                   shader_array_flush(gc);
1368                   goto again;
1369                }
1370              gc->state.top_pipe = pn;
1371              gc->pipe[pn].region.type = RTYPE_RECT;
1372              gc->pipe[pn].shader.cur_tex = 0;
1373              gc->pipe[pn].shader.cur_prog = prog;
1374              gc->pipe[pn].shader.blend = blend;
1375              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1376              gc->pipe[pn].shader.clip = 0;
1377              gc->pipe[pn].shader.cx = 0;
1378              gc->pipe[pn].shader.cy = 0;
1379              gc->pipe[pn].shader.cw = 0;
1380              gc->pipe[pn].shader.ch = 0;
1381              gc->pipe[pn].array.line = 0;
1382              gc->pipe[pn].array.use_vertex = 1;
1383              gc->pipe[pn].array.use_color = 1;
1384              gc->pipe[pn].array.use_texuv = 0;
1385              gc->pipe[pn].array.use_texuv2 = 0;
1386              gc->pipe[pn].array.use_texuv3 = 0;
1387          }
1388      }
1389 #else
1390    if ((gc->pipe[pn].shader.cur_tex != 0)
1391        || (gc->pipe[pn].shader.cur_prog != prog)
1392        || (gc->pipe[pn].shader.blend != blend)
1393        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1394        || (gc->pipe[pn].shader.clip != 0)
1395        )
1396      {
1397         shader_array_flush(gc);
1398         pn = gc->state.top_pipe;
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      }
1409
1410    gc->pipe[pn].region.type = RTYPE_RECT;
1411    gc->pipe[pn].array.line = 0;
1412    gc->pipe[pn].array.use_vertex = 1;
1413    gc->pipe[pn].array.use_color = 1;
1414    gc->pipe[pn].array.use_texuv = 0;
1415    gc->pipe[pn].array.use_texuv2 = 0;
1416    gc->pipe[pn].array.use_texuv3 = 0;
1417 #endif
1418
1419    pipe_region_expand(gc, pn, x, y, w, h);
1420
1421    pnum = gc->pipe[pn].array.num;
1422    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
1423    gc->pipe[pn].array.num += 6;
1424    array_alloc(gc, pn);
1425
1426    PUSH_VERTEX(pn, x    , y    , 0);
1427    PUSH_VERTEX(pn, x + w, y    , 0);
1428    PUSH_VERTEX(pn, x    , y + h, 0);
1429
1430    PUSH_VERTEX(pn, x + w, y    , 0);
1431    PUSH_VERTEX(pn, x + w, y + h, 0);
1432    PUSH_VERTEX(pn, x    , y + h, 0);
1433
1434    for (i = 0; i < 6; i++)
1435      {
1436         PUSH_COLOR(pn, r, g, b, a);
1437      }
1438 }
1439
1440 void
1441 evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
1442                                   Evas_GL_Texture *tex,
1443                                   double sx, double sy, double sw, double sh,
1444                                   int x, int y, int w, int h,
1445                                   int r, int g, int b, int a,
1446                                   Eina_Bool smooth, Eina_Bool tex_only)
1447 {
1448    int pnum, nv, nc, nu, nu2, nt, i;
1449    GLfloat tx1, tx2, ty1, ty2;
1450    Eina_Bool blend = 1;
1451    GLuint prog = gc->shared->shader.img.prog;
1452    int pn = 0;
1453
1454    if (!tex->alpha) blend = 0;
1455    if (a < 255) blend = 1;
1456
1457    if (gc->filter_prog)
1458      {
1459         prog = gc->filter_prog;
1460      }
1461    else if (tex_only)
1462      {
1463         if (tex->pt->dyn.img)
1464           {
1465              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1466                 prog = gc->shared->shader.img_nomul.prog;
1467              else
1468                 prog = gc->shared->shader.img.prog;
1469           }
1470         else
1471           {
1472              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1473                 prog = gc->shared->shader.tex_nomul.prog;
1474              else
1475                 prog = gc->shared->shader.tex.prog;
1476           }
1477      }
1478    else
1479      {
1480         if (tex->gc->shared->info.bgra)
1481           {
1482              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1483                prog = gc->shared->shader.img_bgra_nomul.prog;
1484              else
1485                prog = gc->shared->shader.img_bgra.prog;
1486           }
1487         else
1488           {
1489              if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
1490                prog = gc->shared->shader.img_nomul.prog;
1491              else
1492                prog = gc->shared->shader.img.prog;
1493           }
1494      }
1495
1496 again:
1497    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1498    pn = gc->state.top_pipe;
1499 #ifdef GLPIPES
1500    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1501      {
1502         gc->pipe[pn].region.type = RTYPE_IMAGE;
1503         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1504         gc->pipe[pn].shader.cur_prog = prog;
1505         gc->pipe[pn].shader.smooth = smooth;
1506         gc->pipe[pn].shader.blend = blend;
1507         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1508         gc->pipe[pn].shader.clip = 0;
1509         gc->pipe[pn].shader.cx = 0;
1510         gc->pipe[pn].shader.cy = 0;
1511         gc->pipe[pn].shader.cw = 0;
1512         gc->pipe[pn].shader.ch = 0;
1513         gc->pipe[pn].array.line = 0;
1514         gc->pipe[pn].array.use_vertex = 1;
1515         // if nomul... dont need this
1516         gc->pipe[pn].array.use_color = 1;
1517         gc->pipe[pn].array.use_texuv = 1;
1518         gc->pipe[pn].array.use_texuv2 = 0;
1519         gc->pipe[pn].array.use_texuv3 = 0;
1520      }
1521    else
1522      {
1523         int found = 0;
1524
1525         for (i = pn; i >= 0; i--)
1526           {
1527              if ((gc->pipe[i].region.type == RTYPE_IMAGE)
1528                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
1529                  && (gc->pipe[i].shader.cur_prog == prog)
1530                  && (gc->pipe[i].shader.smooth == smooth)
1531                  && (gc->pipe[i].shader.blend == blend)
1532                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1533                  && (gc->pipe[i].shader.clip == 0)
1534                 )
1535                {
1536                   found = 1;
1537                   pn = i;
1538                   break;
1539                }
1540              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1541           }
1542         if (!found)
1543           {
1544              pn = gc->state.top_pipe + 1;
1545              if (pn >= gc->shared->info.tune.pipes.max)
1546                {
1547                   shader_array_flush(gc);
1548                   goto again;
1549                }
1550              gc->state.top_pipe = pn;
1551              gc->pipe[pn].region.type = RTYPE_IMAGE;
1552              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1553              gc->pipe[pn].shader.cur_prog = prog;
1554              gc->pipe[pn].shader.smooth = smooth;
1555              gc->pipe[pn].shader.blend = blend;
1556              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1557              gc->pipe[pn].shader.clip = 0;
1558              gc->pipe[pn].shader.cx = 0;
1559              gc->pipe[pn].shader.cy = 0;
1560              gc->pipe[pn].shader.cw = 0;
1561              gc->pipe[pn].shader.ch = 0;
1562              gc->pipe[pn].array.line = 0;
1563              gc->pipe[pn].array.use_vertex = 1;
1564              // if nomul... dont need this
1565              gc->pipe[pn].array.use_color = 1;
1566              gc->pipe[pn].array.use_texuv = 1;
1567              gc->pipe[pn].array.use_texuv2 = 0;
1568              gc->pipe[pn].array.use_texuv3 = 0;
1569
1570          }
1571      }
1572    if ((tex->im) && (tex->im->native.data))
1573      {
1574         if (gc->pipe[pn].array.im != tex->im)
1575           {
1576              shader_array_flush(gc);
1577              pn = gc->state.top_pipe;
1578              gc->pipe[pn].array.im = tex->im;
1579              goto again;
1580           }
1581      }
1582    if (tex->pt->dyn.img)
1583      {
1584         if (gc->pipe[pn].array.im != tex->im)
1585           {
1586              shader_array_flush(gc);
1587              pn = gc->state.top_pipe;
1588              gc->pipe[pn].array.im = tex->im;
1589              goto again;
1590           }
1591      }
1592 #else
1593    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
1594        || (gc->pipe[pn].shader.cur_prog != prog)
1595        || (gc->pipe[pn].shader.smooth != smooth)
1596        || (gc->pipe[pn].shader.blend != blend)
1597        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1598        || (gc->pipe[pn].shader.clip != 0)
1599        )
1600      {
1601         shader_array_flush(gc);
1602         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1603         gc->pipe[pn].shader.cur_prog = prog;
1604         gc->pipe[pn].shader.smooth = smooth;
1605         gc->pipe[pn].shader.blend = blend;
1606         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1607         gc->pipe[pn].shader.clip = 0;
1608         gc->pipe[pn].shader.cx = 0;
1609         gc->pipe[pn].shader.cy = 0;
1610         gc->pipe[pn].shader.cw = 0;
1611         gc->pipe[pn].shader.ch = 0;
1612      }
1613    if ((tex->im) && (tex->im->native.data))
1614      {
1615         if (gc->pipe[pn].array.im != tex->im)
1616           {
1617              shader_array_flush(gc);
1618              gc->pipe[pn].array.im = tex->im;
1619           }
1620      }
1621    if (tex->pt->dyn.img)
1622      {
1623         if (gc->pipe[pn].array.im != tex->im)
1624           {
1625              shader_array_flush(gc);
1626              gc->pipe[pn].array.im = tex->im;
1627           }
1628      }
1629
1630    gc->pipe[pn].array.line = 0;
1631    gc->pipe[pn].array.use_vertex = 1;
1632    // if nomul... dont need this
1633    gc->pipe[pn].array.use_color = 1;
1634    gc->pipe[pn].array.use_texuv = 1;
1635    gc->pipe[pn].array.use_texuvm = 0;
1636    gc->pipe[pn].array.use_texuv2 = 0;
1637    gc->pipe[pn].array.use_texuv3 = 0;
1638 #endif
1639
1640    pipe_region_expand(gc, pn, x, y, w, h);
1641
1642    pnum = gc->pipe[pn].array.num;
1643    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
1644    nt = pnum * 4;
1645    gc->pipe[pn].array.num += 6;
1646    array_alloc(gc, pn);
1647
1648    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
1649      {
1650         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1651         ty1 = 1.0 - ((double)(tex->y) + sy) / (double)tex->pt->h;
1652         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1653         ty2 = 1.0 - ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1654      }
1655    else
1656      {
1657         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1658         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1659         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1660         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1661      }
1662
1663    PUSH_VERTEX(pn, x    , y    , 0);
1664    PUSH_VERTEX(pn, x + w, y    , 0);
1665    PUSH_VERTEX(pn, x    , y + h, 0);
1666
1667    PUSH_TEXUV(pn, tx1, ty1);
1668    PUSH_TEXUV(pn, tx2, ty1);
1669    PUSH_TEXUV(pn, tx1, ty2);
1670
1671    PUSH_VERTEX(pn, x + w, y    , 0);
1672    PUSH_VERTEX(pn, x + w, y + h, 0);
1673    PUSH_VERTEX(pn, x    , y + h, 0);
1674
1675    PUSH_TEXUV(pn, tx2, ty1);
1676    PUSH_TEXUV(pn, tx2, ty2);
1677    PUSH_TEXUV(pn, tx1, ty2);
1678
1679    // if nomul... dont need this
1680    for (i = 0; i < 6; i++)
1681      {
1682         PUSH_COLOR(pn, r, g, b, a);
1683      }
1684 }
1685
1686 void
1687 evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
1688                                   Evas_GL_Texture *tex,
1689                                   Evas_GL_Texture *texm,
1690                                   double sx, double sy, double sw, double sh,
1691                                   double sxm, double sym, double swm,double shm,
1692                                   int x, int y, int w, int h,
1693                                   int r, int g, int b, int a,
1694                                   Eina_Bool smooth)
1695 {
1696    int pnum, nv, nc, nu, nm, nt, i;
1697    GLfloat tx1, tx2, ty1, ty2;
1698    GLfloat txm1, txm2, tym1, tym2;
1699    Eina_Bool blend = 1;
1700    GLuint prog = gc->shared->shader.img_mask.prog;
1701    int pn = 0;
1702
1703 #if 0
1704    if (tex->gc->shared->info.bgra)
1705    {
1706            prog = gc->shared->shader.img_mask.prog;
1707    }
1708    else
1709    {
1710 #warning Nash: FIXME: Need two shaders?
1711            printf("Not good: Need other texture\n");
1712            prog = gc->shared->shader.img.prog;
1713    }
1714 #endif
1715
1716 again:
1717    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1718    pn = gc->state.top_pipe;
1719 #ifdef GLPIPES
1720    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1721      {
1722         gc->pipe[pn].region.type = RTYPE_IMASK;
1723         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1724         gc->pipe[pn].shader.cur_texm = texm->pt->texture;
1725         gc->pipe[pn].shader.cur_prog = prog;
1726         gc->pipe[pn].shader.smooth = smooth;
1727         gc->pipe[pn].shader.blend = blend;
1728         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1729         gc->pipe[pn].shader.clip = 0;
1730         gc->pipe[pn].shader.cx = 0;
1731         gc->pipe[pn].shader.cy = 0;
1732         gc->pipe[pn].shader.cw = 0;
1733         gc->pipe[pn].shader.ch = 0;
1734         gc->pipe[pn].array.line = 0;
1735         gc->pipe[pn].array.use_vertex = 1;
1736         // if nomul... dont need this
1737         gc->pipe[pn].array.use_color = 1;
1738         gc->pipe[pn].array.use_texuv = 1;
1739         gc->pipe[pn].array.use_texuv2 = 0;
1740         gc->pipe[pn].array.use_texuv3 = 0;
1741         gc->pipe[pn].array.use_texm = 1;
1742      }
1743    else
1744      {
1745         int found = 0;
1746
1747         for (i = pn; i >= 0; i--)
1748           {
1749              if ((gc->pipe[i].region.type == RTYPE_IMASK)
1750                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
1751                  && (gc->pipe[i].shader.cur_texm == texm->pt->texture)
1752                  && (gc->pipe[i].shader.cur_prog == prog)
1753                  && (gc->pipe[i].shader.smooth == smooth)
1754                  && (gc->pipe[i].shader.blend == blend)
1755                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1756                  && (gc->pipe[i].shader.clip == 0)
1757                 )
1758                {
1759                   found = 1;
1760                   pn = i;
1761                   break;
1762                }
1763              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1764           }
1765         if (!found)
1766           {
1767              pn = gc->state.top_pipe + 1;
1768              if (pn >= gc->shared->info.tune.pipes.max)
1769                {
1770                   shader_array_flush(gc);
1771                   goto again;
1772                }
1773              gc->state.top_pipe = pn;
1774              gc->pipe[pn].region.type = RTYPE_IMASK;
1775              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1776              gc->pipe[pn].shader.cur_texm = texm->pt->texture;
1777              gc->pipe[pn].shader.cur_prog = prog;
1778              gc->pipe[pn].shader.smooth = smooth;
1779              gc->pipe[pn].shader.blend = blend;
1780              gc->pipe[pn].shader.render_op = gc->dc->render_op;
1781              gc->pipe[pn].shader.clip = 0;
1782              gc->pipe[pn].shader.cx = 0;
1783              gc->pipe[pn].shader.cy = 0;
1784              gc->pipe[pn].shader.cw = 0;
1785              gc->pipe[pn].shader.ch = 0;
1786              gc->pipe[pn].array.line = 0;
1787              gc->pipe[pn].array.use_vertex = 1;
1788              gc->pipe[pn].array.use_color = 1;
1789              gc->pipe[pn].array.use_texuv = 1;
1790              gc->pipe[pn].array.use_texuv2 = 0;
1791              gc->pipe[pn].array.use_texuv3 = 0;
1792              gc->pipe[pn].array.use_texm = 1;
1793
1794          }
1795      }
1796    if ((tex->im) && (tex->im->native.data))
1797      {
1798         if (gc->pipe[pn].array.im != tex->im)
1799           {
1800              shader_array_flush(gc);
1801              pn = gc->state.top_pipe;
1802              gc->pipe[pn].array.im = tex->im;
1803              goto again;
1804           }
1805      }
1806    if (tex->pt->dyn.img)
1807      {
1808         if (gc->pipe[pn].array.im != tex->im)
1809           {
1810              shader_array_flush(gc);
1811              pn = gc->state.top_pipe;
1812              gc->pipe[pn].array.im = tex->im;
1813              goto again;
1814           }
1815      }
1816 #else
1817    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
1818        || (gc->pipe[pn].shader.cur_prog != prog)
1819        || (gc->pipe[pn].shader.smooth != smooth)
1820        || (gc->pipe[pn].shader.blend != blend)
1821        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
1822        || (gc->pipe[pn].shader.clip != 0)
1823        )
1824      {
1825         shader_array_flush(gc);
1826         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1827         gc->pipe[pn].shader.cur_texm = texm->pt->texture;
1828         gc->pipe[pn].shader.cur_prog = prog;
1829         gc->pipe[pn].shader.smooth = smooth;
1830         gc->pipe[pn].shader.blend = blend;
1831         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1832         gc->pipe[pn].shader.clip = 0;
1833         gc->pipe[pn].shader.cx = 0;
1834         gc->pipe[pn].shader.cy = 0;
1835         gc->pipe[pn].shader.cw = 0;
1836         gc->pipe[pn].shader.ch = 0;
1837      }
1838    if ((tex->im) && (tex->im->native.data))
1839      {
1840         if (gc->pipe[pn].array.im != tex->im)
1841           {
1842              shader_array_flush(gc);
1843              gc->pipe[pn].array.im = tex->im;
1844           }
1845      }
1846    if (tex->pt->dyn.img)
1847      {
1848         if (gc->pipe[pn].array.im != tex->im)
1849           {
1850              shader_array_flush(gc);
1851              gc->pipe[pn].array.im = tex->im;
1852           }
1853      }
1854
1855    gc->pipe[pn].array.line = 0;
1856    gc->pipe[pn].array.use_vertex = 1;
1857    gc->pipe[pn].array.use_color = 1;
1858    gc->pipe[pn].array.use_texuv = 1;
1859    gc->pipe[pn].array.use_texuv2 = 0;
1860    gc->pipe[pn].array.use_texuv3 = 0;
1861    gc->pipe[pn].array.use_texm = 1;
1862 #endif
1863
1864    pipe_region_expand(gc, pn, x, y, w, h);
1865
1866    pnum = gc->pipe[pn].array.num;
1867    nv = pnum * 3; nc = pnum * 4; nm = pnum * 2; nu = pnum * 2;
1868    nt = pnum * 4;
1869    gc->pipe[pn].array.num += 6;
1870    array_alloc(gc, pn);
1871
1872    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
1873      {
1874         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1875         ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1876         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1877         ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1878
1879         txm1 = ((double)(texm->x) + sxm) / (double)texm->pt->w;
1880         tym1 = ((double)(texm->y) + sym + shm) / (double)texm->pt->h;
1881         txm2 = ((double)(texm->x) + sxm + swm) / (double)texm->pt->w;
1882         tym2 = ((double)(texm->y) + sym) / (double)texm->pt->h;
1883      }
1884    else
1885      {
1886         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
1887         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
1888         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
1889         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
1890
1891         txm1 = (texm->x + sxm) / (double)texm->pt->w;
1892         tym1 = (texm->y + sym) / (double)texm->pt->h;
1893         txm2 = (texm->x + sxm + swm) / (double)texm->pt->w;
1894         tym2 = (texm->y + sym + shm) / (double)texm->pt->h;
1895      }
1896  // printf(" %3.6lf %3.6lf %3.6lf %3.6lf\n",sx,sy,sw,sh);
1897  //  printf("m%3.6lf %3.6lf %3.6lf %3.6lf\n",sxm,sym,swm,shm);
1898  // printf(" %3f %3f %3f %3f\n",tx1,ty1,tx2,ty2);
1899  // printf("m%3f %3f %3f %3f\n",txm1,tym1,txm2,tym2);
1900
1901    PUSH_VERTEX(pn, x    , y    , 0);
1902    PUSH_VERTEX(pn, x + w, y    , 0);
1903    PUSH_VERTEX(pn, x    , y + h, 0);
1904
1905    PUSH_TEXUV(pn, tx1, ty1);
1906    PUSH_TEXUV(pn, tx2, ty1);
1907    PUSH_TEXUV(pn, tx1, ty2);
1908
1909    PUSH_TEXM(pn, txm1, tym1);
1910    PUSH_TEXM(pn, txm2, tym1);
1911    PUSH_TEXM(pn, txm1, tym2);
1912
1913    PUSH_VERTEX(pn, x + w, y    , 0);
1914    PUSH_VERTEX(pn, x + w, y + h, 0);
1915    PUSH_VERTEX(pn, x    , y + h, 0);
1916
1917    PUSH_TEXUV(pn, tx2, ty1);
1918    PUSH_TEXUV(pn, tx2, ty2);
1919    PUSH_TEXUV(pn, tx1, ty2);
1920
1921    PUSH_TEXM(pn, txm2, tym1);
1922    PUSH_TEXM(pn, txm2, tym2);
1923    PUSH_TEXM(pn, txm1, tym2);
1924
1925    // if nomul... dont need this
1926    for (i = 0; i < 6; i++)
1927      {
1928         PUSH_COLOR(pn, r, g, b, a);
1929      }
1930 }
1931
1932
1933 void
1934 evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
1935                                  Evas_GL_Texture *tex,
1936                                  double sx, double sy, double sw, double sh,
1937                                  int x, int y, int w, int h,
1938                                  int r, int g, int b, int a)
1939 {
1940    int pnum, nv, nc, nu, nt, i;
1941    GLfloat tx1, tx2, ty1, ty2;
1942    int pn = 0;
1943
1944 again:
1945    vertex_array_size_check(gc, gc->state.top_pipe, 6);
1946    pn = gc->state.top_pipe;
1947 #ifdef GLPIPES
1948    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
1949      {
1950         gc->pipe[pn].region.type = RTYPE_FONT;
1951         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
1952         gc->pipe[pn].shader.cur_prog = gc->shared->shader.font.prog;
1953         gc->pipe[pn].shader.smooth = 0;
1954         gc->pipe[pn].shader.blend = 1;
1955         gc->pipe[pn].shader.render_op = gc->dc->render_op;
1956         gc->pipe[pn].shader.clip = 0;
1957         gc->pipe[pn].shader.cx = 0;
1958         gc->pipe[pn].shader.cy = 0;
1959         gc->pipe[pn].shader.cw = 0;
1960         gc->pipe[pn].shader.ch = 0;
1961         gc->pipe[pn].array.line = 0;
1962         gc->pipe[pn].array.use_vertex = 1;
1963         gc->pipe[pn].array.use_color = 1;
1964         gc->pipe[pn].array.use_texuv = 1;
1965         gc->pipe[pn].array.use_texuv2 = 0;
1966         gc->pipe[pn].array.use_texuv3 = 0;
1967      }
1968    else
1969      {
1970         int found = 0;
1971
1972         for (i = pn; i >= 0; i--)
1973           {
1974              if ((gc->pipe[i].region.type == RTYPE_FONT)
1975                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
1976                  && (gc->pipe[i].shader.cur_prog == gc->shared->shader.font.prog)
1977                  && (gc->pipe[i].shader.smooth == 0)
1978                  && (gc->pipe[i].shader.blend == 1)
1979                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
1980                  && (gc->pipe[i].shader.clip == 0)
1981                 )
1982                {
1983                   found = 1;
1984                   pn = i;
1985                   break;
1986                }
1987              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
1988           }
1989         if (!found)
1990           {
1991              pn = gc->state.top_pipe + 1;
1992              if (pn >= gc->shared->info.tune.pipes.max)
1993                {
1994                   shader_array_flush(gc);
1995                   goto again;
1996                }
1997              gc->state.top_pipe = pn;
1998              gc->pipe[pn].region.type = RTYPE_FONT;
1999              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2000              gc->pipe[pn].shader.cur_prog = gc->shared->shader.font.prog;
2001              gc->pipe[pn].shader.smooth = 0;
2002              gc->pipe[pn].shader.blend = 1;
2003              gc->pipe[pn].shader.render_op = gc->dc->render_op;
2004              gc->pipe[pn].shader.clip = 0;
2005              gc->pipe[pn].shader.cx = 0;
2006              gc->pipe[pn].shader.cy = 0;
2007              gc->pipe[pn].shader.cw = 0;
2008              gc->pipe[pn].shader.ch = 0;
2009              gc->pipe[pn].array.line = 0;
2010              gc->pipe[pn].array.use_vertex = 1;
2011              gc->pipe[pn].array.use_color = 1;
2012              gc->pipe[pn].array.use_texuv = 1;
2013              gc->pipe[pn].array.use_texuv2 = 0;
2014              gc->pipe[pn].array.use_texuv3 = 0;
2015          }
2016      }
2017 #else
2018    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
2019        || (gc->pipe[pn].shader.cur_prog != gc->shared->shader.font.prog)
2020        || (gc->pipe[pn].shader.smooth != 0)
2021        || (gc->pipe[pn].shader.blend != 1)
2022        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
2023        || (gc->pipe[pn].shader.clip != 0)
2024        )
2025      {
2026         shader_array_flush(gc);
2027         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2028         gc->pipe[pn].shader.cur_prog = gc->shared->shader.font.prog;
2029         gc->pipe[pn].shader.smooth = 0;
2030         gc->pipe[pn].shader.blend = 1;
2031         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2032         gc->pipe[pn].shader.clip = 0;
2033         gc->pipe[pn].shader.cx = 0;
2034         gc->pipe[pn].shader.cy = 0;
2035         gc->pipe[pn].shader.cw = 0;
2036         gc->pipe[pn].shader.ch = 0;
2037      }
2038
2039    gc->pipe[pn].region.type = RTYPE_FONT;
2040    gc->pipe[pn].array.line = 0;
2041    gc->pipe[pn].array.use_vertex = 1;
2042    gc->pipe[pn].array.use_color = 1;
2043    gc->pipe[pn].array.use_texuv = 1;
2044    gc->pipe[pn].array.use_texuv2 = 0;
2045    gc->pipe[pn].array.use_texuv3 = 0;
2046 #endif
2047
2048    pipe_region_expand(gc, pn, x, y, w, h);
2049
2050    pnum = gc->pipe[pn].array.num;
2051    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nt = pnum * 4;
2052    gc->pipe[pn].array.num += 6;
2053    array_alloc(gc, pn);
2054
2055    if (sw == 0.0)
2056      {
2057         tx1 = tex->sx1;
2058         ty1 = tex->sy1;
2059         tx2 = tex->sx2;
2060         ty2 = tex->sy2;
2061      }
2062    else
2063      {
2064         tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
2065         ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
2066         tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
2067         ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
2068      }
2069
2070    PUSH_VERTEX(pn, x    , y    , 0);
2071    PUSH_VERTEX(pn, x + w, y    , 0);
2072    PUSH_VERTEX(pn, x    , y + h, 0);
2073
2074    PUSH_TEXUV(pn, tx1, ty1);
2075    PUSH_TEXUV(pn, tx2, ty1);
2076    PUSH_TEXUV(pn, tx1, ty2);
2077
2078    PUSH_VERTEX(pn, x + w, y    , 0);
2079    PUSH_VERTEX(pn, x + w, y + h, 0);
2080    PUSH_VERTEX(pn, x    , y + h, 0);
2081
2082    PUSH_TEXUV(pn, tx2, ty1);
2083    PUSH_TEXUV(pn, tx2, ty2);
2084    PUSH_TEXUV(pn, tx1, ty2);
2085
2086    for (i = 0; i < 6; i++)
2087      {
2088         PUSH_COLOR(pn, r, g, b, a);
2089      }
2090 }
2091
2092 void
2093 evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
2094                                 Evas_GL_Texture *tex,
2095                                 double sx, double sy, double sw, double sh,
2096                                 int x, int y, int w, int h,
2097                                 int r, int g, int b, int a,
2098                                 Eina_Bool smooth)
2099 {
2100    int pnum, nv, nc, nu, nu2, nu3, nt, i;
2101    GLfloat tx1, tx2, ty1, ty2, t2x1, t2x2, t2y1, t2y2;
2102    Eina_Bool blend = 0;
2103    GLuint prog = gc->shared->shader.yuv.prog;
2104    int pn = 0;
2105
2106    if (a < 255) blend = 1;
2107
2108    if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2109      prog = gc->shared->shader.yuv_nomul.prog;
2110    else
2111      prog = gc->shared->shader.yuv.prog;
2112
2113 again:
2114    vertex_array_size_check(gc, gc->state.top_pipe, 6);
2115    pn = gc->state.top_pipe;
2116 #ifdef GLPIPES
2117    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
2118      {
2119         gc->pipe[pn].region.type = RTYPE_YUV;
2120         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2121         gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2122         gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2123         gc->pipe[pn].shader.cur_prog = prog;
2124         gc->pipe[pn].shader.smooth = smooth;
2125         gc->pipe[pn].shader.blend = blend;
2126         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2127         gc->pipe[pn].shader.clip = 0;
2128         gc->pipe[pn].shader.cx = 0;
2129         gc->pipe[pn].shader.cy = 0;
2130         gc->pipe[pn].shader.cw = 0;
2131         gc->pipe[pn].shader.ch = 0;
2132         gc->pipe[pn].array.line = 0;
2133         gc->pipe[pn].array.use_vertex = 1;
2134         gc->pipe[pn].array.use_color = 1;
2135         gc->pipe[pn].array.use_texuv = 1;
2136         gc->pipe[pn].array.use_texuv2 = 1;
2137         gc->pipe[pn].array.use_texuv3 = 1;
2138      }
2139    else
2140      {
2141         int found = 0;
2142
2143         for (i = pn; i >= 0; i--)
2144           {
2145              if ((gc->pipe[i].region.type == RTYPE_YUV)
2146                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
2147                  && (gc->pipe[i].shader.cur_prog == gc->shared->shader.font.prog)
2148                  && (gc->pipe[i].shader.smooth == smooth)
2149                  && (gc->pipe[i].shader.blend == blend)
2150                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
2151                  && (gc->pipe[i].shader.clip == 0)
2152                 )
2153                {
2154                   found = 1;
2155                   pn = i;
2156                   break;
2157                }
2158              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
2159           }
2160         if (!found)
2161           {
2162              pn = gc->state.top_pipe + 1;
2163              if (pn >= gc->shared->info.tune.pipes.max)
2164                {
2165                   shader_array_flush(gc);
2166                   goto again;
2167                }
2168              gc->state.top_pipe = pn;
2169              gc->pipe[pn].region.type = RTYPE_YUV;
2170              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2171              gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2172              gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2173              gc->pipe[pn].shader.cur_prog = prog;
2174              gc->pipe[pn].shader.smooth = smooth;
2175              gc->pipe[pn].shader.blend = blend;
2176              gc->pipe[pn].shader.render_op = gc->dc->render_op;
2177              gc->pipe[pn].shader.clip = 0;
2178              gc->pipe[pn].shader.cx = 0;
2179              gc->pipe[pn].shader.cy = 0;
2180              gc->pipe[pn].shader.cw = 0;
2181              gc->pipe[pn].shader.ch = 0;
2182              gc->pipe[pn].array.line = 0;
2183              gc->pipe[pn].array.use_vertex = 1;
2184              gc->pipe[pn].array.use_color = 1;
2185              gc->pipe[pn].array.use_texuv = 1;
2186              gc->pipe[pn].array.use_texuv2 = 1;
2187              gc->pipe[pn].array.use_texuv3 = 1;
2188          }
2189      }
2190 #else
2191    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
2192        || (gc->pipe[pn].shader.cur_prog != prog)
2193        || (gc->pipe[pn].shader.smooth != smooth)
2194        || (gc->pipe[pn].shader.blend != blend)
2195        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
2196        || (gc->pipe[pn].shader.clip != 0)
2197        )
2198      {
2199         shader_array_flush(gc);
2200         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2201         gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2202         gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2203         gc->pipe[pn].shader.cur_prog = prog;
2204         gc->pipe[pn].shader.smooth = smooth;
2205         gc->pipe[pn].shader.blend = blend;
2206         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2207         gc->pipe[pn].shader.clip = 0;
2208         gc->pipe[pn].shader.cx = 0;
2209         gc->pipe[pn].shader.cy = 0;
2210         gc->pipe[pn].shader.cw = 0;
2211         gc->pipe[pn].shader.ch = 0;
2212      }
2213
2214    gc->pipe[pn].region.type = RTYPE_YUV;
2215    gc->pipe[pn].array.line = 0;
2216    gc->pipe[pn].array.use_vertex = 1;
2217    gc->pipe[pn].array.use_color = 1;
2218    gc->pipe[pn].array.use_texuv = 1;
2219    gc->pipe[pn].array.use_texuv2 = 1;
2220    gc->pipe[pn].array.use_texuv3 = 1;
2221 #endif
2222
2223    pipe_region_expand(gc, pn, x, y, w, h);
2224
2225    pnum = gc->pipe[pn].array.num;
2226    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2;
2227    nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
2228    gc->pipe[pn].array.num += 6;
2229    array_alloc(gc, pn);
2230
2231    tx1 = (sx) / (double)tex->pt->w;
2232    ty1 = (sy) / (double)tex->pt->h;
2233    tx2 = (sx + sw) / (double)tex->pt->w;
2234    ty2 = (sy + sh) / (double)tex->pt->h;
2235
2236    t2x1 = ((sx) / 2) / (double)tex->ptu->w;
2237    t2y1 = ((sy) / 2) / (double)tex->ptu->h;
2238    t2x2 = ((sx + sw) / 2) / (double)tex->ptu->w;
2239    t2y2 = ((sy + sh) / 2) / (double)tex->ptu->h;
2240
2241    PUSH_VERTEX(pn, x    , y    , 0);
2242    PUSH_VERTEX(pn, x + w, y    , 0);
2243    PUSH_VERTEX(pn, x    , y + h, 0);
2244
2245    PUSH_TEXUV(pn, tx1, ty1);
2246    PUSH_TEXUV(pn, tx2, ty1);
2247    PUSH_TEXUV(pn, tx1, ty2);
2248
2249    PUSH_TEXUV2(pn, t2x1, t2y1);
2250    PUSH_TEXUV2(pn, t2x2, t2y1);
2251    PUSH_TEXUV2(pn, t2x1, t2y2);
2252
2253    PUSH_TEXUV3(pn, t2x1, t2y1);
2254    PUSH_TEXUV3(pn, t2x2, t2y1);
2255    PUSH_TEXUV3(pn, t2x1, t2y2);
2256
2257    PUSH_VERTEX(pn, x + w, y    , 0);
2258    PUSH_VERTEX(pn, x + w, y + h, 0);
2259    PUSH_VERTEX(pn, x    , y + h, 0);
2260
2261    PUSH_TEXUV(pn, tx2, ty1);
2262    PUSH_TEXUV(pn, tx2, ty2);
2263    PUSH_TEXUV(pn, tx1, ty2);
2264
2265    PUSH_TEXUV2(pn, t2x2, t2y1);
2266    PUSH_TEXUV2(pn, t2x2, t2y2);
2267    PUSH_TEXUV2(pn, t2x1, t2y2);
2268
2269    PUSH_TEXUV3(pn, t2x2, t2y1);
2270    PUSH_TEXUV3(pn, t2x2, t2y2);
2271    PUSH_TEXUV3(pn, t2x1, t2y2);
2272
2273    for (i = 0; i < 6; i++)
2274      {
2275         PUSH_COLOR(pn, r, g, b, a);
2276      }
2277 }
2278
2279 void
2280 evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
2281                                       Evas_GL_Texture *tex,
2282                                       int npoints,
2283                                       RGBA_Map_Point *p,
2284                                       int clip, int cx, int cy, int cw, int ch,
2285                                       int r, int g, int b, int a,
2286                                       Eina_Bool smooth, Eina_Bool tex_only,
2287                                       Eina_Bool yuv)
2288 {
2289    int pnum, nv, nc, nu, nu2, nu3, nt, i;
2290    const int points[6] = { 0, 1, 2, 0, 2, 3 };
2291    int x = 0, y = 0, w = 0, h = 0, px = 0, py = 0;
2292    GLfloat tx[4], ty[4], t2x[4], t2y[4];
2293    Eina_Bool blend = 1;
2294    DATA32 cmul;
2295    GLuint prog = gc->shared->shader.img.prog;
2296    int pn = 0;
2297    int flat = 0;
2298
2299    if (!tex->alpha) blend = 0;
2300    if (a < 255) blend = 1;
2301    if (npoints != 4)
2302      {
2303         // FIXME: nash - you didn't fix this for n points. its still all
2304         // 4 point stuff!!! grrrr.
2305         abort();
2306      }
2307    if ((A_VAL(&(p[0].col)) < 0xff) || (A_VAL(&(p[1].col)) < 0xff) ||
2308        (A_VAL(&(p[2].col)) < 0xff) || (A_VAL(&(p[3].col)) < 0xff))
2309      blend = 1;
2310
2311    if ((p[0].z == p[1].z) && (p[1].z == p[2].z) && (p[2].z == p[3].z))
2312       flat = 1;
2313
2314    if (!clip) cx = cy = cw = ch = 0;
2315
2316    if (!flat)
2317      {
2318         if (p[0].foc <= 0) flat = 1;
2319      }
2320    if (yuv)
2321      {
2322         prog = gc->shared->shader.yuv.prog;
2323         if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2324           {
2325              if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2326                  (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2327                 prog = gc->shared->shader.yuv_nomul.prog;
2328              else
2329                 prog = gc->shared->shader.yuv.prog;
2330           }
2331         else
2332            prog = gc->shared->shader.yuv.prog;
2333      }
2334    else
2335      {
2336         if (tex_only)
2337           {
2338              if (tex->pt->dyn.img)
2339                {
2340                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2341                     {
2342                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2343                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2344                           prog = gc->shared->shader.img_nomul.prog;
2345                        else
2346                           prog = gc->shared->shader.img.prog;
2347                     }
2348                   else
2349                      prog = gc->shared->shader.img.prog;
2350                }
2351              else
2352                {
2353                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2354                     {
2355                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2356                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2357                           prog = gc->shared->shader.tex_nomul.prog;
2358                        else
2359                           prog = gc->shared->shader.tex.prog;
2360                     }
2361                   else
2362                      prog = gc->shared->shader.tex.prog;
2363                }
2364           }
2365         else
2366           {
2367              if (tex->gc->shared->info.bgra)
2368                {
2369                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2370                     {
2371                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2372                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2373                           prog = gc->shared->shader.img_bgra_nomul.prog;
2374                        else
2375                           prog = gc->shared->shader.img_bgra.prog;
2376                     }
2377                   else
2378                      prog = gc->shared->shader.img_bgra.prog;
2379                }
2380              else
2381                {
2382                   if ((a == 255) && (r == 255) && (g == 255) && (b == 255))
2383                     {
2384                        if ((p[0].col == 0xffffffff) && (p[1].col == 0xffffffff) &&
2385                            (p[2].col == 0xffffffff) && (p[3].col == 0xffffffff))
2386                           prog = gc->shared->shader.img_nomul.prog;
2387                        else
2388                           prog = gc->shared->shader.img.prog;
2389                     }
2390                   else
2391                      prog = gc->shared->shader.img.prog;
2392                }
2393           }
2394      }
2395
2396    x = w = (p[points[0]].x >> FP);
2397    y = h = (p[points[0]].y >> FP);
2398    for (i = 0; i < 4; i++)
2399      {
2400         tx[i] = ((double)(tex->x) + (((double)p[i].u) / FP1)) /
2401           (double)tex->pt->w;
2402         ty[i] = ((double)(tex->y) + (((double)p[i].v) / FP1)) /
2403           (double)tex->pt->h;
2404         px = (p[points[i]].x >> FP);
2405         if      (px < x) x = px;
2406         else if (px > w) w = px;
2407         py = (p[points[i]].y >> FP);
2408         if      (py < y) y = py;
2409         else if (py > h) h = py;
2410         if (yuv)
2411           {
2412              t2x[i] = ((((double)p[i].u / 2) / FP1)) / (double)tex->ptu->w;
2413              t2y[i] = ((((double)p[i].v / 2) / FP1)) / (double)tex->ptu->h;
2414           }
2415      }
2416    w = w - x;
2417    h = h - y;
2418
2419    if (clip)
2420      {
2421         int nx = x, ny = y, nw = w, nh = h;
2422
2423         RECTS_CLIP_TO_RECT(nx, ny, nw, nh, cx, cy, cw, ch);
2424         if ((nx == x) && (ny == y) && (nw == w) && (nh == h))
2425           {
2426              clip = 0; cx = 0; cy = 0; cw = 0; ch = 0;
2427           }
2428         x = nx; y = nw; w = nw; h = nh;
2429      }
2430
2431    if (!flat)
2432      {
2433         shader_array_flush(gc);
2434         gc->foc = p[0].foc >> FP;
2435         gc->z0 = p[0].z0 >> FP;
2436         gc->px = p[0].px >> FP;
2437         gc->py = p[0].py >> FP;
2438         gc->change.size = 1;
2439         _evas_gl_common_viewport_set(gc);
2440      }
2441 again:
2442    vertex_array_size_check(gc, gc->state.top_pipe, 6);
2443    pn = gc->state.top_pipe;
2444 #ifdef GLPIPES
2445    if ((pn == 0) && (gc->pipe[pn].array.num == 0))
2446      {
2447         gc->pipe[pn].region.type = RTYPE_MAP;
2448         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2449         if (yuv)
2450           {
2451              gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2452              gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2453           }
2454         gc->pipe[pn].shader.cur_prog = prog;
2455         gc->pipe[pn].shader.smooth = smooth;
2456         gc->pipe[pn].shader.blend = blend;
2457         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2458         gc->pipe[pn].shader.clip = clip;
2459         gc->pipe[pn].shader.cx = cx;
2460         gc->pipe[pn].shader.cy = cy;
2461         gc->pipe[pn].shader.cw = cw;
2462         gc->pipe[pn].shader.ch = ch;
2463         gc->pipe[pn].array.line = 0;
2464         gc->pipe[pn].array.use_vertex = 1;
2465         gc->pipe[pn].array.use_color = 1;
2466         gc->pipe[pn].array.use_texuv = 1;
2467         if (yuv)
2468           {
2469              gc->pipe[pn].array.use_texuv2 = 1;
2470              gc->pipe[pn].array.use_texuv3 = 1;
2471           }
2472         else
2473           {
2474              gc->pipe[pn].array.use_texuv2 = 0;
2475              gc->pipe[pn].array.use_texuv3 = 0;
2476           }
2477      }
2478    else
2479      {
2480         int found = 0;
2481
2482         for (i = pn; i >= 0; i--)
2483           {
2484              if ((gc->pipe[i].region.type == RTYPE_MAP)
2485                  && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
2486                  && (gc->pipe[i].shader.cur_prog == prog)
2487                  && (gc->pipe[i].shader.smooth == smooth)
2488                  && (gc->pipe[i].shader.blend == blend)
2489                  && (gc->pipe[i].shader.render_op == gc->dc->render_op)
2490                  && (gc->pipe[i].shader.clip == clip)
2491                  && (gc->pipe[i].shader.cx == cx)
2492                  && (gc->pipe[i].shader.cy == cy)
2493                  && (gc->pipe[i].shader.cw == cw)
2494                  && (gc->pipe[i].shader.ch == ch)
2495                 )
2496                {
2497                   found = 1;
2498                   pn = i;
2499                   break;
2500                }
2501              if (pipe_region_intersects(gc, i, x, y, w, h)) break;
2502           }
2503         if (!found)
2504           {
2505              pn = gc->state.top_pipe + 1;
2506              if (pn >= gc->shared->info.tune.pipes.max)
2507                {
2508                   shader_array_flush(gc);
2509                   goto again;
2510                }
2511              gc->state.top_pipe = pn;
2512              gc->pipe[pn].region.type = RTYPE_MAP;
2513              gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2514              if (yuv)
2515                {
2516                   gc->pipe[pn].shader.cur_texu = tex->ptu->texture;
2517                   gc->pipe[pn].shader.cur_texv = tex->ptv->texture;
2518                }
2519              gc->pipe[pn].shader.cur_prog = prog;
2520              gc->pipe[pn].shader.smooth = smooth;
2521              gc->pipe[pn].shader.blend = blend;
2522              gc->pipe[pn].shader.render_op = gc->dc->render_op;
2523              gc->pipe[pn].shader.clip = clip;
2524              gc->pipe[pn].shader.cx = cx;
2525              gc->pipe[pn].shader.cy = cy;
2526              gc->pipe[pn].shader.cw = cw;
2527              gc->pipe[pn].shader.ch = ch;
2528              gc->pipe[pn].array.line = 0;
2529              gc->pipe[pn].array.use_vertex = 1;
2530              gc->pipe[pn].array.use_color = 1;
2531              gc->pipe[pn].array.use_texuv = 1;
2532              if (yuv)
2533                {
2534                   gc->pipe[pn].array.use_texuv2 = 1;
2535                   gc->pipe[pn].array.use_texuv3 = 1;
2536                }
2537              else
2538                {
2539                   gc->pipe[pn].array.use_texuv2 = 0;
2540                   gc->pipe[pn].array.use_texuv3 = 0;
2541                }
2542          }
2543      }
2544    if ((tex->im) && (tex->im->native.data))
2545      {
2546         if (gc->pipe[pn].array.im != tex->im)
2547           {
2548              shader_array_flush(gc);
2549              pn = gc->state.top_pipe;
2550              gc->pipe[pn].array.im = tex->im;
2551              goto again;
2552           }
2553      }
2554    if (tex->pt->dyn.img)
2555      {
2556         if (gc->pipe[pn].array.im != tex->im)
2557           {
2558              shader_array_flush(gc);
2559              pn = gc->state.top_pipe;
2560              gc->pipe[pn].array.im = tex->im;
2561              goto again;
2562           }
2563      }
2564 #else
2565    if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
2566        || (gc->pipe[pn].shader.cur_prog != prog)
2567        || (gc->pipe[pn].shader.smooth != smooth)
2568        || (gc->pipe[pn].shader.blend != blend)
2569        || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
2570        || (gc->pipe[pn].shader.clip != clip)
2571        || (gc->pipe[pn].shader.cx != cx)
2572        || (gc->pipe[pn].shader.cy != cy)
2573        || (gc->pipe[pn].shader.cw != cw)
2574        || (gc->pipe[pn].shader.ch != ch)
2575        )
2576      {
2577         shader_array_flush(gc);
2578         gc->pipe[pn].shader.cur_tex = tex->pt->texture;
2579         gc->pipe[pn].shader.cur_prog = prog;
2580         gc->pipe[pn].shader.smooth = smooth;
2581         gc->pipe[pn].shader.blend = blend;
2582         gc->pipe[pn].shader.render_op = gc->dc->render_op;
2583         gc->pipe[pn].shader.clip = clip;
2584         gc->pipe[pn].shader.cx = cx;
2585         gc->pipe[pn].shader.cy = cy;
2586         gc->pipe[pn].shader.cw = cw;
2587         gc->pipe[pn].shader.ch = ch;
2588      }
2589    if ((tex->im) && (tex->im->native.data))
2590      {
2591         if (gc->pipe[pn].array.im != tex->im)
2592           {
2593              shader_array_flush(gc);
2594              gc->pipe[pn].array.im = tex->im;
2595           }
2596      }
2597    if (tex->pt->dyn.img)
2598      {
2599         if (gc->pipe[pn].array.im != tex->im)
2600           {
2601              shader_array_flush(gc);
2602              gc->pipe[pn].array.im = tex->im;
2603           }
2604      }
2605
2606    gc->pipe[pn].region.type = RTYPE_MAP;
2607    gc->pipe[pn].array.line = 0;
2608    gc->pipe[pn].array.use_vertex = 1;
2609    gc->pipe[pn].array.use_color = 1;
2610    gc->pipe[pn].array.use_texuv = 1;
2611    if (yuv)
2612      {
2613         gc->pipe[pn].array.use_texuv2 = 1;
2614         gc->pipe[pn].array.use_texuv3 = 1;
2615      }
2616    else
2617      {
2618         gc->pipe[pn].array.use_texuv2 = 0;
2619         gc->pipe[pn].array.use_texuv3 = 0;
2620      }
2621 #endif
2622
2623    pipe_region_expand(gc, pn, x, y, w, h);
2624
2625    pnum = gc->pipe[pn].array.num;
2626    nv = pnum * 3; nc = pnum * 4; nu = pnum * 2; nu2 = pnum * 2;
2627    nu2 = pnum * 2; nu3 = pnum * 2; nt = pnum * 4;
2628    gc->pipe[pn].array.num += 6;
2629    array_alloc(gc, pn);
2630
2631    if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
2632      {
2633         for (i = 0; i < 4; i++)
2634           {
2635              ty[i] = 1.0 - ty[i];
2636              if (yuv)
2637                 t2y[i] = 1.0 - t2y[i];
2638           }
2639      }
2640
2641    cmul = ARGB_JOIN(a, r, g, b);
2642    for (i = 0; i < 6; i++)
2643      {
2644         DATA32 cl = MUL4_SYM(cmul, p[points[i]].col);
2645         if (flat)
2646           {
2647              PUSH_VERTEX(pn,
2648                          (p[points[i]].x >> FP),
2649                          (p[points[i]].y >> FP),
2650                          0);
2651           }
2652         else
2653           {
2654              PUSH_VERTEX(pn,
2655                          (p[points[i]].fx) + gc->shared->ax,
2656                          (p[points[i]].fy) + gc->shared->ay,
2657                          (p[points[i]].fz)
2658                          + (gc->shared->foc - gc->shared->z0));
2659           }
2660         PUSH_TEXUV(pn,
2661                    tx[points[i]],
2662                    ty[points[i]]);
2663         if (yuv)
2664           {
2665              PUSH_TEXUV2(pn,
2666                          t2x[points[i]],
2667                          t2y[points[i]]);
2668              PUSH_TEXUV3(pn,
2669                          t2x[points[i]],
2670                          t2y[points[i]]);
2671           }
2672
2673         PUSH_COLOR(pn,
2674                    R_VAL(&cl),
2675                    G_VAL(&cl),
2676                    B_VAL(&cl),
2677                    A_VAL(&cl));
2678      }
2679    if (!flat)
2680      {
2681         shader_array_flush(gc);
2682         gc->foc = 0;
2683         gc->z0 = 0;
2684         gc->px = 0;
2685         gc->py = 0;
2686         gc->change.size = 1;
2687         _evas_gl_common_viewport_set(gc);
2688      }
2689 }
2690
2691 void
2692 evas_gl_common_context_flush(Evas_Engine_GL_Context *gc)
2693 {
2694    shader_array_flush(gc);
2695 }
2696
2697 static void
2698 scissor_rot(Evas_Engine_GL_Context *gc __UNUSED__,
2699             int rot, int gw, int gh, int cx, int cy, int cw, int ch)
2700 {
2701    switch (rot)
2702      {
2703       case 0: // UP this way: ^
2704         glScissor(cx, cy, cw, ch);
2705         break;
2706       case 90: // UP this way: <
2707         glScissor(gh - (cy + ch), cx, ch, cw);
2708         break;
2709       case 180: // UP this way: v
2710         glScissor(gw - (cx + cw), gh - (cy + ch), cw, ch);
2711         break;
2712       case 270: // UP this way: >
2713         glScissor(cy, gw - (cx + cw), ch, cw);
2714         break;
2715       default: // assume up is up
2716         glScissor(cx, cy, cw, ch);
2717         break;
2718      }
2719 }
2720
2721 static void
2722 shader_array_flush(Evas_Engine_GL_Context *gc)
2723 {
2724    int i, gw, gh, setclip, cy, fbo = 0, done = 0;
2725
2726    if (!gc->havestuff) return;
2727    gw = gc->w;
2728    gh = gc->h;
2729    if (!((gc->pipe[0].shader.surface == gc->def_surface) ||
2730          (!gc->pipe[0].shader.surface)))
2731      {
2732         gw = gc->pipe[0].shader.surface->w;
2733         gh = gc->pipe[0].shader.surface->h;
2734         fbo = 1;
2735      }
2736    for (i = 0; i < gc->shared->info.tune.pipes.max; i++)
2737      {
2738         if (gc->pipe[i].array.num <= 0) break;
2739         setclip = 0;
2740         done++;
2741         gc->flushnum++;
2742         GLERR(__FUNCTION__, __FILE__, __LINE__, "<flush err>");
2743         if (gc->pipe[i].shader.cur_prog != gc->state.current.cur_prog)
2744           {
2745              glUseProgram(gc->pipe[i].shader.cur_prog);
2746              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2747           }
2748
2749         if (gc->pipe[i].shader.cur_tex != gc->state.current.cur_tex)
2750           {
2751 #if 0
2752              if (gc->pipe[i].shader.cur_tex)
2753                {
2754                   glEnable(GL_TEXTURE_2D);
2755                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2756                }
2757              else
2758                {
2759                   glDisable(GL_TEXTURE_2D);
2760                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2761                }
2762 #endif
2763              glActiveTexture(GL_TEXTURE0);
2764              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2765              glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_tex);
2766              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2767           }
2768         if (gc->pipe[i].array.im)
2769           {
2770 #if defined (GLES_VARIETY_S3C6410) || defined (GLES_VARIETY_SGX)
2771              if (gc->pipe[i].array.im->tex->pt->dyn.img)
2772                {
2773                   secsym_glEGLImageTargetTexture2DOES
2774                      (GL_TEXTURE_2D, gc->pipe[i].array.im->tex->pt->dyn.img);
2775                }
2776              else
2777 #endif
2778                {
2779                   if (!gc->pipe[i].array.im->native.loose)
2780                     {
2781                        if (gc->pipe[i].array.im->native.func.bind)
2782                           gc->pipe[i].array.im->native.func.bind(gc->pipe[i].array.im->native.func.data,
2783                                                                  gc->pipe[i].array.im);
2784                     }
2785                }
2786           }
2787         if (gc->pipe[i].shader.render_op != gc->state.current.render_op)
2788           {
2789              switch (gc->pipe[i].shader.render_op)
2790                {
2791                case EVAS_RENDER_BLEND: /**< default op: d = d*(1-sa) + s */
2792                   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2793                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2794                   break;
2795                case EVAS_RENDER_COPY: /**< d = s */
2796                   gc->pipe[i].shader.blend = 0;
2797                   glBlendFunc(GL_ONE, GL_ONE);
2798                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2799                   break;
2800                   // FIXME: fix blend funcs below!
2801                case EVAS_RENDER_BLEND_REL: /**< d = d*(1 - sa) + s*da */
2802                case EVAS_RENDER_COPY_REL: /**< d = s*da */
2803                case EVAS_RENDER_ADD: /**< d = d + s */
2804                case EVAS_RENDER_ADD_REL: /**< d = d + s*da */
2805                case EVAS_RENDER_SUB: /**< d = d - s */
2806                case EVAS_RENDER_SUB_REL: /**< d = d - s*da */
2807                case EVAS_RENDER_TINT: /**< d = d*s + d*(1 - sa) + s*(1 - da) */
2808                case EVAS_RENDER_TINT_REL: /**< d = d*(1 - sa + s) */
2809                case EVAS_RENDER_MASK: /**< d = d*sa */
2810                case EVAS_RENDER_MUL: /**< d = d*s */
2811                default:
2812                   glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2813                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2814                   break;
2815                }
2816           }
2817         if (gc->pipe[i].shader.blend != gc->state.current.blend)
2818           {
2819              if (gc->pipe[i].shader.blend)
2820                {
2821                   glEnable(GL_BLEND);
2822                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2823                }
2824              else
2825                {
2826                   glDisable(GL_BLEND);
2827                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2828                }
2829           }
2830         if ((gc->pipe[i].shader.smooth != gc->state.current.smooth) ||
2831             (gc->pipe[i].shader.cur_tex != gc->state.current.cur_tex))
2832           {
2833              if (gc->pipe[i].shader.smooth)
2834                {
2835 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2836                   if (shared->info.anisotropic > 0.0)
2837                     {
2838                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, shared->info.anisotropic);
2839                        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2840                     }
2841 #endif
2842                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2843                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2844                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2845                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2846                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2847                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2848                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2849                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2850                }
2851              else
2852                {
2853 #ifdef GL_TEXTURE_MAX_ANISOTROPY_EXT
2854                   if (shared->info.anisotropic > 0.0)
2855                     {
2856                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0);
2857                        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2858                     }
2859 #endif
2860                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2861                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2862                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2863                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2864                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2865                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2866                   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2867                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2868                }
2869           }
2870         if (gc->pipe[i].shader.clip != gc->state.current.clip)
2871           {
2872
2873              if (gc->pipe[i].shader.clip)
2874                {
2875                   cy = gh - gc->pipe[i].shader.cy - gc->pipe[i].shader.ch;
2876                   if (fbo) cy = gc->pipe[i].shader.cy;
2877                   glEnable(GL_SCISSOR_TEST);
2878                   if (!fbo)
2879                      scissor_rot(gc, gc->rot, gw, gh,
2880                                  gc->pipe[i].shader.cx,
2881                                  cy,
2882                                  gc->pipe[i].shader.cw,
2883                                  gc->pipe[i].shader.ch);
2884                   else
2885                      glScissor(gc->pipe[i].shader.cx, cy,
2886                                gc->pipe[i].shader.cw, gc->pipe[i].shader.ch);
2887                   setclip = 1;
2888                }
2889              else
2890                {
2891                   glDisable(GL_SCISSOR_TEST);
2892                   glScissor(0, 0, 0, 0);
2893                }
2894           }
2895         if ((gc->pipe[i].shader.clip) && (!setclip))
2896           {
2897              if ((gc->pipe[i].shader.cx != gc->state.current.cx) ||
2898                  (gc->pipe[i].shader.cy != gc->state.current.cy) ||
2899                  (gc->pipe[i].shader.cw != gc->state.current.cw) ||
2900                  (gc->pipe[i].shader.ch != gc->state.current.ch))
2901                {
2902                   cy = gh - gc->pipe[i].shader.cy - gc->pipe[i].shader.ch;
2903                   if (fbo) cy = gc->pipe[i].shader.cy;
2904                   if (!fbo)
2905                      scissor_rot(gc, gc->rot, gw, gh,
2906                                  gc->pipe[i].shader.cx,
2907                                  cy,
2908                                  gc->pipe[i].shader.cw,
2909                                  gc->pipe[i].shader.ch);
2910                   else
2911                      glScissor(gc->pipe[i].shader.cx, cy,
2912                                gc->pipe[i].shader.cw, gc->pipe[i].shader.ch);
2913                }
2914           }
2915
2916         glVertexAttribPointer(SHAD_VERTEX, 3, GL_SHORT, GL_FALSE, 0, gc->pipe[i].array.vertex);
2917         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2918         glVertexAttribPointer(SHAD_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, gc->pipe[i].array.color);
2919         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2920         if (gc->pipe[i].array.use_texuv)
2921           {
2922              glEnableVertexAttribArray(SHAD_TEXUV);
2923              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2924              glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv);
2925              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2926           }
2927         else
2928           {
2929              glDisableVertexAttribArray(SHAD_TEXUV);
2930              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2931           }
2932
2933         if (gc->pipe[i].array.line)
2934           {
2935              glDisableVertexAttribArray(SHAD_TEXUV);
2936              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2937              glDisableVertexAttribArray(SHAD_TEXUV2);
2938              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2939              glDisableVertexAttribArray(SHAD_TEXUV3);
2940              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2941              glDrawArrays(GL_LINES, 0, gc->pipe[i].array.num);
2942              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2943           }
2944         else
2945           {
2946              if (gc->pipe[i].array.use_texm)
2947                {
2948                   glEnableVertexAttribArray(SHAD_TEXM);
2949                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2950                   glVertexAttribPointer(SHAD_TEXM, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texm);
2951                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2952                   glActiveTexture(GL_TEXTURE1);
2953                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2954                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texm);
2955                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2956                   glActiveTexture(GL_TEXTURE0);
2957                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2958                }
2959              else
2960                {
2961                   glDisableVertexAttribArray(SHAD_TEXM);
2962                }
2963              if ((gc->pipe[i].array.use_texuv2) && (gc->pipe[i].array.use_texuv3))
2964                {
2965                   glEnableVertexAttribArray(SHAD_TEXUV2);
2966                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2967                   glEnableVertexAttribArray(SHAD_TEXUV3);
2968                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2969                   glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
2970                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2971                   glVertexAttribPointer(SHAD_TEXUV3, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv3);
2972                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2973                   glActiveTexture(GL_TEXTURE1);
2974                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2975                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
2976                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2977                   glActiveTexture(GL_TEXTURE2);
2978                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2979                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texv);
2980                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2981                   glActiveTexture(GL_TEXTURE0);
2982                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2983                }
2984              else if (gc->pipe[i].array.use_texuv2)
2985                {
2986                   glEnableVertexAttribArray(SHAD_TEXUV2);
2987                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2988                   glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
2989                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2990                   glActiveTexture(GL_TEXTURE1);
2991                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2992                   glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
2993                   glActiveTexture(GL_TEXTURE0);
2994                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
2995                }
2996              else
2997                {
2998                   glDisableVertexAttribArray(SHAD_TEXUV2);
2999                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
3000                   glDisableVertexAttribArray(SHAD_TEXUV3);
3001                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
3002                }
3003              if (dbgflushnum)
3004                {
3005                   const char *types[6] =
3006                     {"----", "RECT", "IMAG", "FONT", "YUV-", "MAP"};
3007                   printf("  DRAW#%3i %4i -> %p[%4ix%4i] @ %4ix%4i -{ tex %4i type %s }-\n",
3008                          i,
3009                          gc->pipe[i].array.num / 6,
3010                          gc->pipe[0].shader.surface,
3011                          gc->pipe[0].shader.surface->w,
3012                          gc->pipe[0].shader.surface->h,
3013                          gw, gh,
3014                          gc->pipe[i].shader.cur_tex,
3015                          types[gc->pipe[i].region.type]
3016                         );
3017                }
3018              glDrawArrays(GL_TRIANGLES, 0, gc->pipe[i].array.num);
3019              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
3020           }
3021         if (gc->pipe[i].array.im)
3022           {
3023              if (!gc->pipe[i].array.im->native.loose)
3024                {
3025                   if (gc->pipe[i].array.im->native.func.unbind)
3026                      gc->pipe[i].array.im->native.func.unbind(gc->pipe[i].array.im->native.func.data,
3027                                                               gc->pipe[i].array.im);
3028                }
3029              gc->pipe[i].array.im = NULL;
3030           }
3031
3032         gc->state.current.cur_prog  = gc->pipe[i].shader.cur_prog;
3033         gc->state.current.cur_tex   = gc->pipe[i].shader.cur_tex;
3034         gc->state.current.blend     = gc->pipe[i].shader.blend;
3035         gc->state.current.smooth    = gc->pipe[i].shader.smooth;
3036         gc->state.current.render_op = gc->pipe[i].shader.render_op;
3037         gc->state.current.clip      = gc->pipe[i].shader.clip;
3038         gc->state.current.cx        = gc->pipe[i].shader.cx;
3039         gc->state.current.cy        = gc->pipe[i].shader.cy;
3040         gc->state.current.cw        = gc->pipe[i].shader.cw;
3041         gc->state.current.ch        = gc->pipe[i].shader.ch;
3042
3043         if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
3044         if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);
3045         if (gc->pipe[i].array.texuv) free(gc->pipe[i].array.texuv);
3046         if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
3047         if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
3048         if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
3049
3050         gc->pipe[i].array.vertex = NULL;
3051         gc->pipe[i].array.color = NULL;
3052         gc->pipe[i].array.texuv = NULL;
3053         gc->pipe[i].array.texm = NULL;
3054         gc->pipe[i].array.texuv2 = NULL;
3055         gc->pipe[i].array.texuv3 = NULL;
3056
3057         gc->pipe[i].array.num = 0;
3058         gc->pipe[i].array.alloc = 0;
3059
3060         gc->pipe[i].region.x = 0;
3061         gc->pipe[i].region.y = 0;
3062         gc->pipe[i].region.w = 0;
3063         gc->pipe[i].region.h = 0;
3064         gc->pipe[i].region.type = 0;
3065      }
3066    gc->state.top_pipe = 0;
3067    if (dbgflushnum)
3068      {
3069         if (done > 0) printf("DONE (pipes): %i\n", done);
3070      }
3071    gc->havestuff = EINA_FALSE;
3072 }
3073
3074 Eina_Bool
3075 evas_gl_common_module_open(void)
3076 {
3077    if (_evas_engine_GL_common_log_dom < 0)
3078      _evas_engine_GL_common_log_dom = eina_log_domain_register
3079        ("evas-gl_common", EVAS_DEFAULT_LOG_COLOR);
3080    if (_evas_engine_GL_common_log_dom < 0)
3081      {
3082         EINA_LOG_ERR("Can not create a module log domain.");
3083         return EINA_FALSE;
3084      }
3085    return EINA_TRUE;
3086 }
3087
3088 void
3089 evas_gl_common_module_close(void)
3090 {
3091    if (_evas_engine_GL_common_log_dom < 0) return;
3092    eina_log_domain_unregister(_evas_engine_GL_common_log_dom);
3093    _evas_engine_GL_common_log_dom = -1;
3094 }