ector/gl: rafactor gl_surface code to ecto_gl_engine
authorsubhransu mohanty <smohantty@gmail.com>
Thu, 8 Dec 2016 06:10:01 +0000 (15:10 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Mon, 2 Jan 2017 07:23:59 +0000 (16:23 +0900)
Change-Id: I18c5b3977997e43e3e0d900773b4312429c78ee1

src/Makefile_Ector.am
src/lib/ector/gl/ector_gl_engine.c [new file with mode: 0644]
src/lib/ector/gl/ector_gl_private.h
src/lib/ector/gl/ector_gl_shaders.x [new file with mode: 0644]
src/lib/ector/gl/ector_gl_surface.c
src/lib/ector/gl/ector_gl_surface.eo
src/lib/ector/gl/ector_renderer_gl_shape.c
src/modules/evas/engines/gl_generic/evas_engine.c

index 62db3c6..18dbffb 100644 (file)
@@ -120,6 +120,8 @@ lib/ector/gl/ector_renderer_gl_gradient_linear.c \
 lib/ector/gl/ector_renderer_gl_gradient_radial.c \
 lib/ector/gl/ector_renderer_gl_shape.c \
 lib/ector/gl/ector_gl_surface.c \
+lib/ector/gl/ector_gl_engine.c \
+lib/ector/gl/ector_gl_shaders.x \
 static_libs/triangulator/triangulator_stroker.c \
 static_libs/triangulator/triangulator_simple.c
 
diff --git a/src/lib/ector/gl/ector_gl_engine.c b/src/lib/ector/gl/ector_gl_engine.c
new file mode 100644 (file)
index 0000000..85ed208
--- /dev/null
@@ -0,0 +1,928 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Ector_Gl.h>
+#include "ector_private.h"
+#include "ector_gl_private.h"
+#include "ector_gl_shaders.x"
+
+static void
+_init_matrix(float *m)
+{
+   m[0] = 1.0f;
+   m[1] = 0.0f;
+   m[2] = 0.0f;
+   m[3] = 0.0f;
+
+   m[4] = 0.0f;
+   m[5] = 1.0f;
+   m[6] = 0.0f;
+   m[7] = 0.0f;
+
+   m[8] = 0.0f;
+   m[9] = 0.0f;
+   m[10] = 1.0f;
+   m[11] = 0.0f;
+
+   m[12] = 0.0f;
+   m[13] = 0.0f;
+   m[14] = 0.0f;
+   m[15] = 1.0f;
+}
+
+static void
+_matrix_ortho(GLfloat *m,
+             GLfloat l, GLfloat r,
+             GLfloat t, GLfloat b,
+             GLfloat near_, GLfloat far_,
+             int rot, int vw, int vh,
+             int foc, GLfloat orth)
+{
+   GLfloat rotf;
+   GLfloat cosv, sinv;
+   GLfloat tx, ty;
+
+   rotf = (((rot / 90) & 0x3) * M_PI) / 2.0;
+
+   tx = -0.5 * (1.0 - orth);
+   ty = -0.5 * (1.0 - orth);
+
+   if (rot == 90)
+     {
+        tx += -(vw * 1.0);
+        ty += -(vh * 0.0);
+     }
+   if (rot == 180)
+     {
+        tx += -(vw * 1.0);
+        ty += -(vh * 1.0);
+     }
+   if (rot == 270)
+     {
+        tx += -(vw * 0.0);
+        ty += -(vh * 1.0);
+     }
+
+   cosv = cos(rotf);
+   sinv = sin(rotf);
+
+   m[0] = (2.0 / (r - l)) * ( cosv);
+   m[1] = (2.0 / (r - l)) * ( sinv);
+   m[2] = 0.0;
+   m[3] = 0.0;
+
+   m[4] = (2.0 / (t - b)) * (-sinv);
+   m[5] = (2.0 / (t - b)) * ( cosv);
+   m[6] = 0.0;
+   m[7] = 0.0;
+
+   m[8] = 0.0;
+   m[9] = 0.0;
+   m[10] = -(2.0 / (far_ - near_));
+   m[11] = 1.0 / (GLfloat)foc;
+
+   m[12] = (m[0] * tx) + (m[4] * ty) - ((r + l) / (r - l));
+   m[13] = (m[1] * tx) + (m[5] * ty) - ((t + b) / (t - b));
+   m[14] = (m[2] * tx) + (m[6] * ty) - ((near_ + far_) / (far_ - near_));
+   m[15] = (m[3] * tx) + (m[7] * ty) + orth;
+}
+
+
+static Ector_Gl_Engine_Data *ENG = NULL;
+
+static void
+_destroy_shader_program(Shader_Program *shader)
+{
+   if (shader)
+     {
+        if (shader->v_shader) GL.glDeleteShader(shader->v_shader);
+        if (shader->f_shader)GL.glDeleteShader(shader->f_shader);
+        if (shader->program) GL.glDeleteProgram(shader->program);
+        free(shader);
+     }
+}
+static Shader_Program *
+_create_shader_program(const char *v_shader, const char* f_shader)
+{
+   Shader_Program *shader = calloc(1, sizeof(Shader_Program));
+   GLint ok = 0;
+
+   shader->v_shader = GL.glCreateShader(GL_VERTEX_SHADER);
+   GL.glShaderSource(shader->v_shader, 1, &v_shader, NULL);
+   GL.glCompileShader(shader->v_shader);
+   GL.glGetShaderiv(shader->v_shader, GL_COMPILE_STATUS, &ok);
+   if (!ok)
+     {
+        ERR("vertex shader compilation failed ");
+        goto fail;
+     }
+
+   shader->f_shader = GL.glCreateShader(GL_FRAGMENT_SHADER);
+   GL.glShaderSource(shader->f_shader, 1, &f_shader, NULL);
+   GL.glCompileShader(shader->f_shader);
+   GL.glGetShaderiv(shader->f_shader, GL_COMPILE_STATUS, &ok);
+   if (!ok)
+     {
+        ERR("fragment shader compilation failed ");
+        goto fail;
+     }
+
+   shader->program = GL.glCreateProgram();
+   GL.glAttachShader(shader->program, shader->v_shader);
+   GL.glAttachShader(shader->program, shader->f_shader);
+   GL.glBindAttribLocation(shader->program, ECTOR_SHAD_VERTEX, "vertex");
+   GL.glBindAttribLocation(shader->program, ECTOR_SHAD_TEXUV,  "v_tex_coord");
+   GL.glLinkProgram(shader->program);
+   GL.glGetProgramiv(shader->program, GL_LINK_STATUS, &ok);
+   if (!ok)
+     {
+        ERR("linking failed for shader program");
+        goto fail;
+     }
+   shader->u_color = GL.glGetUniformLocation(shader->program, "color");
+   shader->u_pos = GL.glGetUniformLocation(shader->program, "pos");
+   shader->u_mvp = GL.glGetUniformLocation(shader->program, "mvp");
+   shader->u_texture = GL.glGetUniformLocation(shader->program, "texture");
+   return shader;
+fail:
+   _destroy_shader_program(shader);
+   return NULL;
+}
+
+static void
+_update_lg_uniform()
+{
+  ENG->shader.lg->u_half_viewport_size = GL.glGetUniformLocation(ENG->shader.lg->program, "half_viewport_size");
+  ENG->shader.lg->linear.u_linear_data = GL.glGetUniformLocation(ENG->shader.lg->program, "linear_data");
+}
+
+static void
+_update_rg_uniform()
+{
+  ENG->shader.rg->u_half_viewport_size = GL.glGetUniformLocation(ENG->shader.rg->program, "half_viewport_size");
+  ENG->shader.rg->radial.u_fmp = GL.glGetUniformLocation(ENG->shader.rg->program, "fmp");
+  ENG->shader.rg->radial.u_bradius = GL.glGetUniformLocation(ENG->shader.rg->program, "bradius");
+  ENG->shader.rg->radial.u_fmp2_m_radius2 = GL.glGetUniformLocation(ENG->shader.rg->program, "fmp2_m_radius2");
+  ENG->shader.rg->radial.u_inverse_2_fmp2_m_radius2 = GL.glGetUniformLocation(ENG->shader.rg->program, "inverse_2_fmp2_m_radius2");
+  ENG->shader.rg->radial.u_sqrfr = GL.glGetUniformLocation(ENG->shader.rg->program, "sqrfr");
+}
+
+void
+update_gradient_texture(Ector_Renderer_Gl_Gradient_Data *gdata)
+{
+   if (gdata->color_table) return;
+
+   GLenum wrapMode = GL_CLAMP_TO_EDGE;
+
+   gdata->color_table = malloc(GRADIENT_ARRAY_SIZE * 4);
+   gdata->alpha = _generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count, gdata->color_table, GRADIENT_ARRAY_SIZE);
+
+   if (gdata->gd->s == EFL_GFX_GRADIENT_SPREAD_REPEAT)
+     wrapMode = GL_REPEAT;
+   else if (gdata->gd->s == EFL_GFX_GRADIENT_SPREAD_REFLECT)
+     wrapMode = GL_MIRRORED_REPEAT;
+
+   GL.glGenTextures(1, &(gdata->texture));
+   GL.glBindTexture(GL_TEXTURE_2D, gdata->texture);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
+   GL.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GRADIENT_ARRAY_SIZE, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, gdata->color_table);
+
+   GL.glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void
+destroy_gradient_texture(Ector_Renderer_Gl_Gradient_Data *gdata)
+{
+   if (gdata->color_table)
+     {
+        free(gdata->color_table);
+        gdata->color_table = NULL;
+        GL.glDeleteTextures(1, &(gdata->texture));
+        gdata->texture = 0;
+     }
+}
+
+static void
+_ector_gl_engine_destroy_surface()
+{
+   if (!ENG->surface.fbo.id) return;
+
+   if (ENG->surface.fbo.rbo_color)
+     GL.glDeleteRenderbuffers(1, &(ENG->surface.fbo.rbo_color));
+   if (ENG->surface.fbo.rbo_stencil)
+     GL.glDeleteRenderbuffers(1, &(ENG->surface.fbo.rbo_stencil));
+   if (ENG->surface.fbo.texture)
+     GL.glDeleteTextures(1, &(ENG->surface.fbo.texture));
+   if (ENG->surface.fbo.id)
+     GL.glDeleteFramebuffers(1, &(ENG->surface.fbo.id));
+
+   ENG->surface.fbo.id = 0;
+   ENG->surface.fbo.rbo_color = 0;
+   ENG->surface.fbo.rbo_stencil = 0;
+   ENG->surface.fbo.texture = 0;
+}
+
+static Eina_Bool
+_ector_gl_engine_create_fbo_rbo_surface()
+{
+   GL.glGenRenderbuffers(1, &ENG->surface.fbo.rbo_color);
+   GL.glBindRenderbuffer(GL_RENDERBUFFER, ENG->surface.fbo.rbo_color);
+   GL.glRenderbufferStorageMultisample(GL_RENDERBUFFER,
+                                       ENG->surface.capability.multisample_size,
+                                       GL_RGBA,
+                                       ENG->surface.fbo.w, ENG->surface.fbo.h);
+
+   // create a 4x MSAA renderbuffer object for depthbuffer
+   GL.glGenRenderbuffers(1, &ENG->surface.fbo.rbo_stencil);
+   GL.glBindRenderbuffer(GL_RENDERBUFFER, ENG->surface.fbo.rbo_stencil);
+   GL.glRenderbufferStorageMultisample(GL_RENDERBUFFER,
+                                       ENG->surface.capability.multisample_size,
+                                       GL_STENCIL_INDEX8,
+                                       ENG->surface.fbo.w, ENG->surface.fbo.h);
+
+
+   GL.glGenFramebuffers(1, &ENG->surface.fbo.id);
+   GL.glBindFramebuffer(GL_FRAMEBUFFER, ENG->surface.fbo.id);
+
+   // attach colorbuffer image to FBO
+   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                GL_COLOR_ATTACHMENT0,
+                                GL_RENDERBUFFER,
+                                ENG->surface.fbo.rbo_color);
+
+   // attach stencil buffer to FBO
+   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                GL_STENCIL_ATTACHMENT,
+                                GL_RENDERBUFFER,
+                                ENG->surface.fbo.rbo_stencil);
+
+   // check FBO status
+   GLenum status = GL.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+   if(status != GL_FRAMEBUFFER_COMPLETE)
+     {
+        ERR("cretaing MSAA fbo rbo failed");
+        GL.glDeleteRenderbuffers(1, &(ENG->surface.fbo.rbo_color));
+        GL.glDeleteRenderbuffers(1, &(ENG->surface.fbo.rbo_stencil));
+        GL.glDeleteFramebuffers(1, &(ENG->surface.fbo.id));
+        ENG->surface.fbo.id = 0;
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ector_gl_engine_create_fbo_text_ext_surface()
+{
+   GL.glGenTextures(1, &ENG->surface.fbo.texture);
+   GL.glBindTexture(GL_TEXTURE_2D, ENG->surface.fbo.texture);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   GL.glTexImage2D(GL_TEXTURE_2D, 0,
+                   GL_RGBA, ENG->surface.fbo.w, ENG->surface.fbo.h, 0, GL_RGBA,
+                   GL_UNSIGNED_BYTE, NULL);
+   GL.glBindTexture(GL_TEXTURE_2D, 0);
+
+
+   // create a MSAA renderbuffer object for stencil buffer
+   GL.glGenRenderbuffers(1, &ENG->surface.fbo.rbo_stencil);
+   GL.glBindRenderbuffer(GL_RENDERBUFFER, ENG->surface.fbo.rbo_stencil);
+   GL.glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
+                                          ENG->surface.capability.multisample_size,
+                                          GL_STENCIL_INDEX8,
+                                          ENG->surface.fbo.w, ENG->surface.fbo.h);
+
+
+   GL.glGenFramebuffers(1, &ENG->surface.fbo.id);
+   GL.glBindFramebuffer(GL_FRAMEBUFFER, ENG->surface.fbo.id);
+
+   // attach texture to FBO
+   GL.glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,
+                                           GL_COLOR_ATTACHMENT0,
+                                           GL_TEXTURE_2D,
+                                           ENG->surface.fbo.texture,
+                                           0,
+                                           ENG->surface.capability.multisample_size);
+
+   // attach stencil buffer to FBO
+   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                GL_STENCIL_ATTACHMENT,
+                                GL_RENDERBUFFER,
+                                ENG->surface.fbo.rbo_stencil);
+
+   // check FBO status
+   GLenum status = GL.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+   if(status != GL_FRAMEBUFFER_COMPLETE)
+     {
+        ERR("cretaing MSAA fbo texture failed");
+        GL.glDeleteTextures(1, &(ENG->surface.fbo.texture));
+        GL.glDeleteRenderbuffers(1, &(ENG->surface.fbo.rbo_stencil));
+        GL.glDeleteFramebuffers(1, &(ENG->surface.fbo.id));
+        ENG->surface.fbo.id = 0;
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ector_gl_engine_create_fbo_text_surface()
+{
+   GL.glGenTextures(1, &ENG->surface.fbo.texture);
+   GL.glBindTexture(GL_TEXTURE_2D, ENG->surface.fbo.texture);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+   GL.glTexImage2D(GL_TEXTURE_2D, 0,
+                   GL_RGBA, ENG->surface.fbo.w, ENG->surface.fbo.h, 0, GL_RGBA,
+                   GL_UNSIGNED_BYTE, NULL);
+   GL.glBindTexture(GL_TEXTURE_2D, 0);
+
+
+   GL.glGenRenderbuffers(1, &ENG->surface.fbo.rbo_stencil);
+   GL.glBindRenderbuffer(GL_RENDERBUFFER, ENG->surface.fbo.rbo_stencil);
+   GL.glRenderbufferStorage(GL_RENDERBUFFER,
+                            GL_STENCIL_INDEX8,
+                            ENG->surface.fbo.w, ENG->surface.fbo.h);
+
+
+   GL.glGenFramebuffers(1, &ENG->surface.fbo.id);
+   GL.glBindFramebuffer(GL_FRAMEBUFFER, ENG->surface.fbo.id);
+
+   // attach texture to FBO
+   GL.glFramebufferTexture2D(GL_FRAMEBUFFER,
+                             GL_COLOR_ATTACHMENT0,
+                             GL_TEXTURE_2D,
+                             ENG->surface.fbo.texture,
+                             0);
+
+   // attach stencil buffer to FBO
+   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+                                GL_STENCIL_ATTACHMENT,
+                                GL_RENDERBUFFER,
+                                ENG->surface.fbo.rbo_stencil);
+
+   // check FBO status
+   GLenum status = GL.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+   if(status != GL_FRAMEBUFFER_COMPLETE)
+     {
+        ERR("cretaing normal fbo texture failed");
+        GL.glDeleteTextures(1, &(ENG->surface.fbo.texture));
+        GL.glDeleteRenderbuffers(1, &(ENG->surface.fbo.rbo_stencil));
+        GL.glDeleteFramebuffers(1, &(ENG->surface.fbo.id));
+        ENG->surface.fbo.id = 0;
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+Eina_Bool
+_ector_gl_engine_update_surface()
+{
+   if (ENG->info.direct_draw)
+     return EINA_TRUE;
+
+   if (ENG->surface.fbo.w >= ENG->surface.w && ENG->surface.fbo.h >= ENG->surface.h)
+     {
+        // no need to update the scratch buffer
+        GL.glBindFramebuffer(GL_FRAMEBUFFER, ENG->surface.fbo.id);
+        return EINA_TRUE;
+     }
+
+   // delete old buffer if any
+   _ector_gl_engine_destroy_surface();
+
+   // update the new size
+   ENG->surface.fbo.w = ENG->surface.w > ENG->surface.fbo.w ? ENG->surface.w : ENG->surface.fbo.w;
+   ENG->surface.fbo.h = ENG->surface.h > ENG->surface.fbo.h ? ENG->surface.h : ENG->surface.fbo.h;
+
+   if (ENG->surface.capability.multisample)
+     {
+        return _ector_gl_engine_create_fbo_rbo_surface();
+     }
+   else if (ENG->surface.capability.ext_multisample)
+     {
+        return _ector_gl_engine_create_fbo_text_ext_surface();
+     }
+   else
+     {
+       return _ector_gl_engine_create_fbo_text_surface();
+     }
+}
+
+static void
+_update_viewport(int width, int height)
+{
+   if ((ENG->info.rotation == 0) || (ENG->info.rotation == 180))
+   {
+     GL.glViewport(0, 0, width, height);
+   }
+   else
+   {
+     GL.glViewport(0, 0, height, width);
+   }
+
+   _init_matrix(ENG->mvp);
+
+   if (ENG->info.flip)
+   {
+     _matrix_ortho(ENG->mvp,
+                   0, width,
+                   height, 0,
+                   -1000000.0, 1000000.0, ENG->info.rotation,
+                   width, height,
+                   1, 1.0);
+   }
+   else
+   {
+     _matrix_ortho(ENG->mvp,
+                   0, width,
+                   0, height,
+                   -1000000.0, 1000000.0, ENG->info.rotation,
+                   width, height,
+                   1, 1.0);
+   }
+}
+
+Eina_Bool
+ector_gl_engine_begin()
+{
+   if (!_ector_gl_engine_update_surface()) return EINA_FALSE;
+
+   _update_viewport(ENG->surface.w, ENG->surface.h);
+
+   GL.glEnable(GL_SCISSOR_TEST);
+   GL.glScissor(ENG->master.clip.x, ENG->master.clip.y, ENG->master.clip.w, ENG->master.clip.h);
+   GL.glClearStencil(0);
+   GL.glClearColor(0, 0, 0, 0);
+   if (!(ENG->info.direct_draw) || ENG->info.clear_surface)
+   {
+     GL.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+   }
+   GL.glDisable(GL_DEPTH_TEST);
+   GL.glEnable(GL_BLEND);
+   GL.glDisable(GL_STENCIL_TEST);
+   GL.glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
+
+   return EINA_TRUE;
+}
+
+void
+ector_gl_engine_end()
+{
+   GL.glDisable(GL_DEPTH_TEST);
+   GL.glDisable(GL_STENCIL_TEST);
+   GL.glDisable(GL_BLEND);
+   GL.glDisable(GL_SCISSOR_TEST);
+   GL.glScissor(0, 0, 0, 0);
+
+   ENG->state.program = NULL;
+   ENG->state.u_color = 0;
+   ENG->state.u_pos_x = 0;
+   ENG->state.u_pos_y = 0;
+}
+
+static inline void
+_update_color_uniform(GLuint pos, unsigned int color)
+{
+   GL.glUniform4f(pos, (R_VAL(&color)/255.0), (G_VAL(&color)/255.0), (B_VAL(&color)/255.0), (A_VAL(&color)/255.0));
+}
+
+static void
+_load_simple_program()
+{
+   //Already the program is used
+   if (ENG->state.program == ENG->shader.simple)
+     {
+        GL.glUniform4f(ENG->shader.simple->u_pos, ENG->master.offset.x + ENG->offset.x, ENG->master.offset.y + ENG->offset.y, 0, 0);
+        _update_color_uniform(ENG->shader.simple->u_color, ECTOR_MUL4_SYM(ENG->brush.color, ENG->info.color));
+     }
+   else
+     {
+        GL.glUseProgram(ENG->shader.simple->program);
+        GL.glEnableVertexAttribArray(ECTOR_SHAD_VERTEX);
+        GL.glUniformMatrix4fv(ENG->shader.simple->u_mvp, 1, GL_FALSE, ENG->mvp);
+        GL.glUniform4f(ENG->shader.simple->u_pos, ENG->master.offset.x + ENG->offset.x, ENG->master.offset.y + ENG->offset.y, 0, 0);
+        _update_color_uniform(ENG->shader.simple->u_color, ECTOR_MUL4_SYM(ENG->brush.color, ENG->info.color));
+
+        // keep the state
+        ENG->state.program = ENG->shader.simple;
+        ENG->state.u_pos_x = ENG->master.offset.x + ENG->offset.x;
+        ENG->state.u_pos_y = ENG->master.offset.y + ENG->offset.y;
+        ENG->state.u_color = ENG->brush.color;
+     }
+}
+
+static void
+_load_lg_program()
+{
+   //Already the program is used
+   GL.glUseProgram(ENG->shader.lg->program);
+   GL.glEnableVertexAttribArray(ECTOR_SHAD_VERTEX);
+   GL.glUniformMatrix4fv(ENG->shader.lg->u_mvp, 1, GL_FALSE, ENG->mvp);
+   GL.glUniform4f(ENG->shader.lg->u_pos, ENG->master.offset.x + ENG->offset.x, ENG->master.offset.y + ENG->offset.y, 0, 0);
+   GL.glUniform2f(ENG->shader.lg->u_half_viewport_size, ENG->surface.w * 0.5, ENG->surface.h * 0.5);
+   GL.glUniform3f(ENG->shader.lg->linear.u_linear_data, ENG->brush.g->linear.dx, ENG->brush.g->linear.dy, ENG->brush.g->linear.l);
+
+   GL.glActiveTexture(GL_TEXTURE0);
+   GL.glBindTexture(GL_TEXTURE_2D, ENG->brush.g->texture);
+   GL.glUniform1i(ENG->shader.lg->u_texture, 0);
+
+   // keep the state
+   ENG->state.program = ENG->shader.lg;
+   ENG->state.u_pos_x = ENG->master.offset.x + ENG->offset.x;
+   ENG->state.u_pos_y = ENG->master.offset.y + ENG->offset.y;
+   ENG->state.u_color = 0;
+}
+
+static void
+_load_rg_program()
+{
+   //Already the program is used
+   GL.glUseProgram(ENG->shader.rg->program);
+   GL.glEnableVertexAttribArray(ECTOR_SHAD_VERTEX);
+   GL.glUniformMatrix4fv(ENG->shader.rg->u_mvp, 1, GL_FALSE, ENG->mvp);
+   GL.glUniform4f(ENG->shader.rg->u_pos, ENG->master.offset.x + ENG->offset.x, ENG->master.offset.y + ENG->offset.y, 0, 0);
+   GL.glUniform2f(ENG->shader.rg->u_half_viewport_size, ENG->surface.w * 0.5, ENG->surface.h * 0.5);
+
+   GL.glUniform2f(ENG->shader.rg->radial.u_fmp, ENG->brush.g->radial.dx, ENG->brush.g->radial.dy);
+   GL.glUniform1f(ENG->shader.rg->radial.u_fmp2_m_radius2, ENG->brush.g->radial.a);
+   GL.glUniform1f(ENG->shader.rg->radial.u_inverse_2_fmp2_m_radius2, ENG->brush.g->radial.inv2a);
+   GL.glUniform1f(ENG->shader.rg->radial.u_sqrfr, ENG->brush.g->radial.fradius * ENG->brush.g->radial.fradius);
+
+   GL.glUniform3f(ENG->shader.rg->radial.u_bradius,
+                  2 * ENG->brush.g->radial.dr * ENG->brush.g->radial.fradius,
+                  ENG->brush.g->radial.fradius,
+                  ENG->brush.g->radial.dr);
+
+
+   GL.glActiveTexture(GL_TEXTURE0);
+   GL.glBindTexture(GL_TEXTURE_2D, ENG->brush.g->texture);
+   GL.glUniform1i(ENG->shader.rg->u_texture, 0);
+
+   // keep the state
+   ENG->state.program = ENG->shader.rg;
+   ENG->state.u_pos_x = ENG->master.offset.x + ENG->offset.x;
+   ENG->state.u_pos_y = ENG->master.offset.y + ENG->offset.y;
+   ENG->state.u_color = 0;
+}
+
+static void
+_update_brush()
+{
+   switch(ENG->brush.type)
+     {
+        case Solid:
+           {
+             _load_simple_program();
+             break;
+           }
+        case LinearGradient:
+           {
+             _load_lg_program();
+             break;
+           }
+        case RadialGradient:
+           {
+             _load_rg_program();
+             break;
+           }
+        default:
+          break;
+     }
+}
+
+static Eina_Bool
+_is_stencil_available()
+{
+   if (ENG->info.direct_draw && !(ENG->info.stencil))
+     return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_is_solid_brush()
+{
+   if ((ENG->brush.type == Solid) && (A_VAL(&(ENG->brush.color)) == 255))
+     return EINA_TRUE;
+   else if ((ENG->brush.g) && (!ENG->brush.g->alpha))
+     return EINA_TRUE;
+
+   return EINA_FALSE;
+}
+
+void
+ector_gl_engine_path_stroke(float *vertex, int count)
+{
+   if (!(_is_stencil_available()) || _is_solid_brush())
+     {
+        _load_simple_program();
+        GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertex);
+        GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, count/2);
+        return;
+     }
+   else
+     {
+        _load_simple_program();
+        GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertex);
+
+        GL.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
+
+        GL.glEnable(GL_STENCIL_TEST);
+        GL.glStencilMask(0xff);
+        GL.glClear(GL_STENCIL_BUFFER_BIT);
+        GL.glStencilMask(GL_STENCIL_HIGH_BIT);
+
+        GL.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+        GL.glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff);
+
+        GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, count/2); // here the shape is drawn in the stencil
+
+        // Enable color writes & disable stencil writes
+        GL.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+        GL.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+        // Pass when high bit is set, replace stencil value with 0
+        GL.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+
+         // draw a rectangle
+         _update_brush();
+        float rect_bound[10] = {0, 0 ,
+                                ENG->surface.w, 0,
+                                ENG->surface.w, ENG->surface.h,
+                                0, ENG->surface.h};
+         GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, rect_bound);
+         GL.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        // reset
+        GL.glStencilFunc(GL_ALWAYS, 0, 0xff);
+        GL.glDisable(GL_STENCIL_TEST);
+     }
+}
+
+
+void
+ector_gl_engine_path_fill(float *vertex,
+                            unsigned int vertex_count EINA_UNUSED,
+                            int *stops,
+                            unsigned int stop_count)
+{
+   unsigned int i, previous_stop = 0, stop = 0;
+
+   if (!_is_stencil_available())
+     {
+        _update_brush();
+        GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertex);
+        for (i = 0 ; i < stop_count; i++)
+          {
+             stop = stops[i];
+             GL.glDrawArrays(GL_TRIANGLE_FAN, previous_stop/2, (stop - previous_stop)/2);
+             previous_stop = stop;
+          }
+        return;
+     }
+
+   _load_simple_program();
+
+   GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertex);
+
+   // 1. Disable color writes
+   GL.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+   // 2. Enable Stencil and draw the shape in stencil
+   GL.glEnable(GL_STENCIL_TEST);
+   GL.glStencilMask(0xff);
+   GL.glClear(GL_STENCIL_BUFFER_BIT);
+   GL.glStencilMask(GL_STENCIL_HIGH_BIT);
+
+   // 3. set the Op for odd/even fill
+   GL.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
+
+   // 4. draw the shape
+   for (i = 0 ; i < stop_count; i++)
+     {
+        stop = stops[i];
+        GL.glDrawArrays(GL_TRIANGLE_FAN, previous_stop/2, (stop - previous_stop)/2);
+        previous_stop = stop;
+      }
+
+   // 5. Enable color writes
+   GL.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+   // 6. setup stencil op
+   GL.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
+   GL.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+
+   // 7.draw a bounding rectangle covering the shape
+   float rect_bound[10] = {0, 0 ,
+                           ENG->surface.w, 0,
+                           ENG->surface.w, ENG->surface.h,
+                           0, ENG->surface.h};
+   GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, rect_bound);
+
+   _update_brush();
+
+   GL.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+   // reset
+   GL.glStencilFunc(GL_ALWAYS, 0, 0xff);
+   GL.glDisable(GL_STENCIL_TEST);
+}
+
+
+void
+ector_gl_engine_surface_copy(GLuint dst_surface, int dst_surface_w, int dst_surface_h,
+                             Eina_Rectangle *dest)
+{
+   if (ENG->info.direct_draw) return;
+
+   GL.glDisable(GL_SCISSOR_TEST);
+
+   if (ENG->surface.capability.multisample)
+     {
+        GL.glBindFramebuffer(GL_READ_FRAMEBUFFER, ENG->surface.fbo.id);
+        GL.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_surface);
+        GL.glBlitFramebuffer(ENG->master.clip.x, ENG->master.clip.y, ENG->master.clip.w, ENG->master.clip.h,
+                             dest->x, dest->y, dest->w, dest->h,
+                             GL_COLOR_BUFFER_BIT,
+                             GL_LINEAR);
+        return;
+     }
+
+   // copy texture by drawing a quad
+   GL.glBindFramebuffer(GL_FRAMEBUFFER, dst_surface);
+
+   _update_viewport(dst_surface_w, dst_surface_h);
+
+   if (ENG->info.clear_surface)
+     GL.glClear(GL_COLOR_BUFFER_BIT);
+
+   GL.glUseProgram(ENG->shader.tex->program);
+   GL.glUniformMatrix4fv(ENG->shader.tex->u_mvp, 1, GL_FALSE, ENG->mvp);
+   GL.glUniform4f(ENG->shader.tex->u_pos, 0, 0, 0, 0);
+   _update_color_uniform(ENG->shader.tex->u_color, ENG->info.color);
+
+   GL.glEnableVertexAttribArray(ECTOR_SHAD_VERTEX);
+   GL.glEnableVertexAttribArray(ECTOR_SHAD_TEXUV);
+
+   GL.glActiveTexture(GL_TEXTURE0);
+   GL.glBindTexture(GL_TEXTURE_2D, ENG->surface.fbo.texture);
+   GL.glUniform1i(ENG->shader.tex->u_texture, 0);
+
+   float rect_bound[10] = {dest->x, dest->y ,
+                           dest->x + dest->w, dest->y,
+                           dest->x + dest->w, dest->y + dest->h,
+                           dest->x, dest->y + dest->h};
+   float uv_w = (float)(ENG->master.clip.w)/ ENG->surface.fbo.w;
+   float uv_h = (float)(ENG->master.clip.h)/ ENG->surface.fbo.h;
+   float uv_x = (float)(ENG->master.clip.x)/ ENG->surface.fbo.w;
+   float uv_y = (float)(ENG->master.clip.y)/ ENG->surface.fbo.h;
+   float tex_uv[10] = {uv_x, uv_y ,
+                       uv_x + uv_w, uv_y,
+                       uv_x + uv_w, uv_y + uv_h,
+                       uv_x, uv_y + uv_h};
+
+   GL.glVertexAttribPointer(ECTOR_SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, rect_bound);
+   GL.glVertexAttribPointer(ECTOR_SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, tex_uv);
+
+   GL.glEnable(GL_BLEND);
+
+   GL.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+}
+
+void
+ector_gl_engine_param_color(unsigned int color)
+{
+   ENG->brush.color = color;
+   ENG->brush.g = NULL;
+   ENG->brush.type = Solid;
+}
+
+void
+ector_gl_engine_param_linear_gradient(Ector_Renderer_Gl_Gradient_Data* lg)
+{
+   ENG->brush.g = lg;
+   ENG->brush.type = LinearGradient;
+}
+
+void
+ector_gl_engine_param_radial_gradient(Ector_Renderer_Gl_Gradient_Data* rg)
+{
+   ENG->brush.g = rg;
+   ENG->brush.type = RadialGradient;
+}
+
+void
+ector_gl_engine_param_offset(int x, int y)
+{
+   ENG->offset.x = x;
+   ENG->offset.y = y;
+}
+
+void
+ector_gl_engine_surface_size_set(int width, int height)
+{
+   ENG->surface.w = width;
+   ENG->surface.h = height;
+}
+
+void
+ector_gl_engine_info_set(Eina_Bool direct_draw, Eina_Bool stencil, Eina_Bool clear_surface, Eina_Bool flip, int rotation)
+{
+   ENG->info.direct_draw = direct_draw;
+   ENG->info.stencil = stencil;
+   ENG->info.clear_surface = clear_surface;
+   ENG->info.flip = flip;
+   ENG->info.rotation = rotation;
+}
+
+void
+ector_gl_engine_master_clip_set(Eina_Rectangle *clip)
+{
+   ENG->master.clip.x = clip->x;
+   ENG->master.clip.y = clip->y;
+   ENG->master.clip.w = clip->w;
+   ENG->master.clip.h = clip->h;
+}
+
+void
+ector_gl_engine_master_offset_set(int x, int y)
+{
+   ENG->master.offset.x = x;
+   ENG->master.offset.y = y;
+}
+
+void
+ector_gl_engine_mul_color_set(int mul_color)
+{
+   ENG->info.color = mul_color;
+}
+
+
+void
+ector_gl_engine_init()
+{
+   const char *ector_msaa = NULL;
+
+   if (ENG)
+     {
+        ENG->ref++;
+        return;
+     }
+
+   GL.finalize();
+
+   ENG = calloc(1,sizeof(Ector_Gl_Engine_Data));
+   ENG->ref = 1;
+   GL.finalize();
+
+   ENG->shader.simple = _create_shader_program(vertex_shader, fragment_shader);
+   ENG->shader.tex = _create_shader_program(tex_vertex_shader, tex_fragment_shader);
+   ENG->shader.lg = _create_shader_program(linear_gradient_vertex_shader, linear_gradient_fragment_shader);
+   ENG->shader.rg = _create_shader_program(radial_gradient_vertex_shader, radial_gradient_fragment_shader);
+   _update_lg_uniform();
+   _update_rg_uniform();
+
+   ENG->mvp = malloc(16 * sizeof(float));
+
+   if (GL.version == 3) ENG->surface.capability.multisample = EINA_TRUE;
+
+   if (GL.ext_ms_render_to_tex) ENG->surface.capability.ext_multisample = EINA_TRUE;
+
+   ector_msaa = getenv("ECTOR_MSAA");
+
+   if (ector_msaa)
+     {
+        //@TODO parse the msaa level;
+        ENG->surface.capability.multisample_size = 4;
+     }
+   else
+     {
+        ENG->surface.capability.multisample_size = 4;
+     }
+}
+
+void
+ector_gl_engine_shutdown()
+{
+   if (ENG)
+     {
+        ENG->ref--;
+        if (ENG->ref) return;
+
+        _destroy_shader_program(ENG->shader.simple);
+        _destroy_shader_program(ENG->shader.tex);
+        _destroy_shader_program(ENG->shader.lg);
+        _destroy_shader_program(ENG->shader.rg);
+        _ector_gl_engine_destroy_surface();
+        free(ENG->mvp);
+        free(ENG);
+        ENG = NULL;
+     }
+
+}
index 145730b..d8e1cc2 100644 (file)
@@ -1,13 +1,17 @@
 #ifndef ECTOR_GL_PRIVATE_H_
 #define ECTOR_GL_PRIVATE_H_
 
