summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-28 19:40:46 +0100
committerwm4 <wm4@nowhere>2015-01-28 19:40:46 +0100
commit3583559164b922673b2ccdb31f810befae613779 (patch)
treee38e66b50ce6076db8f06def3c296354e182f645
parent7b3feecbc23e3e0b0d9cf66f02af53d127a0b681 (diff)
downloadmpv-3583559164b922673b2ccdb31f810befae613779.tar.bz2
mpv-3583559164b922673b2ccdb31f810befae613779.tar.xz
vo_opengl: move utility functions from loader to a separate file
gl_common.c contained the function loader (which is big) and additional utility functions (not so big, but will grow when moving more out of gl_video.c). Just split them. There are no changes other than some modifications to comments.
-rw-r--r--old-makefile2
-rw-r--r--video/out/gl_common.c201
-rw-r--r--video/out/gl_common.h13
-rw-r--r--video/out/gl_hwdec_vdpau.c1
-rw-r--r--video/out/gl_osd.c1
-rw-r--r--video/out/gl_utils.c213
-rw-r--r--video/out/gl_utils.h46
-rw-r--r--video/out/gl_video.c1
-rw-r--r--video/out/vo_opengl.c1
-rw-r--r--wscript_build.py1
10 files changed, 265 insertions, 215 deletions
diff --git a/old-makefile b/old-makefile
index 41a30f7df7..50d7710484 100644
--- a/old-makefile
+++ b/old-makefile
@@ -62,7 +62,7 @@ SOURCES-$(SDL2) += audio/out/ao_sdl.c video/out/vo_sdl.c
SOURCES-$(GL) += video/out/gl_common.c video/out/gl_osd.c \
video/out/vo_opengl.c video/out/gl_lcms.c \
video/out/gl_video.c video/out/dither.c \
- video/out/gl_hwdec.c \
+ video/out/gl_hwdec.c video/out/gl_utils.c \
video/out/vo_opengl_cb.c
SOURCES-$(ENCODING) += video/out/vo_lavc.c audio/out/ao_lavc.c \
diff --git a/video/out/gl_common.c b/video/out/gl_common.c
index 20d68fd029..6b2bc388ed 100644
--- a/video/out/gl_common.c
+++ b/video/out/gl_common.c
@@ -45,44 +45,6 @@
#include "options/options.h"
#include "options/m_option.h"
-//! \defgroup glgeneral OpenGL general helper functions
-
-// 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 glCheckError(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;
-}
-
struct feature {
int id;
const char *name;
@@ -564,153 +526,6 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
mpgl_load_functions2(gl, get_procaddr_wrapper, getProcAddress, ext2, log);
}
-/**
- * \brief return the number of bytes per pixel for the given format
- * \param format OpenGL format
- * \param type OpenGL type
- * \return bytes per pixel
- * \ingroup glgeneral
- *
- * Does not handle all possible variants, just those used by MPlayer
- */
-int glFmt2bpp(GLenum format, GLenum type)
-{
- int component_size = 0;
- switch (type) {
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- return 1;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- return 2;
- case GL_UNSIGNED_BYTE:
- component_size = 1;
- break;
- case GL_UNSIGNED_SHORT:
- component_size = 2;
- break;
- }
- switch (format) {
- case GL_LUMINANCE:
- case GL_ALPHA:
- return component_size;
- case GL_RGB_422_APPLE:
- return 2;
- case GL_RGB:
- case GL_BGR:
- case GL_RGB_INTEGER:
- return 3 * component_size;
- case GL_RGBA:
- case GL_BGRA:
- case GL_RGBA_INTEGER:
- return 4 * component_size;
- case GL_RED:
- case GL_RED_INTEGER:
- return component_size;
- case GL_RG:
- case GL_LUMINANCE_ALPHA:
- case GL_RG_INTEGER:
- return 2 * component_size;
- }
- abort(); // unknown
-}
-
-/**
- * \brief upload a texture, handling things like stride and slices
- * \param target texture target, usually GL_TEXTURE_2D
- * \param format OpenGL format of data
- * \param type OpenGL type of data
- * \param dataptr data to upload
- * \param stride data stride
- * \param x x offset in texture
- * \param y y offset in texture
- * \param w width of the texture part to upload
- * \param h height of the texture part to upload
- * \param slice height of an upload slice, 0 for all at once
- * \ingroup gltexture
- */
-void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
- const void *dataptr, int stride,
- int x, int y, int w, int h, int slice)
-{
- const uint8_t *data = dataptr;
- int y_max = y + h;
- if (w <= 0 || h <= 0)
- return;
- if (slice <= 0)
- slice = h;
- if (stride < 0) {
- data += (h - 1) * stride;
- stride = -stride;
- }
- gl->PixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(stride));
- bool use_rowlength = slice > 1 && (gl->mpgl_caps & MPGL_CAP_ROW_LENGTH);
- if (use_rowlength) {
- // this is not always correct, but should work for MPlayer
- gl->PixelStorei(GL_UNPACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
- } else {
- if (stride != glFmt2bpp(format, type) * 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 (use_rowlength)
- gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
-}
-
-// Like glUploadTex, but upload a byte array with all elements set to val.
-// If scratch is not NULL, points to a resizeable talloc memory block than can
-// be freely used by the function (for avoiding temporary memory allocations).
-void glClearTex(GL *gl, GLenum target, GLenum format, GLenum type,
- int x, int y, int w, int h, uint8_t val, void **scratch)
-{
- int bpp = glFmt2bpp(format, type);
- int stride = w * bpp;
- int size = h * stride;
- if (size < 1)
- return;
- void *data = scratch ? *scratch : NULL;
- if (talloc_get_size(data) < size)
- data = talloc_realloc(NULL, data, char *, size);
- memset(data, val, size);
- gl->PixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(stride));
- gl->TexSubImage2D(target, 0, x, y, w, h, format, type, data);
- gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
- if (scratch) {
- *scratch = data;
- } else {
- talloc_free(data);
- }
-}
-
-mp_image_t *glGetWindowScreenshot(GL *gl)
-{
- if (gl->es)
- return NULL; // ES can't read from front buffer
- GLint vp[4]; //x, y, w, h
- gl->GetIntegerv(GL_VIEWPORT, vp);
- mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, vp[2], vp[3]);
- if (!image)
- return NULL;
- gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
- gl->ReadBuffer(GL_FRONT);
- //flip image while reading (and also avoid stride-related trouble)
- for (int y = 0; y < vp[3]; y++) {
- gl->ReadPixels(vp[0], vp[1] + vp[3] - y - 1, vp[2], 1,
- GL_RGB, GL_UNSIGNED_BYTE,
- image->planes[0] + y * image->stride[0]);
- }
- gl->PixelStorei(GL_PACK_ALIGNMENT, 4);
- return image;
-}
-
typedef void (*MPGLSetBackendFn)(MPGLContext *ctx);
struct backend {
@@ -876,19 +691,3 @@ bool mpgl_is_thread_safe(MPGLContext *ctx)
{
return !!ctx->set_current;
}
-
-void mp_log_source(struct mp_log *log, int lev, const char *src)
-{
- int line = 1;
- if (!src)
- return;
- while (*src) {
- const char *end = strchr(src, '\n');
- const char *next = end + 1;
- if (!end)
- next = end = src + strlen(src);
- mp_msg(log, lev, "[%3d] %.*s\n", line, (int)(end - src), src);
- line++;
- src = next;
- }
-}
diff --git a/video/out/gl_common.h b/video/out/gl_common.h
index 97e319556d..0143fea843 100644
--- a/video/out/gl_common.h
+++ b/video/out/gl_common.h
@@ -53,15 +53,6 @@
struct GL;
typedef struct GL GL;
-int glFmt2bpp(GLenum format, GLenum type);
-void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
- const void *dataptr, int stride,
- int x, int y, int w, int h, int slice);
-void glClearTex(GL *gl, GLenum target, GLenum format, GLenum type,
- int x, int y, int w, int h, uint8_t val, void **scratch);
-void glCheckError(GL *gl, struct mp_log *log, const char *info);
-mp_image_t *glGetWindowScreenshot(GL *gl);
-
enum {
MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH
MPGL_CAP_FB = (1 << 5),
@@ -159,10 +150,6 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
void *fn_ctx, const char *ext2, struct mp_log *log);
-// print a multi line string with line numbers (e.g. for shader sources)
-// log, lev: module and log level, as in mp_msg()
-void mp_log_source(struct mp_log *log, int lev, const char *src);
-
typedef void (GLAPIENTRY *MP_GLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum,
GLsizei, const GLchar *,const void *);
diff --git a/video/out/gl_hwdec_vdpau.c b/video/out/gl_hwdec_vdpau.c
index 49f8e7c7b5..3028fa10e1 100644
--- a/video/out/gl_hwdec_vdpau.c
+++ b/video/out/gl_hwdec_vdpau.c
@@ -21,6 +21,7 @@
#include <GL/glx.h>
#include "gl_hwdec.h"
+#include "gl_utils.h"
#include "video/vdpau.h"
#include "video/vdpau_mixer.h"
diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c
index 8a92d3ee8c..14c6cc4824 100644
--- a/video/out/gl_osd.c
+++ b/video/out/gl_osd.c
@@ -21,6 +21,7 @@
#include "bitmap_packer.h"
+#include "gl_utils.h"
#include "gl_osd.h"
struct osd_fmt_entry {
diff --git a/video/out/gl_utils.c b/video/out/gl_utils.c
new file mode 100644
index 0000000000..4ab0479062
--- /dev/null
+++ b/video/out/gl_utils.c
@@ -0,0 +1,213 @@
+/*
+ * 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You can alternatively redistribute this file 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.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/common.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 glCheckError(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));
+ }
+}
+
+// return the number of bytes per pixel for the given format
+// does not handle all possible variants, just those used by mpv
+int glFmt2bpp(GLenum format, GLenum type)
+{
+ int component_size = 0;
+ switch (type) {
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ return 1;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return 2;
+ case GL_UNSIGNED_BYTE:
+ component_size = 1;
+ break;
+ case GL_UNSIGNED_SHORT:
+ component_size = 2;
+ break;
+ }
+ switch (format) {
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ return component_size;
+ case GL_RGB_422_APPLE:
+ return 2;
+ case GL_RGB:
+ case GL_BGR:
+ case GL_RGB_INTEGER:
+ return 3 * component_size;
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_RGBA_INTEGER:
+ return 4 * component_size;
+ case GL_RED:
+ case GL_RED_INTEGER:
+ return component_size;
+ case GL_RG:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RG_INTEGER:
+ return 2 * component_size;
+ }
+ abort(); // unknown
+}
+
+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
+// slice: height of an upload slice, 0 for all at once
+void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
+ const void *dataptr, int stride,
+ int x, int y, int w, int h, int slice)
+{
+ const uint8_t *data = dataptr;
+ int y_max = y + h;
+ if (w <= 0 || h <= 0)
+ return;
+ if (slice <= 0)
+ slice = h;
+ if (stride < 0) {
+ data += (h - 1) * stride;
+ stride = -stride;
+ }
+ gl->PixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(stride));
+ bool use_rowlength = slice > 1 && (gl->mpgl_caps & MPGL_CAP_ROW_LENGTH);
+ if (use_rowlength) {
+ // this is not always correct, but should work for MPlayer
+ gl->PixelStorei(GL_UNPACK_ROW_LENGTH, stride / glFmt2bpp(format, type));
+ } else {
+ if (stride != glFmt2bpp(format, type) * 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 (use_rowlength)
+ gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
+}
+
+// Like glUploadTex, but upload a byte array with all elements set to val.
+// If scratch is not NULL, points to a resizeable talloc memory block than can
+// be freely used by the function (for avoiding temporary memory allocations).
+void glClearTex(GL *gl, GLenum target, GLenum format, GLenum type,
+ int x, int y, int w, int h, uint8_t val, void **scratch)
+{
+ int bpp = glFmt2bpp(format, type);
+ int stride = w * bpp;
+ int size = h * stride;
+ if (size < 1)
+ return;
+ void *data = scratch ? *scratch : NULL;
+ if (talloc_get_size(data) < size)
+ data = talloc_realloc(NULL, data, char *, size);
+ memset(data, val, size);
+ gl->PixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(stride));
+ gl->TexSubImage2D(target, 0, x, y, w, h, format, type, data);
+ gl->PixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ if (scratch) {
+ *scratch = data;
+ } else {
+ talloc_free(data);
+ }
+}
+
+mp_image_t *glGetWindowScreenshot(GL *gl)
+{
+ if (gl->es)
+ return NULL; // ES can't read from front buffer
+ GLint vp[4]; //x, y, w, h
+ gl->GetIntegerv(GL_VIEWPORT, vp);
+ mp_image_t *image = mp_image_alloc(IMGFMT_RGB24, vp[2], vp[3]);
+ if (!image)
+ return NULL;
+ gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
+ gl->ReadBuffer(GL_FRONT);
+ //flip image while reading (and also avoid stride-related trouble)
+ for (int y = 0; y < vp[3]; y++) {
+ gl->ReadPixels(vp[0], vp[1] + vp[3] - y - 1, vp[2], 1,
+ GL_RGB, GL_UNSIGNED_BYTE,
+ image->planes[0] + y * image->stride[0]);
+ }
+ gl->PixelStorei(GL_PACK_ALIGNMENT, 4);
+ return image;
+}
+
+void mp_log_source(struct mp_log *log, int lev, const char *src)
+{
+ int line = 1;
+ if (!src)
+ return;
+ while (*src) {
+ const char *end = strchr(src, '\n');
+ const char *next = end + 1;
+ if (!end)
+ next = end = src + strlen(src);
+ mp_msg(log, lev, "[%3d] %.*s\n", line, (int)(end - src), src);
+ line++;
+ src = next;
+ }
+}
diff --git a/video/out/gl_utils.h b/video/out/gl_utils.h
new file mode 100644
index 0000000000..4f32e5ff56
--- /dev/null
+++ b/video/out/gl_utils.h
@@ -0,0 +1,46 @@
+/*
+ * 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You can alternatively redistribute this file 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.
+ */
+
+#ifndef MP_GL_UTILS_
+#define MP_GL_UTILS_
+
+#include "gl_common.h"
+
+struct mp_log;
+
+void glCheckError(GL *gl, struct mp_log *log, const char *info);
+
+int glFmt2bpp(GLenum format, GLenum type);
+void glUploadTex(GL *gl, GLenum target, GLenum format, GLenum type,
+ const void *dataptr, int stride,
+ int x, int y, int w, int h, int slice);
+void glClearTex(GL *gl, GLenum target, GLenum format, GLenum type,
+ int x, int y, int w, int h, uint8_t val, void **scratch);
+
+mp_image_t *glGetWindowScreenshot(GL *gl);
+
+// print a multi line string with line numbers (e.g. for shader sources)
+// log, lev: module and log level, as in mp_msg()
+void mp_log_source(struct mp_log *log, int lev, const char *src);
+
+#endif
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 805df58de6..e518a9233a 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -32,6 +32,7 @@
#include "misc/bstr.h"
#include "gl_common.h"
+#include "gl_utils.h"
#include "gl_hwdec.h"
#include "gl_osd.h"
#include "filter_kernels.h"
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index 910ebb8ca3..9da92e3858 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -44,6 +44,7 @@
#include "sub/osd.h"
#include "gl_common.h"
+#include "gl_utils.h"
#include "gl_hwdec.h"
#include "gl_osd.h"
#include "filter_kernels.h"
diff --git a/wscript_build.py b/wscript_build.py
index 8efaf554d3..565dbbc3b1 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -337,6 +337,7 @@ def build(ctx):
( "video/out/gl_hwdec_vdpau.c", "vdpau-gl-x11" ),
( "video/out/gl_lcms.c", "gl" ),
( "video/out/gl_osd.c", "gl" ),
+ ( "video/out/gl_utils.c", "gl" ),
( "video/out/gl_video.c", "gl" ),
( "video/out/gl_w32.c", "gl-win32" ),
( "video/out/gl_wayland.c", "gl-wayland" ),