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:
parent
688ded2ee6
commit
7627fa5104
@ -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);
|
||||
}
|
||||
|
@ -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().
|
||||
|
||||
|
@ -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);
|
||||
@ -1580,6 +1611,10 @@ 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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user