-#define SHAD_VERTEX 0
-#define SHAD_TEXUV  1
+#include "ector_private.h"
+#include <Eina.h>
+
+#define ECTOR_SHAD_VERTEX 0
+#define ECTOR_SHAD_TEXUV  1
 
 #define GL_STENCIL_HIGH_BIT  0x80
 
 typedef struct _Ector_Renderer_Gl_Gradient_Data    Ector_Renderer_Gl_Gradient_Data;
 typedef struct _Ector_Gl_Surface_Data              Ector_Gl_Surface_Data;
+typedef struct _Ector_Renderer_Gl_Gradient_Data    Ector_Renderer_Gl_Gradient_Data;
 
 typedef struct _Shader_Program                     Shader_Program;
 
@@ -20,38 +24,76 @@ struct _Shader_Program
   GLuint u_mvp;
   GLuint u_pos;
   GLuint u_texture;
+
+  GLuint u_half_viewport_size;
+  struct {
+    GLuint u_linear_data;
+  }linear;
+  struct {
+    GLuint u_fmp;
+    GLuint u_bradius;
+    GLuint u_fmp2_m_radius2;
+    GLuint u_inverse_2_fmp2_m_radius2;
+    GLuint u_sqrfr;
+  }radial;
 };
 
 
 struct _Ector_Gl_Surface_Data
 {
    struct {
-      int x, y;
-   } ref_point;
+     GLuint         fbo;
+     int            w;
+     int            h;
+     int            rotation;
+     Eina_Bool      flip;
+     Eina_Bool      clear;
+     Eina_Bool      stencil;
+     Eina_Rectangle clip;
+   }context;
+
    struct {
-      int x, y;
-   } offset;
+     Eina_Rectangle  geom;
+     int             color;
+   }vg;
 
