* Allocated on first access.
*/
GLuint tmp_tex;
+
+ /*
+ * Ortho matrix for this surface.
+ */
+ GLfloat ortho[16];
};
static __inline struct vigs_winsys_gl_surface
* @{
*/
+static const char *g_vs_tex_source =
+ "attribute vec4 vertCoord;\n"
+ "uniform mat4 proj;\n"
+ "attribute vec2 texCoord;\n"
+ "varying vec2 v_texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " v_texCoord = texCoord;\n"
+ " gl_Position = proj * vertCoord;\n"
+ "}\n";
+
+static const char *g_fs_tex_source =
+ "uniform sampler2D tex;\n"
+ "varying vec2 v_texCoord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, v_texCoord);\n"
+ "}\n";
+
+static const char *g_vs_color_source =
+ "attribute vec4 vertCoord;\n"
+ "uniform mat4 proj;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = proj * vertCoord;\n"
+ "}\n";
+
+static const char *g_fs_color_source =
+ "uniform vec4 color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = color;\n"
+ "}\n";
+
+static GLuint vigs_gl_create_shader(struct vigs_gl_backend *backend,
+ const char *source,
+ GLenum type)
+{
+ GLuint shader = backend->CreateShader(type);
+ GLint tmp = 0;
+
+ if (!shader) {
+ VIGS_LOG_CRITICAL("Unable to create shader type %d", type);
+ return 0;
+ }
+
+ backend->ShaderSource(shader, 1, &source, NULL);
+ backend->CompileShader(shader);
+ backend->GetShaderiv(shader, GL_COMPILE_STATUS, &tmp);
+
+ if (!tmp) {
+ char *buff;
+
+ tmp = 0;
+
+ backend->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &tmp);
+
+ buff = g_malloc0(tmp);
+
+ backend->GetShaderInfoLog(shader, tmp, NULL, buff);
+
+ VIGS_LOG_CRITICAL("Unable to compile shader (type = %d) - %s",
+ type, buff);
+
+ backend->DeleteShader(shader);
+
+ g_free(buff);
+
+ return 0;
+ }
+
+ return shader;
+}
+
+static GLuint vigs_gl_create_program(struct vigs_gl_backend *backend,
+ GLuint vs_id,
+ GLuint fs_id)
+{
+ GLuint program = backend->CreateProgram();
+ GLint tmp = 0;
+
+ if (!program) {
+ VIGS_LOG_CRITICAL("Unable to create program");
+ return 0;
+ }
+
+ backend->AttachShader(program, vs_id);
+ backend->AttachShader(program, fs_id);
+ backend->LinkProgram(program);
+ backend->GetProgramiv(program, GL_LINK_STATUS, &tmp);
+
+ if (!tmp) {
+ char *buff;
+
+ tmp = 0;
+
+ backend->GetProgramiv(program, GL_INFO_LOG_LENGTH, &tmp);
+
+ buff = g_malloc0(tmp);
+
+ backend->GetProgramInfoLog(program, tmp, NULL, buff);
+
+ VIGS_LOG_CRITICAL("Unable to link program - %s", buff);
+
+ backend->DeleteProgram(program);
+
+ g_free(buff);
+
+ return 0;
+ }
+
+ return program;
+}
+
+static void vigs_gl_draw_tex_prog(struct vigs_gl_backend *backend,
+ uint32_t count)
+{
+ uint32_t size = count * 16;
+
+ if (size > backend->vbo_size) {
+ backend->vbo_size = size;
+ backend->BufferData(GL_ARRAY_BUFFER,
+ size,
+ 0,
+ GL_STREAM_DRAW);
+ }
+
+ backend->BufferSubData(GL_ARRAY_BUFFER, 0,
+ (size / 2), vigs_vector_data(&backend->v1));
+ backend->BufferSubData(GL_ARRAY_BUFFER, (size / 2),
+ (size / 2), vigs_vector_data(&backend->v2));
+
+ backend->EnableVertexAttribArray(backend->tex_prog_vertCoord_loc);
+ backend->EnableVertexAttribArray(backend->tex_prog_texCoord_loc);
+
+ backend->VertexAttribPointer(backend->tex_prog_vertCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ backend->VertexAttribPointer(backend->tex_prog_texCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL + (size / 2));
+
+ backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+ backend->DisableVertexAttribArray(backend->tex_prog_texCoord_loc);
+ backend->DisableVertexAttribArray(backend->tex_prog_vertCoord_loc);
+}
+
+static void vigs_gl_draw_color_prog(struct vigs_gl_backend *backend,
+ const GLfloat color[4],
+ uint32_t count)
+{
+ uint32_t size = count * 8;
+
+ if (size > backend->vbo_size) {
+ backend->vbo_size = size;
+ backend->BufferData(GL_ARRAY_BUFFER,
+ size,
+ 0,
+ GL_STREAM_DRAW);
+ }
+
+ backend->BufferSubData(GL_ARRAY_BUFFER, 0, size,
+ vigs_vector_data(&backend->v1));
+
+ backend->Uniform4fv(backend->color_prog_color_loc, 1, color);
+
+ backend->EnableVertexAttribArray(backend->color_prog_vertCoord_loc);
+
+ backend->VertexAttribPointer(backend->color_prog_vertCoord_loc,
+ 2, GL_FLOAT, GL_FALSE, 0, NULL);
+
+ backend->DrawArrays(GL_TRIANGLES, 0, count);
+
+ backend->DisableVertexAttribArray(backend->color_prog_vertCoord_loc);
+}
+
+static void vigs_gl_create_ortho(GLfloat left, GLfloat right,
+ GLfloat bottom, GLfloat top,
+ GLfloat near, GLfloat far,
+ GLfloat ortho[16])
+{
+ ortho[0] = 2.0f / (right - left);
+ ortho[5] = 2.0f / (top - bottom);
+ ortho[10] = -2.0f / (far - near);
+ ortho[12] = -(right + left) / (right - left);
+ ortho[13] = -(top + bottom) / (top - bottom);
+ ortho[14] = -(far + near) / (far - near);
+ ortho[15] = 1.0f;
+}
+
static void vigs_gl_translate_color(vigsp_color color,
vigsp_surface_format format,
- GLubyte *red,
- GLubyte *green,
- GLubyte *blue,
- GLubyte *alpha)
+ GLfloat res[4])
{
- *alpha = 0xFF;
+ res[3] = 1.0f;
switch (format) {
case vigsp_surface_bgra8888:
- *alpha = (GLubyte)((color >> 24) & 0xFF);
+ res[3] = (GLfloat)((color >> 24) & 0xFF) / 255.0f;
/* Fall through. */
case vigsp_surface_bgrx8888:
- *red = (GLubyte)((color >> 16) & 0xFF);
- *green = (GLubyte)((color >> 8) & 0xFF);
- *blue = (GLubyte)(color & 0xFF);
+ res[0] = (GLfloat)((color >> 16) & 0xFF) / 255.0f;
+ res[1] = (GLfloat)((color >> 8) & 0xFF) / 255.0f;
+ res[2] = (GLfloat)(color & 0xFF) / 255.0f;
break;
default:
assert(false);
- *red = 0;
- *green = 0;
- *blue = 0;
+ res[0] = 0.0f;
+ res[1] = 0.0f;
+ res[2] = 0.0f;
}
}
return false;
}
-static bool vigs_gl_surface_create_framebuffer(struct vigs_gl_surface *gl_sfc)
+static bool vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc,
+ GLuint prog_id,
+ GLint proj_loc)
{
struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend;
- if (gl_sfc->fb) {
- return true;
- }
+ if (!gl_sfc->fb) {
+ gl_backend->GenFramebuffers(1, &gl_sfc->fb);
- gl_backend->GenFramebuffers(1, &gl_sfc->fb);
+ if (!gl_sfc->fb) {
+ return false;
+ }
+ }
- if (!gl_sfc->fb) {
- goto fail;
+ if (gl_backend->cur_prog_id != prog_id) {
+ gl_backend->UseProgram(prog_id);
+ gl_backend->cur_prog_id = prog_id;
}
- return true;
+ gl_backend->Viewport(0, 0,
+ gl_sfc->base.ws_sfc->width,
+ gl_sfc->base.ws_sfc->height);
-fail:
- return false;
-}
+ gl_backend->UniformMatrix4fv(proj_loc, 1, GL_FALSE, gl_sfc->ortho);
-static void vigs_gl_surface_setup_framebuffer(struct vigs_gl_surface *gl_sfc)
-{
- struct vigs_gl_backend *gl_backend = (struct vigs_gl_backend*)gl_sfc->base.backend;
+ gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
- gl_backend->Viewport(0, 0,
- gl_sfc->base.ws_sfc->width, gl_sfc->base.ws_sfc->height);
- gl_backend->MatrixMode(GL_PROJECTION);
- gl_backend->LoadIdentity();
- gl_backend->Ortho(0.0, gl_sfc->base.ws_sfc->width,
- 0.0, gl_sfc->base.ws_sfc->height,
- -1.0, 1.0);
- gl_backend->MatrixMode(GL_MODELVIEW);
- gl_backend->LoadIdentity();
- gl_backend->Disable(GL_DEPTH_TEST);
- gl_backend->Disable(GL_BLEND);
+ return true;
}
/*
goto out;
}
- if (!vigs_gl_surface_create_framebuffer(gl_sfc)) {
+ if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+ gl_backend->tex_prog_id,
+ gl_backend->tex_prog_proj_loc)) {
goto out;
}
sfc_w = ws_sfc->base.base.width;
sfc_h = ws_sfc->base.base.height;
- gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
-
- vigs_gl_surface_setup_framebuffer(gl_sfc);
-
- gl_backend->Enable(GL_TEXTURE_2D);
-
gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, gl_sfc->tmp_tex, 0);
vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
tex_coords = vigs_vector_append(&gl_backend->v2,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
- vert_coords[0] = 0;
- vert_coords[1] = sfc_h;
+ vert_coords[6] = vert_coords[0] = 0;
+ vert_coords[7] = vert_coords[1] = sfc_h;
vert_coords[2] = sfc_w;
vert_coords[3] = sfc_h;
- vert_coords[4] = sfc_w;
- vert_coords[5] = 0;
- vert_coords[6] = 0;
- vert_coords[7] = 0;
+ vert_coords[8] = vert_coords[4] = sfc_w;
+ vert_coords[9] = vert_coords[5] = 0;
+ vert_coords[10] = 0;
+ vert_coords[11] = 0;
- tex_coords[0] = 0;
- tex_coords[1] = 0;
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] = tex_coords[1] = 0;
tex_coords[2] = 1;
tex_coords[3] = 0;
- tex_coords[4] = 1;
- tex_coords[5] = 1;
- tex_coords[6] = 0;
- tex_coords[7] = 1;
-
- gl_backend->EnableClientState(GL_VERTEX_ARRAY);
- gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
+ tex_coords[8] = tex_coords[4] = 1;
+ tex_coords[9] = tex_coords[5] = 1;
+ tex_coords[10] = 0;
+ tex_coords[11] = 1;
gl_backend->BindTexture(GL_TEXTURE_2D, ws_sfc->tex);
- gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
- gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
- gl_backend->DrawArrays(GL_QUADS, 0, 4);
-
- gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
- gl_backend->DisableClientState(GL_VERTEX_ARRAY);
+ vigs_gl_draw_tex_prog(gl_backend, 6);
gl_backend->PixelStorei(GL_PACK_ALIGNMENT, 1);
gl_backend->ReadPixels(0, 0, sfc_w, sfc_h,
goto out;
}
- if (!vigs_gl_surface_create_framebuffer(gl_sfc)) {
+ if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+ gl_backend->tex_prog_id,
+ gl_backend->tex_prog_proj_loc)) {
goto out;
}
vigs_vector_resize(&gl_backend->v1, 0);
vigs_vector_resize(&gl_backend->v2, 0);
- gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
-
- vigs_gl_surface_setup_framebuffer(gl_sfc);
-
- gl_backend->Enable(GL_TEXTURE_2D);
-
gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, ws_sfc->tex, 0);
for (i = 0; i < num_entries; ++i) {
vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
tex_coords = vigs_vector_append(&gl_backend->v2,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
- vert_coords[0] = entries[i].pos.x;
- vert_coords[1] = sfc_h - entries[i].pos.y;
+ vert_coords[6] = vert_coords[0] = entries[i].pos.x;
+ vert_coords[7] = vert_coords[1] = sfc_h - entries[i].pos.y;
vert_coords[2] = entries[i].pos.x + entries[i].size.w;
vert_coords[3] = sfc_h - entries[i].pos.y;
- vert_coords[4] = entries[i].pos.x + entries[i].size.w;
- vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
- vert_coords[6] = entries[i].pos.x;
- vert_coords[7] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+ vert_coords[8] = vert_coords[4] = entries[i].pos.x + entries[i].size.w;
+ vert_coords[9] = vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+ vert_coords[10] = entries[i].pos.x;
+ vert_coords[11] = sfc_h - (entries[i].pos.y + entries[i].size.h);
- tex_coords[0] = (GLfloat)entries[i].pos.x / sfc_w;
- tex_coords[1] = (GLfloat)entries[i].pos.y / sfc_h;
+ tex_coords[6] = tex_coords[0] = (GLfloat)entries[i].pos.x / sfc_w;
+ tex_coords[7] = tex_coords[1] = (GLfloat)entries[i].pos.y / sfc_h;
tex_coords[2] = (GLfloat)(entries[i].pos.x + entries[i].size.w) / sfc_w;
tex_coords[3] = (GLfloat)entries[i].pos.y / sfc_h;
- tex_coords[4] = (GLfloat)(entries[i].pos.x + entries[i].size.w) / sfc_w;
- tex_coords[5] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
- tex_coords[6] = (GLfloat)entries[i].pos.x / sfc_w;
- tex_coords[7] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
+ tex_coords[8] = tex_coords[4] = (GLfloat)(entries[i].pos.x + entries[i].size.w) / sfc_w;
+ tex_coords[9] = tex_coords[5] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
+ tex_coords[10] = (GLfloat)entries[i].pos.x / sfc_w;
+ tex_coords[11] = (GLfloat)(entries[i].pos.y + entries[i].size.h) / sfc_h;
}
- gl_backend->EnableClientState(GL_VERTEX_ARRAY);
- gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- gl_backend->BindTexture(GL_TEXTURE_2D, gl_sfc->tmp_tex);
-
- gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
- gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
- gl_backend->DrawArrays(GL_QUADS, 0, num_entries * 4);
-
- gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
- gl_backend->DisableClientState(GL_VERTEX_ARRAY);
+ vigs_gl_draw_tex_prog(gl_backend, num_entries * 6);
out:
gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
goto out;
}
- if (!vigs_gl_surface_create_framebuffer(gl_dst)) {
+ if (!vigs_gl_surface_setup_framebuffer(gl_dst,
+ gl_backend->tex_prog_id,
+ gl_backend->tex_prog_proj_loc)) {
goto out;
}
src_h = ws_src->base.base.height;
dst_h = ws_dst->base.base.height;
- gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_dst->fb);
-
- vigs_gl_surface_setup_framebuffer(gl_dst);
-
- gl_backend->Enable(GL_TEXTURE_2D);
-
if (src == dst) {
/*
* Feedback loop is possible, use 'tmp_tex' instead.
++total_entries;
vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
tex_coords = vigs_vector_append(&gl_backend->v2,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
- vert_coords[0] = 0;
- vert_coords[1] = src_h;
+ vert_coords[6] = vert_coords[0] = 0;
+ vert_coords[7] = vert_coords[1] = src_h;
vert_coords[2] = src_w;
vert_coords[3] = src_h;
- vert_coords[4] = src_w;
- vert_coords[5] = 0;
- vert_coords[6] = 0;
- vert_coords[7] = 0;
+ vert_coords[8] = vert_coords[4] = src_w;
+ vert_coords[9] = vert_coords[5] = 0;
+ vert_coords[10] = 0;
+ vert_coords[11] = 0;
- tex_coords[0] = 0;
- tex_coords[1] = 1;
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] = tex_coords[1] = 1;
tex_coords[2] = 1;
tex_coords[3] = 1;
- tex_coords[4] = 1;
- tex_coords[5] = 0;
- tex_coords[6] = 0;
- tex_coords[7] = 0;
+ tex_coords[8] = tex_coords[4] = 1;
+ tex_coords[9] = tex_coords[5] = 0;
+ tex_coords[10] = 0;
+ tex_coords[11] = 0;
} else {
/*
* No feedback loop possible, render to 'front_tex'.
gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, ws_dst->tex, 0);
-
}
for (i = 0; i < num_entries; ++i) {
vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
tex_coords = vigs_vector_append(&gl_backend->v2,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
- vert_coords[0] = entries[i].to.x;
- vert_coords[1] = dst_h - entries[i].to.y;
+ vert_coords[6] = vert_coords[0] = entries[i].to.x;
+ vert_coords[7] = vert_coords[1] = dst_h - entries[i].to.y;
vert_coords[2] = entries[i].to.x + entries[i].size.w;
vert_coords[3] = dst_h - entries[i].to.y;
- vert_coords[4] = entries[i].to.x + entries[i].size.w;
- vert_coords[5] = dst_h - (entries[i].to.y + entries[i].size.h);
- vert_coords[6] = entries[i].to.x;
- vert_coords[7] = dst_h - (entries[i].to.y + entries[i].size.h);
+ vert_coords[8] = vert_coords[4] = entries[i].to.x + entries[i].size.w;
+ vert_coords[9] = vert_coords[5] = dst_h - (entries[i].to.y + entries[i].size.h);
+ vert_coords[10] = entries[i].to.x;
+ vert_coords[11] = dst_h - (entries[i].to.y + entries[i].size.h);
- tex_coords[0] = (GLfloat)entries[i].from.x / src_w;
- tex_coords[1] = (GLfloat)(src_h - entries[i].from.y) / src_h;
+ tex_coords[6] = tex_coords[0] = (GLfloat)entries[i].from.x / src_w;
+ tex_coords[7] = tex_coords[1] = (GLfloat)(src_h - entries[i].from.y) / src_h;
tex_coords[2] = (GLfloat)(entries[i].from.x + entries[i].size.w) / src_w;
tex_coords[3] = (GLfloat)(src_h - entries[i].from.y) / src_h;
- tex_coords[4] = (GLfloat)(entries[i].from.x + entries[i].size.w) / src_w;
- tex_coords[5] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
- tex_coords[6] = (GLfloat)entries[i].from.x / src_w;
- tex_coords[7] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
+ tex_coords[8] = tex_coords[4] = (GLfloat)(entries[i].from.x + entries[i].size.w) / src_w;
+ tex_coords[9] = tex_coords[5] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
+ tex_coords[10] = (GLfloat)entries[i].from.x / src_w;
+ tex_coords[11] = (GLfloat)(src_h - (entries[i].from.y + entries[i].size.h)) / src_h;
}
- gl_backend->EnableClientState(GL_VERTEX_ARRAY);
- gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
gl_backend->BindTexture(GL_TEXTURE_2D, ws_src->tex);
- gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
- gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
- gl_backend->DrawArrays(GL_QUADS, 0, total_entries * 4);
+ vigs_gl_draw_tex_prog(gl_backend, total_entries * 6);
if (src == dst) {
vigs_vector_resize(&gl_backend->v1, 0);
vigs_vector_resize(&gl_backend->v2, 0);
vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
tex_coords = vigs_vector_append(&gl_backend->v2,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
- vert_coords[0] = 0;
- vert_coords[1] = src_h;
+ vert_coords[6] = vert_coords[0] = 0;
+ vert_coords[7] = vert_coords[1] = src_h;
vert_coords[2] = src_w;
vert_coords[3] = src_h;
- vert_coords[4] = src_w;
- vert_coords[5] = 0;
- vert_coords[6] = 0;
- vert_coords[7] = 0;
+ vert_coords[8] = vert_coords[4] = src_w;
+ vert_coords[9] = vert_coords[5] = 0;
+ vert_coords[10] = 0;
+ vert_coords[11] = 0;
- tex_coords[0] = 0;
- tex_coords[1] = 1;
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] = tex_coords[1] = 1;
tex_coords[2] = 1;
tex_coords[3] = 1;
- tex_coords[4] = 1;
- tex_coords[5] = 0;
- tex_coords[6] = 0;
- tex_coords[7] = 0;
+ tex_coords[8] = tex_coords[4] = 1;
+ tex_coords[9] = tex_coords[5] = 0;
+ tex_coords[10] = 0;
+ tex_coords[11] = 0;
gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, ws_dst->tex, 0);
gl_backend->BindTexture(GL_TEXTURE_2D, gl_dst->tmp_tex);
- gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
- gl_backend->TexCoordPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v2));
-
- gl_backend->DrawArrays(GL_QUADS, 0, 4);
+ vigs_gl_draw_tex_prog(gl_backend, 6);
}
- gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
- gl_backend->DisableClientState(GL_VERTEX_ARRAY);
-
out:
gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
}
struct vigs_gl_surface *gl_sfc = (struct vigs_gl_surface*)sfc;
struct vigs_winsys_gl_surface *ws_sfc = get_ws_sfc(gl_sfc);
uint32_t i;
- GLubyte red, green, blue, alpha;
+ GLfloat colorf[4];
GLfloat sfc_h;
if (!vigs_winsys_gl_surface_create_texture(ws_sfc, &ws_sfc->tex)) {
goto out;
}
- if (!vigs_gl_surface_create_framebuffer(gl_sfc)) {
+ if (!vigs_gl_surface_setup_framebuffer(gl_sfc,
+ gl_backend->color_prog_id,
+ gl_backend->color_prog_proj_loc)) {
goto out;
}
sfc_h = ws_sfc->base.base.height;
- gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_sfc->fb);
-
- vigs_gl_surface_setup_framebuffer(gl_sfc);
-
- gl_backend->Disable(GL_TEXTURE_2D);
-
gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, ws_sfc->tex, 0);
for (i = 0; i < num_entries; ++i) {
GLfloat *vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
- vert_coords[0] = entries[i].pos.x;
- vert_coords[1] = sfc_h - entries[i].pos.y;
+ vert_coords[6] = vert_coords[0] = entries[i].pos.x;
+ vert_coords[7] = vert_coords[1] = sfc_h - entries[i].pos.y;
vert_coords[2] = entries[i].pos.x + entries[i].size.w;
vert_coords[3] = sfc_h - entries[i].pos.y;
- vert_coords[4] = entries[i].pos.x + entries[i].size.w;
- vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
- vert_coords[6] = entries[i].pos.x;
- vert_coords[7] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+ vert_coords[8] = vert_coords[4] = entries[i].pos.x + entries[i].size.w;
+ vert_coords[9] = vert_coords[5] = sfc_h - (entries[i].pos.y + entries[i].size.h);
+ vert_coords[10] = entries[i].pos.x;
+ vert_coords[11] = sfc_h - (entries[i].pos.y + entries[i].size.h);
}
- gl_backend->EnableClientState(GL_VERTEX_ARRAY);
-
- vigs_gl_translate_color(color,
- sfc->format,
- &red,
- &green,
- &blue,
- &alpha);
-
- gl_backend->Color4ub(red, green, blue, alpha);
+ vigs_gl_translate_color(color, sfc->format, colorf);
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vigs_vector_data(&gl_backend->v1));
-
- gl_backend->DrawArrays(GL_QUADS, 0, num_entries * 4);
-
- gl_backend->DisableClientState(GL_VERTEX_ARRAY);
+ vigs_gl_draw_color_prog(gl_backend, colorf, num_entries * 6);
out:
gl_backend->BindFramebuffer(GL_FRAMEBUFFER, 0);
format,
id);
+ vigs_gl_create_ortho(0.0f, width, 0.0f, height,
+ -1.0f, 1.0f, gl_sfc->ortho);
+
ws_sfc->base.base.release(&ws_sfc->base.base);
gl_sfc->base.read_pixels = &vigs_gl_surface_read_pixels;
}
}
- if (!vigs_gl_surface_create_framebuffer(gl_root_sfc)) {
+ if (!vigs_gl_surface_setup_framebuffer(gl_root_sfc,
+ gl_backend->tex_prog_id,
+ gl_backend->tex_prog_proj_loc)) {
goto out;
}
vigs_vector_resize(&gl_backend->v2, 0);
vert_coords = vigs_vector_append(&gl_backend->v1,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
tex_coords = vigs_vector_append(&gl_backend->v2,
- (8 * sizeof(GLfloat)));
+ (12 * sizeof(GLfloat)));
if (surface->ptr) {
/*
surface->ptr);
}
- gl_backend->BindFramebuffer(GL_FRAMEBUFFER, gl_root_sfc->fb);
-
- vigs_gl_surface_setup_framebuffer(gl_root_sfc);
-
- gl_backend->Enable(GL_TEXTURE_2D);
-
gl_backend->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, gl_root_sfc->tmp_tex, 0);
- gl_backend->EnableClientState(GL_VERTEX_ARRAY);
- gl_backend->EnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- gl_backend->Color4f(1.0f, 1.0f, 1.0f, 1.0f);
-
if (!surface->ptr) {
/*
* If root surface is not scanout then we must render
* it.
*/
- vert_coords[0] = 0;
- vert_coords[1] = ws_root_sfc->base.base.height;
+ vert_coords[6] = vert_coords[0] = 0;
+ vert_coords[7] = vert_coords[1] = ws_root_sfc->base.base.height;
vert_coords[2] = ws_root_sfc->base.base.width;
vert_coords[3] = ws_root_sfc->base.base.height;
- vert_coords[4] = ws_root_sfc->base.base.width;
- vert_coords[5] = 0;
- vert_coords[6] = 0;
- vert_coords[7] = 0;
+ vert_coords[8] = vert_coords[4] = ws_root_sfc->base.base.width;
+ vert_coords[9] = vert_coords[5] = 0;
+ vert_coords[10] = 0;
+ vert_coords[11] = 0;
- tex_coords[0] = 0;
- tex_coords[1] = 0;
+ tex_coords[6] = tex_coords[0] = 0;
+ tex_coords[7] =tex_coords[1] = 0;
tex_coords[2] = 1;
tex_coords[3] = 0;
- tex_coords[4] = 1;
- tex_coords[5] = 1;
- tex_coords[6] = 0;
- tex_coords[7] = 1;
+ tex_coords[8] = tex_coords[4] = 1;
+ tex_coords[9] = tex_coords[5] = 1;
+ tex_coords[10] = 0;
+ tex_coords[11] = 1;
gl_backend->BindTexture(GL_TEXTURE_2D, ws_root_sfc->tex);
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vert_coords);
- gl_backend->TexCoordPointer(2, GL_FLOAT, 0, tex_coords);
-
- gl_backend->DrawArrays(GL_QUADS, 0, 4);
+ vigs_gl_draw_tex_prog(gl_backend, 6);
}
/*
src_w = ws_sfc->base.base.width;
src_h = ws_sfc->base.base.height;
- vert_coords[0] = plane->dst_x;
- vert_coords[1] = plane->dst_y;
+ vert_coords[6] = vert_coords[0] = plane->dst_x;
+ vert_coords[7] = vert_coords[1] = plane->dst_y;
vert_coords[2] = plane->dst_x + (int)plane->dst_size.w;
vert_coords[3] = plane->dst_y;
- vert_coords[4] = plane->dst_x + (int)plane->dst_size.w;
- vert_coords[5] = plane->dst_y + (int)plane->dst_size.h;
- vert_coords[6] = plane->dst_x;
- vert_coords[7] = plane->dst_y + (int)plane->dst_size.h;
+ vert_coords[8] = vert_coords[4] = plane->dst_x + (int)plane->dst_size.w;
+ vert_coords[9] = vert_coords[5] = plane->dst_y + (int)plane->dst_size.h;
+ vert_coords[10] = plane->dst_x;
+ vert_coords[11] = plane->dst_y + (int)plane->dst_size.h;
- tex_coords[0] = (GLfloat)plane->src_rect.pos.x / src_w;
- tex_coords[1] = (GLfloat)(src_h - plane->src_rect.pos.y) / src_h;
+ tex_coords[6] = tex_coords[0] = (GLfloat)plane->src_rect.pos.x / src_w;
+ tex_coords[7] = tex_coords[1] = (GLfloat)(src_h - plane->src_rect.pos.y) / src_h;
tex_coords[2] = (GLfloat)(plane->src_rect.pos.x + plane->src_rect.size.w) / src_w;
tex_coords[3] = (GLfloat)(src_h - plane->src_rect.pos.y) / src_h;
- tex_coords[4] = (GLfloat)(plane->src_rect.pos.x + plane->src_rect.size.w) / src_w;
- tex_coords[5] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
- tex_coords[6] = (GLfloat)plane->src_rect.pos.x / src_w;
- tex_coords[7] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
+ tex_coords[8] = tex_coords[4] = (GLfloat)(plane->src_rect.pos.x + plane->src_rect.size.w) / src_w;
+ tex_coords[9] = tex_coords[5] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
+ tex_coords[10] = (GLfloat)plane->src_rect.pos.x / src_w;
+ tex_coords[11] = (GLfloat)(src_h - (plane->src_rect.pos.y + plane->src_rect.size.h)) / src_h;
gl_backend->BindTexture(GL_TEXTURE_2D, ws_sfc->tex);
- gl_backend->VertexPointer(2, GL_FLOAT, 0, vert_coords);
- gl_backend->TexCoordPointer(2, GL_FLOAT, 0, tex_coords);
-
- gl_backend->DrawArrays(GL_QUADS, 0, 4);
+ vigs_gl_draw_tex_prog(gl_backend, 6);
}
- gl_backend->DisableClientState(GL_TEXTURE_COORD_ARRAY);
- gl_backend->DisableClientState(GL_VERTEX_ARRAY);
-
/*
* Now schedule asynchronous glReadPixels.
*/
bool vigs_gl_backend_init(struct vigs_gl_backend *gl_backend)
{
- const char *extensions;
-
if (!gl_backend->make_current(gl_backend, true)) {
return false;
}
- extensions = (const char*)gl_backend->GetString(GL_EXTENSIONS);
+ gl_backend->tex_prog_vs_id = vigs_gl_create_shader(gl_backend,
+ g_vs_tex_source,
+ GL_VERTEX_SHADER);
- if (!extensions) {
- VIGS_LOG_CRITICAL("Unable to get extension string");
+ if (!gl_backend->tex_prog_vs_id) {
goto fail;
}
- /*
- * NPOT is needed in order to
- * store custom sized surfaces as textures.
- */
- if ((strstr(extensions, "GL_OES_texture_npot ") == NULL) &&
- (strstr(extensions, "GL_ARB_texture_non_power_of_two ") == NULL)) {
- VIGS_LOG_CRITICAL("non power of 2 textures not supported");
+ gl_backend->tex_prog_fs_id = vigs_gl_create_shader(gl_backend,
+ g_fs_tex_source,
+ GL_FRAGMENT_SHADER);
+
+ if (!gl_backend->tex_prog_fs_id) {
+ goto fail;
+ }
+
+ gl_backend->tex_prog_id = vigs_gl_create_program(gl_backend,
+ gl_backend->tex_prog_vs_id,
+ gl_backend->tex_prog_fs_id);
+
+ if (!gl_backend->tex_prog_id) {
+ goto fail;
+ }
+
+ gl_backend->tex_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->tex_prog_id, "proj");
+ gl_backend->tex_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->tex_prog_id, "vertCoord");
+ gl_backend->tex_prog_texCoord_loc = gl_backend->GetAttribLocation(gl_backend->tex_prog_id, "texCoord");
+
+ gl_backend->color_prog_vs_id = vigs_gl_create_shader(gl_backend,
+ g_vs_color_source,
+ GL_VERTEX_SHADER);
+
+ if (!gl_backend->color_prog_vs_id) {
+ goto fail;
+ }
+
+ gl_backend->color_prog_fs_id = vigs_gl_create_shader(gl_backend,
+ g_fs_color_source,
+ GL_FRAGMENT_SHADER);
+
+ if (!gl_backend->color_prog_fs_id) {
goto fail;
}
+ gl_backend->color_prog_id = vigs_gl_create_program(gl_backend,
+ gl_backend->color_prog_vs_id,
+ gl_backend->color_prog_fs_id);
+
+ if (!gl_backend->color_prog_id) {
+ goto fail;
+ }
+
+ gl_backend->color_prog_proj_loc = gl_backend->GetUniformLocation(gl_backend->color_prog_id, "proj");
+ gl_backend->color_prog_vertCoord_loc = gl_backend->GetAttribLocation(gl_backend->color_prog_id, "vertCoord");
+ gl_backend->color_prog_color_loc = gl_backend->GetUniformLocation(gl_backend->color_prog_id, "color");
+
+ gl_backend->GenBuffers(1, &gl_backend->vbo);
+
+ if (!gl_backend->vbo) {
+ VIGS_LOG_CRITICAL("cannot create VBO");
+ goto fail;
+ }
+
+ gl_backend->BindBuffer(GL_ARRAY_BUFFER, gl_backend->vbo);
+
+ gl_backend->UseProgram(gl_backend->tex_prog_id);
+ gl_backend->cur_prog_id = gl_backend->tex_prog_id;
+
gl_backend->GenBuffers(1, &gl_backend->pbo);
if (!gl_backend->pbo) {
goto fail;
}
+ gl_backend->Disable(GL_DEPTH_TEST);
+ gl_backend->Disable(GL_BLEND);
+
gl_backend->base.batch_start = &vigs_gl_backend_batch_start;
gl_backend->base.create_surface = &vigs_gl_backend_create_surface;
gl_backend->base.composite = &vigs_gl_backend_composite;
if (gl_backend->make_current(gl_backend, true)) {
gl_backend->DeleteBuffers(1, &gl_backend->pbo);
+ gl_backend->DeleteBuffers(1, &gl_backend->vbo);
+ gl_backend->DetachShader(gl_backend->color_prog_id,
+ gl_backend->color_prog_vs_id);
+ gl_backend->DetachShader(gl_backend->color_prog_id,
+ gl_backend->color_prog_fs_id);
+ gl_backend->DeleteShader(gl_backend->color_prog_vs_id);
+ gl_backend->DeleteShader(gl_backend->color_prog_fs_id);
+ gl_backend->DeleteProgram(gl_backend->color_prog_id);
+ gl_backend->DetachShader(gl_backend->tex_prog_id,
+ gl_backend->tex_prog_vs_id);
+ gl_backend->DetachShader(gl_backend->tex_prog_id,
+ gl_backend->tex_prog_fs_id);
+ gl_backend->DeleteShader(gl_backend->tex_prog_vs_id);
+ gl_backend->DeleteShader(gl_backend->tex_prog_fs_id);
+ gl_backend->DeleteProgram(gl_backend->tex_prog_id);
gl_backend->make_current(gl_backend, false);
}
void (GLAPIENTRY *GenTextures)(GLsizei n, GLuint *textures);
void (GLAPIENTRY *DeleteTextures)(GLsizei n, const GLuint *textures);
void (GLAPIENTRY *BindTexture)(GLenum target, GLuint texture);
- void (GLAPIENTRY *Begin)(GLenum mode);
- void (GLAPIENTRY *End)(void);
void (GLAPIENTRY *CullFace)(GLenum mode);
void (GLAPIENTRY *TexParameterf)(GLenum target, GLenum pname, GLfloat param);
void (GLAPIENTRY *TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params);
void (GLAPIENTRY *TexParameteriv)(GLenum target, GLenum pname, const GLint *params);
void (GLAPIENTRY *TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void (GLAPIENTRY *TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
- void (GLAPIENTRY *TexEnvf)(GLenum target, GLenum pname, GLfloat param);
- void (GLAPIENTRY *TexEnvfv)(GLenum target, GLenum pname, const GLfloat *params);
- void (GLAPIENTRY *TexEnvi)(GLenum target, GLenum pname, GLint param);
- void (GLAPIENTRY *TexEnviv)(GLenum target, GLenum pname, const GLint *params);
void (GLAPIENTRY *Clear)(GLbitfield mask);
void (GLAPIENTRY *ClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
void (GLAPIENTRY *Disable)(GLenum cap);
void (GLAPIENTRY *FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
void (GLAPIENTRY *FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
void (GLAPIENTRY *GetIntegerv)(GLenum pname, GLint *params);
- const GLubyte *(GLAPIENTRY *GetString)(GLenum name);
- void (GLAPIENTRY *LoadIdentity)(void);
- void (GLAPIENTRY *MatrixMode)(GLenum mode);
- void (GLAPIENTRY *Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
- void (GLAPIENTRY *EnableClientState)(GLenum array);
- void (GLAPIENTRY *DisableClientState)(GLenum array);
- void (GLAPIENTRY *Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
- void (GLAPIENTRY *TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
- void (GLAPIENTRY *VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
void (GLAPIENTRY *DrawArrays)(GLenum mode, GLint first, GLsizei count);
- void (GLAPIENTRY *Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
- void (GLAPIENTRY *WindowPos2f)(GLfloat x, GLfloat y);
- void (GLAPIENTRY *PixelZoom)(GLfloat xfactor, GLfloat yfactor);
- void (GLAPIENTRY *DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data);
- void (GLAPIENTRY *BlendFunc)(GLenum sfactor, GLenum dfactor);
- void (GLAPIENTRY *CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
- void (GLAPIENTRY *BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
void (GLAPIENTRY *GenBuffers)(GLsizei n, GLuint *buffers);
void (GLAPIENTRY *DeleteBuffers)(GLsizei n, const GLuint *buffers);
void (GLAPIENTRY *BindBuffer)(GLenum target, GLuint buffer);
void (GLAPIENTRY *BufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+ void (GLAPIENTRY *BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
GLvoid *(GLAPIENTRY *MapBuffer)(GLenum target, GLenum access);
GLboolean (GLAPIENTRY *UnmapBuffer)(GLenum target);
+ GLuint (GLAPIENTRY* CreateProgram)(void);
+ GLuint (GLAPIENTRY* CreateShader)(GLenum type);
+ void (GLAPIENTRY* CompileShader)(GLuint shader);
+ void (GLAPIENTRY* AttachShader)(GLuint program, GLuint shader);
+ void (GLAPIENTRY* LinkProgram)(GLuint program);
+ void (GLAPIENTRY* GetProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (GLAPIENTRY* GetProgramInfoLog)(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+ void (GLAPIENTRY* GetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (GLAPIENTRY* GetShaderInfoLog)(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog);
+ void (GLAPIENTRY* DetachShader)(GLuint program, GLuint shader);
+ void (GLAPIENTRY* DeleteProgram)(GLuint program);
+ void (GLAPIENTRY* DeleteShader)(GLuint shader);
+ void (GLAPIENTRY* DisableVertexAttribArray)(GLuint index);
+ void (GLAPIENTRY* EnableVertexAttribArray)(GLuint index);
+ void (GLAPIENTRY* ShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
+ void (GLAPIENTRY* UseProgram)(GLuint program);
+ GLint (GLAPIENTRY* GetAttribLocation)(GLuint program, const GLchar* name);
+ GLint (GLAPIENTRY* GetUniformLocation)(GLuint program, const GLchar* name);
+ void (GLAPIENTRY* VertexAttribPointer)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);
+ void (GLAPIENTRY* Uniform4fv)(GLint location, GLsizei count, const GLfloat* value);
+ void (GLAPIENTRY* UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
/*
* @}
*/
/*
- *
+ * Other.
*/
+ GLuint tex_prog_vs_id;
+ GLuint tex_prog_fs_id;
+ GLuint tex_prog_id;
+ GLint tex_prog_proj_loc;
+ GLint tex_prog_vertCoord_loc;
+ GLint tex_prog_texCoord_loc;
+
+ GLuint color_prog_vs_id;
+ GLuint color_prog_fs_id;
+ GLuint color_prog_id;
+ GLint color_prog_proj_loc;
+ GLint color_prog_vertCoord_loc;
+ GLint color_prog_color_loc;
+
+ GLuint vbo;
+ uint32_t vbo_size;
+
+ GLuint cur_prog_id;
+
struct work_queue *read_pixels_queue;
GLuint pbo;