summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-11-19 21:17:57 +0100
committerwm4 <wm4@nowhere>2015-11-19 21:17:57 +0100
commit23f3b99003da63c275771b295d6b9069fc56205e (patch)
treed0fd0db869f6b8c680ff23f21894572f6c0e94ca /video
parentb86a59aa4f55c809494a2e5058c51d52d3afc2ce (diff)
downloadmpv-23f3b99003da63c275771b295d6b9069fc56205e.tar.bz2
mpv-23f3b99003da63c275771b295d6b9069fc56205e.tar.xz
vo_opengl: create FBOs in a more GLES conformant way
While desktop GL's glTexImage2D() essentially accepts anything, GLES is much stricter. The combination of allowed formats/types/internal formats is exactly specified. The GLES 3.0.4 specification lists them in table 3.2. (The ANGLE API validation code references this table.) The table could probably be extended into a general declarative table about GL formats covering other uses, but this would be a big non-trivial project, so don't bother and accept a minor degree of duplication with other tables. Note that the format and type do (or should) not matter here, because no image data is transferred to the GPU.
Diffstat (limited to 'video')
-rw-r--r--video/out/opengl/utils.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/video/out/opengl/utils.c b/video/out/opengl/utils.c
index 83bed06498..cdd549a791 100644
--- a/video/out/opengl/utils.c
+++ b/video/out/opengl/utils.c
@@ -312,6 +312,32 @@ void gl_vao_draw_data(struct gl_vao *vao, GLenum prim, void *ptr, size_t num)
gl_vao_unbind(vao);
}
+struct gl_format {
+ GLenum format;
+ GLenum type;
+ GLint internal_format;
+};
+
+static const struct gl_format gl_formats[] = {
+ // GLES 3.0
+ {GL_RGB, GL_UNSIGNED_BYTE, GL_RGB},
+ {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA},
+ {GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8},
+ {GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8},
+ {GL_RGB, GL_UNSIGNED_SHORT, GL_RGB16},
+ {GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2},
+ // not texture filterable in GLES 3.0
+ {GL_RGB, GL_FLOAT, GL_RGB16F},
+ {GL_RGBA, GL_FLOAT, GL_RGBA16F},
+ {GL_RGB, GL_FLOAT, GL_RGB32F},
+ {GL_RGBA, GL_FLOAT, GL_RGBA32F},
+ // Desktop GL
+ {GL_RGB, GL_UNSIGNED_SHORT, GL_RGB10},
+ {GL_RGBA, GL_UNSIGNED_SHORT, GL_RGBA12},
+ {GL_RGBA, GL_UNSIGNED_SHORT, GL_RGBA16},
+ {0}
+};
+
// Create a texture and a FBO using the texture as color attachments.
// iformat: texture internal format
// Returns success.
@@ -349,6 +375,18 @@ bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
GLenum filter = fbo->tex_filter;
+ struct gl_format format = {
+ .format = GL_RGBA,
+ .type = GL_UNSIGNED_BYTE,
+ .internal_format = iformat,
+ };
+ for (int n = 0; gl_formats[n].format; n++) {
+ if (gl_formats[n].internal_format == format.internal_format) {
+ format = gl_formats[n];
+ break;
+ }
+ }
+
*fbo = (struct fbotex) {
.gl = gl,
.w = w,
@@ -364,8 +402,8 @@ bool fbotex_change(struct fbotex *fbo, GL *gl, struct mp_log *log, int w, int h,
gl->GenFramebuffers(1, &fbo->fbo);
gl->GenTextures(1, &fbo->texture);
gl->BindTexture(GL_TEXTURE_2D, fbo->texture);
- gl->TexImage2D(GL_TEXTURE_2D, 0, iformat, fbo->w, fbo->h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ gl->TexImage2D(GL_TEXTURE_2D, 0, format.internal_format, fbo->w, fbo->h, 0,
+ format.format, format.type, NULL);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl->BindTexture(GL_TEXTURE_2D, 0);