X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ui%2Fshader.c;h=d78829f43bcc41ef8f5f07a335a59c6b46c4242a;hb=HEAD;hp=52a46329307c1ba57e988c30f89b46f7726c2652;hpb=874e9aeeeb74c5459639a93439a502d262847e68;p=mirror_qemu.git diff --git a/ui/shader.c b/ui/shader.c index 52a4632930..ab448c41d4 100644 --- a/ui/shader.c +++ b/ui/shader.c @@ -24,31 +24,63 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "qemu-common.h" +#include "qemu/osdep.h" #include "ui/shader.h" +#include "ui/shader/texture-blit-vert.h" +#include "ui/shader/texture-blit-flip-vert.h" +#include "ui/shader/texture-blit-frag.h" + +struct QemuGLShader { + GLint texture_blit_prog; + GLint texture_blit_flip_prog; + GLint texture_blit_vao; +}; + /* ---------------------------------------------------------------------- */ -void qemu_gl_run_texture_blit(GLint texture_blit_prog) +static GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog) { - GLfloat in_position[] = { + static const GLfloat in_position[] = { -1, -1, 1, -1, -1, 1, 1, 1, }; GLint l_position; + GLuint vao, buffer; + + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + /* this is the VBO that holds the vertex data */ + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(in_position), in_position, + GL_STATIC_DRAW); - glUseProgram(texture_blit_prog); l_position = glGetAttribLocation(texture_blit_prog, "in_position"); - glVertexAttribPointer(l_position, 2, GL_FLOAT, GL_FALSE, 0, in_position); + glVertexAttribPointer(l_position, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(l_position); - glDrawArrays(GL_TRIANGLE_STRIP, l_position, 4); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + return vao; +} + +void qemu_gl_run_texture_blit(QemuGLShader *gls, bool flip) +{ + glUseProgram(flip + ? gls->texture_blit_flip_prog + : gls->texture_blit_prog); + glBindVertexArray(gls->texture_blit_vao); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } /* ---------------------------------------------------------------------- */ -GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src) +static GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src) { GLuint shader; GLint status, length; @@ -61,18 +93,18 @@ GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src) glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (!status) { glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); - errmsg = malloc(length); + errmsg = g_malloc(length); glGetShaderInfoLog(shader, length, &length, errmsg); fprintf(stderr, "%s: compile %s error\n%s\n", __func__, (type == GL_VERTEX_SHADER) ? "vertex" : "fragment", errmsg); - free(errmsg); + g_free(errmsg); return 0; } return shader; } -GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag) +static GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag) { GLuint program; GLint status, length; @@ -86,29 +118,62 @@ GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag) glGetProgramiv(program, GL_LINK_STATUS, &status); if (!status) { glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); - errmsg = malloc(length); + errmsg = g_malloc(length); glGetProgramInfoLog(program, length, &length, errmsg); fprintf(stderr, "%s: link program: %s\n", __func__, errmsg); - free(errmsg); + g_free(errmsg); return 0; } return program; } -GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src, - const GLchar *frag_src) +static GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src, + const GLchar *frag_src) { - GLuint vert_shader, frag_shader, program; + GLuint vert_shader, frag_shader, program = 0; vert_shader = qemu_gl_create_compile_shader(GL_VERTEX_SHADER, vert_src); frag_shader = qemu_gl_create_compile_shader(GL_FRAGMENT_SHADER, frag_src); if (!vert_shader || !frag_shader) { - return 0; + goto end; } program = qemu_gl_create_link_program(vert_shader, frag_shader); + +end: glDeleteShader(vert_shader); glDeleteShader(frag_shader); return program; } + +/* ---------------------------------------------------------------------- */ + +QemuGLShader *qemu_gl_init_shader(void) +{ + QemuGLShader *gls = g_new0(QemuGLShader, 1); + + gls->texture_blit_prog = qemu_gl_create_compile_link_program + (texture_blit_vert_src, texture_blit_frag_src); + gls->texture_blit_flip_prog = qemu_gl_create_compile_link_program + (texture_blit_flip_vert_src, texture_blit_frag_src); + if (!gls->texture_blit_prog || !gls->texture_blit_flip_prog) { + exit(1); + } + + gls->texture_blit_vao = + qemu_gl_init_texture_blit(gls->texture_blit_prog); + + return gls; +} + +void qemu_gl_fini_shader(QemuGLShader *gls) +{ + if (!gls) { + return; + } + glDeleteProgram(gls->texture_blit_prog); + glDeleteProgram(gls->texture_blit_flip_prog); + glDeleteProgram(gls->texture_blit_vao); + g_free(gls); +}