diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkCanvas.cpp | 18 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 12 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 20 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 46 | ||||
-rw-r--r-- | src/core/SkRecordDraw.cpp | 2 | ||||
-rw-r--r-- | src/core/SkRecordOpts.cpp | 10 | ||||
-rw-r--r-- | src/core/SkRecorder.cpp | 3 |
7 files changed, 88 insertions, 23 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index a4acbdc94d..82ceba4fa9 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -114,7 +114,6 @@ bool SkCanvas::Internal_Private_GetTreatSpriteAsBitmap() { // experimental for faster tiled drawing... //#define SK_ENABLE_CLIP_QUICKREJECT - //#define SK_TRACE_SAVERESTORE #ifdef SK_TRACE_SAVERESTORE @@ -481,7 +480,7 @@ public: // Make rawBounds include all paint outsets except for those due to image filters. rawBounds = &apply_paint_to_bounds_sans_imagefilter(*fPaint, *rawBounds, &storage); } - (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp, 0), + (void)canvas->internalSaveLayer(SkCanvas::SaveLayerRec(rawBounds, &tmp), SkCanvas::kFullLayer_SaveLayerStrategy); fTempLayerForImageFilter = true; // we remove the imagefilter/xfermode inside doNext() @@ -1173,7 +1172,8 @@ int SkCanvas::saveLayer(const SaveLayerRec& origRec) { return this->getSaveCount() - 1; } -static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, SkBaseDevice* dst) { +static void draw_filter_into_device(SkBaseDevice* src, const SkImageFilter* filter, + SkBaseDevice* dst, const SkMatrix& ctm) { SkBitmap srcBM; @@ -1198,9 +1198,12 @@ static void draw_filter_into_device(SkBaseDevice* src, SkImageFilter* filter, Sk SkCanvas c(dst); + SkAutoTUnref<SkImageFilter> localF(filter->newWithLocalMatrix(ctm)); SkPaint p; - p.setImageFilter(filter); - c.drawBitmap(srcBM, 0, 0, &p); + p.setImageFilter(localF); + const SkScalar x = SkIntToScalar(src->getOrigin().x()); + const SkScalar y = SkIntToScalar(src->getOrigin().y()); + c.drawBitmap(srcBM, x, y, &p); } void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy strategy) { @@ -1268,11 +1271,10 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra } device = newDev; } - device->setOrigin(ir.fLeft, ir.fTop); - if (0) { - draw_filter_into_device(fMCRec->fTopLayer->fDevice, nullptr, device); + if (rec.fBackdrop) { + draw_filter_into_device(fMCRec->fTopLayer->fDevice, rec.fBackdrop, device, fMCRec->fMatrix); } DeviceCM* layer = diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h index cbacc8e664..4eee04fcda 100644 --- a/src/core/SkPictureFlat.h +++ b/src/core/SkPictureFlat.h @@ -75,9 +75,10 @@ enum DrawType { DRAW_IMAGE_NINE, DRAW_IMAGE_RECT, - SAVE_LAYER_SAVELAYERFLAGS, + SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016, + SAVE_LAYER_SAVELAYERREC, - LAST_DRAWTYPE_ENUM = SAVE_LAYER_SAVELAYERFLAGS, + LAST_DRAWTYPE_ENUM = SAVE_LAYER_SAVELAYERREC, }; // In the 'match' method, this constant will match any flavor of DRAW_BITMAP* @@ -95,6 +96,13 @@ enum DrawAtlasFlags { DRAW_ATLAS_HAS_CULL = 1 << 1, }; +enum SaveLayerRecFlatFlags { + SAVELAYERREC_HAS_BOUNDS = 1 << 0, + SAVELAYERREC_HAS_PAINT = 1 << 1, + SAVELAYERREC_HAS_BACKDROP = 1 << 2, + SAVELAYERREC_HAS_FLAGS = 1 << 3, +}; + /////////////////////////////////////////////////////////////////////////////// // clipparams are packed in 5 bits // doAA:1 | regionOp:4 diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 82b8f0e578..4b028f714e 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -483,11 +483,29 @@ void SkPicturePlayback::handleOp(SkReader32* reader, auto flags = SkCanvas::LegacySaveFlagsToSaveLayerFlags(reader->readInt()); canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, flags)); } break; - case SAVE_LAYER_SAVELAYERFLAGS: { + case SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016: { const SkRect* boundsPtr = get_rect_ptr(reader); const SkPaint* paint = fPictureData->getPaint(reader); canvas->saveLayer(SkCanvas::SaveLayerRec(boundsPtr, paint, reader->readInt())); } break; + case SAVE_LAYER_SAVELAYERREC: { + SkCanvas::SaveLayerRec rec(nullptr, nullptr, nullptr, 0); + const uint32_t flatFlags = reader->readInt(); + if (flatFlags & SAVELAYERREC_HAS_BOUNDS) { + rec.fBounds = &reader->skipT<SkRect>(); + } + if (flatFlags & SAVELAYERREC_HAS_PAINT) { + rec.fPaint = fPictureData->getPaint(reader); + } + if (flatFlags & SAVELAYERREC_HAS_BACKDROP) { + const SkPaint* paint = fPictureData->getPaint(reader); + rec.fBackdrop = paint->getImageFilter(); + } + if (flatFlags & SAVELAYERREC_HAS_FLAGS) { + rec.fSaveLayerFlags = reader->readInt(); + } + canvas->saveLayer(rec); + } break; case SCALE: { SkScalar sx = reader->readScalar(); SkScalar sy = reader->readScalar(); diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp index 7907ee0d29..2822a1ac16 100644 --- a/src/core/SkPictureRecord.cpp +++ b/src/core/SkPictureRecord.cpp @@ -76,19 +76,44 @@ SkCanvas::SaveLayerStrategy SkPictureRecord::getSaveLayerStrategy(const SaveLaye void SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) { fContentInfo.onSaveLayer(); - // op + bool for 'bounds' + // op + flatflags size_t size = 2 * kUInt32Size; + uint32_t flatFlags = 0; + if (rec.fBounds) { - size += sizeof(*rec.fBounds); // + rect + flatFlags |= SAVELAYERREC_HAS_BOUNDS; + size += sizeof(*rec.fBounds); + } + if (rec.fPaint) { + flatFlags |= SAVELAYERREC_HAS_PAINT; + size += sizeof(uint32_t); // index + } + if (rec.fBackdrop) { + flatFlags |= SAVELAYERREC_HAS_BACKDROP; + size += sizeof(uint32_t); // (paint) index + } + if (rec.fSaveLayerFlags) { + flatFlags |= SAVELAYERREC_HAS_FLAGS; + size += sizeof(uint32_t); } - // + paint index + flags - size += 2 * kUInt32Size; - - size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERFLAGS, &size); - this->addRectPtr(rec.fBounds); - this->addPaintPtr(rec.fPaint); - this->addInt(rec.fSaveLayerFlags); + const size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERREC, &size); + this->addInt(flatFlags); + if (flatFlags & SAVELAYERREC_HAS_BOUNDS) { + this->addRect(*rec.fBounds); + } + if (flatFlags & SAVELAYERREC_HAS_PAINT) { + this->addPaintPtr(rec.fPaint); + } + if (flatFlags & SAVELAYERREC_HAS_BACKDROP) { + // overkill, but we didn't already track single flattenables, so using a paint for that + SkPaint paint; + paint.setImageFilter(const_cast<SkImageFilter*>(rec.fBackdrop)); + this->addPaint(paint); + } + if (flatFlags & SAVELAYERREC_HAS_FLAGS) { + this->addInt(rec.fSaveLayerFlags); + } this->validate(initialOffset, size); } @@ -224,7 +249,8 @@ void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t uint32_t opSize; DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); SkASSERT(SAVE_LAYER_SAVEFLAGS_DEPRECATED != drawOp); - SkASSERT(SAVE == drawOp || SAVE_LAYER_SAVELAYERFLAGS == drawOp); + SkASSERT(SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016 != drawOp); + SkASSERT(SAVE == drawOp || SAVE_LAYER_SAVELAYERREC == drawOp); } #endif } diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp index 01846676b6..5ca9517d3f 100644 --- a/src/core/SkRecordDraw.cpp +++ b/src/core/SkRecordDraw.cpp @@ -78,7 +78,7 @@ template <> void Draw::draw(const NoOp&) {} #define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; } DRAW(Restore, restore()); DRAW(Save, save()); -DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds, r.paint, r.saveLayerFlags))); +DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds, r.paint, r.backdrop, r.saveLayerFlags))); DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix))); DRAW(Concat, concat(r.matrix)); diff --git a/src/core/SkRecordOpts.cpp b/src/core/SkRecordOpts.cpp index d1520adf56..0121ea54fc 100644 --- a/src/core/SkRecordOpts.cpp +++ b/src/core/SkRecordOpts.cpp @@ -177,6 +177,11 @@ struct SaveLayerDrawRestoreNooper { typedef Pattern<Is<SaveLayer>, IsDraw, Is<Restore>> Match; bool onMatch(SkRecord* record, Match* match, int begin, int end) { + if (match->first<SaveLayer>()->backdrop) { + // can't throw away the layer if we have a backdrop + return false; + } + // A SaveLayer's bounds field is just a hint, so we should be free to ignore it. SkPaint* layerPaint = match->first<SaveLayer>()->paint; if (nullptr == layerPaint) { @@ -224,6 +229,11 @@ struct SvgOpacityAndFilterLayerMergePass { Is<Restore>, Is<Restore>, Is<Restore>> Match; bool onMatch(SkRecord* record, Match* match, int begin, int end) { + if (match->first<SaveLayer>()->backdrop) { + // can't throw away the layer if we have a backdrop + return false; + } + SkPaint* opacityPaint = match->first<SaveLayer>()->paint; if (nullptr == opacityPaint) { // There wasn't really any point to this SaveLayer at all. diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 67429a691e..01c28dfc2b 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -337,7 +337,8 @@ void SkRecorder::willSave() { } SkCanvas::SaveLayerStrategy SkRecorder::getSaveLayerStrategy(const SaveLayerRec& rec) { - APPEND(SaveLayer, this->copy(rec.fBounds), this->copy(rec.fPaint), rec.fSaveLayerFlags); + APPEND(SaveLayer, + this->copy(rec.fBounds), this->copy(rec.fPaint), rec.fBackdrop, rec.fSaveLayerFlags); return SkCanvas::kNoLayer_SaveLayerStrategy; } |