aboutsummaryrefslogtreecommitdiffhomepage
path: root/video
diff options
context:
space:
mode:
authorGravatar wm4 <wm4@nowhere>2016-05-23 18:02:37 +0200
committerGravatar wm4 <wm4@nowhere>2016-05-23 21:27:18 +0200
commit80d702dce8469928012b9a709805a76274cd0256 (patch)
treeff0be1fb603572b41fe5bd74a672ae72ac004ecc /video
parentafcef4c25b8dabff92716c3995e26068362bc3aa (diff)
vo_opengl: make PBOs work on GLES 3.x
For some reason, GLES has no glMapBuffer, only glMapBufferRange. GLES 2 has no buffer mapping at all, and GL 2.1 does not always have glMapBufferRange. On those PBOs remain unsupported (there's no reason to care about GL 2.1 without the extension). This doesn't actually work on ANGLE, and I have no idea why. (There are artifacts on OSD, as if parts of the OSD data weren't copied.) It works on desktop OpenGL and at least 1 other ES 3 implementation. Don't enable it on ANGLE, I guess.
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/common.c12
-rw-r--r--video/out/opengl/common.h3
-rw-r--r--video/out/opengl/osd.c9
-rw-r--r--video/out/opengl/video.c10
4 files changed, 24 insertions, 10 deletions
diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c
index 6287fc488b..7121522f4b 100644
--- a/video/out/opengl/common.c
+++ b/video/out/opengl/common.c
@@ -147,13 +147,22 @@ static const struct gl_functions gl_functions[] = {
.provides = MPGL_CAP_ROW_LENGTH | MPGL_CAP_1D_TEX,
.functions = (const struct gl_function[]) {
DEF_FN(GetTexLevelParameteriv),
- DEF_FN(MapBuffer),
DEF_FN(ReadBuffer),
DEF_FN(TexImage1D),
DEF_FN(UnmapBuffer),
{0}
},
},
+ // GL 2.1 has this as extension only.
+ {
+ .ver_exclude = 300,
+ .ver_es_exclude = 300,
+ .extension = "GL_ARB_map_buffer_range",
+ .functions = (const struct gl_function[]) {
+ DEF_FN(MapBufferRange),
+ {0}
+ },
+ },
// GL 3.0+ and ES 3.x core only functions.
{
.ver_core = 300,
@@ -162,6 +171,7 @@ static const struct gl_functions gl_functions[] = {
DEF_FN(BindBufferBase),
DEF_FN(BlitFramebuffer),
DEF_FN(GetStringi),
+ DEF_FN(MapBufferRange),
// for ES 3.0
DEF_FN(ReadBuffer),
DEF_FN(UnmapBuffer),
diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h
index c55f1654fc..84c27dfea0 100644
--- a/video/out/opengl/common.h
+++ b/video/out/opengl/common.h
@@ -126,7 +126,8 @@ struct GL {
void (GLAPIENTRY *DeleteBuffers)(GLsizei, const GLuint *);
void (GLAPIENTRY *BindBuffer)(GLenum, GLuint);
void (GLAPIENTRY *BindBufferBase)(GLenum, GLuint, GLuint);
- GLvoid * (GLAPIENTRY * MapBuffer)(GLenum, GLenum);
+ GLvoid * (GLAPIENTRY *MapBufferRange)(GLenum, GLintptr, GLsizeiptr,
+ GLbitfield);
GLboolean (GLAPIENTRY *UnmapBuffer)(GLenum);
void (GLAPIENTRY *BufferData)(GLenum, intptr_t, const GLvoid *, GLenum);
void (GLAPIENTRY *ActiveTexture)(GLenum);
diff --git a/video/out/opengl/osd.c b/video/out/opengl/osd.c
index bf03d34e90..d8059166be 100644
--- a/video/out/opengl/osd.c
+++ b/video/out/opengl/osd.c
@@ -139,18 +139,19 @@ static bool upload_pbo(struct mpgl_osd *ctx, struct mpgl_osd_part *osd,
GL *gl = ctx->gl;
bool success = true;
const struct gl_format *fmt = ctx->fmt_table[imgs->format];
- int pix_stride = gl_bytes_per_pixel(fmt->format, fmt->type);
+ size_t pix_stride = gl_bytes_per_pixel(fmt->format, fmt->type);
+ size_t buffer_size = pix_stride * osd->h * osd->w;
if (!osd->buffer) {
gl->GenBuffers(1, &osd->buffer);
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, osd->buffer);
- gl->BufferData(GL_PIXEL_UNPACK_BUFFER, osd->w * osd->h * pix_stride,
- NULL, GL_DYNAMIC_COPY);
+ gl->BufferData(GL_PIXEL_UNPACK_BUFFER, buffer_size, NULL, GL_DYNAMIC_COPY);
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, osd->buffer);
- char *data = gl->MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
+ char *data = gl->MapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, buffer_size,
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
if (!data) {
success = false;
} else {
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index bebe1373d6..edf7c7d1f6 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -2870,15 +2870,17 @@ static bool map_image(struct gl_video *p, struct mp_image *mpi)
for (int n = 0; n < p->plane_count; n++) {
struct texplane *plane = &vimg->planes[n];
mpi->stride[n] = mp_image_plane_w(mpi, n) * p->image_desc.bytes[n];
+ size_t buffer_size = mp_image_plane_h(mpi, n) * mpi->stride[n];
if (!plane->gl_buffer) {
gl->GenBuffers(1, &plane->gl_buffer);
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, plane->gl_buffer);
- size_t buffer_size = mp_image_plane_h(mpi, n) * mpi->stride[n];
gl->BufferData(GL_PIXEL_UNPACK_BUFFER, buffer_size,
NULL, GL_DYNAMIC_DRAW);
}
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, plane->gl_buffer);
- mpi->planes[n] = gl->MapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
+ mpi->planes[n] = gl->MapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0,
+ buffer_size, GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_BUFFER_BIT);
gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
if (!mpi->planes[n]) {
unmap_image(p, mpi);
@@ -3042,9 +3044,9 @@ static void check_gl_features(struct gl_video *p)
}
}
- if (gl->es && p->opts.pbo) {
+ if (!gl->MapBufferRange && p->opts.pbo) {
p->opts.pbo = 0;
- MP_WARN(p, "Disabling PBOs (GLES unsupported).\n");
+ MP_WARN(p, "Disabling PBOs (GL2.1/GLES2 unsupported).\n");
}
p->forced_dumb_mode = p->opts.dumb_mode || !have_fbo || !have_texrg;