add virtuals in prep for device-clipping

Build flag available for backends to begin testing their impl.

Need to formalize save/restore, and how to forward these to device but not on picture canvases.

BUG=skia:6214

Change-Id: Ic5c0afba3e8c84fcf124567e63fe2f5880b623e7
Reviewed-on: https://skia-review.googlesource.com/8183
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Mike Reed 2017-02-08 10:07:53 -05:00 committed by Skia Commit-Bot
parent 688ded2ee6
commit 7627fa5104
4 changed files with 123 additions and 2 deletions

View File

@ -74,6 +74,8 @@ SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap)
{ {
SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr)); SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
fBitmap.lockPixels(); fBitmap.lockPixels();
fRCStack.push_back().setRect(SkIRect::MakeWH(bitmap.width(), bitmap.height()));
} }
SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) { SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& info) {
@ -88,6 +90,8 @@ SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& sur
{ {
SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr)); SkASSERT(valid_for_bitmap_device(bitmap.info(), nullptr));
fBitmap.lockPixels(); fBitmap.lockPixels();
fRCStack.push_back().setRect(SkIRect::MakeWH(bitmap.width(), bitmap.height()));
} }
SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo, SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
@ -439,7 +443,7 @@ SkImageFilterCache* SkBitmapDevice::getImageFilterCache() {
return cache; return cache;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const { bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
if (kN32_SkColorType != fBitmap.colorType() || if (kN32_SkColorType != fBitmap.colorType() ||
@ -453,3 +457,32 @@ bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
} }
return false; return false;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////
void SkBitmapDevice::onSave() {
fRCStack.push_back(fRCStack.back());
}
void SkBitmapDevice::onRestore() {
fRCStack.pop_back();
}
void SkBitmapDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
fRCStack.back().op(rect, this->ctm(), SkIRect::MakeWH(this->width(), this->height()),
(SkRegion::Op)op, aa);
}
void SkBitmapDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
fRCStack.back().op(rrect, this->ctm(), SkIRect::MakeWH(this->width(), this->height()),
(SkRegion::Op)op, aa);
}
void SkBitmapDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
fRCStack.back().op(path, this->ctm(), SkIRect::MakeWH(this->width(), this->height()),
(SkRegion::Op)op, aa);
}
void SkBitmapDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) {
fRCStack.back().op(rgn, (SkRegion::Op)op);
}

View File

@ -14,6 +14,7 @@
#include "SkDevice.h" #include "SkDevice.h"
#include "SkImageInfo.h" #include "SkImageInfo.h"
#include "SkPixelRef.h" #include "SkPixelRef.h"
#include "SkRasterClip.h"
#include "SkRect.h" #include "SkRect.h"
#include "SkScalar.h" #include "SkScalar.h"
#include "SkSize.h" #include "SkSize.h"
@ -125,6 +126,13 @@ protected:
bool onPeekPixels(SkPixmap*) override; bool onPeekPixels(SkPixmap*) override;
bool onAccessPixels(SkPixmap*) override; bool onAccessPixels(SkPixmap*) override;
void onSave() override;
void onRestore() override;
void onClipRect(const SkRect& rect, SkClipOp, bool aa) override;
void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override;
void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
private: private:
friend class SkCanvas; friend class SkCanvas;
friend struct DeviceCM; //for setMatrixClip friend struct DeviceCM; //for setMatrixClip
@ -147,6 +155,7 @@ private:
SkBitmap fBitmap; SkBitmap fBitmap;
void* fRasterHandle = nullptr; void* fRasterHandle = nullptr;
SkTArray<SkRasterClip> fRCStack;
void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture(). void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture().

View File

