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