-   Shader_Program *simple_shader;
-   Shader_Program *texture_shader;
+   struct {
+      int x, y;
+   } ref_point;
 
    struct {
-      int w, h;
-      GLuint fbo;
+      int        w, h;
+      GLuint     fbo;
+      Eina_Bool  flip;
+      int        rotation;
+      Eina_Bool  clear;
    } dest_fbo;
 
-   struct {
-      int       w, h;
-      GLuint    fbo;
-      GLuint    texture;
-      GLuint    rbo_color;
-      GLuint    rbo_stencil;
-      Eina_Bool msaa;
-      Eina_Bool ext_msaa;
-      int       msaa_level;
-   } scratch_fbo;
+   int vg_width;
+   int vg_height;
+
+   Eina_Rectangle clip;
+
+   Eina_Bool  direct_draw;
 };
 
+// GRADIENT
+
+#define GRADIENT_ARRAY_SIZE 512
+
+typedef struct _Gl_Gradient_Linear_Data
+{
+   float x1, y1, x2, y2;
+   float dx, dy, l;
+} Gl_Gradient_Linear_Data;
+
+typedef struct _Gl_Gradient_Radial_Data
+{
+   float cx, cy, fx, fy, cradius, fradius;
+   float dx, dy, dr, sqrfr, a, inv2a;
+   Eina_Bool extended;
+} Gl_Gradient_Radial_Data;
+
 // Gradient related structure
 struct _Ector_Renderer_Gl_Gradient_Data
 {
@@ -60,8 +102,120 @@ struct _Ector_Renderer_Gl_Gradient_Data
       Ector_Renderer_Generic_Gradient_Linear_Data *gld;
       Ector_Renderer_Generic_Gradient_Radial_Data *grd;
    };