@ -387,6 +387,16 @@ private:
typedef SkDraw INHERITED; typedef SkDraw INHERITED;
}; };
#define FOR_EACH_TOP_DEVICE( code ) \
do { \
DeviceCM* layer = fMCRec->fTopLayer; \
while (layer) { \
SkBaseDevice* device = layer->fDevice; \
code; \
layer = layer->fNext; \
} \
} while (0)
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) { static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) {
@ -999,6 +1009,9 @@ void SkCanvas::doSave() {
SkASSERT(fMCRec->fDeferredSaveCount > 0); SkASSERT(fMCRec->fDeferredSaveCount > 0);
fMCRec->fDeferredSaveCount -= 1; fMCRec->fDeferredSaveCount -= 1;
this->internalSave(); this->internalSave();
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->save());
#endif
} }
void SkCanvas::restore() { void SkCanvas::restore() {
@ -1014,6 +1027,9 @@ void SkCanvas::restore() {
fSaveCount -= 1; fSaveCount -= 1;
this->internalRestore(); this->internalRestore();
this->didRestore(); this->didRestore();
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix));
#endif
} }
} }
} }
@ -1456,6 +1472,11 @@ void SkCanvas::concat(const SkMatrix& matrix) {
fDeviceCMDirty = true; fDeviceCMDirty = true;
fMCRec->fMatrix.preConcat(matrix); fMCRec->fMatrix.preConcat(matrix);
fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate(); fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
#endif
this->didConcat(matrix); this->didConcat(matrix);
} }
@ -1505,6 +1526,11 @@ void SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) {
void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
const bool isAA = kSoft_ClipEdgeStyle == edgeStyle; const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA));
#endif
AutoValidateClip avc(this); AutoValidateClip avc(this);
fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA); fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA);
fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
@ -1542,6 +1568,11 @@ void SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edge
fDeviceCMDirty = true; fDeviceCMDirty = true;
bool isAA = kSoft_ClipEdgeStyle == edgeStyle; bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA));
#endif
fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA); fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA);
fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op, fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
isAA); isAA);
@ -1580,6 +1611,10 @@ void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeSty
fDeviceCMDirty = true; fDeviceCMDirty = true;
bool isAA = kSoft_ClipEdgeStyle == edgeStyle; bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA));
#endif
fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA); fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA);
const SkPath* rasterClipPath = &path; const SkPath* rasterClipPath = &path;
@ -1602,6 +1637,10 @@ void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) {
} }
void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) { void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) {
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op));
#endif
AutoValidateClip avc(this); AutoValidateClip avc(this);
fDeviceCMDirty = true; fDeviceCMDirty = true;

View File

@ -13,6 +13,9 @@
#include "SkColor.h" #include "SkColor.h"
#include "SkSurfaceProps.h" #include "SkSurfaceProps.h"
// enable to test new device-base clipping
//#define SK_USE_DEVICE_CLIPPING
class SkBitmap; class SkBitmap;
class SkDraw; class SkDraw;
class SkDrawFilter; class SkDrawFilter;
@ -101,6 +104,35 @@ public:
virtual void* getRasterHandle() const { return nullptr; } virtual void* getRasterHandle() const { return nullptr; }
void save() { this->onSave(); }
void restore(const SkMatrix& ctm) {
this->onRestore();
this->setGlobalCTM(ctm);
}
void clipRect(const SkRect& rect, SkClipOp op, bool aa) {
this->onClipRect(rect, op, aa);
}
void clipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
this->onClipRRect(rrect, op, aa);
}
void clipPath(const SkPath& path, SkClipOp op, bool aa) {
this->onClipPath(path, op, aa);
}
void clipRegion(const SkRegion& region, SkClipOp op) {
this->onClipRegion(region, op);
}
const SkMatrix& ctm() const { return fCTM; }
void setCTM(const SkMatrix& ctm) {
fCTM = ctm;
}
void setGlobalCTM(const SkMatrix& ctm) {
fCTM = ctm;
if (fOrigin.fX | fOrigin.fY) {
fCTM.postTranslate(-SkIntToScalar(fOrigin.fX), -SkIntToScalar(fOrigin.fY));
}
}
protected: protected:
enum TileUsage { enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled kPossible_TileUsage, //!< the created device may be drawn tiled
@ -119,6 +151,13 @@ protected:
virtual bool onShouldDisableLCD(const SkPaint&) const { return false; } virtual bool onShouldDisableLCD(const SkPaint&) const { return false; }
virtual void onSave() {}
virtual void onRestore() {}
virtual void onClipRect(const SkRect& rect, SkClipOp, bool aa) {}
virtual void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) {}
virtual void onClipPath(const SkPath& path, SkClipOp, bool aa) {}
virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp) {}
/** These are called inside the per-device-layer loop for each draw call. /** These are called inside the per-device-layer loop for each draw call.
When these are called, we have already applied any saveLayer operations, When these are called, we have already applied any saveLayer operations,
and are handling any looping from the paint, and any effects from the and are handling any looping from the paint, and any effects from the
@ -348,6 +387,7 @@ private:
SkIPoint fOrigin; SkIPoint fOrigin;
const SkImageInfo fInfo; const SkImageInfo fInfo;
const SkSurfaceProps fSurfaceProps; const SkSurfaceProps fSurfaceProps;
SkMatrix fCTM;
typedef SkRefCnt INHERITED; typedef SkRefCnt INHERITED;
}; };