Commit 8d1900b0 authored by Xida Chen's avatar Xida Chen Committed by Commit Bot

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

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 <xidachen@chromium.org>
Reviewed-by: default avatarVladimir Levin <vmpstr@chromium.org>
Reviewed-by: default avatarXianda Sun <sunxd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#500036}
parent 7232806e
...@@ -45,13 +45,9 @@ bool IsSolidColorPaint(const PaintFlags& flags) { ...@@ -45,13 +45,9 @@ bool IsSolidColorPaint(const PaintFlags& flags) {
flags.getStyle() == PaintFlags::kFill_Style; flags.getStyle() == PaintFlags::kFill_Style;
} }
// Returns true if the specified |drawn_shape| will cover the entire canvas // Returns true if the specified drawn_rect will cover the entire canvas, and
// and that the canvas is not clipped (i.e. it covers ALL of the canvas). // that the canvas is not clipped (i.e. it covers ALL of the canvas).
template <typename T> bool IsFullQuad(const SkCanvas& canvas, const SkRect& drawn_rect) {
bool IsFullQuad(const SkCanvas& canvas, const T& drawn_shape) {
if (!canvas.isClipRect())
return false;
SkIRect clip_irect; SkIRect clip_irect;
if (!canvas.getDeviceClipBounds(&clip_irect)) if (!canvas.getDeviceClipBounds(&clip_irect))
return false; return false;
...@@ -66,13 +62,11 @@ bool IsFullQuad(const SkCanvas& canvas, const T& drawn_shape) { ...@@ -66,13 +62,11 @@ bool IsFullQuad(const SkCanvas& canvas, const T& drawn_shape) {
if (!matrix.rectStaysRect()) if (!matrix.rectStaysRect())
return false; return false;
SkMatrix inverse; SkRect device_rect;
if (!matrix.invert(&inverse)) matrix.mapRect(&device_rect, drawn_rect);
return false; SkRect clip_rect;
clip_rect.set(clip_irect);
SkRect clip_rect = SkRect::Make(clip_irect); return device_rect.contains(clip_rect);
inverse.mapRect(&clip_rect, clip_rect);
return drawn_shape.contains(clip_rect);
} }
void CheckIfSolidColor(const SkCanvas& canvas, void CheckIfSolidColor(const SkCanvas& canvas,
...@@ -103,19 +97,18 @@ void CheckIfSolidColor(const SkCanvas& canvas, ...@@ -103,19 +97,18 @@ void CheckIfSolidColor(const SkCanvas& canvas,
} }
} }
template <typename T> void CheckIfSolidRect(const SkCanvas& canvas,
void CheckIfSolidShape(const SkCanvas& canvas, const SkRect& rect,
const T& shape,
const PaintFlags& flags, const PaintFlags& flags,
bool* is_solid_color, bool* is_solid_color,
bool* is_transparent, bool* is_transparent,
SkColor* color) { SkColor* color) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"SolidColorAnalyzer::CheckIfSolidShape"); "SolidColorAnalyzer::HandleDrawRect");
if (flags.nothingToDraw()) if (flags.nothingToDraw())
return; return;
bool does_cover_canvas = IsFullQuad(canvas, shape); bool does_cover_canvas = IsFullQuad(canvas, rect);
SkBlendMode blendmode = flags.getBlendMode(); SkBlendMode blendmode = flags.getBlendMode();
if (does_cover_canvas && ActsLikeClear(blendmode, flags.getAlpha())) if (does_cover_canvas && ActsLikeClear(blendmode, flags.getAlpha()))
*is_transparent = true; *is_transparent = true;
...@@ -130,13 +123,6 @@ void CheckIfSolidShape(const SkCanvas& canvas, ...@@ -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 } // namespace
base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor( base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
...@@ -174,7 +160,7 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor( ...@@ -174,7 +160,7 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
stack.emplace_back(PaintOpBuffer::CompositeIterator(buffer, offsets), stack.emplace_back(PaintOpBuffer::CompositeIterator(buffer, offsets),
canvas.getTotalMatrix(), canvas.getSaveCount()); canvas.getTotalMatrix(), canvas.getSaveCount());
int num_draw_ops = 0; int num_ops = 0;
while (!stack.empty()) { while (!stack.empty()) {
auto& frame = stack.back(); auto& frame = stack.back();
if (!frame.iter) { if (!frame.iter) {
...@@ -205,15 +191,7 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor( ...@@ -205,15 +191,7 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
case PaintOpType::DrawOval: case PaintOpType::DrawOval:
case PaintOpType::DrawPath: case PaintOpType::DrawPath:
return base::nullopt; return base::nullopt;
// TODO(vmpstr): Add more tests on exceeding max_ops_to_analyze. case PaintOpType::DrawRRect:
case PaintOpType::DrawRRect: {
if (++num_draw_ops > max_ops_to_analyze)
return base::nullopt;
const DrawRRectOp* rrect_op = static_cast<const DrawRRectOp*>(op);
CheckIfSolidShape(canvas, rrect_op->rrect, rrect_op->flags, &is_solid,
&is_transparent, &color);
break;
}
case PaintOpType::DrawTextBlob: case PaintOpType::DrawTextBlob:
// Anything that has to do a save layer is probably not solid. As it will // Anything that has to do a save layer is probably not solid. As it will
// likely need more than one draw op. // likely need more than one draw op.
...@@ -224,27 +202,18 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor( ...@@ -224,27 +202,18 @@ base::Optional<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
// cover the canvas. // cover the canvas.
// TODO(vmpstr): We could investigate handling these. // TODO(vmpstr): We could investigate handling these.
case PaintOpType::ClipPath: case PaintOpType::ClipPath:
case PaintOpType::ClipRRect:
return base::nullopt; return base::nullopt;
case PaintOpType::ClipRRect: {
const ClipRRectOp* rrect_op = static_cast<const ClipRRectOp*>(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: { case PaintOpType::DrawRect: {
if (++num_draw_ops > max_ops_to_analyze) if (++num_ops > max_ops_to_analyze)
return base::nullopt; return base::nullopt;
const DrawRectOp* rect_op = static_cast<const DrawRectOp*>(op); const DrawRectOp* rect_op = static_cast<const DrawRectOp*>(op);
CheckIfSolidShape(canvas, rect_op->rect, rect_op->flags, &is_solid, CheckIfSolidRect(canvas, rect_op->rect, rect_op->flags, &is_solid,
&is_transparent, &color); &is_transparent, &color);
break; break;
} }
case PaintOpType::DrawColor: { case PaintOpType::DrawColor: {
if (++num_draw_ops > max_ops_to_analyze) if (++num_ops > max_ops_to_analyze)
return base::nullopt; return base::nullopt;
const DrawColorOp* color_op = static_cast<const DrawColorOp*>(op); const DrawColorOp* color_op = static_cast<const DrawColorOp*>(op);
CheckIfSolidColor(canvas, color_op->color, color_op->mode, &is_solid, CheckIfSolidColor(canvas, color_op->color, color_op->mode, &is_solid,
......
...@@ -29,11 +29,6 @@ class SolidColorAnalyzerTest : public testing::Test { ...@@ -29,11 +29,6 @@ class SolidColorAnalyzerTest : public testing::Test {
buffer_ = nullptr; buffer_ = nullptr;
} }
void Reset() {
TearDown();
SetUp();
}
void Initialize(const gfx::Rect& rect = gfx::Rect(0, 0, 100, 100)) { void Initialize(const gfx::Rect& rect = gfx::Rect(0, 0, 100, 100)) {
canvas_.emplace(display_item_list_.get(), gfx::RectToSkRect(rect)); canvas_.emplace(display_item_list_.get(), gfx::RectToSkRect(rect));
rect_ = rect; rect_ = rect;
...@@ -132,21 +127,6 @@ TEST_F(SolidColorAnalyzerTest, DrawRect) { ...@@ -132,21 +127,6 @@ TEST_F(SolidColorAnalyzerTest, DrawRect) {
EXPECT_EQ(color, GetColor()); 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) { TEST_F(SolidColorAnalyzerTest, DrawRectClipped) {
Initialize(); Initialize();
PaintFlags flags; PaintFlags flags;
...@@ -298,85 +278,5 @@ TEST_F(SolidColorAnalyzerTest, SaveLayer) { ...@@ -298,85 +278,5 @@ TEST_F(SolidColorAnalyzerTest, SaveLayer) {
EXPECT_FALSE(IsSolidColor()); 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
} // namespace cc } // namespace cc
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