diff options
Diffstat (limited to 'video/out/opengl/gl_utils.c')
-rw-r--r-- | video/out/opengl/gl_utils.c | 291 |
1 files changed, 0 insertions, 291 deletions
diff --git a/video/out/opengl/gl_utils.c b/video/out/opengl/gl_utils.c deleted file mode 100644 index bce2dabe5d..0000000000 --- a/video/out/opengl/gl_utils.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * This file is part of mpv. - * Parts based on MPlayer code by Reimar Döffinger. - * - * mpv is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * mpv is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with mpv. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> - -#include <libavutil/sha.h> -#include <libavutil/intreadwrite.h> -#include <libavutil/mem.h> - -#include "osdep/io.h" - -#include "common/common.h" -#include "options/path.h" -#include "stream/stream.h" -#include "formats.h" -#include "ra_gl.h" -#include "gl_utils.h" - -// GLU has this as gluErrorString (we don't use GLU, as it is legacy-OpenGL) -static const char *gl_error_to_string(GLenum error) -{ - switch (error) { - case GL_INVALID_ENUM: return "INVALID_ENUM"; - case GL_INVALID_VALUE: return "INVALID_VALUE"; - case GL_INVALID_OPERATION: return "INVALID_OPERATION"; - case GL_INVALID_FRAMEBUFFER_OPERATION: return "INVALID_FRAMEBUFFER_OPERATION"; - case GL_OUT_OF_MEMORY: return "OUT_OF_MEMORY"; - default: return "unknown"; - } -} - -void gl_check_error(GL *gl, struct mp_log *log, const char *info) -{ - for (;;) { - GLenum error = gl->GetError(); - if (error == GL_NO_ERROR) - break; - mp_msg(log, MSGL_ERR, "%s: OpenGL error %s.\n", info, - gl_error_to_string(error)); - } -} - -static int get_alignment(int stride) -{ - if (stride % 8 == 0) - return 8; - if (stride % 4 == 0) - return 4; - if (stride % 2 == 0) - return 2; - return 1; -} - -// upload a texture, handling things like stride and slices -// target: texture target, usually GL_TEXTURE_2D -// format, type: texture parameters -// dataptr, stride: image data -// x, y, width, height: part of the image to upload -void gl_upload_tex(GL *gl, GLenum target, GLenum format, GLenum type, - const void *dataptr, int stride, - int x, int y, int w, int h) -{ - int bpp = gl_bytes_per_pixel(format, type); - const uint8_t *data = dataptr; - int y_max = y + h; - if (w <= 0 || h <= 0 || !bpp) - return; - if (stride < 0) { - data += (h - 1) * stride; - stride = -stride; - } - gl->PixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(stride)); - int slice = h; - if (gl->mpgl_caps & MPGL_CAP_ROW_LENGTH) { - // this is not always correct, but should work for MPlayer - gl->PixelStorei(GL_UNPACK_ROW_LENGTH, stride / bpp); - } else { - if (stride != bpp * w) - slice = 1; // very inefficient, but at least it works - } - for (; y + slice <= y_max; y += slice) { - gl->TexSubImage2D(target, 0, x, y, w, slice, format, type, data); - data += stride * slice; - } - if (y < y_max) - gl->TexSubImage2D(target, 0, x, y, w, y_max - y, format, type, data); - if (gl->mpgl_caps & MPGL_CAP_ROW_LENGTH) - gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0); - gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4); -} - -mp_image_t *gl_read_fbo_contents(GL *gl, int fbo, int w, int h) -{ - if (gl->es) - return NULL; // ES can't read from front buffer - mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, w, h); - if (!image) - return NULL; - gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); - GLenum obj = fbo ? GL_COLOR_ATTACHMENT0 : GL_FRONT; - gl->PixelStorei(GL_PACK_ALIGNMENT, 1); - gl->ReadBuffer(obj); - //flip image while reading (and also avoid stride-related trouble) - for (int y = 0; y < h; y++) { - gl->ReadPixels(0, h - y - 1, w, 1, GL_RGB, GL_UNSIGNED_BYTE, - image->planes[0] + y * image->stride[0]); - } - gl->PixelStorei(GL_PACK_ALIGNMENT, 4); - gl->BindFramebuffer(GL_FRAMEBUFFER, 0); - return image; -} - -static void gl_vao_enable_attribs(struct gl_vao *vao) -{ - GL *gl = vao->gl; - - for (int n = 0; n < vao->num_entries; n++) { - const struct ra_renderpass_input *e = &vao->entries[n]; - GLenum type = 0; - bool normalized = false; - switch (e->type) { - case RA_VARTYPE_INT: - type = GL_INT; - break; - case RA_VARTYPE_FLOAT: - type = GL_FLOAT; - break; - case RA_VARTYPE_BYTE_UNORM: - type = GL_UNSIGNED_BYTE; - normalized = true; - break; - default: - abort(); - } - assert(e->dim_m == 1); - - gl->EnableVertexAttribArray(n); - gl->VertexAttribPointer(n, e->dim_v, type, normalized, - vao->stride, (void *)(intptr_t)e->offset); - } -} - -void gl_vao_init(struct gl_vao *vao, GL *gl, int stride, - const struct ra_renderpass_input *entries, - int num_entries) -{ - assert(!vao->vao); - assert(!vao->buffer); - - *vao = (struct gl_vao){ - .gl = gl, - .stride = stride, - .entries = entries, - .num_entries = num_entries, - }; - - gl->GenBuffers(1, &vao->buffer); - - if (gl->BindVertexArray) { - gl->BindBuffer(GL_ARRAY_BUFFER, vao->buffer); - - gl->GenVertexArrays(1, &vao->vao); - gl->BindVertexArray(vao->vao); - gl_vao_enable_attribs(vao); - gl->BindVertexArray(0); - - gl->BindBuffer(GL_ARRAY_BUFFER, 0); - } -} - -void gl_vao_uninit(struct gl_vao *vao) -{ - GL *gl = vao->gl; - if (!gl) - return; - - if (gl->DeleteVertexArrays) - gl->DeleteVertexArrays(1, &vao->vao); - gl->DeleteBuffers(1, &vao->buffer); - - *vao = (struct gl_vao){0}; -} - -static void gl_vao_bind(struct gl_vao *vao) -{ - GL *gl = vao->gl; - - if (gl->BindVertexArray) { - gl->BindVertexArray(vao->vao); - } else { - gl->BindBuffer(GL_ARRAY_BUFFER, vao->buffer); - gl_vao_enable_attribs(vao); - gl->BindBuffer(GL_ARRAY_BUFFER, 0); - } -} - -static void gl_vao_unbind(struct gl_vao *vao) -{ - GL *gl = vao->gl; - - if (gl->BindVertexArray) { - gl->BindVertexArray(0); - } else { - for (int n = 0; n < vao->num_entries; n++) - gl->DisableVertexAttribArray(n); - } -} - -// Draw the vertex data (as described by the gl_vao_entry entries) in ptr -// to the screen. num is the number of vertexes. prim is usually GL_TRIANGLES. -// If ptr is NULL, then skip the upload, and use the data uploaded with the -// previous call. -void gl_vao_draw_data(struct gl_vao *vao, GLenum prim, void *ptr, size_t num) -{ - GL *gl = vao->gl; - - if (ptr) { - gl->BindBuffer(GL_ARRAY_BUFFER, vao->buffer); - gl->BufferData(GL_ARRAY_BUFFER, num * vao->stride, ptr, GL_STREAM_DRAW); - gl->BindBuffer(GL_ARRAY_BUFFER, 0); - } - - gl_vao_bind(vao); - - gl->DrawArrays(prim, 0, num); - - gl_vao_unbind(vao); -} - -static void GLAPIENTRY gl_debug_cb(GLenum source, GLenum type, GLuint id, - GLenum severity, GLsizei length, - const GLchar *message, const void *userParam) -{ - // keep in mind that the debug callback can be asynchronous - struct mp_log *log = (void *)userParam; - int level = MSGL_ERR; - switch (severity) { - case GL_DEBUG_SEVERITY_NOTIFICATION:level = MSGL_V; break; - case GL_DEBUG_SEVERITY_LOW: level = MSGL_INFO; break; - case GL_DEBUG_SEVERITY_MEDIUM: level = MSGL_WARN; break; - case GL_DEBUG_SEVERITY_HIGH: level = MSGL_ERR; break; - } - mp_msg(log, level, "GL: %s\n", message); -} - -void gl_set_debug_logger(GL *gl, struct mp_log *log) -{ - if (gl->DebugMessageCallback) - gl->DebugMessageCallback(log ? gl_debug_cb : NULL, log); -} - -int gl_get_fb_depth(GL *gl, int fbo) -{ - if ((gl->es < 300 && !gl->version) || !(gl->mpgl_caps & MPGL_CAP_FB)) - return -1; - - gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); - - GLenum obj = gl->version ? GL_BACK_LEFT : GL_BACK; - if (fbo) - obj = GL_COLOR_ATTACHMENT0; - - GLint depth_g = -1; - - gl->GetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, obj, - GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, &depth_g); - - gl->BindFramebuffer(GL_FRAMEBUFFER, 0); - - return depth_g > 0 ? depth_g : -1; -} |