Commit 7b73f83a authored by rosca's avatar rosca Committed by Commit bot

Implement mix-blend-mode in GL renderer using shaders.

This implementation brings in several improvements for blending:
- it's done faster, due to reducing the number of readbacks.
- the backdrop doesn't suffer any transformation, so the result is more
  correct.
- the results are similar to the ones obtained using the software paths.
- blending is always applied after filters, even when the filters
  can be expressed using a color matrix.

The initial experiment: https://codereview.chromium.org/555133002/.

BUG=243223

Review URL: https://codereview.chromium.org/658483003

Cr-Commit-Position: refs/heads/master@{#300657}
parent 547c1dd7
......@@ -1416,7 +1416,12 @@ TEST_F(DelegatedRendererLayerImplTest, Occlusion) {
pass1_id,
gfx::Rect(layer_size),
gfx::Transform());
AddRenderPassQuad(pass1, pass2, 0, FilterOperations(), transform);
AddRenderPassQuad(pass1,
pass2,
0,
FilterOperations(),
transform,
SkXfermode::kSrcOver_Mode);
delegated_renderer_layer_impl->SetFrameDataForRenderPasses(
1.f, &delegated_render_passes);
......
This diff is collapsed.
......@@ -153,7 +153,8 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
gfx::Rect GetBackdropBoundingBoxForRenderPassQuad(
DrawingFrame* frame,
const RenderPassDrawQuad* quad,
const gfx::Transform& contents_device_transform);
const gfx::Transform& contents_device_transform,
bool use_aa);
scoped_ptr<ScopedResource> GetBackdropTexture(const gfx::Rect& bounding_rect);
static bool ShouldApplyBackgroundFilters(DrawingFrame* frame,
......@@ -166,7 +167,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
DrawingFrame* frame,
const RenderPassDrawQuad* quad,
const gfx::Transform& contents_device_transform_inverse,
ScopedResource* background_texture,
skia::RefPtr<SkImage> backdrop_bitmap,
const gfx::Rect& backdrop_bounding_rect);
......@@ -328,22 +328,28 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
const TileCheckerboardProgram* GetTileCheckerboardProgram();
const RenderPassProgram* GetRenderPassProgram(
TexCoordPrecision precision);
const RenderPassProgramAA* GetRenderPassProgramAA(
TexCoordPrecision precision);
const RenderPassProgram* GetRenderPassProgram(TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassProgramAA* GetRenderPassProgramAA(TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassMaskProgram* GetRenderPassMaskProgram(
TexCoordPrecision precision);
TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA(
TexCoordPrecision precision);
TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram(
TexCoordPrecision precision);
TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA(
TexCoordPrecision precision);
TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram(
TexCoordPrecision precision);
TexCoordPrecision precision,
BlendMode blend_mode);
const RenderPassMaskColorMatrixProgramAA*
GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision);
GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
BlendMode blend_mode);
const TextureProgram* GetTextureProgram(
TexCoordPrecision precision);
......@@ -388,18 +394,21 @@ class CC_EXPORT GLRenderer : public DirectRenderer {
nonpremultiplied_texture_background_program_[NumTexCoordPrecisions];
TextureProgram texture_io_surface_program_[NumTexCoordPrecisions];
RenderPassProgram render_pass_program_[NumTexCoordPrecisions];
RenderPassProgramAA render_pass_program_aa_[NumTexCoordPrecisions];
RenderPassMaskProgram render_pass_mask_program_[NumTexCoordPrecisions];
RenderPassMaskProgramAA render_pass_mask_program_aa_[NumTexCoordPrecisions];
RenderPassProgram render_pass_program_[NumTexCoordPrecisions][NumBlendModes];
RenderPassProgramAA
render_pass_program_aa_[NumTexCoordPrecisions][NumBlendModes];
RenderPassMaskProgram
render_pass_mask_program_[NumTexCoordPrecisions][NumBlendModes];
RenderPassMaskProgramAA
render_pass_mask_program_aa_[NumTexCoordPrecisions][NumBlendModes];
RenderPassColorMatrixProgram
render_pass_color_matrix_program_[NumTexCoordPrecisions];
RenderPassColorMatrixProgramAA
render_pass_color_matrix_program_aa_[NumTexCoordPrecisions];
RenderPassMaskColorMatrixProgram
render_pass_mask_color_matrix_program_[NumTexCoordPrecisions];
RenderPassMaskColorMatrixProgramAA
render_pass_mask_color_matrix_program_aa_[NumTexCoordPrecisions];
render_pass_color_matrix_program_[NumTexCoordPrecisions][NumBlendModes];
RenderPassColorMatrixProgramAA render_pass_color_matrix_program_aa_
[NumTexCoordPrecisions][NumBlendModes];
RenderPassMaskColorMatrixProgram render_pass_mask_color_matrix_program_
[NumTexCoordPrecisions][NumBlendModes];
RenderPassMaskColorMatrixProgramAA render_pass_mask_color_matrix_program_aa_
[NumTexCoordPrecisions][NumBlendModes];
VideoYUVProgram video_yuv_program_[NumTexCoordPrecisions];
VideoYUVAProgram video_yuva_program_[NumTexCoordPrecisions];
......
This diff is collapsed.
......@@ -58,13 +58,16 @@ class ProgramBinding : public ProgramBindingBase {
void Initialize(ContextProvider* context_provider,
TexCoordPrecision precision,
SamplerType sampler) {
SamplerType sampler,
BlendMode blend_mode = BlendModeNormal) {
DCHECK(context_provider);
DCHECK(!initialized_);
if (context_provider->IsContextLost())
return;
fragment_shader_.set_blend_mode(blend_mode);
if (!ProgramBindingBase::Init(
context_provider->ContextGL(),
vertex_shader_.GetShaderString(),
......
This diff is collapsed.
......@@ -38,6 +38,25 @@ enum SamplerType {
NumSamplerTypes = 4
};
enum BlendMode {
BlendModeNormal,
BlendModeOverlay,
BlendModeDarken,
BlendModeLighten,
BlendModeColorDodge,
BlendModeColorBurn,
BlendModeHardLight,
BlendModeSoftLight,
BlendModeDifference,
BlendModeExclusion,
BlendModeMultiply,
BlendModeHue,
BlendModeSaturation,
BlendModeColor,
BlendModeLuminosity,
NumBlendModes
};
// Note: The highp_threshold_cache must be provided by the caller to make
// the caching multi-thread/context safe in an easy low-overhead manner.
// The caller must make sure to clear highp_threshold_cache to 0, so it can be
......@@ -279,7 +298,32 @@ class VertexShaderVideoTransform {
DISALLOW_COPY_AND_ASSIGN(VertexShaderVideoTransform);
};
class FragmentTexAlphaBinding {
class FragmentTexBlendMode {
public:
int backdrop_location() const { return backdrop_location_; }
int backdrop_rect_location() const { return backdrop_rect_location_; }
BlendMode blend_mode() const { return blend_mode_; }
void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; }
bool is_default_blend_mode() const { return blend_mode_ == BlendModeNormal; }
protected:
FragmentTexBlendMode();
std::string SetBlendModeFunctions(std::string shader_string) const;
int backdrop_location_;
int backdrop_rect_location_;
private:
BlendMode blend_mode_;
std::string GetHelperFunctions() const;
std::string GetBlendFunction() const;
std::string GetBlendFunctionBodyForRGB() const;
};
class FragmentTexAlphaBinding : public FragmentTexBlendMode {
public:
FragmentTexAlphaBinding();
......@@ -297,7 +341,7 @@ class FragmentTexAlphaBinding {
DISALLOW_COPY_AND_ASSIGN(FragmentTexAlphaBinding);
};
class FragmentTexColorMatrixAlphaBinding {
class FragmentTexColorMatrixAlphaBinding : public FragmentTexBlendMode {
public:
FragmentTexColorMatrixAlphaBinding();
......@@ -317,7 +361,7 @@ class FragmentTexColorMatrixAlphaBinding {
int color_offset_location_;
};
class FragmentTexOpaqueBinding {
class FragmentTexOpaqueBinding : public FragmentTexBlendMode {
public:
FragmentTexOpaqueBinding();
......@@ -335,7 +379,7 @@ class FragmentTexOpaqueBinding {
DISALLOW_COPY_AND_ASSIGN(FragmentTexOpaqueBinding);
};
class FragmentTexBackgroundBinding {
class FragmentTexBackgroundBinding : public FragmentTexBlendMode {
public:
FragmentTexBackgroundBinding();
......@@ -417,7 +461,7 @@ class FragmentShaderRGBATexSwizzleOpaque : public FragmentTexOpaqueBinding {
TexCoordPrecision precision, SamplerType sampler) const;
};
class FragmentShaderRGBATexAlphaAA {
class FragmentShaderRGBATexAlphaAA : public FragmentTexBlendMode {
public:
FragmentShaderRGBATexAlphaAA();
......@@ -437,7 +481,7 @@ class FragmentShaderRGBATexAlphaAA {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaAA);
};
class FragmentTexClampAlphaAABinding {
class FragmentTexClampAlphaAABinding : public FragmentTexBlendMode {
public:
FragmentTexClampAlphaAABinding();
......@@ -473,7 +517,7 @@ class FragmentShaderRGBATexClampSwizzleAlphaAA
TexCoordPrecision precision, SamplerType sampler) const;
};
class FragmentShaderRGBATexAlphaMask {
class FragmentShaderRGBATexAlphaMask : public FragmentTexBlendMode {
public:
FragmentShaderRGBATexAlphaMask();
std::string GetShaderString(
......@@ -502,7 +546,7 @@ class FragmentShaderRGBATexAlphaMask {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMask);
};
class FragmentShaderRGBATexAlphaMaskAA {
class FragmentShaderRGBATexAlphaMaskAA : public FragmentTexBlendMode {
public:
FragmentShaderRGBATexAlphaMaskAA();
std::string GetShaderString(
......@@ -531,7 +575,8 @@ class FragmentShaderRGBATexAlphaMaskAA {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMaskAA);
};
class FragmentShaderRGBATexAlphaMaskColorMatrixAA {
class FragmentShaderRGBATexAlphaMaskColorMatrixAA
: public FragmentTexBlendMode {
public:
FragmentShaderRGBATexAlphaMaskColorMatrixAA();
std::string GetShaderString(
......@@ -562,7 +607,7 @@ class FragmentShaderRGBATexAlphaMaskColorMatrixAA {
int color_offset_location_;
};
class FragmentShaderRGBATexAlphaColorMatrixAA {
class FragmentShaderRGBATexAlphaColorMatrixAA : public FragmentTexBlendMode {
public:
FragmentShaderRGBATexAlphaColorMatrixAA();
std::string GetShaderString(
......@@ -583,7 +628,7 @@ class FragmentShaderRGBATexAlphaColorMatrixAA {
int color_offset_location_;
};
class FragmentShaderRGBATexAlphaMaskColorMatrix {
class FragmentShaderRGBATexAlphaMaskColorMatrix : public FragmentTexBlendMode {
public:
FragmentShaderRGBATexAlphaMaskColorMatrix();
std::string GetShaderString(
......@@ -614,7 +659,7 @@ class FragmentShaderRGBATexAlphaMaskColorMatrix {
int color_offset_location_;
};
class FragmentShaderYUVVideo {
class FragmentShaderYUVVideo : public FragmentTexBlendMode {
public:
FragmentShaderYUVVideo();
std::string GetShaderString(
......@@ -641,8 +686,7 @@ class FragmentShaderYUVVideo {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVVideo);
};
class FragmentShaderYUVAVideo {
class FragmentShaderYUVAVideo : public FragmentTexBlendMode {
public:
FragmentShaderYUVAVideo();
std::string GetShaderString(
......@@ -672,7 +716,7 @@ class FragmentShaderYUVAVideo {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVAVideo);
};
class FragmentShaderColor {
class FragmentShaderColor : public FragmentTexBlendMode {
public:
FragmentShaderColor();
std::string GetShaderString(
......@@ -689,7 +733,7 @@ class FragmentShaderColor {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderColor);
};
class FragmentShaderColorAA {
class FragmentShaderColorAA : public FragmentTexBlendMode {
public:
FragmentShaderColorAA();
std::string GetShaderString(
......@@ -706,7 +750,7 @@ class FragmentShaderColorAA {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderColorAA);
};
class FragmentShaderCheckerboard {
class FragmentShaderCheckerboard : public FragmentTexBlendMode {
public:
FragmentShaderCheckerboard();
std::string GetShaderString(
......
......@@ -239,14 +239,16 @@ void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) {
current_canvas_->setMatrix(sk_device_matrix);
current_paint_.reset();
if (!IsScaleAndIntegerTranslate(sk_device_matrix)) {
if (settings_->force_antialiasing ||
!IsScaleAndIntegerTranslate(sk_device_matrix)) {
// TODO(danakj): Until we can enable AA only on exterior edges of the
// layer, disable AA if any interior edges are present. crbug.com/248175
bool all_four_edges_are_exterior = quad->IsTopEdge() &&
quad->IsLeftEdge() &&
quad->IsBottomEdge() &&
quad->IsRightEdge();
if (settings_->allow_antialiasing && all_four_edges_are_exterior)
if (settings_->allow_antialiasing &&
(settings_->force_antialiasing || all_four_edges_are_exterior))
current_paint_.setAntiAlias(true);
current_paint_.setFilterLevel(SkPaint::kLow_FilterLevel);
}
......
......@@ -111,7 +111,8 @@ void AddRenderPassQuad(TestRenderPass* to_pass,
TestRenderPass* contributing_pass,
ResourceProvider::ResourceId mask_resource_id,
const FilterOperations& filters,
gfx::Transform transform) {
gfx::Transform transform,
SkXfermode::Mode blend_mode) {
gfx::Rect output_rect = contributing_pass->output_rect;
SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState();
shared_state->SetAll(transform,
......@@ -120,7 +121,7 @@ void AddRenderPassQuad(TestRenderPass* to_pass,
output_rect,
false,
1,
SkXfermode::kSrcOver_Mode,
blend_mode,
0);
RenderPassDrawQuad* quad =
to_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
......
......@@ -53,7 +53,8 @@ void AddRenderPassQuad(TestRenderPass* toPass,
TestRenderPass* contributing_pass,
ResourceProvider::ResourceId mask_resource_id,
const FilterOperations& filters,
gfx::Transform transform);
gfx::Transform transform,
SkXfermode::Mode blend_mode);
} // namespace cc
......
......@@ -15,6 +15,7 @@ namespace cc {
LayerTreeSettings::LayerTreeSettings()
: impl_side_painting(false),
allow_antialiasing(true),
force_antialiasing(false),
throttle_frame_production(true),
single_thread_proxy_scheduler(true),
begin_frame_scheduling_enabled(false),
......
......@@ -20,6 +20,7 @@ class CC_EXPORT LayerTreeSettings {
bool impl_side_painting;
bool allow_antialiasing;
bool force_antialiasing;
bool throttle_frame_production;
bool single_thread_proxy_scheduler;
bool begin_frame_scheduling_enabled;
......
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