Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: cc/output/shader.cc

Issue 2400033004: cc: custom bilinear filtering for YUV quad.
Patch Set: fix SAMPLER_TYPE_2D_RECT logic Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/output/shader.h ('k') | cc/test/data/intersecting_blue_green_squares_video.png » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/output/shader.h ('k') | cc/test/data/intersecting_blue_green_squares_video.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698