skia2/gm/complexclip4.cpp
Michael Ludwig cfd204a785 Rename/simplify SkCanvas::resetClip() and make recordable
AndroidFramework uses both their own custom display list (which could
handle resetClip with android-side changes) AND conventional picture
recording. In order for replace op emulation to work when they have
been recorded into a picture, we need to make it virtual and supported
in SkPicture.

This also renames the API to ResetClip() from ReplaceClip() and does not
have any additional arguments. Based on AF's usage pattern, it only n
needs to reset the clip to the surface bounds or the device clip
restriction, it seems best to reduce the API as much as possible before
it's adopted.

Bug: skia:10209
Change-Id: I37adb097c84a642f4254b8c0f9d4c7fea8d9abdf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/430897
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
2021-07-23 19:05:42 +00:00

136 lines
4.9 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkClipOpPriv.h"
namespace skiagm {
// This test exercise SkCanvas::androidFramework_replaceClip behavior
class ComplexClip4GM : public GM {
public:
ComplexClip4GM(bool aaclip)
: fDoAAClip(aaclip) {
this->setBGColor(0xFFDEDFDE);
}
protected:
SkString onShortName() override {
SkString str;
str.printf("complexclip4_%s",
fDoAAClip ? "aa" : "bw");
return str;
}
SkISize onISize() override { return SkISize::Make(970, 780); }
// Android Framework will still support the legacy kReplace SkClipOp on older devices, so
// this represents how to do so while also respecting the device restriction using the newer
// androidFramework_resetClip() API.
void emulateDeviceRestriction(SkCanvas* canvas, const SkIRect& deviceRestriction) {
// TODO(michaelludwig): It may make more sense for device clip restriction to move on to
// the SkSurface (which would let this GM draw correctly in viewer).
canvas->androidFramework_setDeviceClipRestriction(deviceRestriction);
}
void emulateClipRectReplace(SkCanvas* canvas,
const SkRect& clipRect,
bool aa) {
SkCanvasPriv::ResetClip(canvas);
canvas->clipRect(clipRect, SkClipOp::kIntersect, aa);
}
void emulateClipRRectReplace(SkCanvas* canvas,
const SkRRect& clipRRect,
bool aa) {
SkCanvasPriv::ResetClip(canvas);
canvas->clipRRect(clipRRect, SkClipOp::kIntersect, aa);
}
void emulateClipPathReplace(SkCanvas* canvas,
const SkPath& path,
bool aa) {
SkCanvasPriv::ResetClip(canvas);
canvas->clipPath(path, SkClipOp::kIntersect, aa);
}
void onDraw(SkCanvas* canvas) override {
SkPaint p;
p.setAntiAlias(fDoAAClip);
p.setColor(SK_ColorYELLOW);
canvas->save();
// draw a yellow rect through a rect clip
canvas->save();
emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(100, 100, 300, 300));
canvas->drawColor(SK_ColorGREEN);
emulateClipRectReplace(canvas, SkRect::MakeLTRB(100, 200, 400, 500), fDoAAClip);
canvas->drawRect(SkRect::MakeLTRB(100, 200, 400, 500), p);
canvas->restore();
// draw a yellow rect through a diamond clip
canvas->save();
emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(500, 100, 800, 300));
canvas->drawColor(SK_ColorGREEN);
SkPath pathClip = SkPath::Polygon({
{650, 200},
{900, 300},
{650, 400},
{650, 300},
}, true);
emulateClipPathReplace(canvas, pathClip, fDoAAClip);
canvas->drawRect(SkRect::MakeLTRB(500, 200, 900, 500), p);
canvas->restore();
// draw a yellow rect through a round rect clip
canvas->save();
emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(500, 500, 800, 700));
canvas->drawColor(SK_ColorGREEN);
emulateClipRRectReplace(
canvas, SkRRect::MakeOval(SkRect::MakeLTRB(500, 600, 900, 750)), fDoAAClip);
canvas->drawRect(SkRect::MakeLTRB(500, 600, 900, 750), p);
canvas->restore();
// fill the clip with yellow color showing that androidFramework_replaceClip is
// in device space
canvas->save();
canvas->clipRect(SkRect::MakeLTRB(100, 400, 300, 750),
kIntersect_SkClipOp, fDoAAClip);
canvas->drawColor(SK_ColorGREEN);
// should not affect the device-space clip
canvas->rotate(20.f);
canvas->translate(50.f, 50.f);
emulateDeviceRestriction(canvas, SkIRect::MakeLTRB(150, 450, 250, 700));
canvas->drawColor(SK_ColorYELLOW);
canvas->restore();
canvas->restore();
}
private:
bool fDoAAClip;
using INHERITED = GM;
};
//////////////////////////////////////////////////////////////////////////////
DEF_GM(return new ComplexClip4GM(false);)
DEF_GM(return new ComplexClip4GM(true);)
} // namespace skiagm