-   Eina_Bool alpha;
-   uint32_t* color_table;
+   union {
+      Gl_Gradient_Linear_Data linear;
+      Gl_Gradient_Radial_Data radial;
+   };
+   Eina_Bool      alpha;
+   unsigned int*  color_table;
+   GLuint         texture;
+};
+
+void update_gradient_texture(Ector_Renderer_Gl_Gradient_Data *gdata);
+void destroy_gradient_texture(Ector_Renderer_Gl_Gradient_Data *gdata);
+
+
+// Ector Gl Engine
+typedef struct _Ector_Gl_Engine_Data      Ector_Gl_Engine_Data;
+
+typedef enum _Brush_Type {
+  Solid,
+  LinearGradient,
+  RadialGradient,
+} Brush_Type;
+
+struct _Ector_Gl_Engine_Data
+{
+   struct {
+     Shader_Program *simple;
+     Shader_Program *tex;
+     Shader_Program *lg;
+     Shader_Program *rg;
+   }shader;
+
+   struct {
+      int         w, h;
+      struct {
+        int       w, h;
+        GLuint    id;
+        GLuint    texture;
+        GLuint    rbo_color;
+        GLuint    rbo_stencil;
+      }fbo;
+
+      struct {
+        Eina_Bool multisample;
+        Eina_Bool ext_multisample;
+        int       multisample_size;
+        int       max_multisample;
+      }capability;
+   } surface;
+
+   struct {
+     Eina_Bool direct_draw; // draw directly to bounded fbo
+     Eina_Bool stencil; // whether stencil buffer available in the bounded fbo
+     Eina_Bool clear_surface; // whether to clear the bounded fbo
+     Eina_Bool flip;
+     int       rotation;
+     int       color;
+   }info;
+
+   struct {
+      unsigned int                      color;
+      Ector_Renderer_Gl_Gradient_Data  *g;
+      Brush_Type                        type;
+   }brush;
+
+   struct{
+     Shader_Program *program;
+     unsigned int    u_color;
+     int             u_pos_x;
+     int             u_pos_y;
+   }state;
+
+   struct {
+     int x;
+     int y;
+   }offset;
+
+   struct {
+     Eina_Rectangle clip;
+     struct {
+       int x;
+       int y;
+     }offset;
+   }master;
+
+   float *mvp;
+
+   int ref;
 };
 
+
+void ector_gl_engine_init();
+void ector_gl_engine_shutdown();
+void ector_gl_engine_info_set(Eina_Bool direct_draw, Eina_Bool stencil, Eina_Bool clear_surface, Eina_Bool flip, int rotation);
+Eina_Bool ector_gl_engine_begin();
+void ector_gl_engine_end();
+void ector_gl_engine_surface_size_set(int width, int height);
+void ector_gl_engine_master_clip_set(Eina_Rectangle *clip);
+void ector_gl_engine_master_offset_set(int x, int y);
+void ector_gl_engine_mul_color_set(int mul_color);
+void ector_gl_engine_surface_copy(GLuint dst_surface, int dst_surface_w, int dst_surface_h,
+                                  Eina_Rectangle *dst);
+
+void ector_gl_engine_param_offset(int x, int y);
+void ector_gl_engine_param_matrix(Eina_Matrix3 *m);
+void ector_gl_engine_param_color(unsigned int color);
+
+void ector_gl_engine_param_linear_gradient(Ector_Renderer_Gl_Gradient_Data* lg);
+void ector_gl_engine_param_radial_gradient(Ector_Renderer_Gl_Gradient_Data* rg);
+
+void ector_gl_engine_fill_set();
+
+void ector_gl_engine_path_fill(float *vertex, unsigned int vertex_count,
+                               int *stops, unsigned int stop_count);
+
+void ector_gl_engine_path_stroke(float *vertex, int count);
+
 #endif
diff --git a/src/lib/ector/gl/ector_gl_shaders.x b/src/lib/ector/gl/ector_gl_shaders.x
new file mode 100644 (file)
index 0000000..0e53140
--- /dev/null
@@ -0,0 +1,134 @@
+static const char vertex_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "uniform vec4 pos;\n"
+   "void main()\n"
+   "{\n"
+   "   vec4 new_vert = pos + vertex;\n"
+   "   gl_Position = mvp * new_vert;\n"
+   "}\n";
+
+static const char fragment_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "# endif\n"
+   "uniform vec4 color;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_FragColor = color;\n"
+   "}\n";
+
+static const char tex_vertex_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "uniform vec4 pos;\n"
+   "varying vec2 v_tex_coord;\n"
+   "void main()\n"
+   "{\n"
+   "   vec4 new_vert = pos + vertex;\n"
+   "   gl_Position = mvp * new_vert;\n"
+   "   v_tex_coord = tex_coord;\n"
+   "}\n";
+
+static const char tex_fragment_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "# endif\n"
+   "varying vec2 v_tex_coord;\n"
+   "uniform sampler2D texture;\n"
+   "uniform vec4 color;\n"
+   "void main()\n"
+   "{\n"
+   "   gl_FragColor = color * texture2D(texture, v_tex_coord);\n"
+   "}\n";
+
+static const char linear_gradient_vertex_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4 mvp;\n"
+   "uniform vec4 pos;\n"
+   "uniform vec2 half_viewport_size; \n"
+   "uniform vec3 linear_data; \n"
+   "varying float index; \n"
+   "void main() \n"
+   "{ \n"
+   "   vec4 new_vert = pos + vertex;\n"
+   "   gl_Position = mvp * new_vert;\n"
+   "   vec2 viewport_coords = (gl_Position.xy + 1.0) * half_viewport_size; \n"
+   "   vec3 hTexCoords = vec3(viewport_coords, 1); \n"
+   "   index = (dot(linear_data.xy, hTexCoords.xy) * linear_data.z); \n"
+   "}\n";
+
+static const char linear_gradient_fragment_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "# endif\n"
+   "uniform sampler2D texture;\n"
+   "varying float index; \n"
+   "void main()\n"
+   "{\n"
+   "vec2 val = vec2(index, 0.5); \n"
+   "gl_FragColor = texture2D(texture, val);\n"
+   "}\n";
+
+
+ // Radial Gradient Brush
+static const char radial_gradient_vertex_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "#endif\n"
+   "attribute vec4 vertex;\n"
+   "attribute vec2 tex_coord;\n"
+   "uniform mat4   mvp;\n"
+   "uniform vec4   pos;\n"
+   "uniform vec2   half_viewport_size; \n"
+   "uniform vec2   fmp; \n"
+   "uniform vec3   bradius; \n"
+   "varying float  b; \n"
+   "varying vec2   A; \n"
+   "void main() \n"
+   "{ \n"
+   "   vec4 new_vert = pos + vertex;\n"
+   "   gl_Position = mvp * new_vert;\n"
+   "   vec2 viewport_coords = (gl_Position.xy + 1.0) * half_viewport_size; \n"
+   "   vec3 hTexCoords = vec3(viewport_coords, 1); \n"
+   "   A = hTexCoords.xy; \n"
+   "   b = bradius.x + 2.0 * dot(A, fmp); \n"
+   "}\n";
+
+  static const char radial_gradient_fragment_shader[] =
+   "#ifdef GL_ES\n"
+   "precision mediump float;\n"
+   "# endif\n"
+   "uniform sampler2D texture;\n"
+   "uniform float     fmp2_m_radius2; \n"
+   "uniform float     inverse_2_fmp2_m_radius2; \n"
+   "uniform float     sqrfr; \n"
+   "uniform vec3      bradius; \n"
+   "varying float     b; \n"
+   "varying vec2      A; \n"
+   "void main()\n"
+   "{\n"
+   "   float c = sqrfr - dot(A, A); \n"
+   "   float det = b*b - 4.0*fmp2_m_radius2*c; \n"
+   "   vec4 result = vec4(0.0); \n"
+   "   if (det >= 0.0) \n"
+   "     { \n"
+   "        float detSqrt = sqrt(det); \n"
+   "        float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n"
+   "        if (bradius.y + w * bradius.z >= 0.0) \n"
+   "          result = texture2D(texture, vec2(w, 0.5)); \n"
+   "     } \n"
+   "   gl_FragColor = result;\n"
+   "}\n";
index 7978e84..4b9fe6f 100644 (file)
@@ -12,197 +12,6 @@ struct _Ector_Renderer_Gl_Base_Data
 {
 };
 
