Commit 2d4b91cc authored by ccameron's avatar ccameron Committed by Commit bot

The great shader refactor: Use ProgramKey to initialize shaders

Replace the SetSubclassProperties method with CheckSubclassProperties,
which checks the properties that were set, and checks that all others
are the default values.

The next step is to delete all of the sub-classes (including the
just-added CheckSubclassProperties functions).

BUG=667966
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel

Review-Url: https://codereview.chromium.org/2628713002
Cr-Commit-Position: refs/heads/master@{#443029}
parent 9b559c69
This diff is collapsed.
...@@ -13,6 +13,96 @@ using gpu::gles2::GLES2Interface; ...@@ -13,6 +13,96 @@ using gpu::gles2::GLES2Interface;
namespace cc { namespace cc {
ProgramKey::ProgramKey() = default;
ProgramKey::ProgramKey(const ProgramKey& other) = default;
ProgramKey::~ProgramKey() = default;
bool ProgramKey::operator==(const ProgramKey& other) const {
return type_ == other.type_ && precision_ == other.precision_ &&
sampler_ == other.sampler_ && blend_mode_ == other.blend_mode_ &&
aa_mode_ == other.aa_mode_ && swizzle_mode_ == other.swizzle_mode_ &&
is_opaque_ == other.is_opaque_ &&
premultiplied_alpha_ == other.premultiplied_alpha_ &&
has_background_color_ == other.has_background_color_ &&
mask_mode_ == other.mask_mode_ &&
mask_for_background_ == other.mask_for_background_ &&
has_color_matrix_ == other.has_color_matrix_;
}
// static
ProgramKey ProgramKey::DebugBorder() {
ProgramKey result;
result.type_ = PROGRAM_TYPE_DEBUG_BORDER;
return result;
}
// static
ProgramKey ProgramKey::SolidColor(AAMode aa_mode) {
ProgramKey result;
result.type_ = PROGRAM_TYPE_SOLID_COLOR;
result.aa_mode_ = aa_mode;
return result;
}
// static
ProgramKey ProgramKey::Tile(TexCoordPrecision precision,
SamplerType sampler,
AAMode aa_mode,
SwizzleMode swizzle_mode,
bool is_opaque) {
ProgramKey result;
result.type_ = PROGRAM_TYPE_TILE;
result.precision_ = precision;
result.sampler_ = sampler;
result.aa_mode_ = aa_mode;
result.swizzle_mode_ = swizzle_mode;
result.is_opaque_ = is_opaque;
return result;
}
// static
ProgramKey ProgramKey::Texture(TexCoordPrecision precision,
SamplerType sampler,
PremultipliedAlphaMode premultiplied_alpha,
bool has_background_color) {
ProgramKey result;
result.type_ = PROGRAM_TYPE_TEXTURE;
result.precision_ = precision;
result.sampler_ = sampler;
result.premultiplied_alpha_ = premultiplied_alpha;
result.has_background_color_ = has_background_color;
return result;
}
// static
ProgramKey ProgramKey::RenderPass(TexCoordPrecision precision,
SamplerType sampler,
BlendMode blend_mode,
AAMode aa_mode,
MaskMode mask_mode,
bool mask_for_background,
bool has_color_matrix) {
ProgramKey result;
result.type_ = PROGRAM_TYPE_RENDER_PASS;
result.precision_ = precision;
result.sampler_ = sampler;
result.blend_mode_ = blend_mode;
result.aa_mode_ = aa_mode;
result.mask_mode_ = mask_mode;
result.mask_for_background_ = mask_for_background;
result.has_color_matrix_ = has_color_matrix;
return result;
}
// static
ProgramKey ProgramKey::VideoStream(TexCoordPrecision precision) {
ProgramKey result;
result.type_ = PROGRAM_TYPE_VIDEO_STREAM;
result.precision_ = precision;
result.sampler_ = SAMPLER_TYPE_EXTERNAL_OES;
return result;
}
ProgramBindingBase::ProgramBindingBase() ProgramBindingBase::ProgramBindingBase()
: program_(0), : program_(0),
vertex_shader_id_(0), vertex_shader_id_(0),
......
...@@ -54,22 +54,106 @@ class ProgramBindingBase { ...@@ -54,22 +54,106 @@ class ProgramBindingBase {
DISALLOW_COPY_AND_ASSIGN(ProgramBindingBase); DISALLOW_COPY_AND_ASSIGN(ProgramBindingBase);
}; };
enum ProgramType {
PROGRAM_TYPE_DEBUG_BORDER,
PROGRAM_TYPE_SOLID_COLOR,
PROGRAM_TYPE_TILE,
PROGRAM_TYPE_TEXTURE,
PROGRAM_TYPE_RENDER_PASS,
PROGRAM_TYPE_VIDEO_STREAM,
};
class CC_EXPORT ProgramKey {
public:
ProgramKey(const ProgramKey& other);
~ProgramKey();
static ProgramKey DebugBorder();
static ProgramKey SolidColor(AAMode aa_mode);
static ProgramKey Tile(TexCoordPrecision precision,
SamplerType sampler,
AAMode aa_mode,
SwizzleMode swizzle_mode,
bool is_opaque);
static ProgramKey Texture(TexCoordPrecision precision,
SamplerType sampler,
PremultipliedAlphaMode premultiplied_alpha,
bool has_background_color);
// TODO(ccameron): Merge |mask_for_background| into MaskMode.
static ProgramKey RenderPass(TexCoordPrecision precision,
SamplerType sampler,
BlendMode blend_mode,
AAMode aa_mode,
MaskMode mask_mode,
bool mask_for_background,
bool has_color_matrix);
static ProgramKey VideoStream(TexCoordPrecision precision);
bool operator==(const ProgramKey& other) const;
private:
ProgramKey();
friend struct ProgramKeyHash;
template <class VertexShader, class FragmentShader>
friend class ProgramBinding;
ProgramType type_ = PROGRAM_TYPE_DEBUG_BORDER;
TexCoordPrecision precision_ = TEX_COORD_PRECISION_NA;
SamplerType sampler_ = SAMPLER_TYPE_NA;
BlendMode blend_mode_ = BLEND_MODE_NONE;
AAMode aa_mode_ = NO_AA;
SwizzleMode swizzle_mode_ = NO_SWIZZLE;
bool is_opaque_ = false;
PremultipliedAlphaMode premultiplied_alpha_ = PREMULTIPLIED_ALPHA;
bool has_background_color_ = false;
MaskMode mask_mode_ = NO_MASK;
bool mask_for_background_ = false;
bool has_color_matrix_ = false;
};
template <class VertexShader, class FragmentShader> template <class VertexShader, class FragmentShader>
class ProgramBinding : public ProgramBindingBase { class ProgramBinding : public ProgramBindingBase {
public: public:
ProgramBinding() {} ProgramBinding() {}
void Initialize(ContextProvider* context_provider, void Initialize(ContextProvider* context_provider, const ProgramKey& key) {
TexCoordPrecision precision, // Set parameters that are common to all sub-classes.
SamplerType sampler) { vertex_shader_.aa_mode_ = key.aa_mode_;
Initialize(context_provider, precision, sampler, BLEND_MODE_NONE, false); fragment_shader_.aa_mode_ = key.aa_mode_;
} fragment_shader_.blend_mode_ = key.blend_mode_;
fragment_shader_.tex_coord_precision_ = key.precision_;
fragment_shader_.sampler_type_ = key.sampler_;
fragment_shader_.swizzle_mode_ = key.swizzle_mode_;
fragment_shader_.premultiply_alpha_mode_ = key.premultiplied_alpha_;
fragment_shader_.mask_mode_ = key.mask_mode_;
fragment_shader_.mask_for_background_ = key.mask_for_background_;
void Initialize(ContextProvider* context_provider, switch (key.type_) {
TexCoordPrecision precision, case PROGRAM_TYPE_DEBUG_BORDER:
SamplerType sampler, InitializeDebugBorderProgram();
BlendMode blend_mode) { break;
Initialize(context_provider, precision, sampler, blend_mode, false); case PROGRAM_TYPE_SOLID_COLOR:
InitializeSolidColorProgram(key);
break;
case PROGRAM_TYPE_TILE:
InitializeTileProgram(key);
break;
case PROGRAM_TYPE_TEXTURE:
InitializeTextureProgram(key);
break;
case PROGRAM_TYPE_RENDER_PASS:
InitializeRenderPassProgram(key);
break;
case PROGRAM_TYPE_VIDEO_STREAM:
InitializeVideoStreamProgram(key);
break;
}
fragment_shader_.CheckSubclassProperties();
vertex_shader_.CheckSubclassProperties();
InitializeInternal(context_provider);
} }
void InitializeVideoYUV(ContextProvider* context_provider, void InitializeVideoYUV(ContextProvider* context_provider,
...@@ -78,23 +162,18 @@ class ProgramBinding : public ProgramBindingBase { ...@@ -78,23 +162,18 @@ class ProgramBinding : public ProgramBindingBase {
bool use_alpha_plane, bool use_alpha_plane,
bool use_nv12, bool use_nv12,
bool use_color_lut) { bool use_color_lut) {
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_ATTRIBUTE;
vertex_shader_.has_matrix_ = true;
vertex_shader_.is_ya_uv_ = true;
fragment_shader_.use_alpha_texture_ = use_alpha_plane; fragment_shader_.use_alpha_texture_ = use_alpha_plane;
fragment_shader_.use_nv12_ = use_nv12; fragment_shader_.use_nv12_ = use_nv12;
fragment_shader_.use_color_lut_ = use_color_lut; fragment_shader_.use_color_lut_ = use_color_lut;
Initialize(context_provider, precision, sampler);
}
void Initialize(ContextProvider* context_provider,
TexCoordPrecision precision,
SamplerType sampler,
BlendMode blend_mode,
bool mask_for_background) {
vertex_shader_.SetSubclassProperties();
fragment_shader_.SetSubclassProperties();
fragment_shader_.blend_mode_ = blend_mode;
fragment_shader_.mask_for_background_ = mask_for_background;
fragment_shader_.tex_coord_precision_ = precision; fragment_shader_.tex_coord_precision_ = precision;
fragment_shader_.sampler_type_ = sampler; fragment_shader_.sampler_type_ = sampler;
fragment_shader_.CheckSubclassProperties();
vertex_shader_.CheckSubclassProperties();
InitializeInternal(context_provider); InitializeInternal(context_provider);
} }
...@@ -102,6 +181,105 @@ class ProgramBinding : public ProgramBindingBase { ...@@ -102,6 +181,105 @@ class ProgramBinding : public ProgramBindingBase {
const FragmentShader& fragment_shader() const { return fragment_shader_; } const FragmentShader& fragment_shader() const { return fragment_shader_; }
private: private:
void InitializeDebugBorderProgram() {
// Initialize vertex program.
vertex_shader_.has_matrix_ = true;
// Initialize fragment program.
fragment_shader_.input_color_type_ = INPUT_COLOR_SOURCE_UNIFORM;
fragment_shader_.frag_color_mode_ = FRAG_COLOR_MODE_DEFAULT;
}
void InitializeSolidColorProgram(const ProgramKey& key) {
// Initialize vertex program.
vertex_shader_.position_source_ = POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM;
vertex_shader_.has_matrix_ = true;
#if defined(OS_ANDROID)
if (key.aa_mode_ == NO_AA)
vertex_shader_.has_dummy_variables_ = true;
#endif
// Initialize fragment program.
fragment_shader_.input_color_type_ = INPUT_COLOR_SOURCE_UNIFORM;
fragment_shader_.frag_color_mode_ = FRAG_COLOR_MODE_DEFAULT;
}
void InitializeTileProgram(const ProgramKey& key) {
// Initialize vertex program.
vertex_shader_.position_source_ = POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM;
vertex_shader_.tex_coord_transform_ = TEX_COORD_TRANSFORM_VEC4;
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_ATTRIBUTE;
vertex_shader_.has_matrix_ = true;
// Initialize fragment program.
if (key.is_opaque_) {
DCHECK_EQ(key.aa_mode_, NO_AA);
fragment_shader_.frag_color_mode_ = FRAG_COLOR_MODE_OPAQUE;
} else {
// TODO(ccameron): This branch shouldn't be needed (this is always
// BLEND_MODE_NONE).
if (key.aa_mode_ == NO_AA && key.swizzle_mode_ == NO_SWIZZLE)
fragment_shader_.frag_color_mode_ = FRAG_COLOR_MODE_APPLY_BLEND_MODE;
fragment_shader_.has_uniform_alpha_ = true;
}
// AA changes the texture coordinate mode (affecting both shaders).
if (key.aa_mode_ == USE_AA) {
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_POSITION;
vertex_shader_.aa_mode_ = USE_AA;
fragment_shader_.has_rgba_fragment_tex_transform_ = true;
}
}
void InitializeTextureProgram(const ProgramKey& key) {
// Initialize vertex program.
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_ATTRIBUTE;
vertex_shader_.tex_coord_transform_ = TEX_COORD_TRANSFORM_VEC4;
vertex_shader_.has_matrix_ = true;
vertex_shader_.has_vertex_opacity_ = true;
vertex_shader_.use_uniform_arrays_ = true;
// Initialize fragment program.
fragment_shader_.has_varying_alpha_ = true;
fragment_shader_.has_background_color_ = key.has_background_color_;
}
void InitializeRenderPassProgram(const ProgramKey& key) {
// Initialize vertex program.
vertex_shader_.has_matrix_ = true;
if (key.aa_mode_ == NO_AA) {
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_ATTRIBUTE;
vertex_shader_.tex_coord_transform_ = TEX_COORD_TRANSFORM_VEC4;
vertex_shader_.has_vertex_opacity_ = true;
vertex_shader_.use_uniform_arrays_ = true;
} else {
vertex_shader_.position_source_ =
POSITION_SOURCE_ATTRIBUTE_INDEXED_UNIFORM;
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_POSITION;
vertex_shader_.tex_coord_transform_ = TEX_COORD_TRANSFORM_TRANSLATED_VEC4;
}
// Initialize fragment program.
fragment_shader_.frag_color_mode_ = FRAG_COLOR_MODE_APPLY_BLEND_MODE;
fragment_shader_.has_uniform_alpha_ = true;
fragment_shader_.has_color_matrix_ = key.has_color_matrix_;
if (key.mask_mode_ == HAS_MASK) {
fragment_shader_.ignore_sampler_type_ = true;
} else {
DCHECK(!key.mask_for_background_);
}
}
void InitializeVideoStreamProgram(const ProgramKey& key) {
vertex_shader_.tex_coord_source_ = TEX_COORD_SOURCE_ATTRIBUTE;
vertex_shader_.tex_coord_transform_ = TEX_COORD_TRANSFORM_MATRIX;
vertex_shader_.has_matrix_ = true;
fragment_shader_.tex_coord_precision_ = key.precision_;
fragment_shader_.sampler_type_ = SAMPLER_TYPE_EXTERNAL_OES;
fragment_shader_.frag_color_mode_ = FRAG_COLOR_MODE_DEFAULT;
}
void InitializeInternal(ContextProvider* context_provider) { void InitializeInternal(ContextProvider* context_provider) {
DCHECK(context_provider); DCHECK(context_provider);
DCHECK(!initialized_); DCHECK(!initialized_);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment