Coverage Report

Created: 2025-10-27 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mpv/video/out/opengl/formats.c
Line
Count
Source
1
#include "common/common.h"
2
#include "formats.h"
3
4
enum {
5
    // --- GL type aliases (for readability)
6
    T_U8        = GL_UNSIGNED_BYTE,
7
    T_U16       = GL_UNSIGNED_SHORT,
8
    T_FL        = GL_FLOAT,
9
};
10
11
// List of allowed formats, and their usability for bilinear filtering and FBOs.
12
// This is limited to combinations that are useful for our renderer.
13
const struct gl_format gl_formats[] = {
14
    // These are used for desktop GL 3+, and GLES 3+ with GL_EXT_texture_norm16.
15
    {"r8",      GL_R8,       GL_RED,             T_U8,  F_CF | F_GL3 | F_GL2F | F_ES3},
16
    {"rg8",     GL_RG8,      GL_RG,              T_U8,  F_CF | F_GL3 | F_GL2F | F_ES3},
17
    {"rgb8",    GL_RGB8,     GL_RGB,             T_U8,  F_CF | F_GL3 | F_GL2F | F_ES3},
18
    {"rgba8",   GL_RGBA8,    GL_RGBA,            T_U8,  F_CF | F_GL3 | F_GL2F | F_ES3},
19
    {"r16",     GL_R16,      GL_RED,             T_U16, F_CF | F_GL3 | F_GL2F | F_EXT16},
20
    {"rg16",    GL_RG16,     GL_RG,              T_U16, F_CF | F_GL3 | F_GL2F | F_EXT16},
21
    {"rgb16",   GL_RGB16,    GL_RGB,             T_U16, F_CF | F_GL3 | F_GL2F},
22
    {"rgba16",  GL_RGBA16,   GL_RGBA,            T_U16, F_CF | F_GL3 | F_GL2F | F_EXT16},
23
24
    // Specifically not color-renderable.
25
    {"rgb16",   GL_RGB16,    GL_RGB,             T_U16, F_TF | F_EXT16},
26
27
    // GL2 legacy. Ignores possibly present FBO extensions (no CF flag set).
28
    {"l8",    GL_LUMINANCE8, GL_LUMINANCE,       T_U8,  F_TF | F_GL2},
29
    {"la8", GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, T_U8,  F_TF | F_GL2},
30
    {"rgb8",    GL_RGB8,     GL_RGB,             T_U8,  F_TF | F_GL2},
31
    {"rgba8",   GL_RGBA8,    GL_RGBA,            T_U8,  F_TF | F_GL2},
32
    {"l16",  GL_LUMINANCE16, GL_LUMINANCE,       T_U16, F_TF | F_GL2},
33
    {"la16", GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, T_U16, F_TF | F_GL2},
34
    {"rgb16",   GL_RGB16,    GL_RGB,             T_U16, F_TF | F_GL2},
35
    {"rgba16",  GL_RGBA16,   GL_RGBA,            T_U16, F_TF | F_GL2},
36
37
    // ES3 legacy. This is literally to compensate for Apple bugs in their iOS
38
    // interop (can they do anything right?). ES3 still allows these formats,
39
    // but they are deprecated.
40
    {"l" ,      GL_LUMINANCE,GL_LUMINANCE,       T_U8,  F_CF | F_ES3},
41
    {"la",GL_LUMINANCE_ALPHA,GL_LUMINANCE_ALPHA, T_U8,  F_CF | F_ES3},
42
43
    // ES2 legacy
44
    {"l" ,      GL_LUMINANCE,GL_LUMINANCE,       T_U8,  F_TF | F_ES2},
45
    {"la",GL_LUMINANCE_ALPHA,GL_LUMINANCE_ALPHA, T_U8,  F_TF | F_ES2},
46
    {"rgb",     GL_RGB,      GL_RGB,             T_U8,  F_TF | F_ES2},
47
    {"rgba",    GL_RGBA,     GL_RGBA,            T_U8,  F_TF | F_ES2},
48
49
    // Non-normalized integer formats.
50
    // Follows ES 3.0 as to which are color-renderable.
51
    {"r8ui",    GL_R8UI,     GL_RED_INTEGER,     T_U8,  F_CR | F_GL3 | F_ES3},
52
    {"rg8ui",   GL_RG8UI,    GL_RG_INTEGER,      T_U8,  F_CR | F_GL3 | F_ES3},
53
    {"rgb8ui",  GL_RGB8UI,   GL_RGB_INTEGER,     T_U8,         F_GL3 | F_ES3},
54
    {"rgba8ui", GL_RGBA8UI,  GL_RGBA_INTEGER,    T_U8,  F_CR | F_GL3 | F_ES3},
55
    {"r16ui",   GL_R16UI,    GL_RED_INTEGER,     T_U16, F_CR | F_GL3 | F_ES3},
56
    {"rg16ui",  GL_RG16UI,   GL_RG_INTEGER,      T_U16, F_CR | F_GL3 | F_ES3},
57
    {"rgb16ui", GL_RGB16UI,  GL_RGB_INTEGER,     T_U16,        F_GL3 | F_ES3},
58
    {"rgba16ui",GL_RGBA16UI, GL_RGBA_INTEGER,    T_U16, F_CR | F_GL3 | F_ES3},
59
60
    // On GL3+ or GL2.1 with GL_ARB_texture_float, floats work fully.
61
    {"r16f",    GL_R16F,     GL_RED,             T_FL,  F_F16 | F_CF | F_GL3 | F_GL2F},
62
    {"rg16f",   GL_RG16F,    GL_RG,              T_FL,  F_F16 | F_CF | F_GL3 | F_GL2F},
63
    {"rgb16f",  GL_RGB16F,   GL_RGB,             T_FL,  F_F16 | F_CF | F_GL3 | F_GL2F},
64
    {"rgba16f", GL_RGBA16F,  GL_RGBA,            T_FL,  F_F16 | F_CF | F_GL3 | F_GL2F},
65
    {"r32f",    GL_R32F,     GL_RED,             T_FL,          F_CF | F_GL3 | F_GL2F},
66
    {"rg32f",   GL_RG32F,    GL_RG,              T_FL,          F_CF | F_GL3 | F_GL2F},
67
    {"rgb32f",  GL_RGB32F,   GL_RGB,             T_FL,          F_CF | F_GL3 | F_GL2F},
68
    {"rgba32f", GL_RGBA32F,  GL_RGBA,            T_FL,          F_CF | F_GL3 | F_GL2F},
69
70
    // Note: we simply don't support float anything on ES2, despite extensions.
71
    // We also don't bother with non-filterable float formats, and we ignore
72
    // 32 bit float formats that are not blendable when rendering to them.
73
74
    // On ES3.2+, both 16 bit floats work fully (except 3-component formats).
75
    // F_EXTF16 implies extensions that also enable 16 bit floats fully.
76
    {"r16f",    GL_R16F,     GL_RED,             T_FL,  F_F16 | F_CF | F_ES32 | F_EXTF16},
77
    {"rg16f",   GL_RG16F,    GL_RG,              T_FL,  F_F16 | F_CF | F_ES32 | F_EXTF16},
78
    {"rgb16f",  GL_RGB16F,   GL_RGB,             T_FL,  F_F16 | F_TF | F_ES32 | F_EXTF16},
79
    {"rgba16f", GL_RGBA16F,  GL_RGBA,            T_FL,  F_F16 | F_CF | F_ES32 | F_EXTF16},
80
81
    // On ES3.0+, 16 bit floats are texture-filterable.
82
    // Don't bother with 32 bit floats; they exist but are neither CR nor TF.
83
    {"r16f",    GL_R16F,     GL_RED,             T_FL,  F_F16 | F_TF | F_ES3},
84
    {"rg16f",   GL_RG16F,    GL_RG,              T_FL,  F_F16 | F_TF | F_ES3},
85
    {"rgb16f",  GL_RGB16F,   GL_RGB,             T_FL,  F_F16 | F_TF | F_ES3},
86
    {"rgba16f", GL_RGBA16F,  GL_RGBA,            T_FL,  F_F16 | F_TF | F_ES3},
87
88
    // These might be useful as FBO formats.
89
    {"rgb10_a2",GL_RGB10_A2, GL_RGBA,
90
     GL_UNSIGNED_INT_2_10_10_10_REV,                    F_CF | F_GL3 | F_ES3},
91
    {"rgba12",  GL_RGBA12,   GL_RGBA,            T_U16, F_CF | F_GL2 | F_GL3},
92
    {"rgb10",   GL_RGB10,    GL_RGB,             T_U16, F_CF | F_GL2 | F_GL3},
93
94
    // Special formats.
95
    {"rgb565",  GL_RGB8,     GL_RGB,
96
     GL_UNSIGNED_SHORT_5_6_5,                           F_TF | F_GL2 | F_GL3},
97
    // Worthless, but needed by macOS videotoolbox interop on old Apple hardware.
98
    {"appleyp", GL_RGB,      GL_RGB_422_APPLE,
99
     GL_UNSIGNED_SHORT_8_8_APPLE,                       F_TF | F_APPL},
100
101
    {0}
102
};
103
104
// Return an or-ed combination of all F_ flags that apply.
105
int gl_format_feature_flags(GL *gl)
106
0
{
107
0
    return (gl->version == 210 ? F_GL2 : 0)
108
0
         | (gl->version >= 300 ? F_GL3 : 0)
109
0
         | (gl->es == 200 ? F_ES2 : 0)
110
0
         | (gl->es >= 300 ? F_ES3 : 0)
111
0
         | (gl->es >= 320 ? F_ES32 : 0)
112
0
         | (gl->mpgl_caps & MPGL_CAP_EXT16 ? F_EXT16 : 0)
113
0
         | ((gl->es >= 300 &&
114
0
            (gl->mpgl_caps & MPGL_CAP_EXT_CR_HFLOAT)) ? F_EXTF16 : 0)
115
0
         | ((gl->version == 210 &&
116
0
            (gl->mpgl_caps & MPGL_CAP_ARB_FLOAT) &&
117
0
            (gl->mpgl_caps & MPGL_CAP_TEX_RG) &&
118
0
            (gl->mpgl_caps & MPGL_CAP_FB)) ? F_GL2F : 0)
119
0
         | (gl->mpgl_caps & MPGL_CAP_APPLE_RGB_422 ? F_APPL : 0);
120
0
}
121
122
int gl_format_type(const struct gl_format *format)
123
0
{
124
0
    if (!format)
125
0
        return 0;
126
0
    if (format->type == GL_FLOAT)
127
0
        return MPGL_TYPE_FLOAT;
128
0
    if (gl_integer_format_to_base(format->format))
129
0
        return MPGL_TYPE_UINT;
130
0
    return MPGL_TYPE_UNORM;
131
0
}
132
133
// Return base internal format of an integer format, or 0 if it's not integer.
134
// "format" is like in struct gl_format.
135
GLenum gl_integer_format_to_base(GLenum format)
136
0
{
137
0
    switch (format) {
138
0
    case GL_RED_INTEGER:        return GL_RED;
139
0
    case GL_RG_INTEGER:         return GL_RG;
140
0
    case GL_RGB_INTEGER:        return GL_RGB;
141
0
    case GL_RGBA_INTEGER:       return GL_RGBA;
142
0
    }
143
0
    return 0;
144
0
}
145
146
// Return the number of bytes per component this format implies.
147
// Returns 0 for formats with non-byte alignments and formats which
148
// merge multiple components (like GL_UNSIGNED_SHORT_5_6_5).
149
// "type" is like in struct gl_format.
150
int gl_component_size(GLenum type)
151
0
{
152
0
    switch (type) {
153
0
    case GL_UNSIGNED_BYTE:                      return 1;
154
0
    case GL_UNSIGNED_SHORT:                     return 2;
155
0
    case GL_FLOAT:                              return 4;
156
0
    }
157
0
    return 0;
158
0
}
159
160
// Return the number of separate color components.
161
// "format" is like in struct gl_format.
162
int gl_format_components(GLenum format)
163
0
{
164
0
    switch (format) {
165
0
    case GL_RED:
166
0
    case GL_RED_INTEGER:
167
0
    case GL_LUMINANCE:
168
0
        return 1;
169
0
    case GL_RG:
170
0
    case GL_RG_INTEGER:
171
0
    case GL_LUMINANCE_ALPHA:
172
0
        return 2;
173
0
    case GL_RGB:
174
0
    case GL_RGB_INTEGER:
175
0
        return 3;
176
0
    case GL_RGBA:
177
0
    case GL_RGBA_INTEGER:
178
0
        return 4;
179
0
    }
180
0
    return 0;
181
0
}
182
183
// Return the number of bytes per pixel for the given format.
184
// Parameter names like in struct gl_format.
185
int gl_bytes_per_pixel(GLenum format, GLenum type)
186
0
{
187
    // Formats with merged components are special.
188
0
    switch (type) {
189
0
    case GL_UNSIGNED_INT_2_10_10_10_REV:        return 4;
190
0
    case GL_UNSIGNED_SHORT_5_6_5:               return 2;
191
0
    case GL_UNSIGNED_SHORT_8_8_APPLE:           return 2;
192
0
    case GL_UNSIGNED_SHORT_8_8_REV_APPLE:       return 2;
193
0
    }
194
195
0
    return gl_component_size(type) * gl_format_components(format);
196
0
}