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) {
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 <typename T>
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 <typename T>
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<SkColor> SolidColorAnalyzer::DetermineIfSolidColor(
......@@ -174,7 +160,7 @@ base::Optional<SkColor> 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<SkColor> 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<const DrawRRectOp*>(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<SkColor> 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<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: {
if (++num_draw_ops > max_ops_to_analyze)
if (++num_ops > max_ops_to_analyze)
return base::nullopt;
const DrawRectOp* rect_op = static_cast<const DrawRectOp*>(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<const DrawColorOp*>(op);
CheckIfSolidColor(canvas, color_op->color, color_op->mode, &is_solid,
......
......@@ -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
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