| 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 2010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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_clamp_rect_location_(-1), | 2026 ya_clamp_rect_location_(-1), |
| 2027 uv_clamp_rect_location_(-1), | 2027 uv_clamp_rect_location_(-1), |
| 2028 resource_multiplier_location_(-1), | 2028 resource_multiplier_location_(-1), |
| 2029 resource_offset_location_(-1) {} | 2029 resource_offset_location_(-1) {} |
| 2030 | 2030 |
| 2031 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, | 2031 void FragmentShaderYUVVideo::SetFeatures(SamplerType sampler, |
| 2032 bool use_alpha_texture, |
| 2032 bool use_nv12, | 2033 bool use_nv12, |
| 2033 bool use_color_lut) { | 2034 bool use_color_lut) { |
| 2035 sampler_ = sampler; |
| 2034 use_alpha_texture_ = use_alpha_texture; | 2036 use_alpha_texture_ = use_alpha_texture; |
| 2035 use_nv12_ = use_nv12; | 2037 use_nv12_ = use_nv12; |
| 2036 use_color_lut_ = use_color_lut; | 2038 use_color_lut_ = use_color_lut; |
| 2037 } | 2039 } |
| 2038 | 2040 |
| 2039 void FragmentShaderYUVVideo::Init(GLES2Interface* context, | 2041 void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
| 2040 unsigned program, | 2042 unsigned program, |
| 2041 int* base_uniform_index) { | 2043 int* base_uniform_index) { |
| 2042 static const char* uniforms[] = { | 2044 static const char* uniforms[] = { |
| 2043 "y_texture", | 2045 "y_texture", |
| 2044 "u_texture", | 2046 "u_texture", |
| 2045 "v_texture", | 2047 "v_texture", |
| 2046 "uv_texture", | 2048 "uv_texture", |
| 2047 "a_texture", | 2049 "a_texture", |
| 2048 "lut_texture", | 2050 "lut_texture", |
| 2049 "resource_multiplier", | 2051 "resource_multiplier", |
| 2050 "resource_offset", | 2052 "resource_offset", |
| 2051 "yuv_matrix", | 2053 "yuv_matrix", |
| 2052 "yuv_adj", | 2054 "yuv_adj", |
| 2055 "ya_size", |
| 2056 "uv_subsampling_factor", |
| 2053 "alpha", | 2057 "alpha", |
| 2054 "ya_clamp_rect", | 2058 "ya_clamp_rect", |
| 2055 "uv_clamp_rect", | 2059 "uv_clamp_rect", |
| 2056 }; | 2060 }; |
| 2057 int locations[arraysize(uniforms)]; | 2061 int locations[arraysize(uniforms)]; |
| 2058 | 2062 |
| 2059 GetProgramUniformLocations(context, | 2063 GetProgramUniformLocations(context, |
| 2060 program, | 2064 program, |
| 2061 arraysize(uniforms), | 2065 arraysize(uniforms), |
| 2062 uniforms, | 2066 uniforms, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2073 a_texture_location_ = locations[4]; | 2077 a_texture_location_ = locations[4]; |
| 2074 } | 2078 } |
| 2075 if (use_color_lut_) { | 2079 if (use_color_lut_) { |
| 2076 lut_texture_location_ = locations[5]; | 2080 lut_texture_location_ = locations[5]; |
| 2077 resource_multiplier_location_ = locations[6]; | 2081 resource_multiplier_location_ = locations[6]; |
| 2078 resource_offset_location_ = locations[7]; | 2082 resource_offset_location_ = locations[7]; |
| 2079 } else { | 2083 } else { |
| 2080 yuv_matrix_location_ = locations[8]; | 2084 yuv_matrix_location_ = locations[8]; |
| 2081 yuv_adj_location_ = locations[9]; | 2085 yuv_adj_location_ = locations[9]; |
| 2082 } | 2086 } |
| 2083 alpha_location_ = locations[10]; | 2087 if (sampler_ != SAMPLER_TYPE_2D_RECT) { |
| 2084 ya_clamp_rect_location_ = locations[11]; | 2088 ya_size_location_ = locations[10]; |
| 2085 uv_clamp_rect_location_ = locations[12]; | 2089 } else { |
| 2090 uv_subsampling_factor_location_ = locations[11]; |
| 2091 } |
| 2092 alpha_location_ = locations[12]; |
| 2093 ya_clamp_rect_location_ = locations[13]; |
| 2094 uv_clamp_rect_location_ = locations[14]; |
| 2086 } | 2095 } |
| 2087 | 2096 |
| 2088 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, | 2097 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
| 2089 SamplerType sampler) const { | 2098 SamplerType sampler) const { |
| 2090 std::string head = SHADER0([]() { | 2099 std::string head = SHADER0([]() { |
| 2091 precision mediump float; | 2100 precision mediump float; |
| 2092 precision mediump int; | 2101 precision mediump int; |
| 2093 varying TexCoordPrecision vec2 v_yaTexCoord; | 2102 varying TexCoordPrecision vec2 v_yaTexCoord; |
| 2094 varying TexCoordPrecision vec2 v_uvTexCoord; | 2103 varying TexCoordPrecision vec2 v_uvTexCoord; |
| 2095 uniform SamplerType y_texture; | 2104 uniform SamplerType y_texture; |
| 2096 uniform float alpha; | 2105 uniform float alpha; |
| 2097 uniform vec4 ya_clamp_rect; | 2106 uniform vec4 ya_clamp_rect; |
| 2098 uniform vec4 uv_clamp_rect; | 2107 uniform vec4 uv_clamp_rect; |
| 2099 }); | 2108 }); |
| 2109 // SHADER0 cannot handle #define |
| 2110 head += "\n"; |
| 2111 head += " #define PLANE_TYPE int\n"; |
| 2112 head += " #define YA 1\n"; |
| 2113 head += " #define UV 2\n"; |
| 2100 | 2114 |
| 2101 std::string functions = ""; | 2115 std::string functions = SHADER0([]() { |
| 2116 vec2 TextureLookupBilinearInternal(SamplerType sampler, vec2 snap_tex_coord, |
| 2117 vec2 unit_texel, vec2 factor) { |
| 2118 vec2 s1 = TextureLookup(sampler, snap_tex_coord).xy; |
| 2119 vec2 s2 = |
| 2120 TextureLookup(sampler, snap_tex_coord + vec2(unit_texel.x, 0.)).xy; |
| 2121 vec2 s3 = |
| 2122 TextureLookup(sampler, snap_tex_coord + vec2(0., unit_texel.y)).xy; |
| 2123 vec2 s4 = TextureLookup(sampler, snap_tex_coord + unit_texel).xy; |
| 2124 return mix(mix(s1, s2, factor.x), mix(s3, s4, factor.x), factor.y); |
| 2125 } |
| 2126 }); |
| 2127 if (sampler_ == SAMPLER_TYPE_2D_RECT) { |
| 2128 head += " uniform vec2 uv_subsampling_factor;\n"; |
| 2129 functions += SHADER0([]() { |
| 2130 vec2 TextureLookupBilinear(SamplerType sampler, vec2 tex_coord, |
| 2131 PLANE_TYPE type) { |
| 2132 vec2 ya_tex_coord = tex_coord; |
| 2133 if (type == UV) { |
| 2134 ya_tex_coord = tex_coord / uv_subsampling_factor; |
| 2135 } |
| 2136 vec2 unnorm_tex_coord = ya_tex_coord - vec2(0.5); |
| 2137 vec2 f = fract(unnorm_tex_coord); |
| 2138 vec2 texel_offset = floor(unnorm_tex_coord) - floor(ya_tex_coord); |
| 2139 vec2 unit_texel = vec2(1.); |
| 2140 if (type == UV) { |
| 2141 texel_offset = texel_offset * uv_subsampling_factor; |
| 2142 unit_texel = unit_texel * uv_subsampling_factor; |
| 2143 } |
| 2144 vec2 snap_tex_coord = |
| 2145 floor(tex_coord) + (unit_texel * 0.5) + texel_offset; |
| 2146 return TextureLookupBilinearInternal(sampler, snap_tex_coord, |
| 2147 unit_texel, f); |
| 2148 } |
| 2149 }); |
| 2150 } else { |
| 2151 head += " uniform vec2 ya_size;\n"; |
| 2152 functions += SHADER0([]() { |
| 2153 // refer to Mesa sample_2d_linear() in s_texfilter.c |
| 2154 // https://cs.chromium.org/chromium/src/third_party/mesa/src/src/mesa/swra
st/s_texfilter.c?q=sample_2d_linear&sq=package:chromium |
| 2155 // |
| 2156 // This shader needs a custom bilinear filter because U plane can be |
| 2157 // smaller than Y plane. |
| 2158 // For example, look at the following figures. When the current fragment |
| 2159 // samples the middle point of (3, 3) texel of Y texture, it points out |
| 2160 // upper left of (1, 1) texel of U texture. The default GL_LINEAR samples |
| 2161 // 4 texels of U plane, while it samples only (3, 3) texel of Y plane. |
| 2162 // TextureLookupBilinear() samples U plane with Y plane fraction to |
| 2163 // sample like Y plane. |
| 2164 // Y 4x4 U 2x2 U sampling by GL_LINEAR |
| 2165 // +-+-+-+-+ +--+--+ +--+--+ |
| 2166 // | | | | | | | | | | | |
| 2167 // +-------+ | | | | +--++ |
| 2168 // | | | | | +-----+ +-----| |
| 2169 // +-------+ | |· | | ||·|| |
| 2170 // | | |·| | | | | | +--+| |
| 2171 // +-------+ +--+--+ +-----+ |
| 2172 // | | | | | |
| 2173 // +-+-+-+-+ |
| 2174 vec2 TextureLookupBilinear(SamplerType sampler, vec2 tex_coord, |
| 2175 PLANE_TYPE type) { |
| 2176 vec2 unit_texel = 1.0 / ya_size; |
| 2177 vec2 unnorm_tex_coord = (tex_coord * ya_size) - vec2(0.5); |
| 2178 vec2 f = fract(unnorm_tex_coord); |
| 2179 vec2 snap_tex_coord = (floor(unnorm_tex_coord) + vec2(0.5)) / ya_size; |
| 2180 return TextureLookupBilinearInternal(sampler, snap_tex_coord, |
| 2181 unit_texel, f); |
| 2182 } |
| 2183 }); |
| 2184 } |
| 2102 if (use_nv12_) { | 2185 if (use_nv12_) { |
| 2103 head += " uniform SamplerType uv_texture;\n"; | 2186 head += " uniform SamplerType uv_texture;\n"; |
| 2104 functions += SHADER0([]() { | 2187 functions += SHADER0([]() { |
| 2105 vec2 GetUV(vec2 uv_clamped) { | 2188 vec2 GetUV(vec2 uv_clamped) { |
| 2106 return TextureLookup(uv_texture, uv_clamped).xy; | 2189 return TextureLookupBilinear(uv_texture, uv_clamped, UV); |
| 2107 } | 2190 } |
| 2108 }); | 2191 }); |
| 2109 } else { | 2192 } else { |
| 2110 head += " uniform SamplerType u_texture;\n"; | 2193 head += " uniform SamplerType u_texture;\n"; |
| 2111 head += " uniform SamplerType v_texture;\n"; | 2194 head += " uniform SamplerType v_texture;\n"; |
| 2112 functions += SHADER0([]() { | 2195 functions += SHADER0([]() { |
| 2113 vec2 GetUV(vec2 uv_clamped) { | 2196 vec2 GetUV(vec2 uv_clamped) { |
| 2114 return vec2(TextureLookup(u_texture, uv_clamped).x, | 2197 return vec2(TextureLookupBilinear(u_texture, uv_clamped, UV).x, |
| 2115 TextureLookup(v_texture, uv_clamped).x); | 2198 TextureLookupBilinear(v_texture, uv_clamped, UV).x); |
| 2116 } | 2199 } |
| 2117 }); | 2200 }); |
| 2118 } | 2201 } |
| 2119 | 2202 |
| 2120 if (use_alpha_texture_) { | 2203 if (use_alpha_texture_) { |
| 2121 head += " uniform SamplerType a_texture;\n"; | 2204 head += " uniform SamplerType a_texture;\n"; |
| 2122 functions += SHADER0([]() { | 2205 functions += SHADER0([]() { |
| 2123 float GetAlpha(vec2 ya_clamped) { | 2206 float GetAlpha(vec2 ya_clamped) { |
| 2124 return alpha * TextureLookup(a_texture, ya_clamped).x; | 2207 return alpha * TextureLookupBilinear(a_texture, ya_clamped, YA).x; |
| 2125 } | 2208 } |
| 2126 }); | 2209 }); |
| 2127 } else { | 2210 } else { |
| 2128 functions += SHADER0([]() { | 2211 functions += SHADER0([]() { |
| 2129 float GetAlpha(vec2 ya_clamped) { return alpha; } | 2212 float GetAlpha(vec2 ya_clamped) { return alpha; } |
| 2130 }); | 2213 }); |
| 2131 } | 2214 } |
| 2132 | 2215 |
| 2133 if (use_color_lut_) { | 2216 if (use_color_lut_) { |
| 2134 head += " uniform sampler2D lut_texture;\n"; | 2217 head += " uniform sampler2D lut_texture;\n"; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2158 head += " uniform vec3 yuv_adj;\n"; | 2241 head += " uniform vec3 yuv_adj;\n"; |
| 2159 functions += SHADER0([]() { | 2242 functions += SHADER0([]() { |
| 2160 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } | 2243 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } |
| 2161 }); | 2244 }); |
| 2162 } | 2245 } |
| 2163 | 2246 |
| 2164 functions += SHADER0([]() { | 2247 functions += SHADER0([]() { |
| 2165 void main() { | 2248 void main() { |
| 2166 vec2 ya_clamped = | 2249 vec2 ya_clamped = |
| 2167 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); | 2250 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); |
| 2168 float y_raw = TextureLookup(y_texture, ya_clamped).x; | 2251 float y_raw = TextureLookupBilinear(y_texture, ya_clamped, YA).x; |
| 2169 vec2 uv_clamped = | 2252 vec2 uv_clamped = |
| 2170 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); | 2253 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); |
| 2171 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); | 2254 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); |
| 2172 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); | 2255 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); |
| 2173 } | 2256 } |
| 2174 }); | 2257 }); |
| 2175 | 2258 |
| 2176 return FRAGMENT_SHADER(head, functions); | 2259 return FRAGMENT_SHADER(head, functions); |
| 2177 } | 2260 } |
| 2178 | 2261 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2252 void main() { | 2335 void main() { |
| 2253 vec4 d4 = min(edge_dist[0], edge_dist[1]); | 2336 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
| 2254 vec2 d2 = min(d4.xz, d4.yw); | 2337 vec2 d2 = min(d4.xz, d4.yw); |
| 2255 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); | 2338 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
| 2256 gl_FragColor = color * aa; | 2339 gl_FragColor = color * aa; |
| 2257 } | 2340 } |
| 2258 }); | 2341 }); |
| 2259 } | 2342 } |
| 2260 | 2343 |
| 2261 } // namespace cc | 2344 } // namespace cc |
| OLD | NEW |