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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/shader.cc
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index b5d163862d14e010aa19d5bcd083278366ed34b4..a34ce07bad174bcf9a20f44831f26a2681b267be 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -2028,9 +2028,11 @@ FragmentShaderYUVVideo::FragmentShaderYUVVideo()
resource_multiplier_location_(-1),
resource_offset_location_(-1) {}
-void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture,
+void FragmentShaderYUVVideo::SetFeatures(SamplerType sampler,
+ bool use_alpha_texture,
bool use_nv12,
bool use_color_lut) {
+ sampler_ = sampler;
use_alpha_texture_ = use_alpha_texture;
use_nv12_ = use_nv12;
use_color_lut_ = use_color_lut;
@@ -2050,6 +2052,8 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context,
"resource_offset",
"yuv_matrix",
"yuv_adj",
+ "ya_size",
+ "uv_subsampling_factor",
"alpha",
"ya_clamp_rect",
"uv_clamp_rect",
@@ -2080,9 +2084,14 @@ void FragmentShaderYUVVideo::Init(GLES2Interface* context,
yuv_matrix_location_ = locations[8];
yuv_adj_location_ = locations[9];
}
- alpha_location_ = locations[10];
- ya_clamp_rect_location_ = locations[11];
- uv_clamp_rect_location_ = locations[12];
+ if (sampler_ != SAMPLER_TYPE_2D_RECT) {
+ ya_size_location_ = locations[10];
+ } else {
+ uv_subsampling_factor_location_ = locations[11];
+ }
+ alpha_location_ = locations[12];
+ ya_clamp_rect_location_ = locations[13];
+ uv_clamp_rect_location_ = locations[14];
}
std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
@@ -2097,13 +2106,87 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
uniform vec4 ya_clamp_rect;
uniform vec4 uv_clamp_rect;
});
-
- std::string functions = "";
+ // SHADER0 cannot handle #define
+ head += "\n";
+ head += " #define PLANE_TYPE int\n";
+ head += " #define YA 1\n";
+ head += " #define UV 2\n";
+
+ std::string functions = SHADER0([]() {
+ vec2 TextureLookupBilinearInternal(SamplerType sampler, vec2 snap_tex_coord,
+ vec2 unit_texel, vec2 factor) {
+ vec2 s1 = TextureLookup(sampler, snap_tex_coord).xy;
+ vec2 s2 =
+ TextureLookup(sampler, snap_tex_coord + vec2(unit_texel.x, 0.)).xy;
+ vec2 s3 =
+ TextureLookup(sampler, snap_tex_coord + vec2(0., unit_texel.y)).xy;
+ vec2 s4 = TextureLookup(sampler, snap_tex_coord + unit_texel).xy;
+ return mix(mix(s1, s2, factor.x), mix(s3, s4, factor.x), factor.y);
+ }
+ });
+ if (sampler_ == SAMPLER_TYPE_2D_RECT) {
+ head += " uniform vec2 uv_subsampling_factor;\n";
+ functions += SHADER0([]() {
+ vec2 TextureLookupBilinear(SamplerType sampler, vec2 tex_coord,
+ PLANE_TYPE type) {
+ vec2 ya_tex_coord = tex_coord;
+ if (type == UV) {
+ ya_tex_coord = tex_coord / uv_subsampling_factor;
+ }
+ vec2 unnorm_tex_coord = ya_tex_coord - vec2(0.5);
+ vec2 f = fract(unnorm_tex_coord);
+ vec2 texel_offset = floor(unnorm_tex_coord) - floor(ya_tex_coord);
+ vec2 unit_texel = vec2(1.);
+ if (type == UV) {
+ texel_offset = texel_offset * uv_subsampling_factor;
+ unit_texel = unit_texel * uv_subsampling_factor;
+ }
+ vec2 snap_tex_coord =
+ floor(tex_coord) + (unit_texel * 0.5) + texel_offset;
+ return TextureLookupBilinearInternal(sampler, snap_tex_coord,
+ unit_texel, f);
+ }
+ });
+ } else {
+ head += " uniform vec2 ya_size;\n";
+ functions += SHADER0([]() {
+ // refer to Mesa sample_2d_linear() in s_texfilter.c
+ // https://cs.chromium.org/chromium/src/third_party/mesa/src/src/mesa/swrast/s_texfilter.c?q=sample_2d_linear&sq=package:chromium
+ //
+ // This shader needs a custom bilinear filter because U plane can be
+ // smaller than Y plane.
+ // For example, look at the following figures. When the current fragment
+ // samples the middle point of (3, 3) texel of Y texture, it points out
+ // upper left of (1, 1) texel of U texture. The default GL_LINEAR samples
+ // 4 texels of U plane, while it samples only (3, 3) texel of Y plane.
+ // TextureLookupBilinear() samples U plane with Y plane fraction to
+ // sample like Y plane.
+ // Y 4x4 U 2x2 U sampling by GL_LINEAR
+ // +-+-+-+-+ +--+--+ +--+--+
+ // | | | | | | | | | | |
+ // +-------+ | | | | +--++
+ // | | | | | +-----+ +-----|
+ // +-------+ | |· | | ||·||
+ // | | |·| | | | | | +--+|
+ // +-------+ +--+--+ +-----+
+ // | | | | |
+ // +-+-+-+-+
+ vec2 TextureLookupBilinear(SamplerType sampler, vec2 tex_coord,
+ PLANE_TYPE type) {
+ vec2 unit_texel = 1.0 / ya_size;
+ vec2 unnorm_tex_coord = (tex_coord * ya_size) - vec2(0.5);
+ vec2 f = fract(unnorm_tex_coord);
+ vec2 snap_tex_coord = (floor(unnorm_tex_coord) + vec2(0.5)) / ya_size;
+ return TextureLookupBilinearInternal(sampler, snap_tex_coord,
+ unit_texel, f);
+ }
+ });
+ }
if (use_nv12_) {
head += " uniform SamplerType uv_texture;\n";
functions += SHADER0([]() {
vec2 GetUV(vec2 uv_clamped) {
- return TextureLookup(uv_texture, uv_clamped).xy;
+ return TextureLookupBilinear(uv_texture, uv_clamped, UV);
}
});
} else {
@@ -2111,8 +2194,8 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
head += " uniform SamplerType v_texture;\n";
functions += SHADER0([]() {
vec2 GetUV(vec2 uv_clamped) {
- return vec2(TextureLookup(u_texture, uv_clamped).x,
- TextureLookup(v_texture, uv_clamped).x);
+ return vec2(TextureLookupBilinear(u_texture, uv_clamped, UV).x,
+ TextureLookupBilinear(v_texture, uv_clamped, UV).x);
}
});
}
@@ -2121,7 +2204,7 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
head += " uniform SamplerType a_texture;\n";
functions += SHADER0([]() {
float GetAlpha(vec2 ya_clamped) {
- return alpha * TextureLookup(a_texture, ya_clamped).x;
+ return alpha * TextureLookupBilinear(a_texture, ya_clamped, YA).x;
}
});
} else {
@@ -2165,7 +2248,7 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
void main() {
vec2 ya_clamped =
max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));
- float y_raw = TextureLookup(y_texture, ya_clamped).x;
+ float y_raw = TextureLookupBilinear(y_texture, ya_clamped, YA).x;
vec2 uv_clamped =
max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));
vec3 yuv = vec3(y_raw, GetUV(uv_clamped));
« 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