SkTCopyOnFirstWrite-based SkPaintFilterCanvas API
I find this version preferable because 1) it consolidates the in/out paint args without compromising efficiency or flexibility 2) relieves overriders from having to set the SkTLazy explicitly BUG=skia:4782 R=mtklein@google.com,reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1576183002 Review URL: https://codereview.chromium.org/1576183002
This commit is contained in:
parent
a51e7782b2
commit
32cdc32522
@ -131,6 +131,8 @@ class SkTCopyOnFirstWrite {
|
||||
public:
|
||||
SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
|
||||
|
||||
SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
|
||||
|
||||
// Constructor for delayed initialization.
|
||||
SkTCopyOnFirstWrite() : fObj(NULL) {}
|
||||
|
||||
|
@ -49,22 +49,18 @@ public:
|
||||
protected:
|
||||
/**
|
||||
* Called with the paint that will be used to draw the specified type.
|
||||
*
|
||||
* Upon return, if filteredPaint is initialized it will replace the original paint
|
||||
* for the current draw. Note that that implementation is responsible for
|
||||
* initializing *filteredPaint (e.g. via set(*paint)).
|
||||
* The implementation may modify the paint as they wish (using SkTCopyOnFirstWrite::writable).
|
||||
*
|
||||
* The result bool is used to determine whether the draw op is to be
|
||||
* executed (true) or skipped (false). When the draw is skipped, filteredPaint is
|
||||
* ignored.
|
||||
* executed (true) or skipped (false).
|
||||
*
|
||||
* Note: The base implementation calls onFilter() for top-level/explicit paints only.
|
||||
* To also filter encapsulated paints (e.g. SkPicture, SkTextBlob), clients may need to
|
||||
* override the relevant methods (i.e. drawPicture, drawTextBlob).
|
||||
*/
|
||||
virtual bool onFilter(const SkPaint* paint, Type type, SkTLazy<SkPaint>* filteredPaint) const {
|
||||
if (paint) {
|
||||
this->onFilterPaint(filteredPaint->set(*paint), type);
|
||||
virtual bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const {
|
||||
if (*paint) {
|
||||
this->onFilterPaint(paint->writable(), type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -475,27 +475,25 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
bool onFilter(const SkPaint* paint, Type t, SkTLazy<SkPaint>* filteredPaint) const override {
|
||||
if (!paint) {
|
||||
bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type t) const override {
|
||||
if (!*paint) {
|
||||
return true;
|
||||
}
|
||||
|
||||
filteredPaint->set(*paint);
|
||||
if (kText_Type == t && SkOSMenu::kMixedState != fLCDState) {
|
||||
filteredPaint->get()->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
|
||||
paint->writable()->setLCDRenderText(SkOSMenu::kOnState == fLCDState);
|
||||
}
|
||||
if (SkOSMenu::kMixedState != fAAState) {
|
||||
filteredPaint->get()->setAntiAlias(SkOSMenu::kOnState == fAAState);
|
||||
paint->writable()->setAntiAlias(SkOSMenu::kOnState == fAAState);
|
||||
}
|
||||
if (0 != fFilterQualityIndex) {
|
||||
filteredPaint->get()->setFilterQuality(
|
||||
gFilterQualityStates[fFilterQualityIndex].fQuality);
|
||||
paint->writable()->setFilterQuality(gFilterQualityStates[fFilterQualityIndex].fQuality);
|
||||
}
|
||||
if (SkOSMenu::kMixedState != fSubpixelState) {
|
||||
filteredPaint->get()->setSubpixelText(SkOSMenu::kOnState == fSubpixelState);
|
||||
paint->writable()->setSubpixelText(SkOSMenu::kOnState == fSubpixelState);
|
||||
}
|
||||
if (0 != fHintingState && fHintingState < (int)SK_ARRAY_COUNT(gHintingStates)) {
|
||||
filteredPaint->get()->setHinting(gHintingStates[fHintingState].hinting);
|
||||
paint->writable()->setHinting(gHintingStates[fHintingState].hinting);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -13,23 +13,20 @@
|
||||
class SkPaintFilterCanvas::AutoPaintFilter {
|
||||
public:
|
||||
AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint* paint)
|
||||
: fOrigPaint(paint) {
|
||||
fShouldDraw = canvas->onFilter(fOrigPaint, type, &fFilteredPaint);
|
||||
: fPaint(paint) {
|
||||
fShouldDraw = canvas->onFilter(&fPaint, type);
|
||||
}
|
||||
|
||||
AutoPaintFilter(const SkPaintFilterCanvas* canvas, Type type, const SkPaint& paint)
|
||||
: AutoPaintFilter(canvas, type, &paint) { }
|
||||
|
||||
const SkPaint* paint() const {
|
||||
return fFilteredPaint.isValid() ? fFilteredPaint.get() : fOrigPaint;
|
||||
}
|
||||
const SkPaint* paint() const { return fPaint; }
|
||||
|
||||
bool shouldDraw() const { return fShouldDraw; }
|
||||
|
||||
private:
|
||||
const SkPaint* fOrigPaint;
|
||||
SkTLazy<SkPaint> fFilteredPaint;
|
||||
bool fShouldDraw;
|
||||
SkTCopyOnFirstWrite<SkPaint> fPaint;
|
||||
bool fShouldDraw;
|
||||
};
|
||||
|
||||
SkPaintFilterCanvas::SkPaintFilterCanvas(int width, int height) : INHERITED(width, height) { }
|
||||
|
@ -69,16 +69,15 @@ public:
|
||||
, fFilterQuality(quality) {}
|
||||
|
||||
protected:
|
||||
bool onFilter(const SkPaint* paint, Type, SkTLazy<SkPaint>* filteredPaint) const override {
|
||||
if (paint) {
|
||||
filteredPaint->set(*paint);
|
||||
bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type) const override {
|
||||
if (*paint) {
|
||||
if (nullptr != fOverdrawXfermode.get()) {
|
||||
filteredPaint->get()->setAntiAlias(false);
|
||||
filteredPaint->get()->setXfermode(fOverdrawXfermode.get());
|
||||
paint->writable()->setAntiAlias(false);
|
||||
paint->writable()->setXfermode(fOverdrawXfermode.get());
|
||||
}
|
||||
|
||||
if (fOverrideFilterQuality) {
|
||||
filteredPaint->get()->setFilterQuality(fFilterQuality);
|
||||
paint->writable()->setFilterQuality(fFilterQuality);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -730,7 +730,7 @@ public:
|
||||
MockFilterCanvas(SkCanvas* canvas) : INHERITED(canvas) { }
|
||||
|
||||
protected:
|
||||
bool onFilter(const SkPaint*, Type, SkTLazy<SkPaint>*) const override { return true; }
|
||||
bool onFilter(SkTCopyOnFirstWrite<SkPaint>*, Type) const override { return true; }
|
||||
|
||||
private:
|
||||
typedef SkPaintFilterCanvas INHERITED;
|
||||
|
Loading…
Reference in New Issue
Block a user