diff options
author | Will Thompson <will@willthompson.co.uk> | 2012-05-11 17:08:24 +0100 |
---|---|---|
committer | Will Thompson <will@willthompson.co.uk> | 2012-05-11 17:08:24 +0100 |
commit | 4c93055714b5e52c864e0e768e153d7c6600d07f (patch) | |
tree | 9e04c14fa74c393cf85a41a6c78a8d35a5163a00 | |
parent | 049a8178675310901d504a508445e73c87acd634 (diff) |
Implement FinishAccess for the screen pixmap
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/videocore-exa.c | 15 | ||||
-rw-r--r-- | src/videocore-shaders.c | 178 | ||||
-rw-r--r-- | src/videocore-shaders.h | 30 |
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 |