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));
fBitmap.lockPixels();
fRCStack.push_back().setRect(SkIRect::MakeWH(bitmap.width(), bitmap.height()));
}
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));
fBitmap.lockPixels();
fRCStack.push_back().setRect(SkIRect::MakeWH(bitmap.width(), bitmap.height()));
}
SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
@ -439,7 +443,7 @@ SkImageFilterCache* SkBitmapDevice::getImageFilterCache() {
return cache;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
if (kN32_SkColorType != fBitmap.colorType() ||
@ -453,3 +457,32 @@ bool SkBitmapDevice::onShouldDisableLCD(const SkPaint& paint) const {
}
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 "SkImageInfo.h"
#include "SkPixelRef.h"
#include "SkRasterClip.h"
#include "SkRect.h"
#include "SkScalar.h"
#include "SkSize.h"
@ -125,6 +126,13 @@ protected:
bool onPeekPixels(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:
friend class SkCanvas;
friend struct DeviceCM; //for setMatrixClip
@ -147,6 +155,7 @@ private:
SkBitmap fBitmap;
void* fRasterHandle = nullptr;
SkTArray<SkRasterClip> fRCStack;
void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture().

View File

@ -387,6 +387,16 @@ private:
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) {
@ -999,6 +1009,9 @@ void SkCanvas::doSave() {
SkASSERT(fMCRec->fDeferredSaveCount > 0);
fMCRec->fDeferredSaveCount -= 1;
this->internalSave();
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->save());
#endif
}
void SkCanvas::restore() {
@ -1014,6 +1027,9 @@ void SkCanvas::restore() {
fSaveCount -= 1;
this->internalRestore();
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;
fMCRec->fMatrix.preConcat(matrix);
fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
#endif
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) {
const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
#ifdef SK_USE_DEVICE_CLIPPING
FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA));
#endif
AutoValidateClip avc(this);
fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA);
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;
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);
fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
isAA);
@ -1579,7 +1610,11 @@ void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeSty
fDeviceCMDirty = true;
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);
const SkPath* rasterClipPath = &path;
@ -1602,6 +1637,10 @@ void SkCanvas::clipRegion(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);
fDeviceCMDirty = true;

View File

@ -13,6 +13,9 @@
#include "SkColor.h"
#include "SkSurfaceProps.h"
// enable to test new device-base clipping
//#define SK_USE_DEVICE_CLIPPING
class SkBitmap;
class SkDraw;
class SkDrawFilter;
@ -101,6 +104,35 @@ public:
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:
enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled
@ -119,6 +151,13 @@ protected:
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.
When these are called, we have already applied any saveLayer operations,
and are handling any looping from the paint, and any effects from the
@ -348,6 +387,7 @@ private:
SkIPoint fOrigin;
const SkImageInfo fInfo;
const SkSurfaceProps fSurfaceProps;
SkMatrix fCTM;
typedef SkRefCnt INHERITED;
};