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

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

Issue 2647743002: The great shader refactor: Finish merging YUV shaders (Closed)
Patch Set: Rebase Created 3 years, 11 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') | no next file » | 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 #include <vector> 10 #include <vector>
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 SRC("dummy_varying = dummy_uniform;"); 378 SRC("dummy_varying = dummy_uniform;");
379 } 379 }
380 380
381 source += "}\n"; 381 source += "}\n";
382 return header + source; 382 return header + source;
383 } 383 }
384 384
385 FragmentShader::FragmentShader() {} 385 FragmentShader::FragmentShader() {}
386 386
387 std::string FragmentShader::GetShaderString() const { 387 std::string FragmentShader::GetShaderString() const {
388 // TODO(ccameron): Merge YUV shaders into the main shader generator.
389 std::string source;
390 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV)
391 source = GetShaderStringYUVVideo();
392 else
393 source = GetShaderSource();
394
395 TexCoordPrecision precision = tex_coord_precision_; 388 TexCoordPrecision precision = tex_coord_precision_;
396 // The AA shader values will use TexCoordPrecision. 389 // The AA shader values will use TexCoordPrecision.
397 if (aa_mode_ == USE_AA && precision == TEX_COORD_PRECISION_NA) 390 if (aa_mode_ == USE_AA && precision == TEX_COORD_PRECISION_NA)
398 precision = TEX_COORD_PRECISION_MEDIUM; 391 precision = TEX_COORD_PRECISION_MEDIUM;
399 return SetFragmentTexCoordPrecision( 392 return SetFragmentTexCoordPrecision(
400 precision, 393 precision, SetFragmentSamplerType(
401 SetFragmentSamplerType(sampler_type_, SetBlendModeFunctions(source))); 394 sampler_type_, SetBlendModeFunctions(GetShaderSource())));
402 } 395 }
403 396
404 void FragmentShader::Init(GLES2Interface* context, 397 void FragmentShader::Init(GLES2Interface* context,
405 unsigned program, 398 unsigned program,
406 int* base_uniform_index) { 399 int* base_uniform_index) {
407 // TODO(ccameron): Merge YUV shaders into the main shader generator.
408 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV) {
409 InitYUVVideo(context, program, base_uniform_index);
410 return;
411 }
412
413 std::vector<const char*> uniforms; 400 std::vector<const char*> uniforms;
414 std::vector<int> locations; 401 std::vector<int> locations;
415 if (has_blend_mode()) { 402 if (has_blend_mode()) {
416 uniforms.push_back("s_backdropTexture"); 403 uniforms.push_back("s_backdropTexture");
417 uniforms.push_back("s_originalBackdropTexture"); 404 uniforms.push_back("s_originalBackdropTexture");
418 uniforms.push_back("backdropRect"); 405 uniforms.push_back("backdropRect");
419 } 406 }
420 if (mask_mode_ != NO_MASK) { 407 if (mask_mode_ != NO_MASK) {
421 uniforms.push_back("s_mask"); 408 uniforms.push_back("s_mask");
422 uniforms.push_back("maskTexCoordScale"); 409 uniforms.push_back("maskTexCoordScale");
(...skipping 18 matching lines...) Expand all
441 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) 428 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV)
442 uniforms.push_back("uv_texture"); 429 uniforms.push_back("uv_texture");
443 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) { 430 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
444 uniforms.push_back("u_texture"); 431 uniforms.push_back("u_texture");
445 uniforms.push_back("v_texture"); 432 uniforms.push_back("v_texture");
446 } 433 }
447 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) 434 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE)
448 uniforms.push_back("a_texture"); 435 uniforms.push_back("a_texture");
449 uniforms.push_back("ya_clamp_rect"); 436 uniforms.push_back("ya_clamp_rect");
450 uniforms.push_back("uv_clamp_rect"); 437 uniforms.push_back("uv_clamp_rect");
451 uniforms.push_back("yuv_matrix"); 438 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
452 uniforms.push_back("yuv_adj"); 439 uniforms.push_back("lut_texture");
440 uniforms.push_back("lut_size");
441 uniforms.push_back("resource_multiplier");
442 uniforms.push_back("resource_offset");
443 } else {
444 uniforms.push_back("yuv_matrix");
445 uniforms.push_back("yuv_adj");
446 }
453 break; 447 break;
454 case INPUT_COLOR_SOURCE_UNIFORM: 448 case INPUT_COLOR_SOURCE_UNIFORM:
455 uniforms.push_back("color"); 449 uniforms.push_back("color");
456 break; 450 break;
457 } 451 }
458 452
459 locations.resize(uniforms.size()); 453 locations.resize(uniforms.size());
460 454
461 GetProgramUniformLocations(context, program, uniforms.size(), uniforms.data(), 455 GetProgramUniformLocations(context, program, uniforms.size(), uniforms.data(),
462 locations.data(), base_uniform_index); 456 locations.data(), base_uniform_index);
(...skipping 28 matching lines...) Expand all
491 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) 485 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV)
492 uv_texture_location_ = locations[index++]; 486 uv_texture_location_ = locations[index++];
493 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) { 487 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
494 u_texture_location_ = locations[index++]; 488 u_texture_location_ = locations[index++];
495 v_texture_location_ = locations[index++]; 489 v_texture_location_ = locations[index++];
496 } 490 }
497 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) 491 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE)
498 a_texture_location_ = locations[index++]; 492 a_texture_location_ = locations[index++];
499 ya_clamp_rect_location_ = locations[index++]; 493 ya_clamp_rect_location_ = locations[index++];
500 uv_clamp_rect_location_ = locations[index++]; 494 uv_clamp_rect_location_ = locations[index++];
501 yuv_matrix_location_ = locations[index++]; 495 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
502 yuv_adj_location_ = locations[index++]; 496 lut_texture_location_ = locations[index++];
497 lut_size_location_ = locations[index++];
498 resource_multiplier_location_ = locations[index++];
499 resource_offset_location_ = locations[index++];
500 } else {
501 yuv_matrix_location_ = locations[index++];
502 yuv_adj_location_ = locations[index++];
503 }
503 break; 504 break;
504 case INPUT_COLOR_SOURCE_UNIFORM: 505 case INPUT_COLOR_SOURCE_UNIFORM:
505 color_location_ = locations[index++]; 506 color_location_ = locations[index++];
506 break; 507 break;
507 } 508 }
508 DCHECK_EQ(index, locations.size()); 509 DCHECK_EQ(index, locations.size());
509 } 510 }
510 511
511 std::string FragmentShader::SetBlendModeFunctions( 512 std::string FragmentShader::SetBlendModeFunctions(
512 const std::string& shader_string) const { 513 const std::string& shader_string) const {
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 DCHECK(!ignore_sampler_type_); 826 DCHECK(!ignore_sampler_type_);
826 } else { 827 } else {
827 SRC("// Texture lookup"); 828 SRC("// Texture lookup");
828 if (ignore_sampler_type_) 829 if (ignore_sampler_type_)
829 SRC("vec4 texColor = texture2D(s_texture, v_texCoord);"); 830 SRC("vec4 texColor = texture2D(s_texture, v_texCoord);");
830 else 831 else
831 SRC("vec4 texColor = TextureLookup(s_texture, v_texCoord);"); 832 SRC("vec4 texColor = TextureLookup(s_texture, v_texCoord);");
832 } 833 }
833 break; 834 break;
834 case INPUT_COLOR_SOURCE_YUV_TEXTURES: 835 case INPUT_COLOR_SOURCE_YUV_TEXTURES:
836 // Compute the clamped texture coordinates for the YA and UV textures.
835 HDR("uniform SamplerType y_texture;"); 837 HDR("uniform SamplerType y_texture;");
838 SRC("// YUV texture lookup and conversion to RGB.");
836 SRC("vec2 ya_clamped ="); 839 SRC("vec2 ya_clamped =");
837 SRC(" max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));"); 840 SRC(" max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));");
838 SRC("vec2 uv_clamped ="); 841 SRC("vec2 uv_clamped =");
839 SRC(" max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));"); 842 SRC(" max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));");
843 // Read the Y and UV or U and V textures into |yuv|.
840 SRC("vec3 yuv;"); 844 SRC("vec3 yuv;");
841 SRC("yuv.x = TextureLookup(y_texture, ya_clamped).x;"); 845 SRC("yuv.x = TextureLookup(y_texture, ya_clamped).x;");
842 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) { 846 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) {
843 HDR("uniform SamplerType uv_texture;"); 847 HDR("uniform SamplerType uv_texture;");
844 SRC("yuv.yz = TextureLookup(uv_texture, uv_clamped).xy;"); 848 SRC("yuv.yz = TextureLookup(uv_texture, uv_clamped).xy;");
845 } 849 }
846 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) { 850 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
847 HDR("uniform SamplerType u_texture;"); 851 HDR("uniform SamplerType u_texture;");
848 HDR("uniform SamplerType v_texture;"); 852 HDR("uniform SamplerType v_texture;");
849 SRC("yuv.y = TextureLookup(u_texture, uv_clamped).x;"); 853 SRC("yuv.y = TextureLookup(u_texture, uv_clamped).x;");
850 SRC("yuv.z = TextureLookup(v_texture, uv_clamped).x;"); 854 SRC("yuv.z = TextureLookup(v_texture, uv_clamped).x;");
851 } 855 }
852 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) 856 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE)
853 HDR("uniform SamplerType a_texture;"); 857 HDR("uniform SamplerType a_texture;");
854 HDR("uniform vec4 ya_clamp_rect;"); 858 HDR("uniform vec4 ya_clamp_rect;");
855 HDR("uniform vec4 uv_clamp_rect;"); 859 HDR("uniform vec4 uv_clamp_rect;");
856 HDR("uniform mat3 yuv_matrix;"); 860 // Convert YUV to RGB.
857 HDR("uniform vec3 yuv_adj;"); 861 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
862 HDR("uniform sampler2D lut_texture;");
863 HDR("uniform float lut_size;");
864 HDR("uniform float resource_multiplier;");
865 HDR("uniform float resource_offset;");
866 HDR("vec4 LUT(sampler2D sampler, vec3 pos, float size) {");
867 HDR(" pos *= size - 1.0;");
868 HDR(" // Select layer");
869 HDR(" float layer = min(floor(pos.z), size - 2.0);");
870 HDR(" // Compress the xy coordinates so they stay within");
871 HDR(" // [0.5 .. 31.5] / N (assuming a LUT size of 17^3)");
872 HDR(" pos.xy = (pos.xy + vec2(0.5)) / size;");
873 HDR(" pos.y = (pos.y + layer) / size;");
874 HDR(" return mix(texture2D(sampler, pos.xy),");
875 HDR(" texture2D(sampler, pos.xy + vec2(0, 1.0 / size)),");
876 HDR(" pos.z - layer);");
877 HDR("}");
878 HDR("vec3 yuv2rgb(vec3 yuv) {");
879 HDR(" yuv = (yuv - vec3(resource_offset)) * resource_multiplier;");
880 HDR(" return LUT(lut_texture, yuv, lut_size).xyz;");
881 HDR("}");
882 } else {
883 HDR("uniform mat3 yuv_matrix;");
884 HDR("uniform vec3 yuv_adj;");
885 HDR("vec3 yuv2rgb(vec3 yuv) {");
886 HDR(" return yuv_matrix * (yuv + yuv_adj);");
887 HDR("}");
888 }
858 HDR("varying TexCoordPrecision vec2 v_yaTexCoord;"); 889 HDR("varying TexCoordPrecision vec2 v_yaTexCoord;");
859 HDR("varying TexCoordPrecision vec2 v_uvTexCoord;"); 890 HDR("varying TexCoordPrecision vec2 v_uvTexCoord;");
860 SRC("vec4 texColor = vec4(yuv_matrix * (yuv + yuv_adj), 1.0);"); 891 SRC("vec4 texColor = vec4(yuv2rgb(yuv), 1.0);");
861 break; 892 break;
862 case INPUT_COLOR_SOURCE_UNIFORM: 893 case INPUT_COLOR_SOURCE_UNIFORM:
863 DCHECK(!ignore_sampler_type_); 894 DCHECK(!ignore_sampler_type_);
864 DCHECK(!has_rgba_fragment_tex_transform_); 895 DCHECK(!has_rgba_fragment_tex_transform_);
865 HDR("uniform vec4 color;"); 896 HDR("uniform vec4 color;");
866 SRC("// Uniform color"); 897 SRC("// Uniform color");
867 SRC("vec4 texColor = color;"); 898 SRC("vec4 texColor = color;");
868 break; 899 break;
869 } 900 }
870 // Apply the color matrix to texColor. 901 // Apply the color matrix to texColor.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 SRC("gl_FragColor = ApplyBlendMode(texColor, maskColor.w);"); 993 SRC("gl_FragColor = ApplyBlendMode(texColor, maskColor.w);");
963 else 994 else
964 SRC("gl_FragColor = ApplyBlendMode(texColor, 0.0);"); 995 SRC("gl_FragColor = ApplyBlendMode(texColor, 0.0);");
965 break; 996 break;
966 } 997 }
967 source += "}\n"; 998 source += "}\n";
968 999
969 return header + source; 1000 return header + source;
970 } 1001 }
971 1002
972 void FragmentShader::InitYUVVideo(GLES2Interface* context,
973 unsigned program,
974 int* base_uniform_index) {
975 static const char* uniforms[] = {
976 "y_texture",
977 "u_texture",
978 "v_texture",
979 "uv_texture",
980 "a_texture",
981 "lut_texture",
982 "resource_multiplier",
983 "resource_offset",
984 "yuv_matrix",
985 "yuv_adj",
986 "alpha",
987 "ya_clamp_rect",
988 "uv_clamp_rect",
989 };
990 int locations[arraysize(uniforms)];
991
992 GetProgramUniformLocations(context,
993 program,
994 arraysize(uniforms),
995 uniforms,
996 locations,
997 base_uniform_index);
998 y_texture_location_ = locations[0];
999 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
1000 u_texture_location_ = locations[1];
1001 v_texture_location_ = locations[2];
1002 }
1003 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) {
1004 uv_texture_location_ = locations[3];
1005 }
1006 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) {
1007 a_texture_location_ = locations[4];
1008 }
1009 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV) {
1010 lut_texture_location_ = locations[5];
1011 resource_multiplier_location_ = locations[6];
1012 resource_offset_location_ = locations[7];
1013 }
1014 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_NONE) {
1015 yuv_matrix_location_ = locations[8];
1016 yuv_adj_location_ = locations[9];
1017 }
1018 alpha_location_ = locations[10];
1019 ya_clamp_rect_location_ = locations[11];
1020 uv_clamp_rect_location_ = locations[12];
1021 }
1022
1023 std::string FragmentShader::GetShaderStringYUVVideo() const {
1024 std::string head = SHADER0([]() {
1025 precision mediump float;
1026 precision mediump int;
1027 varying TexCoordPrecision vec2 v_yaTexCoord;
1028 varying TexCoordPrecision vec2 v_uvTexCoord;
1029 uniform SamplerType y_texture;
1030 uniform float alpha;
1031 uniform vec4 ya_clamp_rect;
1032 uniform vec4 uv_clamp_rect;
1033 });
1034
1035 std::string functions = "";
1036 if (uv_texture_mode_ == UV_TEXTURE_MODE_UV) {
1037 head += " uniform SamplerType uv_texture;\n";
1038 functions += SHADER0([]() {
1039 vec2 GetUV(vec2 uv_clamped) {
1040 return TextureLookup(uv_texture, uv_clamped).xy;
1041 }
1042 });
1043 }
1044 if (uv_texture_mode_ == UV_TEXTURE_MODE_U_V) {
1045 head += " uniform SamplerType u_texture;\n";
1046 head += " uniform SamplerType v_texture;\n";
1047 functions += SHADER0([]() {
1048 vec2 GetUV(vec2 uv_clamped) {
1049 return vec2(TextureLookup(u_texture, uv_clamped).x,
1050 TextureLookup(v_texture, uv_clamped).x);
1051 }
1052 });
1053 }
1054
1055 if (yuv_alpha_texture_mode_ == YUV_HAS_ALPHA_TEXTURE) {
1056 head += " uniform SamplerType a_texture;\n";
1057 functions += SHADER0([]() {
1058 float GetAlpha(vec2 ya_clamped) {
1059 return alpha * TextureLookup(a_texture, ya_clamped).x;
1060 }
1061 });
1062 } else {
1063 functions += SHADER0([]() {
1064 float GetAlpha(vec2 ya_clamped) { return alpha; }
1065 });
1066 }
1067
1068 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV) {
1069 head += " uniform sampler2D lut_texture;\n";
1070 head += " uniform float resource_multiplier;\n";
1071 head += " uniform float resource_offset;\n";
1072 functions += SHADER0([]() {
1073 vec4 LUT(sampler2D sampler, vec3 pos, float size) {
1074 pos *= size - 1.0;
1075 // Select layer
1076 float layer = min(floor(pos.z), size - 2.0);
1077 // Compress the xy coordinates so they stay within
1078 // [0.5 .. 31.5] / 17 (assuming a LUT size of 17^3)
1079 pos.xy = (pos.xy + vec2(0.5)) / size;
1080 pos.y = (pos.y + layer) / size;
1081 return mix(texture2D(sampler, pos.xy),
1082 texture2D(sampler, pos.xy + vec2(0, 1.0 / size)),
1083 pos.z - layer);
1084 }
1085
1086 vec3 yuv2rgb(vec3 yuv) {
1087 yuv = (yuv - vec3(resource_offset)) * resource_multiplier;
1088 return LUT(lut_texture, yuv, 17.0).xyz;
1089 }
1090 });
1091 }
1092 if (color_conversion_mode_ == COLOR_CONVERSION_MODE_NONE) {
1093 head += " uniform mat3 yuv_matrix;\n";
1094 head += " uniform vec3 yuv_adj;\n";
1095 functions += SHADER0([]() {
1096 vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); }
1097 });
1098 }
1099
1100 functions += SHADER0([]() {
1101 void main() {
1102 vec2 ya_clamped =
1103 max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));
1104 float y_raw = TextureLookup(y_texture, ya_clamped).x;
1105 vec2 uv_clamped =
1106 max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));
1107 vec3 yuv = vec3(y_raw, GetUV(uv_clamped));
1108 gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped);
1109 }
1110 });
1111
1112 return head + functions;
1113 }
1114
1115 } // namespace cc 1003 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/shader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698