From c4aff051f7e47011ace905719ea3898ea58d4d17 Mon Sep 17 00:00:00 2001 From: Xida Chen Date: Wed, 6 Sep 2017 20:14:33 +0000 Subject: [PATCH] Manually revert: cc: Support ClipRRect in SolidColorAnalyzer This CL reverts a previous CL here: https://chromium-review.googlesource.com/c/chromium/src/+/591913 The previous CL caused a regression on Mac. GL renderer has difficulties dealing with RPDQs converted from SolidColorDrawQuads, this CL will make mask layer produce solid quads. We need to keep it reverted before we fix the gl renderer bug. NOTRY=true TBR=xidachen@chromium.org (cherry picked from commit 8d1900b0fd708cbe8b298a4f5d8a4cb566007255) Bug: 760807 Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel Change-Id: I844d02886329acbbbebd98200f8d2f90681adb8a Reviewed-on: https://chromium-review.googlesource.com/653317 Commit-Queue: Xida Chen Reviewed-by: Vladimir Levin Reviewed-by: Xianda Sun Cr-Original-Commit-Position: refs/heads/master@{#500036} Reviewed-on: https://chromium-review.googlesource.com/653803 Reviewed-by: Xida Chen Cr-Commit-Position: refs/branch-heads/3202@{#55} Cr-Branched-From: fa6a5d87adff761bc16afc5498c3f5944c1daa68-refs/heads/master@{#499098} --- cc/paint/solid_color_analyzer.cc | 77 +++++------------ cc/paint/solid_color_analyzer_unittest.cc | 100 ---------------------- 2 files changed, 23 insertions(+), 154 deletions(-) diff --git a/cc/paint/solid_color_analyzer.cc b/cc/paint/solid_color_analyzer.cc index 79b3a43911ed0..fe341d2ef046b 100644 --- a/cc/paint/solid_color_analyzer.cc +++ b/cc/paint/solid_color_analyzer.cc @@ -45,13 +45,9 @@ bool IsSolidColorPaint(const PaintFlags& flags) { flags.getStyle() == PaintFlags::kFill_Style; } -// Returns true if the specified |drawn_shape| will cover the entire canvas -// and that the canvas is not clipped (i.e. it covers ALL of the canvas). -template -bool IsFullQuad(const SkCanvas& canvas, const T& drawn_shape) { - if (!canvas.isClipRect()) - return false; - +// Returns true if the specified drawn_rect will cover the entire canvas, and +// that the canvas is not clipped (i.e. it covers ALL of the canvas). +bool IsFullQuad(const SkCanvas& canvas, const SkRect& drawn_rect) { SkIRect clip_irect; if (!canvas.getDeviceClipBounds(&clip_irect)) return false; @@ -66,13 +62,11 @@ bool IsFullQuad(const SkCanvas& canvas, const T& drawn_shape) { if (!matrix.rectStaysRect()) return false; - SkMatrix inverse; - if (!matrix.invert(&inverse)) - return false; - - SkRect clip_rect = SkRect::Make(clip_irect); - inverse.mapRect(&clip_rect, clip_rect); - return drawn_shape.contains(clip_rect); + SkRect device_rect; + matrix.mapRect(&device_rect, drawn_rect); + SkRect clip_rect; + clip_rect.set(clip_irect); + return device_rect.contains(clip_rect); } void CheckIfSolidColor(const SkCanvas& canvas, @@ -103,19 +97,18 @@ void CheckIfSolidColor(const SkCanvas& canvas, } } -template -void CheckIfSolidShape(const SkCanvas& canvas, - const T& shape, - const PaintFlags& flags, - bool* is_solid_color, - bool* is_transparent, - SkColor* color) { +void CheckIfSolidRect(const SkCanvas& canvas, + const SkRect& rect, + const PaintFlags& flags, + bool* is_solid_color, + bool* is_transparent, + SkColor* color) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), - "SolidColorAnalyzer::CheckIfSolidShape"); + "SolidColorAnalyzer::HandleDrawRect"); if (flags.nothingToDraw()) return; - bool does_cover_canvas = IsFullQuad(canvas, shape); + bool does_cover_canvas = IsFullQuad(canvas, rect); SkBlendMode blendmode = flags.getBlendMode(); if (does_cover_canvas && ActsLikeClear(blendmode, flags.getAlpha())) *is_transparent = true; @@ -130,13 +123,6 @@ void CheckIfSolidShape(const SkCanvas& canvas, } } -bool CheckIfRRectClipCoversCanvas(const SkCanvas& canvas, - const SkRRect& rrect) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), - "SolidColorAnalyzer::CheckIfRRectClipCoversCanvas"); - return IsFullQuad(canvas, rrect); -} - } // namespace base::Optional SolidColorAnalyzer::DetermineIfSolidColor( @@ -174,7 +160,7 @@ base::Optional SolidColorAnalyzer::DetermineIfSolidColor( stack.emplace_back(PaintOpBuffer::CompositeIterator(buffer, offsets), canvas.getTotalMatrix(), canvas.getSaveCount()); - int num_draw_ops = 0; + int num_ops = 0; while (!stack.empty()) { auto& frame = stack.back(); if (!frame.iter) { @@ -205,15 +191,7 @@ base::Optional SolidColorAnalyzer::DetermineIfSolidColor( case PaintOpType::DrawOval: case PaintOpType::DrawPath: return base::nullopt; - // TODO(vmpstr): Add more tests on exceeding max_ops_to_analyze. - case PaintOpType::DrawRRect: { - if (++num_draw_ops > max_ops_to_analyze) - return base::nullopt; - const DrawRRectOp* rrect_op = static_cast(op); - CheckIfSolidShape(canvas, rrect_op->rrect, rrect_op->flags, &is_solid, - &is_transparent, &color); - break; - } + case PaintOpType::DrawRRect: case PaintOpType::DrawTextBlob: // Anything that has to do a save layer is probably not solid. As it will // likely need more than one draw op. @@ -224,27 +202,18 @@ base::Optional SolidColorAnalyzer::DetermineIfSolidColor( // cover the canvas. // TODO(vmpstr): We could investigate handling these. case PaintOpType::ClipPath: + case PaintOpType::ClipRRect: return base::nullopt; - case PaintOpType::ClipRRect: { - const ClipRRectOp* rrect_op = static_cast(op); - bool does_cover_canvas = - CheckIfRRectClipCoversCanvas(canvas, rrect_op->rrect); - // If the clip covers the full canvas, we can treat it as if there's no - // clip at all and continue, otherwise this is no longer a solid color. - if (!does_cover_canvas) - return base::nullopt; - break; - } case PaintOpType::DrawRect: { - if (++num_draw_ops > max_ops_to_analyze) + if (++num_ops > max_ops_to_analyze) return base::nullopt; const DrawRectOp* rect_op = static_cast(op); - CheckIfSolidShape(canvas, rect_op->rect, rect_op->flags, &is_solid, - &is_transparent, &color); + CheckIfSolidRect(canvas, rect_op->rect, rect_op->flags, &is_solid, + &is_transparent, &color); break; } case PaintOpType::DrawColor: { - if (++num_draw_ops > max_ops_to_analyze) + if (++num_ops > max_ops_to_analyze) return base::nullopt; const DrawColorOp* color_op = static_cast(op); CheckIfSolidColor(canvas, color_op->color, color_op->mode, &is_solid, diff --git a/cc/paint/solid_color_analyzer_unittest.cc b/cc/paint/solid_color_analyzer_unittest.cc index c73cbe9c7ff9e..a944cc6faedc4 100644 --- a/cc/paint/solid_color_analyzer_unittest.cc +++ b/cc/paint/solid_color_analyzer_unittest.cc @@ -29,11 +29,6 @@ class SolidColorAnalyzerTest : public testing::Test { buffer_ = nullptr; } - void Reset() { - TearDown(); - SetUp(); - } - void Initialize(const gfx::Rect& rect = gfx::Rect(0, 0, 100, 100)) { canvas_.emplace(display_item_list_.get(), gfx::RectToSkRect(rect)); rect_ = rect; @@ -132,21 +127,6 @@ TEST_F(SolidColorAnalyzerTest, DrawRect) { EXPECT_EQ(color, GetColor()); } -// TODO(vmpstr): Generalize the DrawRect test cases so that we can test both -// Rect and RRect. -TEST_F(SolidColorAnalyzerTest, DrawRRect) { - SkRect rect = SkRect::MakeWH(200, 200); - SkRRect rrect; - rrect.setRectXY(rect, 5, 5); - gfx::Rect canvas_rect(5, 5, 190, 190); - Initialize(canvas_rect); - PaintFlags flags; - SkColor color = SkColorSetARGB(255, 11, 22, 33); - flags.setColor(color); - canvas()->drawRRect(rrect, flags); - EXPECT_EQ(color, GetColor()); -} - TEST_F(SolidColorAnalyzerTest, DrawRectClipped) { Initialize(); PaintFlags flags; @@ -298,85 +278,5 @@ TEST_F(SolidColorAnalyzerTest, SaveLayer) { EXPECT_FALSE(IsSolidColor()); } -TEST_F(SolidColorAnalyzerTest, ClipRRectCoversCanvas) { - SkVector radii[4] = { - SkVector::Make(10.0, 15.0), SkVector::Make(20.0, 25.0), - SkVector::Make(30.0, 35.0), SkVector::Make(40.0, 45.0), - }; - - SkVector radii_scale[4] = { - SkVector::Make(100.0, 150.0), SkVector::Make(200.0, 250.0), - SkVector::Make(300.0, 350.0), SkVector::Make(400.0, 450.0), - }; - - int rr_size = 600; - int canvas_size = 255; - gfx::Rect canvas_rect(canvas_size, canvas_size); - PaintFlags flags; - flags.setColor(SK_ColorWHITE); - - struct { - SkVector offset; - SkVector offset_scale; - bool expected; - } cases[] = { - // Not within bounding box of |rr|. - {SkVector::Make(100, 100), SkVector::Make(100, 100), false}, - - // Intersects UL corner. - {SkVector::Make(0, 0), SkVector::Make(0, 0), false}, - - // Between UL and UR. - {SkVector::Make(-50, 0), SkVector::Make(-50, -15), true}, - - // Intersects UR corner. - {SkVector::Make(canvas_size - rr_size, 0), - SkVector::Make(canvas_size - rr_size, 0), false}, - - // Between UR and LR. - {SkVector::Make(canvas_size - rr_size, -50), SkVector::Make(-305, -80), - true}, - - // Intersects LR corner. - {SkVector::Make(canvas_size - rr_size, canvas_size - rr_size), - SkVector::Make(canvas_size - rr_size, canvas_size - rr_size), false}, - - // Between LL and LR - {SkVector::Make(-50, canvas_size - rr_size), SkVector::Make(-205, -310), - true}, - - // Intersects LL corner - {SkVector::Make(0, canvas_size - rr_size), - SkVector::Make(0, canvas_size - rr_size), false}, - - // Between UL and LL - {SkVector::Make(0, -50), SkVector::Make(-15, -60), true}, - - // In center - {SkVector::Make(-100, -100), SkVector::Make(-100, -100), true}, - }; - - for (int case_scale = 0; case_scale < 2; ++case_scale) { - bool scaled = case_scale > 0; - for (size_t i = 0; i < arraysize(cases); ++i) { - Reset(); - Initialize(canvas_rect); - - SkRect bounding_rect = SkRect::MakeXYWH( - scaled ? cases[i].offset_scale.x() : cases[i].offset.x(), - scaled ? cases[i].offset_scale.y() : cases[i].offset.y(), rr_size, - rr_size); - - SkRRect rr; - rr.setRectRadii(bounding_rect, scaled ? radii_scale : radii); - - canvas()->clipRRect(rr, SkClipOp::kIntersect, false); - canvas()->drawRect(RectToSkRect(canvas_rect), flags); - EXPECT_EQ(cases[i].expected, IsSolidColor()) - << "Case " << i << ", " << scaled << " failed."; - } - } -} - } // namespace } // namespace cc