summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <will@willthompson.co.uk>2012-05-11 17:08:24 +0100
committerWill Thompson <will@willthompson.co.uk>2012-05-11 17:08:24 +0100
commit4c93055714b5e52c864e0e768e153d7c6600d07f (patch)
tree9e04c14fa74c393cf85a41a6c78a8d35a5163a00
parent049a8178675310901d504a508445e73c87acd634 (diff)
Implement FinishAccess for the screen pixmap
-rw-r--r--src/Makefile.am2
-rw-r--r--src/videocore-exa.c15
-rw-r--r--src/videocore-shaders.c178
-rw-r--r--src/videocore-shaders.h30
4 files changed, 221 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 724ae42..bd75d69 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,6 +39,8 @@ videocore_drv_la_SOURCES = \
videocore-debug.h \
videocore-exa.c \
videocore-exa.h \
+ videocore-shaders.c \
+ videocore-shaders.h \
$(NULL)
# vim: set et :
diff --git a/src/videocore-exa.c b/src/videocore-exa.c
index f3303ac..333c43b 100644
--- a/src/videocore-exa.c
+++ b/src/videocore-exa.c
@@ -39,6 +39,7 @@
#include "videocore-exa.h"
#include "videocore-debug.h"
+#include "videocore-shaders.h"
struct _VideoCoreExa {
ExaDriverPtr exa;
@@ -510,6 +511,8 @@ VideoCoreFinishAccess(PixmapPtr pPixmap, int index)
{
VideoCorePixmapPrivPtr priv = exaGetPixmapDriverPrivate(pPixmap);
ScrnInfoPtr pScrn = pix2scrn(pPixmap);
+ VideoCorePtr vcPtr = VIDEOCOREPTR(pScrn);
+ VideoCoreExaPtr vcExa = VideoCoreGetExa(vcPtr);
unsigned short width, height;
DEBUG_MSG("called for pixmap %p, is_screen_pixmap %s, texture %u, index %u",
@@ -529,6 +532,7 @@ VideoCoreFinishAccess(PixmapPtr pPixmap, int index)
if (priv->texture_id != 0) {
CopyToTexture(pScrn, priv->texture_id, 0, 0, width, height, priv->data, 0 /* FIXME: pitch */);
+ CheckGLError("CopyToTexture");
} else {
GLuint texture_id;
@@ -537,7 +541,10 @@ VideoCoreFinishAccess(PixmapPtr pPixmap, int index)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, priv->data);
- /* TODO: put it on the screen */
+ if (VideoCoreDrawIdentity(pScrn)) {
+ eglSwapBuffers(vcExa->display, vcExa->surf);
+ CheckGLError("eglSwapBuffers");
+ }
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteTextures(1, &texture_id);
@@ -545,8 +552,6 @@ VideoCoreFinishAccess(PixmapPtr pPixmap, int index)
free(priv->data);
priv->data = NULL;
-
- CheckGLError("FinishAccess");
}
static Bool
@@ -664,7 +669,9 @@ VideoCoreExaInit(ScreenPtr pScreen)
vcExa->exa = exa;
if (InitEGL(pScreen, vcExa)) {
- if (!exaDriverInit(pScreen, exa)) {
+ if (!VideoCoreShadersInit(pScrn)) {
+ ERROR_MSG("VideoCoreShadersInit failed");
+ } else if (!exaDriverInit(pScreen, exa)) {
ERROR_MSG("exaDriverInit failed");
}
}
diff --git a/src/videocore-shaders.c b/src/videocore-shaders.c
new file mode 100644
index 0000000..644a5d1
--- /dev/null
+++ b/src/videocore-shaders.c
@@ -0,0 +1,178 @@
+/* vim: set noet sw=8 sts=8 cino=:0,t0,(0 :
+ *
+ * Copyright © 2012 Collabora Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is fur-
+ * nished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+ * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "videocore-shaders.h"
+
+#include <GLES2/gl2.h>
+
+#include "videocore-debug.h"
+
+static Bool
+print_shader_info_log(ScrnInfoPtr pScrn, GLuint shader)
+{
+ GLint length, success;
+
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
+
+ if (length) {
+ char* buffer = malloc(length);
+ glGetShaderInfoLog(shader, length, NULL, buffer);
+ DEBUG_MSG("shader info: %s\n", buffer);
+ free(buffer);
+ }
+
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
+ return !!success;
+}
+
+static GLuint
+load_shader(ScrnInfoPtr pScrn, const char *shader_source, GLenum type)
+{
+ GLuint shader = glCreateShader(type);
+
+ glShaderSource(shader, 1, &shader_source, NULL);
+ glCompileShader(shader);
+
+ if (!print_shader_info_log(pScrn, shader)) {
+ glDeleteShader(shader);
+ shader = 0;
+ }
+
+ return shader;
+}
+
+static const char
+identity_vertex_src[] =
+ "attribute vec4 a_position; "
+ "attribute vec2 a_texCoord; "
+ "varying vec2 v_texCoord; "
+ "void main() "
+ "{ "
+ " gl_Position = a_position; "
+ " v_texCoord = a_texCoord; "
+ "} ";
+
+static const char
+identity_fragment_src[] =
+ "precision mediump float; "
+ "varying vec2 v_texCoord; "
+ "uniform sampler2D s_texture; "
+ "void main() "
+ "{ "
+ " gl_FragColor = texture2D(s_texture, v_texCoord); "
+ "} ";
+
+static GLuint
+assemble_identity_program(ScrnInfoPtr pScrn)
+{
+ GLuint vertex_shader, fragment_shader, program;
+ GLint log_length;
+
+ vertex_shader = load_shader(pScrn, identity_vertex_src, GL_VERTEX_SHADER);
+ fragment_shader = load_shader(pScrn, identity_fragment_src, GL_FRAGMENT_SHADER);
+ if (vertex_shader == 0 || fragment_shader == 0) {
+ glDeleteShader(vertex_shader);
+ glDeleteShader(fragment_shader);
+ return 0;
+ }
+
+ program = glCreateProgram();
+ glAttachShader(program, vertex_shader);
+ glAttachShader(program, fragment_shader);
+
+ glLinkProgram(program);
+ glUseProgram(program);
+
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
+ if (log_length) {
+ char *buffer = malloc(log_length);
+ glGetProgramInfoLog(program, log_length, NULL, buffer);
+ DEBUG_MSG("program info: %s\n", buffer);
+ free(buffer);
+ }
+
+ return program;
+}
+
+static GLuint identity_program = 0;
+static GLint a_texCoord, s_texture, a_position;
+
+/**
+ * Draws the texture currently bound to GL_TEXTURE_2D over the entire screen.
+ */
+Bool
+VideoCoreDrawIdentity(ScrnInfoPtr pScrn)
+{
+ float vertex_coords[] = {
+ -1.0, 1.0,
+ -1.0, -1.0,
+ 1.0, 1.0,
+ 1.0, -1.0
+ };
+
+ float tex_coords[] = {
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ 1.0, 1.0,
+ };
+
+ GLushort indices[] = {
+ 0, 1, 2,
+ 1, 2, 3,
+ };
+
+ glVertexAttribPointer(a_position, 2, GL_FLOAT, GL_FALSE,
+ 2 * sizeof(GLfloat), vertex_coords);
+ glVertexAttribPointer(a_texCoord, 2, GL_FLOAT, GL_FALSE, 2 *
+ sizeof(GLfloat), tex_coords);
+
+ glEnableVertexAttribArray(a_position);
+ glEnableVertexAttribArray(a_texCoord);
+
+ glActiveTexture(GL_TEXTURE0);
+ glUniform1i(s_texture, 0);
+
+ glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+ return CheckGLError("");
+}
+
+Bool
+VideoCoreShadersInit(ScrnInfoPtr pScrn)
+{
+ identity_program = assemble_identity_program(pScrn);
+
+ if (identity_program == 0) {
+ return FALSE;
+ }
+
+ a_position = glGetAttribLocation(identity_program, "a_position");
+ a_texCoord = glGetAttribLocation(identity_program, "a_texCoord");
+ s_texture = glGetUniformLocation(identity_program, "s_texture");
+
+ if (a_position < 0 || a_texCoord < 0 || s_texture < 0) {
+ DEBUG_MSG("Unable to get variable locations");
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/videocore-shaders.h b/src/videocore-shaders.h
new file mode 100644
index 0000000..e4851a7
--- /dev/null
+++ b/src/videocore-shaders.h
@@ -0,0 +1,30 @@
+/* vim: set noet sw=8 sts=8 cino=:0,t0,(0 :
+ *
+ * Copyright © 2012 Collabora Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is fur-
+ * nished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+ * NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef VIDEOCORE_SHADERS_H
+#define VIDEOCORE_SHADERS_H
+
+#include "xf86.h"
+
+Bool VideoCoreShadersInit(ScrnInfoPtr pScrn);
+Bool VideoCoreDrawIdentity(ScrnInfoPtr pScrn);
+
+#endif