-static const char vertex_shader[] =
-   "#ifdef GL_ES\n"
-   "precision mediump float;\n"
-   "#endif\n"
-   "attribute vec4 vertex;\n"
-   "attribute vec2 tex_coord;\n"
-   "uniform mat4 mvp;\n"
-   "uniform vec4 pos;\n"
-   "void main()\n"
-   "{\n"
-   "   vec4 new_vert = pos + vertex;\n"
-   "   gl_Position = mvp * new_vert;\n"
-   "}\n";
-
-static const char fragment_shader[] =
-   "#ifdef GL_ES\n"
-   "precision mediump float;\n"
-   "# endif\n"
-   "uniform vec4 color;\n"
-   "void main()\n"
-   "{\n"
-   "   gl_FragColor = color;\n"
-   "}\n";
-
-static const char tex_vertex_shader[] =
-   "#ifdef GL_ES\n"
-   "precision mediump float;\n"
-   "#endif\n"
-   "attribute vec4 vertex;\n"
-   "attribute vec2 tex_coord;\n"
-   "uniform mat4 mvp;\n"
-   "uniform vec4 pos;\n"
-   "varying vec2 v_tex_coord;\n"
-   "void main()\n"
-   "{\n"
-   "   vec4 new_vert = pos + vertex;\n"
-   "   gl_Position = mvp * new_vert;\n"
-   "   v_tex_coord = tex_coord;\n"
-   "}\n";
-
-static const char tex_fragment_shader[] =
-   "#ifdef GL_ES\n"
-   "precision mediump float;\n"
-   "# endif\n"
-   "varying vec2 v_tex_coord;\n"
-   "uniform sampler2D texture;\n"
-   "void main()\n"
-   "{\n"
-   "   gl_FragColor = texture2D(texture, v_tex_coord);\n"
-   "}\n";
-
-static void
-init_matrix(float matrix[16])
-{
-   matrix[0] = 1.0f;
-   matrix[1] = 0.0f;
-   matrix[2] = 0.0f;
-   matrix[3] = 0.0f;
-
-   matrix[4] = 0.0f;
-   matrix[5] = 1.0f;
-   matrix[6] = 0.0f;
-   matrix[7] = 0.0f;
-
-   matrix[8] = 0.0f;
-   matrix[9] = 0.0f;
-   matrix[10] = 1.0f;
-   matrix[11] = 0.0f;
-
-   matrix[12] = 0.0f;
-   matrix[13] = 0.0f;
-   matrix[14] = 0.0f;
-   matrix[15] = 1.0f;
-}
-
-static void
-matrix_ortho(GLfloat *m,
-             GLfloat l, GLfloat r,
-             GLfloat t, GLfloat b,
-             GLfloat near_, GLfloat far_,
-             int rot, int vw, int vh,
-             int foc, GLfloat orth)
-{
-   GLfloat rotf;
-   GLfloat cosv, sinv;
-   GLfloat tx, ty;
-
-   rotf = (((rot / 90) & 0x3) * M_PI) / 2.0;
-
-   tx = -0.5 * (1.0 - orth);
-   ty = -0.5 * (1.0 - orth);
-
-   if (rot == 90)
-     {
-        tx += -(vw * 1.0);
-        ty += -(vh * 0.0);
-     }
-   if (rot == 180)
-     {
-        tx += -(vw * 1.0);
-        ty += -(vh * 1.0);
-     }
-   if (rot == 270)
-     {
-        tx += -(vw * 0.0);
-        ty += -(vh * 1.0);
-     }
-
-   cosv = cos(rotf);
-   sinv = sin(rotf);
-
-   m[0] = (2.0 / (r - l)) * ( cosv);
-   m[1] = (2.0 / (r - l)) * ( sinv);
-   m[2] = 0.0;
-   m[3] = 0.0;
-
-   m[4] = (2.0 / (t - b)) * (-sinv);
-   m[5] = (2.0 / (t - b)) * ( cosv);
-   m[6] = 0.0;
-   m[7] = 0.0;
-
-   m[8] = 0.0;
-   m[9] = 0.0;
-   m[10] = -(2.0 / (far_ - near_));
-   m[11] = 1.0 / (GLfloat)foc;
-
-   m[12] = (m[0] * tx) + (m[4] * ty) - ((r + l) / (r - l));
-   m[13] = (m[1] * tx) + (m[5] * ty) - ((t + b) / (t - b));
-   m[14] = (m[2] * tx) + (m[6] * ty) - ((near_ + far_) / (far_ - near_));
-   m[15] = (m[3] * tx) + (m[7] * ty) + orth;
-}
-
-static void
-_destroy_shader_program(Shader_Program *shader)
-{
-   if (shader)
-     {
-        if (shader->v_shader) GL.glDeleteShader(shader->v_shader);
-        if (shader->f_shader)GL.glDeleteShader(shader->f_shader);
-        if (shader->program) GL.glDeleteProgram(shader->program);
-        free(shader);
-     }
-}
-static Shader_Program *
-_create_shader_program(const char *v_shader, const char* f_shader)
-{
-   Shader_Program *shader = calloc(1, sizeof(Shader_Program));
-   GLint ok = 0;
-
-   shader->v_shader = GL.glCreateShader(GL_VERTEX_SHADER);
-   GL.glShaderSource(shader->v_shader, 1, &v_shader, NULL);
-   GL.glCompileShader(shader->v_shader);
-   GL.glGetShaderiv(shader->v_shader, GL_COMPILE_STATUS, &ok);
-   if (!ok)
-     {
-        ERR("vertex shader compilation failed ");
-        goto fail;
-     }
-
-   shader->f_shader = GL.glCreateShader(GL_FRAGMENT_SHADER);
-   GL.glShaderSource(shader->f_shader, 1, &f_shader, NULL);
-   GL.glCompileShader(shader->f_shader);
-   GL.glGetShaderiv(shader->f_shader, GL_COMPILE_STATUS, &ok);
-   if (!ok)
-     {
-        ERR("fragment shader compilation failed ");
-        goto fail;
-     }
-
-   shader->program = GL.glCreateProgram();
-   GL.glAttachShader(shader->program, shader->v_shader);
-   GL.glAttachShader(shader->program, shader->f_shader);
-   GL.glBindAttribLocation(shader->program, SHAD_VERTEX, "vertex");
-   GL.glBindAttribLocation(shader->program, SHAD_TEXUV,  "v_tex_coord");
-   GL.glLinkProgram(shader->program);
-   GL.glGetProgramiv(shader->program, GL_LINK_STATUS, &ok);
-   if (!ok)
-     {
-        ERR("linking failed for shader program");
-        goto fail;
-     }
-   shader->u_color = GL.glGetUniformLocation(shader->program, "color");
-   shader->u_pos = GL.glGetUniformLocation(shader->program, "pos");
-   shader->u_mvp = GL.glGetUniformLocation(shader->program, "mvp");
-   shader->u_texture = GL.glGetUniformLocation(shader->program, "texture");
-   return shader;
-fail:
-   _destroy_shader_program(shader);
-   return NULL;
-}
-
 static Ector_Renderer *
 _ector_gl_surface_ector_generic_surface_renderer_factory_new(Eo *obj,
                                                              Ector_Gl_Surface_Data *pd EINA_UNUSED,
@@ -219,434 +28,107 @@ _ector_gl_surface_ector_generic_surface_renderer_factory_new(Eo *obj,
 }
 
 static void
-_ector_gl_surface_path_fill(Eo *obj EINA_UNUSED,
-                              Ector_Gl_Surface_Data *pd,
-                              float *vertex,
-                              unsigned int vertex_count EINA_UNUSED,
-                              int *stops,
-                              unsigned int stop_count,
-                              unsigned int color)
+_ector_gl_surface_context_info_set(Eo *obj EINA_UNUSED, Ector_Gl_Surface_Data *pd, int width, int height, int rotation, Eina_Rectangle *clip, Eina_Bool clear)
 {
-   unsigned int i, previous_stop = 0, stop = 0;
-
-   GL.glUniform4f(pd->simple_shader->u_color, (R_VAL(&color)/255.0), (G_VAL(&color)/255.0), (B_VAL(&color)/255.0), (A_VAL(&color)/255.0));
-   GL.glVertexAttribPointer(SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertex);
-
-   // 1. Disable color writes
-   GL.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-   // 2. Enable Stencil and draw the shape in stencil
-   GL.glEnable(GL_STENCIL_TEST);
-   GL.glStencilMask(0xff);
-   GL.glClear(GL_STENCIL_BUFFER_BIT);
-   GL.glStencilMask(GL_STENCIL_HIGH_BIT);
-
-   // 3. set the Op for odd/even fill
-   GL.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit
-
-   // 4. draw the shape
-   for (i = 0 ; i < stop_count; i++)
-     {
-        stop = stops[i];
-        GL.glDrawArrays(GL_TRIANGLE_FAN, previous_stop/2, (stop - previous_stop)/2);
-        previous_stop = stop;
-      }
-
-   // 5. Enable color writes
-   GL.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+   GLint current_fbo;
 
-   // 6. setup stencil op
-   GL.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
-   GL.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+   GL.glGetIntegerv(GL_FRAMEBUFFER_BINDING, &current_fbo);
 
-   if (A_VAL(&color) == 255)
-     {
-         GL.glDisable(GL_BLEND);
-     }
-   else
+   if (current_fbo) // render to texture
      {
-        GL.glEnable(GL_BLEND);
+        pd->context.flip = EINA_TRUE;
+        pd->context.rotation = 0;
      }
-
-   // 7.draw a bounding rectangle covering the shape
-   float rect_bound[10] = {0, 0 , pd->dest_fbo.w, 0, pd->dest_fbo.w, pd->dest_fbo.h, 0, pd->dest_fbo.h};
-   GL.glVertexAttribPointer(SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, rect_bound);
-   GL.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-   // reset
-   GL.glStencilFunc(GL_ALWAYS, 0, 0xff);
-   GL.glDisable(GL_STENCIL_TEST);
-}
-
-static void
-_ector_gl_surface_path_stroke(Eo *obj EINA_UNUSED,
-                            Ector_Gl_Surface_Data *pd,
-                            float *vertex,
-                            unsigned int vertex_count,
-                            unsigned int color)
-{
-   GL.glUniform4f(pd->simple_shader->u_color, (R_VAL(&color)/255.0), (G_VAL(&color)/255.0), (B_VAL(&color)/255.0), (A_VAL(&color)/255.0));
-   GL.glVertexAttribPointer(SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, vertex);
-
-   if (A_VAL(&color) == 255)
+   else // default frame buffer
      {
-        GL.glDisable(GL_BLEND);
-        GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count/2);
-        return;
+        pd->context.flip = EINA_FALSE;
+        pd->context.rotation = rotation;
      }
-   else
-     {
-        GL.glEnable(GL_BLEND);
-
-        GL.glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes
-
-        GL.glEnable(GL_STENCIL_TEST);
-        GL.glStencilMask(0xff);
-        GL.glClear(GL_STENCIL_BUFFER_BIT);
-        GL.glStencilMask(GL_STENCIL_HIGH_BIT);
-
-        GL.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
-        GL.glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff);
 
-        GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count/2); // here the shape is drawn in the stencil
+   //@TODO update the stencil info
+   pd->context.stencil = EINA_FALSE;
 
