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 2001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2012 if (mask_for_background()) | 2012 if (mask_for_background()) |
2013 locations->original_backdrop = original_backdrop_location(); | 2013 locations->original_backdrop = original_backdrop_location(); |
2014 } | 2014 } |
2015 | 2015 |
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 alpha_location_(-1), | 2023 alpha_location_(-1), |
2023 yuv_matrix_location_(-1), | 2024 yuv_matrix_location_(-1), |
2024 yuv_adj_location_(-1), | 2025 yuv_adj_location_(-1), |
2025 ya_clamp_rect_location_(-1), | 2026 ya_clamp_rect_location_(-1), |
2026 uv_clamp_rect_location_(-1) {} | 2027 uv_clamp_rect_location_(-1), |
2028 resource_multiplier_location_(-1), | |
2029 resource_offset_location_(-1) {} | |
2027 | 2030 |
2028 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, | 2031 void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, |
2029 bool use_nv12) { | 2032 bool use_nv12, |
2033 bool use_color_lut) { | |
2030 use_alpha_texture_ = use_alpha_texture; | 2034 use_alpha_texture_ = use_alpha_texture; |
2031 use_nv12_ = use_nv12; | 2035 use_nv12_ = use_nv12; |
2036 use_color_lut_ = use_color_lut; | |
2032 } | 2037 } |
2033 | 2038 |
2034 void FragmentShaderYUVVideo::Init(GLES2Interface* context, | 2039 void FragmentShaderYUVVideo::Init(GLES2Interface* context, |
2035 unsigned program, | 2040 unsigned program, |
2036 int* base_uniform_index) { | 2041 int* base_uniform_index) { |
2037 static const char* uniforms[] = { | 2042 static const char* uniforms[] = { |
2038 "y_texture", "u_texture", "v_texture", "uv_texture", "a_texture", | 2043 "y_texture", |
2039 "alpha", "yuv_matrix", "yuv_adj", "ya_clamp_rect", "uv_clamp_rect"}; | 2044 "u_texture", |
2045 "v_texture", | |
2046 "uv_texture", | |
2047 "a_texture", | |
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 }; | |
2040 int locations[arraysize(uniforms)]; | 2057 int locations[arraysize(uniforms)]; |
2041 | 2058 |
2042 GetProgramUniformLocations(context, | 2059 GetProgramUniformLocations(context, |
2043 program, | 2060 program, |
2044 arraysize(uniforms), | 2061 arraysize(uniforms), |
2045 uniforms, | 2062 uniforms, |
2046 locations, | 2063 locations, |
2047 base_uniform_index); | 2064 base_uniform_index); |
2048 y_texture_location_ = locations[0]; | 2065 y_texture_location_ = locations[0]; |
2049 u_texture_location_ = locations[1]; | 2066 if (!use_nv12_) { |
2050 v_texture_location_ = locations[2]; | 2067 u_texture_location_ = locations[1]; |
2051 uv_texture_location_ = locations[3]; | 2068 v_texture_location_ = locations[2]; |
2052 a_texture_location_ = locations[4]; | 2069 } else { |
2053 alpha_location_ = locations[5]; | 2070 uv_texture_location_ = locations[3]; |
2054 yuv_matrix_location_ = locations[6]; | 2071 } |
2055 yuv_adj_location_ = locations[7]; | 2072 if (use_alpha_texture_) { |
2056 ya_clamp_rect_location_ = locations[8]; | 2073 a_texture_location_ = locations[4]; |
2057 uv_clamp_rect_location_ = locations[9]; | 2074 } |
2075 if (use_color_lut_) { | |
2076 lut_texture_location_ = locations[5]; | |
2077 resource_multiplier_location_ = locations[6]; | |
2078 resource_offset_location_ = locations[7]; | |
2079 } else { | |
2080 yuv_matrix_location_ = locations[8]; | |
2081 yuv_adj_location_ = locations[9]; | |
2082 } | |
2083 alpha_location_ = locations[10]; | |
2084 ya_clamp_rect_location_ = locations[11]; | |
2085 uv_clamp_rect_location_ = locations[12]; | |
2058 } | 2086 } |
2059 | 2087 |
2060 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, | 2088 std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, |
2061 SamplerType sampler) const { | 2089 SamplerType sampler) const { |
2062 std::string head = SHADER0([]() { | 2090 std::string head = SHADER0([]() { |
2063 precision mediump float; | 2091 precision mediump float; |
2064 precision mediump int; | 2092 precision mediump int; |
2065 varying TexCoordPrecision vec2 v_yaTexCoord; | 2093 varying TexCoordPrecision vec2 v_yaTexCoord; |
2066 varying TexCoordPrecision vec2 v_uvTexCoord; | 2094 varying TexCoordPrecision vec2 v_uvTexCoord; |
2067 uniform SamplerType y_texture; | 2095 uniform SamplerType y_texture; |
2068 uniform float alpha; | 2096 uniform float alpha; |
2069 uniform vec3 yuv_adj; | |
2070 uniform mat3 yuv_matrix; | |
2071 uniform vec4 ya_clamp_rect; | 2097 uniform vec4 ya_clamp_rect; |
2072 uniform vec4 uv_clamp_rect; | 2098 uniform vec4 uv_clamp_rect; |
2073 }); | 2099 }); |
2100 | |
2101 std::string functions = ""; | |
2074 if (use_nv12_) { | 2102 if (use_nv12_) { |
2075 head += " uniform SamplerType uv_texture;\n"; | 2103 head += " uniform SamplerType uv_texture;\n"; |
2076 } else { | 2104 functions += SHADER0([]() { |
2077 head += " uniform SamplerType u_texture;\n"; | |
2078 head += " uniform SamplerType v_texture;\n"; | |
2079 } | |
2080 if (use_alpha_texture_) { | |
2081 head += " uniform SamplerType a_texture;\n"; | |
2082 } | |
2083 | |
2084 std::string main = SHADER0([]() { | |
2085 void main() { | |
2086 vec2 ya_clamped = | |
2087 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); | |
2088 float y_raw = TextureLookup(y_texture, ya_clamped).x; | |
2089 vec2 uv_clamped = | |
2090 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); | |
2091 vec2 uv_unsigned = GetUV(uv_clamped); | |
2092 vec3 yuv = vec3(y_raw, uv_unsigned) + yuv_adj; | |
2093 vec3 rgb = yuv_matrix * yuv; | |
2094 gl_FragColor = vec4(rgb, 1.0) * GetAlpha(ya_clamped); | |
2095 } | |
2096 }); | |
2097 | |
2098 std::string get_uv; | |
2099 if (use_nv12_) { | |
2100 get_uv = SHADER0([]() { | |
2101 vec2 GetUV(vec2 uv_clamped) { | 2105 vec2 GetUV(vec2 uv_clamped) { |
2102 return TextureLookup(uv_texture, uv_clamped).xy; | 2106 return TextureLookup(uv_texture, uv_clamped).xy; |
2103 } | 2107 } |
2104 }); | 2108 }); |
2105 } else { | 2109 } else { |
2106 get_uv = SHADER0([]() { | 2110 head += " uniform SamplerType u_texture;\n"; |
2111 head += " uniform SamplerType v_texture;\n"; | |
2112 functions += SHADER0([]() { | |
2107 vec2 GetUV(vec2 uv_clamped) { | 2113 vec2 GetUV(vec2 uv_clamped) { |
2108 return vec2(TextureLookup(u_texture, uv_clamped).x, | 2114 return vec2(TextureLookup(u_texture, uv_clamped).x, |
2109 TextureLookup(v_texture, uv_clamped).x); | 2115 TextureLookup(v_texture, uv_clamped).x); |
2110 } | 2116 } |
2111 }); | 2117 }); |
2112 } | 2118 } |
2113 | 2119 |
2114 std::string get_alpha; | |
2115 if (use_alpha_texture_) { | 2120 if (use_alpha_texture_) { |
2116 get_alpha = SHADER0([]() { | 2121 head += " uniform SamplerType a_texture;\n"; |
2122 functions += SHADER0([]() { | |
2117 float GetAlpha(vec2 ya_clamped) { | 2123 float GetAlpha(vec2 ya_clamped) { |
2118 return alpha * TextureLookup(a_texture, ya_clamped).x; | 2124 return alpha * TextureLookup(a_texture, ya_clamped).x; |
2119 } | 2125 } |
2120 }); | 2126 }); |
2121 } else { | 2127 } else { |
2122 get_alpha = SHADER0([]() { | 2128 functions += SHADER0([]() { |
2123 float GetAlpha(vec2 ya_clamped) { return alpha; } | 2129 float GetAlpha(vec2 ya_clamped) { return alpha; } |
2124 }); | 2130 }); |
2125 } | 2131 } |
2126 | 2132 |
2127 return FRAGMENT_SHADER(head, get_uv + get_alpha + main); | 2133 if (use_color_lut_) { |
2134 head += " uniform sampler2D lut_texture;\n"; | |
2135 head += " uniform float resource_multiplier;\n"; | |
2136 head += " uniform float resource_offset;\n"; | |
2137 functions += SHADER0([]() { | |
2138 vec4 LUT(sampler2D sampler, vec3 pos, float size) { | |
ccameron
2016/08/08 18:45:07
With sampler3D, this just becomes texture3D(sample
hubbe
2016/08/08 19:45:38
Agreed, but it's a performance minefield...
textur
| |
2139 pos *= size - 1.0; | |
2140 // Select layer | |
2141 float layer = min(floor(pos.x), size - 2.0); | |
2142 // Compress the yz coordinates so they stay within | |
2143 // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) | |
2144 pos.yz = (pos.yz + vec2(0.5)) / size; | |
2145 pos.z = (pos.z + layer) / size; | |
2146 return mix(texture2D(sampler, pos.yz), | |
2147 texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), | |
2148 pos.x - layer); | |
2149 } | |
2150 | |
2151 vec3 yuv2rgb(vec3 yuv) { | |
2152 yuv = yuv * resource_multiplier - vec3(resource_offset); | |
2153 return LUT(lut_texture, yuv, 32.0).xyz; | |
2154 } | |
2155 }); | |
2156 } else { | |
2157 head += " uniform mat3 yuv_matrix;\n"; | |
2158 head += " uniform vec3 yuv_adj;\n"; | |
2159 functions += SHADER0([]() { | |
2160 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } | |
2161 }); | |
2162 } | |
2163 | |
2164 functions += SHADER0([]() { | |
2165 void main() { | |
2166 vec2 ya_clamped = | |
2167 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); | |
2168 float y_raw = TextureLookup(y_texture, ya_clamped).x; | |
2169 vec2 uv_clamped = | |
2170 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); | |
2171 vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); | |
2172 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); | |
2173 } | |
2174 }); | |
2175 | |
2176 return FRAGMENT_SHADER(head, functions); | |
2128 } | 2177 } |
2129 | 2178 |
2130 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) { | 2179 FragmentShaderColor::FragmentShaderColor() : color_location_(-1) { |
2131 } | 2180 } |
2132 | 2181 |
2133 void FragmentShaderColor::Init(GLES2Interface* context, | 2182 void FragmentShaderColor::Init(GLES2Interface* context, |
2134 unsigned program, | 2183 unsigned program, |
2135 int* base_uniform_index) { | 2184 int* base_uniform_index) { |
2136 static const char* uniforms[] = { | 2185 static const char* uniforms[] = { |
2137 "color", | 2186 "color", |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2203 void main() { | 2252 void main() { |
2204 vec4 d4 = min(edge_dist[0], edge_dist[1]); | 2253 vec4 d4 = min(edge_dist[0], edge_dist[1]); |
2205 vec2 d2 = min(d4.xz, d4.yw); | 2254 vec2 d2 = min(d4.xz, d4.yw); |
2206 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); | 2255 float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0); |
2207 gl_FragColor = color * aa; | 2256 gl_FragColor = color * aa; |
2208 } | 2257 } |
2209 }); | 2258 }); |
2210 } | 2259 } |
2211 | 2260 |
2212 } // namespace cc | 2261 } // namespace cc |
OLD | NEW |