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