-        // Enable color writes & disable stencil writes
-        GL.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+   pd->context.fbo = current_fbo;
+   pd->context.w = width;
+   pd->context.h = height;
+   pd->context.clear = clear;
 
-        GL.glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
-        // Pass when high bit is set, replace stencil value with 0
-        GL.glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT);
+   pd->context.clip.x = clip->x;
+   pd->context.clip.y = clip->y;
+   pd->context.clip.w = clip->w;
+   pd->context.clip.h = clip->h;
 
-         // draw a rectangle
-         float rect_bound[10] = {0, 0 , pd->dest_fbo.w, 0, pd->dest_fbo.w, pd->dest_fbo.h, 0, pd->dest_fbo.h};
-         GL.glVertexAttribPointer(SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, rect_bound);
-         GL.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-        // reset
-        GL.glStencilFunc(GL_ALWAYS, 0, 0xff);
-        GL.glDisable(GL_STENCIL_TEST);
-     }
 }
 
-static void
-_delete_fbo(Ector_Gl_Surface_Data *pd)
-{
-   if (!pd->scratch_fbo.fbo) return;
-
-   if (pd->scratch_fbo.rbo_color)
-     GL.glDeleteRenderbuffers(1, &(pd->scratch_fbo.rbo_color));
-   if (pd->scratch_fbo.rbo_stencil)
-     GL.glDeleteRenderbuffers(1, &(pd->scratch_fbo.rbo_stencil));
-   if (pd->scratch_fbo.texture)
-     GL.glDeleteTextures(1, &(pd->scratch_fbo.texture));
-   if (pd->scratch_fbo.fbo)
-     GL.glDeleteFramebuffers(1, &(pd->scratch_fbo.fbo));
-
-   pd->scratch_fbo.fbo = 0;
-   pd->scratch_fbo.rbo_color = 0;
-   pd->scratch_fbo.rbo_stencil = 0;
-   pd->scratch_fbo.texture = 0;
-}
-
-static void
-_create_msaa_fbo_rbo(Ector_Gl_Surface_Data *pd)
+void
+_ector_gl_surface_vg_info_set(Eo *obj EINA_UNUSED, Ector_Gl_Surface_Data *pd, Eina_Rectangle  *geom, int color)
 {
-   GL.glGenRenderbuffers(1, &pd->scratch_fbo.rbo_color);
-   GL.glBindRenderbuffer(GL_RENDERBUFFER, pd->scratch_fbo.rbo_color);
-   GL.glRenderbufferStorageMultisample(GL_RENDERBUFFER,
-                                       pd->scratch_fbo.msaa_level,
-                                       GL_RGBA,
-                                       pd->scratch_fbo.w, pd->scratch_fbo.h);
-
-   // create a 4x MSAA renderbuffer object for depthbuffer
-   GL.glGenRenderbuffers(1, &pd->scratch_fbo.rbo_stencil);
-   GL.glBindRenderbuffer(GL_RENDERBUFFER, pd->scratch_fbo.rbo_stencil);
-   GL.glRenderbufferStorageMultisample(GL_RENDERBUFFER,
-                                       pd->scratch_fbo.msaa_level,
-                                       GL_STENCIL_INDEX8,
-                                       pd->scratch_fbo.w, pd->scratch_fbo.h);
-
-
-   GL.glGenFramebuffers(1, &pd->scratch_fbo.fbo);
-   GL.glBindFramebuffer(GL_FRAMEBUFFER, pd->scratch_fbo.fbo);
-
-   // attach colorbuffer image to FBO
-   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
-                                GL_COLOR_ATTACHMENT0,
-                                GL_RENDERBUFFER,
-                                pd->scratch_fbo.rbo_color);
-
-   // attach stencil buffer to FBO
-   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
-                                GL_STENCIL_ATTACHMENT,
-                                GL_RENDERBUFFER,
-                                pd->scratch_fbo.rbo_stencil);
-
-   // check FBO status
-   GLenum status = GL.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-   if(status != GL_FRAMEBUFFER_COMPLETE)
-     {
-        ERR("cretaing MSAA fbo rbo failed");
-        GL.glDeleteRenderbuffers(1, &(pd->scratch_fbo.rbo_color));
-        GL.glDeleteRenderbuffers(1, &(pd->scratch_fbo.rbo_stencil));
-        GL.glDeleteFramebuffers(1, &(pd->scratch_fbo.fbo));
-        pd->scratch_fbo.fbo = 0;
-     }
+   pd->vg.geom.x = geom->x;
+   pd->vg.geom.y = geom->y;
+   pd->vg.geom.w = geom->w;
+   pd->vg.geom.h = geom->h;
+   pd->vg.color = color;
 }
 
 static void
-_create_msaa_fbo_texture_ext(Ector_Gl_Surface_Data *pd)
+_ector_gl_surface_draw_begin(Eo *obj EINA_UNUSED, Ector_Gl_Surface_Data *pd EINA_UNUSED)
 {
-   GL.glGenTextures(1, &pd->scratch_fbo.texture);
-   GL.glBindTexture(GL_TEXTURE_2D, pd->scratch_fbo.texture);
-   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-   GL.glTexImage2D(GL_TEXTURE_2D, 0,
-                   GL_RGBA, pd->scratch_fbo.w, pd->scratch_fbo.h, 0, GL_RGBA,
-                   GL_UNSIGNED_BYTE, NULL);
-   GL.glBindTexture(GL_TEXTURE_2D, 0);
-
-
-   // create a MSAA renderbuffer object for stencil buffer
-   GL.glGenRenderbuffers(1, &pd->scratch_fbo.rbo_stencil);
-   GL.glBindRenderbuffer(GL_RENDERBUFFER, pd->scratch_fbo.rbo_stencil);
-   GL.glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
-                                          pd->scratch_fbo.msaa_level,
-                                          GL_STENCIL_INDEX8,
-                                          pd->scratch_fbo.w, pd->scratch_fbo.h);
-
-
-   GL.glGenFramebuffers(1, &pd->scratch_fbo.fbo);
-   GL.glBindFramebuffer(GL_FRAMEBUFFER, pd->scratch_fbo.fbo);
-
-   // attach texture to FBO
-   GL.glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER,
-                                           GL_COLOR_ATTACHMENT0,
-                                           GL_TEXTURE_2D,
-                                           pd->scratch_fbo.texture,
-                                           0,
-                                           pd->scratch_fbo.msaa_level);
 
-   // attach stencil buffer to FBO
-   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
-                                GL_STENCIL_ATTACHMENT,
-                                GL_RENDERBUFFER,
-                                pd->scratch_fbo.rbo_stencil);
-
-   // check FBO status
-   GLenum status = GL.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-   if(status != GL_FRAMEBUFFER_COMPLETE)
+   if (pd->direct_draw)
      {
-        ERR("cretaing MSAA fbo texture failed");
-        GL.glDeleteTextures(1, &(pd->scratch_fbo.texture));
-        GL.glDeleteRenderbuffers(1, &(pd->scratch_fbo.rbo_stencil));
-        GL.glDeleteFramebuffers(1, &(pd->scratch_fbo.fbo));
-        pd->scratch_fbo.fbo = 0;
+        ector_gl_engine_surface_size_set(pd->context.w, pd->context.h);
+        ector_gl_engine_master_clip_set(&(pd->context.clip));
+        ector_gl_engine_master_offset_set(pd->vg.geom.x, pd->vg.geom.y);
+        ector_gl_engine_info_set(pd->direct_draw, pd->context.stencil,
+                                 pd->context.clear, pd->context.flip, pd->context.rotation);
      }
-}
-
-static void
-_create_fbo_texture(Ector_Gl_Surface_Data *pd)
-{
-   GL.glGenTextures(1, &pd->scratch_fbo.texture);
-   GL.glBindTexture(GL_TEXTURE_2D, pd->scratch_fbo.texture);
-   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-   GL.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-   GL.glTexImage2D(GL_TEXTURE_2D, 0,
-                   GL_RGBA, pd->scratch_fbo.w, pd->scratch_fbo.h, 0, GL_RGBA,
-                   GL_UNSIGNED_BYTE, NULL);
-   GL.glBindTexture(GL_TEXTURE_2D, 0);
-
-
-   GL.glGenRenderbuffers(1, &pd->scratch_fbo.rbo_stencil);
-   GL.glBindRenderbuffer(GL_RENDERBUFFER, pd->scratch_fbo.rbo_stencil);
-   GL.glRenderbufferStorage(GL_RENDERBUFFER,
-                            GL_STENCIL_INDEX8,
-                            pd->scratch_fbo.w, pd->scratch_fbo.h);
-
-
-   GL.glGenFramebuffers(1, &pd->scratch_fbo.fbo);
-   GL.glBindFramebuffer(GL_FRAMEBUFFER, pd->scratch_fbo.fbo);
-
-   // attach texture to FBO
-   GL.glFramebufferTexture2D(GL_FRAMEBUFFER,
-                             GL_COLOR_ATTACHMENT0,
-                             GL_TEXTURE_2D,
-                             pd->scratch_fbo.texture,
-                             0);
-
-   // attach stencil buffer to FBO
-   GL.glFramebufferRenderbuffer(GL_FRAMEBUFFER,
-                                GL_STENCIL_ATTACHMENT,
-                                GL_RENDERBUFFER,
-                                pd->scratch_fbo.rbo_stencil);
-
-   // check FBO status
-   GLenum status = GL.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-   if(status != GL_FRAMEBUFFER_COMPLETE)
+   else
      {
-        ERR("cretaing normal fbo texture failed");
-        GL.glDeleteTextures(1, &(pd->scratch_fbo.texture));
-        GL.glDeleteRenderbuffers(1, &(pd->scratch_fbo.rbo_stencil));
-        GL.glDeleteFramebuffers(1, &(pd->scratch_fbo.fbo));
-        pd->scratch_fbo.fbo = 0;
-     }
-}
-
-
-Eina_Bool
-_update_scratch_fbo(Ector_Gl_Surface_Data *pd, int width, int height)
-{
-   GLint current_fbo;
+        Eina_Rectangle vg_clip = {0, 0, pd->vg.geom.w, pd->vg.geom.h};
+        Eina_Rectangle ctx_clip;
+        // translate clip to vg co-ordinate
+        ctx_clip.x = pd->context.clip.x - pd->vg.geom.x;
+        ctx_clip.y = pd->context.clip.y - pd->vg.geom.y;
+        ctx_clip.w = pd->context.clip.w;
+        ctx_clip.h = pd->context.clip.h;
 
-   GL.glGetIntegerv(GL_FRAMEBUFFER_BINDING, &current_fbo);
-   // update dest info
-   pd->dest_fbo.fbo = current_fbo;
-   pd->dest_fbo.w = width;
-   pd->dest_fbo.h = height;
-
-   if (pd->scratch_fbo.w >= width && pd->scratch_fbo.h >= height)
-     {
-        // no need to update the scratch buffer
-        GL.glBindFramebuffer(GL_FRAMEBUFFER, pd->scratch_fbo.fbo);
-        return EINA_TRUE;
+        if (!eina_rectangle_intersection(&vg_clip, &ctx_clip))
+          return;
+        ector_gl_engine_surface_size_set(pd->vg.geom.w, pd->vg.geom.h);
+        ector_gl_engine_master_clip_set(&vg_clip);
+        ector_gl_engine_master_offset_set(0, 0);
+        ector_gl_engine_info_set(pd->direct_draw, EINA_FALSE, EINA_TRUE, EINA_TRUE, 0);
      }
 
-   // delete old buffer if any
-   _delete_fbo(pd);
-
-   // update the new size
-   pd->scratch_fbo.w = pd->dest_fbo.w > pd->scratch_fbo.w ? pd->dest_fbo.w : pd->scratch_fbo.w;
-   pd->scratch_fbo.h = pd->dest_fbo.h > pd->scratch_fbo.h ? pd->dest_fbo.h : pd->scratch_fbo.h;
+   ector_gl_engine_mul_color_set(pd->vg.color);
 
-   if (pd->scratch_fbo.msaa)
-     {
-        _create_msaa_fbo_rbo(pd);
-     }
-   else if (pd->scratch_fbo.ext_msaa)
-     {
-        _create_msaa_fbo_texture_ext(pd);
-     }
-   else
-     {
-       _create_fbo_texture(pd);
-     }
-   return EINA_TRUE;
+   ector_gl_engine_begin();
 }
 
