OLD | NEW |
---|---|
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/output/shader.h" | 5 #include "cc/output/shader.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2016 FragmentShaderYUVVideo::FragmentShaderYUVVideo() | 2016 FragmentShaderYUVVideo::FragmentShaderYUVVideo() |
2017 : y_texture_location_(-1), | 2017 : y_texture_location_(-1), |
2018 u_texture_location_(-1), | 2018 u_texture_location_(-1), |
2019 v_texture_location_(-1), | 2019 v_texture_location_(-1), |
2020 uv_texture_location_(-1), | 2020 uv_texture_location_(-1), |
2021 a_texture_location_(-1), | 2021 a_texture_location_(-1), |
2022 lut_texture_location_(-1), | 2022 lut_texture_location_(-1), |
2023 alpha_location_(-1), | 2023 alpha_location_(-1), |
2024 yuv_matrix_location_(-1), | 2024 yuv_matrix_location_(-1), |
2025 yuv_adj_location_(-1), | 2025 yuv_adj_location_(-1), |
2026 ya_size_location_(-1), | |
2027 uv_size_location_(-1), | |
2026 ya_clamp_rect_location_(-1), | 2028 ya_clamp_rect_location_(-1), |
2027 uv_clamp_rect_location_(-1), | 2029 uv_clamp_rect_location_(-1), |
2028 resource_multiplier_location_(-1), | 2030 resource_multiplier_location_(-1), |
2029 resource_offset_location_(-1) {} | 2031 resource_offset_location_(-1) {} |
2030 | 2032 |
2031 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, | 2033 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, |
2032 bool use_nv12, | 2034 bool use_nv12, |
2033 bool use_color_lut) { | 2035 bool use_color_lut, |
2036 HighbitTexture highbit_texture) { | |
2034 use_alpha_texture_ = use_alpha_texture; | 2037 use_alpha_texture_ = use_alpha_texture; |
2035 use_nv12_ = use_nv12; | 2038 use_nv12_ = use_nv12; |
2036 use_color_lut_ = use_color_lut; | 2039 use_color_lut_ = use_color_lut; |
2040 highbit_texture_ = highbit_texture; | |
2037 } | 2041 } |
2038 | 2042 |
2039 void FragmentShaderYUVVideo::Init(GLES2Interface* context, | 2043 void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
2040 unsigned program, | 2044 unsigned program, |
2041 int* base_uniform_index) { | 2045 int* base_uniform_index) { |
2042 static const char* uniforms[] = { | 2046 static const char* uniforms[] = { |
2043 "y_texture", | 2047 "y_texture", "u_texture", "v_texture", |
2044 "u_texture", | 2048 "uv_texture", "a_texture", "lut_texture", |
2045 "v_texture", | 2049 "yuv_matrix", "yuv_adj", "resource_multiplier", |
2046 "uv_texture", | 2050 "resource_offset", "ya_size", "uv_size", |
2047 "a_texture", | 2051 "alpha", "ya_clamp_rect", "uv_clamp_rect", |
2048 "lut_texture", | |
2049 "resource_multiplier", | |
2050 "resource_offset", | |
2051 "yuv_matrix", | |
2052 "yuv_adj", | |
2053 "alpha", | |
2054 "ya_clamp_rect", | |
2055 "uv_clamp_rect", | |
2056 }; | 2052 }; |
2057 int locations[arraysize(uniforms)]; | 2053 int locations[arraysize(uniforms)]; |
2058 | 2054 |
2059 GetProgramUniformLocations(context, | 2055 GetProgramUniformLocations(context, |
2060 program, | 2056 program, |
2061 arraysize(uniforms), | 2057 arraysize(uniforms), |
2062 uniforms, | 2058 uniforms, |
2063 locations, | 2059 locations, |
2064 base_uniform_index); | 2060 base_uniform_index); |
2065 y_texture_location_ = locations[0]; | 2061 y_texture_location_ = locations[0]; |
2066 if (!use_nv12_) { | 2062 if (!use_nv12_) { |
2067 u_texture_location_ = locations[1]; | 2063 u_texture_location_ = locations[1]; |
2068 v_texture_location_ = locations[2]; | 2064 v_texture_location_ = locations[2]; |
2069 } else { | 2065 } else { |
2070 uv_texture_location_ = locations[3]; | 2066 uv_texture_location_ = locations[3]; |
2071 } | 2067 } |
2072 if (use_alpha_texture_) { | 2068 if (use_alpha_texture_) { |
2073 a_texture_location_ = locations[4]; | 2069 a_texture_location_ = locations[4]; |
2074 } | 2070 } |
2075 if (use_color_lut_) { | 2071 if (use_color_lut_) { |
2076 lut_texture_location_ = locations[5]; | 2072 lut_texture_location_ = locations[5]; |
2077 resource_multiplier_location_ = locations[6]; | |
2078 resource_offset_location_ = locations[7]; | |
2079 } else { | 2073 } else { |
2080 yuv_matrix_location_ = locations[8]; | 2074 yuv_matrix_location_ = locations[6]; |
2081 yuv_adj_location_ = locations[9]; | 2075 yuv_adj_location_ = locations[7]; |
2082 } | 2076 } |
2083 alpha_location_ = locations[10]; | 2077 if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { |
2084 ya_clamp_rect_location_ = locations[11]; | 2078 resource_multiplier_location_ = locations[8]; |
2085 uv_clamp_rect_location_ = locations[12]; | 2079 resource_offset_location_ = locations[9]; |
2080 } else if (highbit_texture_ == HIGHBIT_RG88) { | |
2081 resource_multiplier_location_ = locations[8]; | |
2082 ya_size_location_ = locations[10]; | |
2083 uv_size_location_ = locations[11]; | |
2084 } | |
2085 alpha_location_ = locations[12]; | |
2086 ya_clamp_rect_location_ = locations[13]; | |
2087 uv_clamp_rect_location_ = locations[14]; | |
2086 } | 2088 } |
2087 | 2089 |
2088 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, | 2090 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
2089 SamplerType sampler) const { | 2091 SamplerType sampler) const { |
2090 std::string head = SHADER0([]() { | 2092 std::string head = SHADER0([]() { |
2091 precision mediump float; | 2093 precision mediump float; |
2092 precision mediump int; | 2094 precision mediump int; |
2093 varying TexCoordPrecision vec2 v_yaTexCoord; | 2095 varying TexCoordPrecision vec2 v_yaTexCoord; |
2094 varying TexCoordPrecision vec2 v_uvTexCoord; | 2096 varying TexCoordPrecision vec2 v_uvTexCoord; |
2095 uniform SamplerType y_texture; | 2097 uniform SamplerType y_texture; |
2096 uniform float alpha; | 2098 uniform float alpha; |
2097 uniform vec4 ya_clamp_rect; | 2099 uniform vec4 ya_clamp_rect; |
2098 uniform vec4 uv_clamp_rect; | 2100 uniform vec4 uv_clamp_rect; |
2099 }); | 2101 }); |
2100 | 2102 |
2101 std::string functions = ""; | 2103 std::string functions = ""; |
2104 if (highbit_texture_ == HIGHBIT_RG88) { | |
2105 head += " uniform float resource_multiplier;\n"; | |
2106 head += " uniform vec2 ya_size;\n"; | |
2107 head += " uniform vec2 uv_size;\n"; | |
2108 functions += SHADER0([]() { | |
2109 float GetFloat(SamplerType sampler, vec2 tex_coord) { | |
2110 vec2 rg = TextureLookup(sampler, tex_coord).xy; | |
2111 return ((rg.g * 256.0) + rg.r) * resource_multiplier; | |
hubbe
2016/10/05 18:03:25
Instead of multiplying by resource_multiplier here
dshwang
2016/10/07 12:35:01
Good point! Done.
| |
2112 } | |
2113 | |
2114 float RGTextureLookupBilinear(SamplerType sampler, vec2 tex_coord, | |
2115 vec2 tex_size) { | |
2116 vec2 snap_tex_coord = | |
2117 (floor(tex_coord * tex_size) + vec2(0.5)) / tex_size; | |
2118 vec2 negativeOffset = | |
2119 -vec2(lessThan(tex_coord, snap_tex_coord)) / tex_size; | |
2120 // |snap_tex_coord| points out middle of texel. e.g. 1.5 | |
2121 // |snap_tex_coord| is always less than or equal to |tex_coord|. | |
2122 // When |tex_coord| points 1.6, sample |snap_tex_coord| texel and | |
2123 // |snap_tex_coord| + 1 texel. | |
2124 // When |tex_coord| points 1.4, sample |snap_tex_coord| texel and | |
2125 // |snap_tex_coord| - 1 texel. | |
2126 snap_tex_coord = snap_tex_coord + negativeOffset; | |
2127 vec2 unit_texel = 1.0 / tex_size; | |
2128 float s1 = GetFloat(sampler, snap_tex_coord); | |
2129 float s2 = GetFloat(sampler, snap_tex_coord + vec2(unit_texel.x, 0.)); | |
2130 float s3 = GetFloat(sampler, snap_tex_coord + vec2(0., unit_texel.y)); | |
2131 float s4 = GetFloat(sampler, snap_tex_coord + unit_texel); | |
2132 vec2 f = fract((tex_coord - snap_tex_coord) * tex_size); | |
2133 return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y); | |
2134 } | |
2135 | |
2136 float GetY(vec2 ya_clamped) { | |
2137 return RGTextureLookupBilinear(y_texture, ya_clamped, ya_size); | |
2138 } | |
2139 }); | |
2140 } else { | |
2141 functions += SHADER0([]() { | |
2142 float GetY(vec2 ya_clamped) { | |
2143 return TextureLookup(y_texture, ya_clamped).x; | |
2144 } | |
2145 }); | |
2146 } | |
2147 | |
2102 if (use_nv12_) { | 2148 if (use_nv12_) { |
2103 head += " uniform SamplerType uv_texture;\n"; | 2149 head += " uniform SamplerType uv_texture;\n"; |
2104 functions += SHADER0([]() { | 2150 functions += SHADER0([]() { |
2105 vec2 GetUV(vec2 uv_clamped) { | 2151 vec2 GetUV(vec2 uv_clamped) { |
2106 return TextureLookup(uv_texture, uv_clamped).xy; | 2152 return TextureLookup(uv_texture, uv_clamped).xy; |
2107 } | 2153 } |
2108 }); | 2154 }); |
2109 } else { | 2155 } else { |
2110 head += " uniform SamplerType u_texture;\n"; | 2156 head += " uniform SamplerType u_texture;\n"; |
2111 head += " uniform SamplerType v_texture;\n"; | 2157 head += " uniform SamplerType v_texture;\n"; |
2112 functions += SHADER0([]() { | 2158 if (highbit_texture_ == HIGHBIT_RG88) { |
2113 vec2 GetUV(vec2 uv_clamped) { | 2159 functions += SHADER0([]() { |
2114 return vec2(TextureLookup(u_texture, uv_clamped).x, | 2160 vec2 GetUV(vec2 uv_clamped) { |
2115 TextureLookup(v_texture, uv_clamped).x); | 2161 vec2 uv = |
2116 } | 2162 vec2(RGTextureLookupBilinear(u_texture, uv_clamped, uv_size), |
2117 }); | 2163 RGTextureLookupBilinear(v_texture, uv_clamped, uv_size)); |
2164 return uv; | |
2165 } | |
2166 }); | |
2167 } else { | |
2168 functions += SHADER0([]() { | |
2169 vec2 GetUV(vec2 uv_clamped) { | |
2170 vec2 uv = vec2(TextureLookup(u_texture, uv_clamped).x, | |
2171 TextureLookup(v_texture, uv_clamped).x); | |
2172 return uv; | |
2173 } | |
2174 }); | |
2175 } | |
2118 } | 2176 } |
2119 | 2177 |
2120 if (use_alpha_texture_) { | 2178 if (use_alpha_texture_) { |
2121 head += " uniform SamplerType a_texture;\n"; | 2179 head += " uniform SamplerType a_texture;\n"; |
2122 functions += SHADER0([]() { | 2180 functions += SHADER0([]() { |
2123 float GetAlpha(vec2 ya_clamped) { | 2181 float GetAlpha(vec2 ya_clamped) { |
2124 return alpha * TextureLookup(a_texture, ya_clamped).x; | 2182 return alpha * TextureLookup(a_texture, ya_clamped).x; |
2125 } | 2183 } |
2126 }); | 2184 }); |
2127 } else { | 2185 } else { |
2128 functions += SHADER0([]() { | 2186 functions += SHADER0([]() { |
2129 float GetAlpha(vec2 ya_clamped) { return alpha; } | 2187 float GetAlpha(vec2 ya_clamped) { return alpha; } |
2130 }); | 2188 }); |
2131 } | 2189 } |
2132 | 2190 |
2133 if (use_color_lut_) { | 2191 if (use_color_lut_) { |
2134 head += " uniform sampler2D lut_texture;\n"; | 2192 head += " uniform sampler2D lut_texture;\n"; |
2135 head += " uniform float resource_multiplier;\n"; | |
2136 head += " uniform float resource_offset;\n"; | |
2137 functions += SHADER0([]() { | 2193 functions += SHADER0([]() { |
2138 vec4 LUT(sampler2D sampler, vec3 pos, float size) { | 2194 vec4 LUT(sampler2D sampler, vec3 pos, float size) { |
2139 pos *= size - 1.0; | 2195 pos *= size - 1.0; |
2140 // Select layer | 2196 // Select layer |
2141 float layer = min(floor(pos.x), size - 2.0); | 2197 float layer = min(floor(pos.x), size - 2.0); |
2142 // Compress the yz coordinates so they stay within | 2198 // Compress the yz coordinates so they stay within |
2143 // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) | 2199 // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) |
2144 pos.yz = (pos.yz + vec2(0.5)) / size; | 2200 pos.yz = (pos.yz + vec2(0.5)) / size; |
2145 pos.z = (pos.z + layer) / size; | 2201 pos.z = (pos.z + layer) / size; |
2146 return mix(texture2D(sampler, pos.yz), | 2202 return mix(texture2D(sampler, pos.yz), |
2147 texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), | 2203 texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), |
2148 pos.x - layer); | 2204 pos.x - layer); |
2149 } | 2205 } |
2150 | |
2151 vec3 yuv2rgb(vec3 yuv) { | |
2152 yuv = (yuv - vec3(resource_offset)) * resource_multiplier; | |
2153 return LUT(lut_texture, yuv, 32.0).xyz; | |
2154 } | |
2155 }); | 2206 }); |
2207 if (highbit_texture_ == HIGHBIT_LUMINANCE_F16) { | |
2208 head += " uniform float resource_multiplier;\n"; | |
2209 head += " uniform float resource_offset;\n"; | |
2210 functions += SHADER0([]() { | |
2211 vec3 yuv2rgb(vec3 yuv) { | |
2212 yuv = (yuv - vec3(resource_offset)) * resource_multiplier; | |
2213 return LUT(lut_texture, yuv, 32.0).xyz; | |
2214 } | |
2215 }); | |
2216 } else { | |
2217 functions += SHADER0([]() { | |
2218 vec3 yuv2rgb(vec3 yuv) { return LUT(lut_texture, yuv, 32.0).xyz; } | |
2219 }); | |
2220 } | |
2156 } else { | 2221 } else { |
2157 head += " uniform mat3 yuv_matrix;\n"; | 2222 head += " uniform mat3 yuv_matrix;\n"; |
2158 head += " uniform vec3 yuv_adj;\n"; | 2223 head += " uniform vec3 yuv_adj;\n"; |
2159 functions += SHADER0([]() { | 2224 functions += SHADER0([]() { |
2160 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } | 2225 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } |
2161 }); | 2226 }); |
2162 } | 2227 } |
2163 | 2228 |
2164 functions += SHADER0([]() { | 2229 functions += SHADER0([]() { |
2165 void main() { | 2230 void main() { |
2166 vec2 ya_clamped = | 2231 vec2 ya_clamped = |
2167 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); | 2232 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); |
2168 float y_raw = TextureLookup(y_texture, ya_clamped).x; | 2233 float y_raw = GetY(ya_clamped); |
2169 vec2 uv_clamped = | 2234 vec2 uv_clamped = |
2170 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); | 2235 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); |
2171 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); | 2236 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); |
2172 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); | 2237 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); |
2173 } | 2238 } |
2174 }); | 2239 }); |
2175 | 2240 |
2176 return FRAGMENT_SHADER(head, functions); | 2241 return FRAGMENT_SHADER(head, functions); |
2177 } | 2242 } |
2178 | 2243 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2252 void main() { | 2317 void main() { |
2253 vec4 d4 = min(edge_dist[0], edge_dist[1]); | 2318 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
2254 vec2 d2 = min(d4.xz, d4.yw); | 2319 vec2 d2 = min(d4.xz, d4.yw); |
2255 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); | 2320 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
2256 gl_FragColor = color * aa; | 2321 gl_FragColor = color * aa; |
2257 } | 2322 } |
2258 }); | 2323 }); |
2259 } | 2324 } |
2260 | 2325 |
2261 } // namespace cc | 2326 } // namespace cc |
OLD | NEW |