]> git.proxmox.com Git - mirror_qemu.git/blobdiff - ui/shader.c
Merge tag 'pull-maintainer-may24-160524-2' of https://gitlab.com/stsquad/qemu into...
[mirror_qemu.git] / ui / shader.c
index 0588655cfed8152cbd885f806396469ecb1ea60e..ab448c41d4c67b6db48623ba26b5c2994d6900e1 100644 (file)
  * 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;
+};
+
 /* ---------------------------------------------------------------------- */
 
-GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
+static GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
 {
     static const GLfloat in_position[] = {
         -1, -1,
@@ -59,17 +69,18 @@ GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
     return vao;
 }
 
-void qemu_gl_run_texture_blit(GLint texture_blit_prog,
-                              GLint texture_blit_vao)
+void qemu_gl_run_texture_blit(QemuGLShader *gls, bool flip)
 {
-    glUseProgram(texture_blit_prog);
-    glBindVertexArray(texture_blit_vao);
+    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;
@@ -82,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;
@@ -107,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);
+}