-
-void
-_ector_gl_surface_surface_set(Eo *obj EINA_UNUSED,
-                              Ector_Gl_Surface_Data *pd,
-                              void *pixels EINA_UNUSED, unsigned int width,
-                              unsigned int height, unsigned int stride EINA_UNUSED)
+static void
+_ector_gl_surface_draw_end(Eo *obj EINA_UNUSED, Ector_Gl_Surface_Data *pd)
 {
-   if (pixels)
+   if (!pd->direct_draw)
      {
-        if (!_update_scratch_fbo(pd, width, height))
-          return;
-
-        float  mvp[16];
-        GL.glViewport(0, 0, pd->dest_fbo.w, pd->dest_fbo.h);
-        GL.glClearStencil(0);
-        GL.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-        GL.glClearColor(0, 0, 0, 0);
-        GL.glDisable(GL_DEPTH_TEST);
-        GL.glDisable(GL_BLEND);
-        GL.glDisable(GL_STENCIL_TEST);
-        GL.glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
-        init_matrix(mvp);
-        matrix_ortho(mvp,0, pd->dest_fbo.w, pd->dest_fbo.h, 0,-1000000.0, 1000000.0,0, pd->dest_fbo.w, pd->dest_fbo.h,1, 1.0);
-        GL.glUseProgram(pd->simple_shader->program);
-        GL.glUniformMatrix4fv(pd->simple_shader->u_mvp, 1, GL_FALSE, mvp);
-        GL.glEnableVertexAttribArray(SHAD_VERTEX);
+        if (!eina_rectangle_intersection(&(pd->vg.geom), &(pd->context.clip)))
+          goto end;
+        ector_gl_engine_info_set(pd->direct_draw, pd->context.stencil,
+                                 pd->context.clear, pd->context.flip, pd->context.rotation);
+        ector_gl_engine_surface_copy(pd->context.fbo, pd->context.w, pd->context.h, &(pd->vg.geom));
      }
-   else
-    {
-       if (pd->scratch_fbo.msaa)
-         {
-            GL.glBindFramebuffer(GL_READ_FRAMEBUFFER, pd->scratch_fbo.fbo);
-            GL.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pd->dest_fbo.fbo);
-            GL.glBlitFramebuffer(0, 0, pd->dest_fbo.w, pd->dest_fbo.h,
-                                 0, 0, pd->dest_fbo.w, pd->dest_fbo.h,
-                                 GL_COLOR_BUFFER_BIT,
-                                 GL_LINEAR);
-         }
-       else
-         {
-            float  mvp[16];
-            GL.glBindFramebuffer(GL_FRAMEBUFFER, pd->dest_fbo.fbo);
-            GL.glViewport(0, 0, pd->dest_fbo.w, pd->dest_fbo.h);
-            GL.glClearColor(0, 0, 0, 0);
-            GL.glDisable(GL_BLEND);
-            GL.glClear(GL_COLOR_BUFFER_BIT);
-            init_matrix(mvp);
-            matrix_ortho(mvp,0, pd->dest_fbo.w, pd->dest_fbo.h, 0,-1000000.0, 1000000.0,0, pd->dest_fbo.w, pd->dest_fbo.h,1, 1.0);
-            GL.glUseProgram(pd->texture_shader->program);
-            GL.glUniformMatrix4fv(pd->texture_shader->u_mvp, 1, GL_FALSE, mvp);
-            GL.glUniform4f(pd->texture_shader->u_pos, 0, 0, 0, 0);
-            GL.glEnableVertexAttribArray(SHAD_VERTEX);
-            GL.glEnableVertexAttribArray(SHAD_TEXUV);
-            GL.glActiveTexture(GL_TEXTURE0);
-            GL.glBindTexture(GL_TEXTURE_2D, pd->scratch_fbo.texture);
-            GL.glUniform1i(pd->texture_shader->u_texture, 0);
-            float rect_bound[10] = {0, 0 , pd->dest_fbo.w, 0, pd->dest_fbo.w, pd->dest_fbo.h, 0, pd->dest_fbo.h};
-            float w_r = (float)pd->dest_fbo.w/ pd->scratch_fbo.w;
-            float h_r = (float)pd->dest_fbo.h/ pd->scratch_fbo.h;
-            float tex_uv[10] = {0, 0 , w_r, 0, w_r, h_r, 0, h_r};
-            GL.glVertexAttribPointer(SHAD_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, rect_bound);
-            GL.glVertexAttribPointer(SHAD_TEXUV, 2, GL_FLOAT, GL_FALSE, 0, tex_uv);
-            GL.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-         }
-    }
-}
-
-static void
-_ector_gl_surface_offset(Eo *obj EINA_UNUSED,
-                         Ector_Gl_Surface_Data *pd, int x, int y)
-{
-   pd->offset.x = x;
-   pd->offset.y = y;
-   GL.glUniform4f(pd->simple_shader->u_pos, pd->ref_point.x + pd->offset.x, pd->ref_point.y + pd->offset.y, 0, 0);
-}
-
-void
-_ector_gl_surface_surface_get(Eo *obj EINA_UNUSED,
-                              Ector_Gl_Surface_Data *pd EINA_UNUSED,
-                              void **pixels EINA_UNUSED, unsigned int *width EINA_UNUSED,
-                              unsigned int *height EINA_UNUSED, unsigned int *stride EINA_UNUSED)
-{
-
+end:
+   ector_gl_engine_end();
 }
 
 static Eo *
 _ector_gl_surface_eo_base_constructor(Eo *obj,
                                       Ector_Gl_Surface_Data *pd EINA_UNUSED)
 {
-   const char *ector_msaa = NULL;
-
    obj = eo_do_super_ret(obj, ECTOR_GL_SURFACE_CLASS, obj, eo_constructor());
 
-   GL.finalize();
+   ector_gl_engine_init();
 
-   pd->simple_shader = _create_shader_program(vertex_shader, fragment_shader);
-   pd->texture_shader = _create_shader_program(tex_vertex_shader, tex_fragment_shader);
-   ector_msaa = getenv("ECTOR_MSAA");
-   if (ector_msaa)
-     {
-        //@TODO parse the msaa level;
-        pd->scratch_fbo.msaa_level = 4;
-     }
-   else
-     {
-        pd->scratch_fbo.msaa_level = 4;
-     }
-
-   if (GL.version == 3)
-     pd->scratch_fbo.msaa = EINA_TRUE;
-   if (GL.ext_ms_render_to_tex)
-     pd->scratch_fbo.ext_msaa = EINA_TRUE;
+   pd->direct_draw = EINA_FALSE;
 
    return obj;
 }
@@ -655,20 +137,10 @@ static void
 _ector_gl_surface_eo_base_destructor(Eo *obj EINA_UNUSED,
                                      Ector_Gl_Surface_Data *pd EINA_UNUSED)
 {
-  _destroy_shader_program(pd->simple_shader);
-  _destroy_shader_program(pd->texture_shader);
-   _delete_fbo(pd);
+   ector_gl_engine_shutdown();
 
    eo_do_super(obj, ECTOR_GL_SURFACE_CLASS, eo_destructor());
 }
 
-static void
-_ector_gl_surface_ector_generic_surface_reference_point_set(Eo *obj EINA_UNUSED,
-                                                            Ector_Gl_Surface_Data *pd,
-                                                            int x, int y)
-{
-   pd->ref_point.x = x;
-   pd->ref_point.y = y;
-}
 #include "ector_gl_surface.eo.c"
 #include "ector_renderer_gl_base.eo.c"
