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