index c600c80..44414c8 100644 (file)
@@ -3,45 +3,34 @@ class Ector.Gl.Surface (Ector.Generic.Surface)
    eo_prefix: ector_gl_surface;
    legacy_prefix: null;
    methods {
-      @property surface {
-         set {
-         }
-         get {
-         }
-         values {
-            pixels: void *;
-            width: uint32_t;
-            height: uint32_t;
-            stride: uint32_t;
+      context_info_set {
+         params {
+            width:          int;
+            height:         int;
+            rotation:       int;
+            clip:           Eina_Rectangle *;
+            clear:          Eina_Bool;
          }
       }
-      offset {
-        params {
-          x:int;
-          y:int;
-        }
+      vg_info_set {
+         params {
+            geom:    Eina_Rectangle *;
+            color:   int;
+         }
       }
-      path_fill {
-        params {
-          vertex:float *;
-          vertex_count: uint32_t;
-          stops: int *;
-          stop_count: uint32_t;
-          color: uint32_t;
-        }
+
+       draw_begin {
+         params {
+         }
       }
-      path_stroke {
-        params {
-          vertex:float *;
-          vertex_count: uint32_t;
-          color: uint32_t;
-        }
+       draw_end {
+         params {
+         }
       }
    }
 
    implements {
       Ector.Generic.Surface.renderer_factory_new;
-      Ector.Generic.Surface.reference_point.set;
       Eo.Base.destructor;
       Eo.Base.constructor;
    }
index dd959b1..743de1e 100644 (file)
 typedef struct _Ector_Renderer_Gl_Shape_Data Ector_Renderer_Gl_Shape_Data;
 struct _Ector_Renderer_Gl_Shape_Data
 {
-   Eo                                  *surface;
    Efl_Gfx_Shape_Public                *public_shape;
    Ector_Renderer_Generic_Shape_Data   *shape;
    Ector_Renderer_Generic_Base_Data    *base;
+
+   Triangulator_Simple                 *filler;
+   Triangulator_Stroker                *stroker;
 };
 
 static Eina_Bool
@@ -33,16 +35,33 @@ _ector_renderer_gl_shape_ector_renderer_generic_base_prepare(Eo *obj EINA_UNUSED
    if (pd->shape->stroke.fill)
      eo_do(pd->shape->stroke.fill, ector_renderer_prepare());
 
-   if (!pd->surface)
-     {
-        eo_do(obj, pd->surface = eo_parent_get());
-        if (!pd->surface)
-          return EINA_FALSE;
-     }
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_generate_stroke_data(Ector_Renderer_Gl_Shape_Data *pd)
+{
+   if (pd->stroker) return EINA_FALSE;
+
+   if (!pd->shape->stroke.fill &&
+       ((pd->public_shape->stroke.color.a == 0) ||
+        (pd->public_shape->stroke.width < 0.01)))
+     return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_generate_shape_data(Ector_Renderer_Gl_Shape_Data *pd)
+{
+   if (pd->filler) return EINA_FALSE;
+
+   if (!pd->shape->fill && (pd->base->color.a == 0)) return EINA_FALSE;
 
    return EINA_TRUE;
 }
 
+
 static void _shape_transform(double *pts, int count , Eina_Matrix3 *m)
 {
    int i;
@@ -62,6 +81,56 @@ static void _shape_transform(double *pts, int count , Eina_Matrix3 *m)
      }
 }
 
+static void
+_update_triangulators(Eo *obj, Ector_Renderer_Gl_Shape_Data *pd)
+{
+   const Efl_Gfx_Path_Command *cmds = NULL;
+   const double *pts;
+   double *new_pts;
+   unsigned int cmd_count = 0, pt_count = 0;
+   Eina_Bool cleanup = EINA_FALSE;
+
+   eo_do(obj, efl_gfx_shape_path_get(&cmds, &pts));
+   if (cmds && (_generate_stroke_data(pd) || _generate_shape_data(pd)))
+     {
+        eo_do(obj, efl_gfx_shape_path_length_get(&cmd_count, &pt_count));
+
+        if (pd->base->m &&
+            (eina_matrix3_type_get(pd->base->m) != EINA_MATRIX_TYPE_IDENTITY))
+          {
+             new_pts =  malloc(sizeof(double) * pt_count);
+             memcpy(new_pts, pts, sizeof(double) * pt_count);
+             _shape_transform(new_pts, pt_count, pd->base->m);
+             cleanup = EINA_TRUE;
+          }
+        else
+          {
+             new_pts = (double *)pts;
+          }
+
+        //shape triangulator creation
+        if (_generate_shape_data(pd))
+          {
+             pd->filler = triangulator_simple_new();
+             triangulator_simple_process(pd->filler, cmds, new_pts, 0);
+          }
+
+        //stroke triangulator creation
+        if ( _generate_stroke_data(pd))
+          {
+             pd->stroker = triangulator_stroker_new();
+             triangulator_stroker_stroke_set(pd->stroker,
+                                             (pd->public_shape->stroke.width * pd->public_shape->stroke.scale),
+                                             pd->public_shape->stroke.cap,
+                                             pd->public_shape->stroke.join,
+                                             pd->base->m);
+
+             triangulator_stroker_process(pd->stroker, cmds, new_pts, cmd_count, pt_count);
+          }
+        if (cleanup) free(new_pts);
+     }
+}
+
 
 static Eina_Bool
 _ector_renderer_gl_shape_ector_renderer_generic_base_draw(Eo *obj EINA_UNUSED,
@@ -69,54 +138,69 @@ _ector_renderer_gl_shape_ector_renderer_generic_base_draw(Eo *obj EINA_UNUSED,
                                                           Ector_Rop op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
                                                           unsigned int mul_col EINA_UNUSED)
 {
-   const Efl_Gfx_Path_Command *cmds = NULL;
-   const double *pts = NULL;
-   double *new_pts = NULL;
-   unsigned int cmd_count = 0, pt_count = 0;
-   int count;
    float *vertex;
+   int *stops , count, stop_count;
+   unsigned int color;
 
-   eo_do(obj, efl_gfx_shape_path_get(&cmds, &pts));
-   eo_do(obj, efl_gfx_shape_path_length_get(&cmd_count, &pt_count));
-   if (!cmd_count) return EINA_FALSE;
+   _update_triangulators(obj, pd);
 
-   new_pts =  malloc(sizeof(double) * pt_count);
-   memcpy(new_pts, pts, sizeof(double) * pt_count);
-   _shape_transform(new_pts, pt_count, pd->base->m);
+   ector_gl_engine_param_offset(pd->base->origin.x, pd->base->origin.y);
 
-   eo_do(pd->surface, ector_gl_surface_offset(pd->base->origin.x, pd->base->origin.y));
-   if (pd->base->color.a > 0)
-     {
-        unsigned int fill_color = ECTOR_ARGB_JOIN(pd->base->color.a, pd->base->color.r, pd->base->color.g, pd->base->color.b);
-        unsigned int res_color = ECTOR_MUL4_SYM(fill_color, mul_col);
-        Triangulator_Simple *s = triangulator_simple_new();
-        triangulator_simple_process(s, cmds, new_pts, 0);
-        vertex = eina_inarray_nth(s->vertices, 0);
-        count = eina_inarray_count(s->vertices);
-        int stop_count = eina_inarray_count(s->stops);
-        int *stops = eina_inarray_nth(s->stops, 0);
-        eo_do(pd->surface, ector_gl_surface_path_fill(vertex, count, stops, stop_count, res_color));
-        triangulator_simple_free(s);
-     }
-   if (pd->public_shape->stroke.color.a > 0)
+   if (pd->filler)
      {
-        unsigned int stroke_color = ECTOR_ARGB_JOIN(pd->public_shape->stroke.color.a, pd->public_shape->stroke.color.r,
-                                                    pd->public_shape->stroke.color.g, pd->public_shape->stroke.color.b);
-        unsigned int res_color = ECTOR_MUL4_SYM(stroke_color, mul_col);
-        Triangulator_Stroker *s = triangulator_stroker_new();
-        triangulator_stroker_stroke_set(s, (pd->public_shape->stroke.width * pd->public_shape->stroke.scale),
-                                        pd->public_shape->stroke.cap, pd->public_shape->stroke.join, pd->base->m);
-
-         triangulator_stroker_process(s, cmds, new_pts, cmd_count, pt_count);
-         vertex = eina_inarray_nth(s->vertices, 0);
-         count = eina_inarray_count(s->vertices);
-         eo_do(pd->surface, ector_gl_surface_path_stroke(vertex, count, res_color));
-         triangulator_stroker_free(s);
+        if (pd->shape->fill)
+          eo_do(pd->shape->fill, ector_renderer_gl_base_fill());
+        else
+          {
+             color = ECTOR_ARGB_JOIN(pd->base->color.a,
+                                     pd->base->color.r,
+                                     pd->base->color.g,
+                                     pd->base->color.b);
+             color = ECTOR_MUL4_SYM(color, mul_col);
+             ector_gl_engine_param_color(color);
+          }
+
+        vertex = eina_inarray_nth(pd->filler->vertices, 0);
+        count = eina_inarray_count(pd->filler->vertices);
+        stop_count = eina_inarray_count(pd->filler->stops);
+        stops = eina_inarray_nth(pd->filler->stops, 0);
+
+        ector_gl_engine_path_fill(vertex, count, stops, stop_count);
      }
-   free(new_pts);
+
+  if (pd->stroker)
+    {
+        if (pd->shape->stroke.fill)
+          eo_do(pd->shape->stroke.fill, ector_renderer_gl_base_fill());
+        else
+          {
+             color = ECTOR_ARGB_JOIN(pd->public_shape->stroke.color.a,
+                                     pd->public_shape->stroke.color.r,
+                                     pd->public_shape->stroke.color.g,
+                                     pd->public_shape->stroke.color.b);
+             color = ECTOR_MUL4_SYM(color, mul_col);
+             ector_gl_engine_param_color(color);
+          }
+
+        vertex = eina_inarray_nth(pd->stroker->vertices, 0);
+        count = eina_inarray_count(pd->stroker->vertices);
+
+        ector_gl_engine_path_stroke(vertex, count);
+    }
+
    return EINA_TRUE;
 }
 
+static void
+_clear_path_compute_data(Ector_Renderer_Gl_Shape_Data *pd)
+{
+   if (pd->filler) triangulator_simple_free(pd->filler);
+   if (pd->stroker) triangulator_stroker_free(pd->stroker);
+
+   pd->filler = NULL;
+   pd->stroker = NULL;
+}
+
 static Eina_Bool
 _ector_renderer_gl_shape_ector_renderer_gl_base_fill(Eo *obj EINA_UNUSED,
                                                      Ector_Renderer_Gl_Shape_Data *pd EINA_UNUSED)
@@ -134,6 +218,8 @@ _ector_renderer_gl_shape_efl_gfx_shape_path_set(Eo *obj,
 {
 
    eo_do_super(obj, ECTOR_RENDERER_GL_SHAPE_CLASS, efl_gfx_shape_path_set(op, points));
+
+   _clear_path_compute_data(pd);
 }
 
 
@@ -142,6 +228,9 @@ _ector_renderer_gl_shape_path_changed(void *data EINA_UNUSED, Eo *obj EINA_UNUSE
                                       const Eo_Event_Description *desc EINA_UNUSED,
                                       void *event_info EINA_UNUSED)
 {
+   Ector_Renderer_Gl_Shape_Data *pd = data;
+
+   _clear_path_compute_data(pd);
    return EINA_TRUE;
 }
 
@@ -167,6 +256,8 @@ _ector_renderer_gl_shape_eo_base_destructor(Eo *obj, Ector_Renderer_Gl_Shape_Dat
    // call explicit API to free shape data.
    eo_do(obj, efl_gfx_shape_reset());
 
+   _clear_path_compute_data(pd);
+
    eo_data_xunref(obj, pd->public_shape, obj);
    eo_data_xunref(obj, pd->shape, obj);
    eo_data_xunref(obj, pd->base, obj);
index 420c659..4e5b519 100644 (file)
@@ -2556,8 +2556,8 @@ eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer
 
 static void
 eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector,
-                void *surface, Eina_Bool surface_clear EINA_UNUSED,
-                int x, int y, int width EINA_UNUSED, int height EINA_UNUSED,
+                void *surface, Eina_Bool surface_clear,
+                int x, int y, int width, int height,
                 Eina_Bool do_async EINA_UNUSED)
 {
    int w, h, stride;
@@ -2569,13 +2569,50 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
      {
         Evas_Engine_GL_Context *gl_context;
         Render_Engine_GL_Generic *re = data;
+        RGBA_Draw_Context *dc;
+        Eina_Rectangle clip;
+        int mul_color = 0xffffffff;
 
         re->window_use(re->software.ob);
         gl_context = re->window_gl_context_get(re->software.ob);
         evas_gl_common_context_target_surface_set(gl_context, surface);
+
+        // handle clip
+        dc = gl_context->dc;
+        if (surface_clear)
+          {
+             clip.x = 0;
+             clip.y = 0;
+             clip.w = width;
+             clip.h = height;
+          }
+        else
+          {
+             if (dc->clip.use)
+               {
+                  clip.x = dc->clip.x;
+                  clip.y = dc->clip.y;
+                  clip.w = dc->clip.w;
+                  clip.h = dc->clip.h;
+                  // clip the clip rect to surface boundary.
+                  RECTS_CLIP_TO_RECT(clip.x, clip.y, clip.w, clip.h, 0, 0, glim->w, glim->h);
+               }
+             else
+               {
+                  clip.x = 0;
+                  clip.y = 0;
+                  clip.w = glim->w;
+                  clip.h = glim->h;
+               }
+
+             mul_color = ector_color_multiply(dc->mul.use ? dc->mul.col : 0xffffffff, dc->col.col);
+
+          }
+        Eina_Rectangle vg_rect = {x, y, width, height};
         eo_do(ector,
-              ector_gl_surface_set(glim, glim->w, glim->h, 0),
-              ector_surface_reference_point_set(x, y));
+              ector_gl_surface_vg_info_set(&vg_rect, mul_color),
+              ector_gl_surface_context_info_set(glim->w, glim->h, gl_context->rot, &clip, surface_clear),
+              ector_gl_surface_draw_begin());
         return;
      }
 
@@ -2605,7 +2642,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *
 
    if (use_gl)
      {
-        eo_do(ector, ector_gl_surface_set(NULL, 0, 0, 0));
+        eo_do(ector, ector_gl_surface_draw_end());
         return;
      }