diff options
author | Mike Klein <mtklein@google.com> | 2018-10-12 12:23:41 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-10-12 16:50:21 +0000 |
commit | 36528e91c2c0ff935504c5e31d4858bdb7ad03c2 (patch) | |
tree | c67a8c8c03482503b24d64ae3d0b244edc87349b /experimental | |
parent | 419709dbb167cb0399313998c60c86d622024028 (diff) | |
download | skqp-36528e91c2c0ff935504c5e31d4858bdb7ad03c2.tar.gz |
clean up SkPipe
One less SkCanvas subclass to deal with...
Change-Id: I21e81648026be5d732e8d9a28baed55015492a04
Reviewed-on: https://skia-review.googlesource.com/c/161584
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
Diffstat (limited to 'experimental')
-rw-r--r-- | experimental/pipe/SkPipe.h | 76 | ||||
-rw-r--r-- | experimental/pipe/SkPipeCanvas.cpp | 996 | ||||
-rw-r--r-- | experimental/pipe/SkPipeCanvas.h | 169 | ||||
-rw-r--r-- | experimental/pipe/SkPipeFormat.h | 217 | ||||
-rw-r--r-- | experimental/pipe/SkPipeReader.cpp | 905 | ||||
-rw-r--r-- | experimental/pipe/SkRefSet.h | 38 |
6 files changed, 0 insertions, 2401 deletions
diff --git a/experimental/pipe/SkPipe.h b/experimental/pipe/SkPipe.h deleted file mode 100644 index 65b4e01828..0000000000 --- a/experimental/pipe/SkPipe.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkPipe_DEFINED -#define SkPipe_DEFINED - -#include "SkData.h" -#include "SkImage.h" -#include "SkPicture.h" -#include "SkSerialProcs.h" - -class SkCanvas; -class SkTypeface; -class SkWStream; - -struct SkRect; - -class SkPipeSerializer { -public: - SkPipeSerializer(); - ~SkPipeSerializer(); - - void setSerialProcs(const SkSerialProcs&); - - void resetCache(); - - sk_sp<SkData> writeImage(SkImage*); - sk_sp<SkData> writePicture(SkPicture*); - - void writeImage(SkImage*, SkWStream*); - void writePicture(SkPicture*, SkWStream*); - - SkCanvas* beginWrite(const SkRect& cullBounds, SkWStream*); - void endWrite(); - -private: - class Impl; - std::unique_ptr<Impl> fImpl; -}; - -class SkPipeDeserializer { -public: - SkPipeDeserializer(); - ~SkPipeDeserializer(); - - void setDeserialProcs(const SkDeserialProcs&); - - sk_sp<SkImage> readImage(const SkData* data) { - if (!data) { - return nullptr; - } - return this->readImage(data->data(), data->size()); - } - - sk_sp<SkPicture> readPicture(const SkData* data) { - if (!data) { - return nullptr; - } - return this->readPicture(data->data(), data->size()); - } - - sk_sp<SkImage> readImage(const void*, size_t); - sk_sp<SkPicture> readPicture(const void*, size_t); - - bool playback(const void*, size_t, SkCanvas*); - -private: - class Impl; - std::unique_ptr<Impl> fImpl; -}; - -#endif diff --git a/experimental/pipe/SkPipeCanvas.cpp b/experimental/pipe/SkPipeCanvas.cpp deleted file mode 100644 index 93e382bce9..0000000000 --- a/experimental/pipe/SkPipeCanvas.cpp +++ /dev/null @@ -1,996 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkPipeCanvas.h" - -#include "SkAutoMalloc.h" -#include "SkCanvasPriv.h" -#include "SkColorFilter.h" -#include "SkDrawLooper.h" -#include "SkDrawShadowInfo.h" -#include "SkDrawable.h" -#include "SkImageFilter.h" -#include "SkMaskFilter.h" -#include "SkPathEffect.h" -#include "SkPipeFormat.h" -#include "SkRSXform.h" -#include "SkShader.h" -#include "SkStream.h" -#include "SkTextBlobPriv.h" -#include "SkTo.h" -#include "SkTypeface.h" - -template <typename T> void write_rrect(T* writer, const SkRRect& rrect) { - char tmp[SkRRect::kSizeInMemory]; - rrect.writeToMemory(tmp); - writer->write(tmp, SkRRect::kSizeInMemory); -} - -template <typename T> void write_pad(T* writer, const void* buffer, size_t len) { - writer->write(buffer, len & ~3); - if (len & 3) { - const char* src = (const char*)buffer + (len & ~3); - len &= 3; - uint32_t tmp = 0; - memcpy(&tmp, src, len); - writer->write(&tmp, 4); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static uint16_t compute_nondef(const SkPaint& paint, PaintUsage usage) { - // kRespectsStroke_PaintUsage is only valid if other bits are also set - SkASSERT(0 != (usage & ~kRespectsStroke_PaintUsage)); - - const SkScalar kTextSize_Default = 12; - const SkScalar kTextScaleX_Default = 1; - const SkScalar kTextSkewX_Default = 0; - const SkScalar kStrokeWidth_Default = 0; - const SkScalar kStrokeMiter_Default = 4; - const SkColor kColor_Default = SK_ColorBLACK; - - unsigned bits = (paint.getColor() != kColor_Default) ? kColor_NonDef : 0; - - if (usage & kText_PaintUsage) { - bits |= (paint.getTextSize() != kTextSize_Default ? kTextSize_NonDef : 0); - bits |= (paint.getTextScaleX() != kTextScaleX_Default ? kTextScaleX_NonDef : 0); - bits |= (paint.getTextSkewX() != kTextSkewX_Default ? kTextSkewX_NonDef : 0); - bits |= (paint.getTypeface() ? kTypeface_NonDef : 0); - } - - // TODO: kImage_PaintUsage only needs the shader/maskfilter IF its colortype is kAlpha_8 - - if (usage & (kVertices_PaintUsage | kDrawPaint_PaintUsage | kImage_PaintUsage | - kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) { - bits |= (paint.getShader() ? kShader_NonDef : 0); - } - - if (usage & (kText_PaintUsage | kGeometry_PaintUsage | kTextBlob_PaintUsage)) { - bits |= (paint.getPathEffect() ? kPathEffect_NonDef : 0); - - if (paint.getStyle() != SkPaint::kFill_Style || (usage & kRespectsStroke_PaintUsage)) { - bits |= (paint.getStrokeWidth() != kStrokeWidth_Default ? kStrokeWidth_NonDef : 0); - bits |= (paint.getStrokeMiter() != kStrokeMiter_Default ? kStrokeMiter_NonDef : 0); - } - } - - if (usage & - (kText_PaintUsage | kGeometry_PaintUsage | kImage_PaintUsage | kTextBlob_PaintUsage)) - { - bits |= (paint.getMaskFilter() ? kMaskFilter_NonDef : 0); - } - - bits |= (paint.getColorFilter() ? kColorFilter_NonDef : 0); - bits |= (paint.getImageFilter() ? kImageFilter_NonDef : 0); - bits |= (paint.getDrawLooper() ? kDrawLooper_NonDef : 0); - - return SkToU16(bits); -} - -static uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align, - unsigned filter, unsigned style, unsigned caps, unsigned joins, - unsigned encoding) { - SkASSERT(kFlags_BPF + kHint_BPF + kAlign_BPF + kFilter_BPF <= 32); - - ASSERT_FITS_IN(flags, kFlags_BPF); - ASSERT_FITS_IN(filter, kFilter_BPF); - ASSERT_FITS_IN(style, kStyle_BPF); - ASSERT_FITS_IN(caps, kCaps_BPF); - ASSERT_FITS_IN(joins, kJoins_BPF); - ASSERT_FITS_IN(hint, kHint_BPF); - ASSERT_FITS_IN(align, kAlign_BPF); - ASSERT_FITS_IN(encoding, kEncoding_BPF); - - // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly - // add more bits in the future. - - uint32_t packed = 0; - int shift = 32; - - shift -= kFlags_BPF; packed |= (flags << shift); - shift -= kFilter_BPF; packed |= (filter << shift); - shift -= kStyle_BPF; packed |= (style << shift); - // these are only needed for stroking (geometry or text) - shift -= kCaps_BPF; packed |= (caps << shift); - shift -= kJoins_BPF; packed |= (joins << shift); - // these are only needed for text - shift -= kHint_BPF; packed |= (hint << shift); - shift -= kAlign_BPF; packed |= (align << shift); - shift -= kEncoding_BPF; packed |= (encoding << shift); - - return packed; -} - -#define CHECK_WRITE_SCALAR(writer, nondef, paint, Field) \ - do { if (nondef & (k##Field##_NonDef)) { \ - writer.writeScalar(paint.get##Field()); \ - }} while (0) - -#define CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Field) \ - do { if (nondef & (k##Field##_NonDef)) { \ - SkFlattenable* f = paint.get##Field(); \ - SkASSERT(f != nullptr); \ - writer.writeFlattenable(f); \ - } } while (0) - -/* - * Header: - * paint flags : 32 - * non_def bits : 16 - * xfermode enum : 8 - * pad zeros : 8 - */ -static void write_paint(SkWriteBuffer& writer, const SkPaint& paint, unsigned usage) { - uint32_t packedFlags = pack_paint_flags(paint.getFlags(), paint.getHinting(), - paint.getTextAlign(), paint.getFilterQuality(), - paint.getStyle(), paint.getStrokeCap(), - paint.getStrokeJoin(), paint.getTextEncoding()); - writer.write32(packedFlags); - - unsigned nondef = compute_nondef(paint, (PaintUsage)usage); - const uint8_t pad = 0; - writer.write32((nondef << 16) | ((unsigned)paint.getBlendMode() << 8) | pad); - - CHECK_WRITE_SCALAR(writer, nondef, paint, TextSize); - CHECK_WRITE_SCALAR(writer, nondef, paint, TextScaleX); - CHECK_WRITE_SCALAR(writer, nondef, paint, TextSkewX); - CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeWidth); - CHECK_WRITE_SCALAR(writer, nondef, paint, StrokeMiter); - - if (nondef & kColor_NonDef) { - writer.write32(paint.getColor()); - } - if (nondef & kTypeface_NonDef) { - // TODO: explore idea of writing bits indicating "use the prev (or prev N) face" - // e.g. 1-N bits is an index into a ring buffer of typefaces - SkTypeface* tf = paint.getTypeface(); - SkASSERT(tf); - writer.writeTypeface(tf); - } - - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, PathEffect); - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, Shader); - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, MaskFilter); - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ColorFilter); - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, ImageFilter); - CHECK_WRITE_FLATTENABLE(writer, nondef, paint, DrawLooper); -} - -class SkPipeWriter : public SkBinaryWriteBuffer { - enum { - N = 1024/4, - }; - uint32_t fStorage[N]; - SkWStream* fStream; - -public: - SkPipeWriter(SkWStream* stream, SkDeduper* deduper) - : SkBinaryWriteBuffer(fStorage, sizeof(fStorage)) - , fStream(stream) - { - this->setDeduper(deduper); - } - - SkPipeWriter(SkPipeCanvas* pc) : SkPipeWriter(pc->fStream, pc->fDeduper) {} - - ~SkPipeWriter() override { - SkASSERT(SkIsAlign4(fStream->bytesWritten())); - this->writeToStream(fStream); - } - - void writePaint(const SkPaint& paint) override { - write_paint(*this, paint, kUnknown_PaintUsage); - } -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -SkPipeCanvas::SkPipeCanvas(const SkRect& cull, SkPipeDeduper* deduper, SkWStream* stream) - : INHERITED(cull.roundOut()) - , fDeduper(deduper) - , fStream(stream) -{} - -SkPipeCanvas::~SkPipeCanvas() {} - -void SkPipeCanvas::willSave() { - fStream->write32(pack_verb(SkPipeVerb::kSave)); - this->INHERITED::willSave(); -} - -SkCanvas::SaveLayerStrategy SkPipeCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { - SkPipeWriter writer(this); - uint32_t extra = rec.fSaveLayerFlags; - - // remap this wacky flag - if (extra & SkCanvasPriv::kDontClipToLayer_SaveLayerFlag) { - extra &= ~SkCanvasPriv::kDontClipToLayer_SaveLayerFlag; - extra |= kDontClipToLayer_SaveLayerMask; - } - - if (rec.fBounds) { - extra |= kHasBounds_SaveLayerMask; - } - if (rec.fPaint) { - extra |= kHasPaint_SaveLayerMask; - } - if (rec.fBackdrop) { - extra |= kHasBackdrop_SaveLayerMask; - } - if (rec.fClipMask) { - extra |= kHasClipMask_SaveLayerMask; - } - if (rec.fClipMatrix) { - extra |= kHasClipMatrix_SaveLayerMask; - } - - writer.write32(pack_verb(SkPipeVerb::kSaveLayer, extra)); - if (rec.fBounds) { - writer.writeRect(*rec.fBounds); - } - if (rec.fPaint) { - write_paint(writer, *rec.fPaint, kSaveLayer_PaintUsage); - } - if (rec.fBackdrop) { - writer.writeFlattenable(rec.fBackdrop); - } - if (rec.fClipMask) { - writer.writeImage(rec.fClipMask); - } - if (rec.fClipMatrix) { - writer.writeMatrix(*rec.fClipMatrix); - } - - return kNoLayer_SaveLayerStrategy; -} - -void SkPipeCanvas::willRestore() { - fStream->write32(pack_verb(SkPipeVerb::kRestore)); - this->INHERITED::willRestore(); -} - -template <typename T> void write_sparse_matrix(T* writer, const SkMatrix& matrix) { - SkMatrix::TypeMask tm = matrix.getType(); - SkScalar tmp[9]; - if (tm & SkMatrix::kPerspective_Mask) { - matrix.get9(tmp); - writer->write(tmp, 9 * sizeof(SkScalar)); - } else if (tm & SkMatrix::kAffine_Mask) { - tmp[0] = matrix[SkMatrix::kMScaleX]; - tmp[1] = matrix[SkMatrix::kMSkewX]; - tmp[2] = matrix[SkMatrix::kMTransX]; - tmp[3] = matrix[SkMatrix::kMScaleY]; - tmp[4] = matrix[SkMatrix::kMSkewY]; - tmp[5] = matrix[SkMatrix::kMTransY]; - writer->write(tmp, 6 * sizeof(SkScalar)); - } else if (tm & SkMatrix::kScale_Mask) { - tmp[0] = matrix[SkMatrix::kMScaleX]; - tmp[1] = matrix[SkMatrix::kMTransX]; - tmp[2] = matrix[SkMatrix::kMScaleY]; - tmp[3] = matrix[SkMatrix::kMTransY]; - writer->write(tmp, 4 * sizeof(SkScalar)); - } else if (tm & SkMatrix::kTranslate_Mask) { - tmp[0] = matrix[SkMatrix::kMTransX]; - tmp[1] = matrix[SkMatrix::kMTransY]; - writer->write(tmp, 2 * sizeof(SkScalar)); - } - // else write nothing for Identity -} - -static void do_concat(SkWStream* stream, const SkMatrix& matrix, bool isSetMatrix) { - unsigned mtype = matrix.getType(); - SkASSERT(0 == (mtype & ~kTypeMask_ConcatMask)); - unsigned extra = mtype; - if (isSetMatrix) { - extra |= kSetMatrix_ConcatMask; - } - if (mtype || isSetMatrix) { - stream->write32(pack_verb(SkPipeVerb::kConcat, extra)); - write_sparse_matrix(stream, matrix); - } -} - -void SkPipeCanvas::didConcat(const SkMatrix& matrix) { - do_concat(fStream, matrix, false); - this->INHERITED::didConcat(matrix); -} - -void SkPipeCanvas::didSetMatrix(const SkMatrix& matrix) { - do_concat(fStream, matrix, true); - this->INHERITED::didSetMatrix(matrix); -} - -void SkPipeCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { - fStream->write32(pack_verb(SkPipeVerb::kClipRect, ((unsigned)op << 1) | edgeStyle)); - fStream->write(&rect, 4 * sizeof(SkScalar)); - - this->INHERITED::onClipRect(rect, op, edgeStyle); -} - -void SkPipeCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { - fStream->write32(pack_verb(SkPipeVerb::kClipRRect, ((unsigned)op << 1) | edgeStyle)); - write_rrect(fStream, rrect); - - this->INHERITED::onClipRRect(rrect, op, edgeStyle); -} - -void SkPipeCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kClipPath, ((unsigned)op << 1) | edgeStyle)); - writer.writePath(path); - - this->INHERITED::onClipPath(path, op, edgeStyle); -} - -void SkPipeCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kClipRegion, (unsigned)op << 1)); - writer.writeRegion(deviceRgn); - - this->INHERITED::onClipRegion(deviceRgn, op); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void SkPipeCanvas::onDrawArc(const SkRect& bounds, SkScalar startAngle, SkScalar sweepAngle, - bool useCenter, const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawArc, (int)useCenter)); - writer.writeRect(bounds); - writer.writeScalar(startAngle); - writer.writeScalar(sweepAngle); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawAtlas(const SkImage* image, const SkRSXform xform[], const SkRect rect[], - const SkColor colors[], int count, SkBlendMode mode, - const SkRect* cull, const SkPaint* paint) { - unsigned extra = (unsigned)mode; - SkASSERT(0 == (extra & ~kMode_DrawAtlasMask)); - if (colors) { - extra |= kHasColors_DrawAtlasMask; - } - if (cull) { - extra |= kHasCull_DrawAtlasMask; - } - if (paint) { - extra |= kHasPaint_DrawAtlasMask; - } - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawAtlas, extra)); - writer.writeImage(image); - writer.write32(count); - writer.write(xform, count * sizeof(SkRSXform)); - writer.write(rect, count * sizeof(SkRect)); - if (colors) { - writer.write(colors, count * sizeof(SkColor)); - } - if (cull) { - writer.writeRect(*cull); - } - if (paint) { - write_paint(writer, *paint, kImage_PaintUsage); - } -} - -void SkPipeCanvas::onDrawPaint(const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawPaint)); - write_paint(writer, paint, kDrawPaint_PaintUsage); -} - -void SkPipeCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawPoints, mode)); - writer.write32(SkToU32(count)); - writer.write(pts, count * sizeof(SkPoint)); - write_paint(writer, paint, kGeometry_PaintUsage | kRespectsStroke_PaintUsage); -} - -void SkPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawRect)); - writer.write(&rect, sizeof(SkRect)); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawOval)); - writer.write(&rect, sizeof(SkRect)); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawRRect)); - write_rrect(&writer, rrect); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawDRRect)); - write_rrect(&writer, outer); - write_rrect(&writer, inner); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawPath)); - writer.writePath(path); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawShadowRec)); - writer.writePath(path); - writer.write(&rec, sizeof(rec)); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static sk_sp<SkImage> make_from_bitmap(const SkBitmap& bitmap) { - // If we just "make" an image, it will force a CPU copy (if its mutable), only to have - // us then either find it in our cache, or compress and send it. - // - // Better could be to look it up in our cache first, and only create/compress it if we have to. - // - // But for now, just do the dumb thing... - return SkImage::MakeFromBitmap(bitmap); -} - -void SkPipeCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, - const SkPaint* paint) { - sk_sp<SkImage> image = make_from_bitmap(bitmap); - if (image) { - this->onDrawImage(image.get(), x, y, paint); - } -} - -void SkPipeCanvas::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, - const SkPaint* paint, SrcRectConstraint constraint) { - sk_sp<SkImage> image = make_from_bitmap(bitmap); - if (image) { - this->onDrawImageRect(image.get(), src, dst, paint, constraint); - } -} - -void SkPipeCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, - const SkRect& dst, const SkPaint* paint) { - sk_sp<SkImage> image = make_from_bitmap(bitmap); - if (image) { - this->onDrawImageNine(image.get(), center, dst, paint); - } -} - -void SkPipeCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, - const SkRect& dst, const SkPaint* paint) { - sk_sp<SkImage> image = make_from_bitmap(bitmap); - if (image) { - this->onDrawImageLattice(image.get(), lattice, dst, paint); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void SkPipeCanvas::onDrawImage(const SkImage* image, SkScalar left, SkScalar top, - const SkPaint* paint) { - unsigned extra = 0; - if (paint) { - extra |= kHasPaint_DrawImageMask; - } - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawImage, extra)); - writer.writeImage(image); - writer.writeScalar(left); - writer.writeScalar(top); - if (paint) { - write_paint(writer, *paint, kImage_PaintUsage); - } -} - -void SkPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, - const SkPaint* paint, SrcRectConstraint constraint) { - SkASSERT(0 == ((unsigned)constraint & ~1)); - unsigned extra = (unsigned)constraint; - if (paint) { - extra |= kHasPaint_DrawImageRectMask; - } - if (src) { - extra |= kHasSrcRect_DrawImageRectMask; - } - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawImageRect, extra)); - writer.writeImage(image); - if (src) { - writer.write(src, sizeof(*src)); - } - writer.write(&dst, sizeof(dst)); - if (paint) { - write_paint(writer, *paint, kImage_PaintUsage); - } -} - -void SkPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, - const SkPaint* paint) { - unsigned extra = 0; - if (paint) { - extra |= kHasPaint_DrawImageNineMask; - } - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawImageNine, extra)); - writer.writeImage(image); - writer.write(¢er, sizeof(center)); - writer.write(&dst, sizeof(dst)); - if (paint) { - write_paint(writer, *paint, kImage_PaintUsage); - } -} - -void SkPipeCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice, - const SkRect& dst, const SkPaint* paint) { - unsigned extra = 0; - if (paint) { - extra |= kHasPaint_DrawImageLatticeMask; - } - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawImageLattice, extra)); - writer.writeImage(image); - SkCanvasPriv::WriteLattice(writer, lattice); - writer.write(&dst, sizeof(dst)); - if (paint) { - write_paint(writer, *paint, kImage_PaintUsage); - } -} - -void SkPipeCanvas::onDrawImageSet(const ImageSetEntry set[], int count, float alpha, - SkFilterQuality filterQuality, SkBlendMode mode) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawImageSet)); - writer.writeInt(count); - writer.writeScalar(SkFloatToScalar(alpha)); - writer.writeInt((int)filterQuality); - writer.writeInt((int)mode); - for (int i = 0; i < count; ++i) { - writer.writeImage(set[i].fImage.get()); - writer.writeRect(set[i].fSrcRect); - writer.writeRect(set[i].fDstRect); - writer.writeUInt(set[i].fAAFlags); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void SkPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, - const SkPaint& paint) { - SkASSERT(byteLength); - - bool compact = fits_in(byteLength, 24); - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawText, compact ? (unsigned)byteLength : 0)); - if (!compact) { - writer.write32(SkToU32(byteLength)); - } - write_pad(&writer, text, byteLength); - writer.writeScalar(x); - writer.writeScalar(y); - write_paint(writer, paint, kText_PaintUsage); -} - -void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], - const SkPaint& paint) { - SkASSERT(byteLength); - - bool compact = fits_in(byteLength, 24); - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawPosText, compact ? (unsigned)byteLength : 0)); - if (!compact) { - writer.write32(SkToU32(byteLength)); - } - write_pad(&writer, text, byteLength); - writer.writePointArray(pos, paint.countText(text, byteLength)); - write_paint(writer, paint, kText_PaintUsage); -} - -void SkPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], - SkScalar constY, const SkPaint& paint) { - SkASSERT(byteLength); - - bool compact = fits_in(byteLength, 24); - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawPosTextH, compact ? (unsigned)byteLength : 0)); - if (!compact) { - writer.write32(SkToU32(byteLength)); - } - write_pad(&writer, text, byteLength); - writer.writeScalarArray(xpos, paint.countText(text, byteLength)); - writer.writeScalar(constY); - write_paint(writer, paint, kText_PaintUsage); -} - -void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], - const SkRect* cull, const SkPaint& paint) { - SkASSERT(byteLength); - - bool compact = fits_in(byteLength, 23); - unsigned extra = compact ? (byteLength << 1) : 0; - if (cull) { - extra |= 1; - } - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawTextRSXform, extra)); - if (!compact) { - writer.write32(SkToU32(byteLength)); - } - write_pad(&writer, text, byteLength); - - int count = paint.countText(text, byteLength); - writer.write32(count); // maybe we can/should store this in extra as well? - writer.write(xform, count * sizeof(SkRSXform)); - if (cull) { - writer.writeRect(*cull); - } - write_paint(writer, paint, kText_PaintUsage); -} - -void SkPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, - const SkPaint &paint) { - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawTextBlob, 0)); - SkTextBlobPriv::Flatten(*blob, writer); - writer.writeScalar(x); - writer.writeScalar(y); - write_paint(writer, paint, kTextBlob_PaintUsage); -} - -void SkPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint) { - unsigned extra = fDeduper->findOrDefinePicture(const_cast<SkPicture*>(picture)); - if (matrix) { - extra |= kHasMatrix_DrawPictureExtra; - } - if (paint) { - extra |= kHasPaint_DrawPictureExtra; - } - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawPicture, extra)); - if (matrix) { - writer.writeMatrix(*matrix); - } - if (paint) { - write_paint(writer, *paint, kSaveLayer_PaintUsage); - } -} - -void SkPipeCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { - // TODO: Is there a better solution than just exploding the drawable? - drawable->draw(this, matrix); -} - -void SkPipeCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) { - size_t size = region.writeToMemory(nullptr); - unsigned extra = 0; - if (fits_in(size, 24)) { - extra = SkToUInt(size); - } - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawRegion, extra)); - if (0 == extra) { - writer.write32(size); - } - SkAutoSMalloc<2048> storage(size); - region.writeToMemory(storage.get()); - write_pad(&writer, storage.get(), size); - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[], - int boneCount, SkBlendMode bmode, const SkPaint& paint) { - unsigned extra = static_cast<unsigned>(bmode); - - SkPipeWriter writer(this); - writer.write32(pack_verb(SkPipeVerb::kDrawVertices, extra)); - // TODO: dedup vertices? - writer.writeDataAsByteArray(vertices->encode().get()); - writer.write32(boneCount); - writer.write(bones, sizeof(SkVertices::Bone) * boneCount); - write_paint(writer, paint, kVertices_PaintUsage); -} - -void SkPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], - const SkPoint texCoords[4], SkBlendMode bmode, - const SkPaint& paint) { - SkPipeWriter writer(this); - unsigned extra = 0; - SkASSERT(0 == ((int)bmode & ~kModeEnum_DrawPatchExtraMask)); - extra = (unsigned)bmode; - if (colors) { - extra |= kHasColors_DrawPatchExtraMask; - } - if (texCoords) { - extra |= kHasTexture_DrawPatchExtraMask; - } - writer.write32(pack_verb(SkPipeVerb::kDrawPatch, extra)); - writer.write(cubics, sizeof(SkPoint) * 12); - if (colors) { - writer.write(colors, sizeof(SkColor) * 4); - } - if (texCoords) { - writer.write(texCoords, sizeof(SkPoint) * 4); - } - write_paint(writer, paint, kGeometry_PaintUsage); -} - -void SkPipeCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) { - const size_t len = strlen(key) + 1; // must write the trailing 0 - bool compact = fits_in(len, 23); - uint32_t extra = compact ? (unsigned)len : 0; - extra <<= 1; // make room for has_data_sentinel - if (data) { - extra |= 1; - } - - fStream->write32(pack_verb(SkPipeVerb::kDrawAnnotation, extra)); - fStream->write(&rect, sizeof(SkRect)); - if (!compact) { - fStream->write32(SkToU32(len)); - } - write_pad(fStream, key, len); - if (data) { - fStream->write32(SkToU32(data->size())); - write_pad(fStream, data->data(), data->size()); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static sk_sp<SkData> encode(SkImage* img, SkSerialImageProc proc, void* ctx) { - if (proc) { - if (auto data = proc(img, ctx)) { - return data; - } - } - return img->encodeToData(); -} - -static bool show_deduper_traffic = false; - -int SkPipeDeduper::findOrDefineImage(SkImage* image) { - int index = fImages.find(image->uniqueID()); - SkASSERT(index >= 0); - if (index) { - if (show_deduper_traffic) { - SkDebugf(" reuseImage(%d)\n", index - 1); - } - return index; - } - - sk_sp<SkData> data = encode(image, fProcs.fImageProc, fProcs.fImageCtx); - if (data) { - index = fImages.add(image->uniqueID()); - SkASSERT(index > 0); - SkASSERT(fits_in(index, 24)); - fStream->write32(pack_verb(SkPipeVerb::kDefineImage, index)); - - uint32_t len = SkToU32(data->size()); - fStream->write32(SkAlign4(len)); - write_pad(fStream, data->data(), len); - - if (show_deduper_traffic) { - int size = image->width() * image->height() << 2; - SkDebugf(" defineImage(%d) %d -> %d\n", index - 1, size, len); - } - return index; - } - SkDebugf("+++ failed to encode image [%d %d]\n", image->width(), image->height()); - return 0; // failed to encode -} - -int SkPipeDeduper::findOrDefinePicture(SkPicture* picture) { - int index = fPictures.find(picture->uniqueID()); - SkASSERT(index >= 0); - if (index) { - if (show_deduper_traffic) { - SkDebugf(" reusePicture(%d)\n", index - 1); - } - return index; - } - - size_t prevWritten = fStream->bytesWritten(); - unsigned extra = 0; // 0 means we're defining a new picture, non-zero means undef_index + 1 - fStream->write32(pack_verb(SkPipeVerb::kDefinePicture, extra)); - const SkRect cull = picture->cullRect(); - fStream->write(&cull, sizeof(cull)); - picture->playback(fPipeCanvas); - // call fPictures.add *after* we're written the picture, so that any nested pictures will have - // already been defined, and we get the "last" index value. - index = fPictures.add(picture->uniqueID()); - ASSERT_FITS_IN(index, kObjectDefinitionBits); - fStream->write32(pack_verb(SkPipeVerb::kEndPicture, index)); - - if (show_deduper_traffic) { - SkDebugf(" definePicture(%d) %d\n", - index - 1, SkToU32(fStream->bytesWritten() - prevWritten)); - } - return index; -} - -static sk_sp<SkData> encode(const SkSerialProcs& procs, SkTypeface* tf) { - if (procs.fTypefaceProc) { - auto data = procs.fTypefaceProc(tf, procs.fTypefaceCtx); - if (data) { - return data; - } - } - SkDynamicMemoryWStream stream; - tf->serialize(&stream); - return sk_sp<SkData>(stream.detachAsData()); -} - -int SkPipeDeduper::findOrDefineTypeface(SkTypeface* typeface) { - if (!typeface) { - return 0; // default - } - - int index = fTypefaces.find(typeface->uniqueID()); - SkASSERT(index >= 0); - if (index) { - if (show_deduper_traffic) { - SkDebugf(" reuseTypeface(%d)\n", index - 1); - } - return index; - } - - sk_sp<SkData> data = encode(fProcs, typeface); - if (data) { - index = fTypefaces.add(typeface->uniqueID()); - SkASSERT(index > 0); - SkASSERT(fits_in(index, 24)); - fStream->write32(pack_verb(SkPipeVerb::kDefineTypeface, index)); - - uint32_t len = SkToU32(data->size()); - fStream->write32(SkAlign4(len)); - write_pad(fStream, data->data(), len); - - if (show_deduper_traffic) { - SkDebugf(" defineTypeface(%d) %d\n", index - 1, len); - } - return index; - } - SkDebugf("+++ failed to encode typeface %d\n", typeface->uniqueID()); - return 0; // failed to encode -} - -int SkPipeDeduper::findOrDefineFactory(SkFlattenable* flattenable) { - if (!flattenable) { - return 0; - } - - int index = fFactories.find(flattenable->getFactory()); - SkASSERT(index >= 0); - if (index) { - if (show_deduper_traffic) { - SkDebugf(" reuseFactory(%d)\n", index - 1); - } - return index; - } - - index = fFactories.add(flattenable->getFactory()); - ASSERT_FITS_IN(index, kIndex_DefineFactoryExtraBits); - const char* name = flattenable->getTypeName(); - size_t len = strlen(name); - ASSERT_FITS_IN(len, kNameLength_DefineFactoryExtraBits); - unsigned extra = (index << kNameLength_DefineFactoryExtraBits) | len; - size_t prevWritten = fStream->bytesWritten(); - fStream->write32(pack_verb(SkPipeVerb::kDefineFactory, extra)); - write_pad(fStream, name, len + 1); - if (false) { - SkDebugf(" defineFactory(%d) %d %s\n", - index - 1, SkToU32(fStream->bytesWritten() - prevWritten), name); - } - return index; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -#include "SkPipe.h" - -class SkPipeSerializer::Impl { -public: - SkPipeDeduper fDeduper; - std::unique_ptr<SkPipeCanvas> fCanvas; -}; - -SkPipeSerializer::SkPipeSerializer() : fImpl(new Impl) {} - -SkPipeSerializer::~SkPipeSerializer() { - if (fImpl->fCanvas) { - this->endWrite(); - } -} - -void SkPipeSerializer::resetCache() { - fImpl->fDeduper.resetCaches(); -} - -sk_sp<SkData> SkPipeSerializer::writeImage(SkImage* image) { - SkDynamicMemoryWStream stream; - this->writeImage(image, &stream); - return stream.detachAsData(); -} - -sk_sp<SkData> SkPipeSerializer::writePicture(SkPicture* picture) { - SkDynamicMemoryWStream stream; - this->writePicture(picture, &stream); - return stream.detachAsData(); -} - -void SkPipeSerializer::writePicture(SkPicture* picture, SkWStream* stream) { - int index = fImpl->fDeduper.findPicture(picture); - if (0 == index) { - // Try to define the picture - this->beginWrite(picture->cullRect(), stream); - index = fImpl->fDeduper.findOrDefinePicture(picture); - this->endWrite(); - } - stream->write32(pack_verb(SkPipeVerb::kWritePicture, index)); -} - -void SkPipeSerializer::writeImage(SkImage* image, SkWStream* stream) { - int index = fImpl->fDeduper.findImage(image); - if (0 == index) { - // Try to define the image - fImpl->fDeduper.setStream(stream); - index = fImpl->fDeduper.findOrDefineImage(image); - } - stream->write32(pack_verb(SkPipeVerb::kWriteImage, index)); -} - -SkCanvas* SkPipeSerializer::beginWrite(const SkRect& cull, SkWStream* stream) { - SkASSERT(nullptr == fImpl->fCanvas); - fImpl->fCanvas.reset(new SkPipeCanvas(cull, &fImpl->fDeduper, stream)); - fImpl->fDeduper.setStream(stream); - fImpl->fDeduper.setCanvas(fImpl->fCanvas.get()); - return fImpl->fCanvas.get(); -} - -void SkPipeSerializer::endWrite() { - fImpl->fCanvas->restoreToCount(1); - fImpl->fCanvas.reset(nullptr); - fImpl->fDeduper.setCanvas(nullptr); -} diff --git a/experimental/pipe/SkPipeCanvas.h b/experimental/pipe/SkPipeCanvas.h deleted file mode 100644 index f72c6a03d3..0000000000 --- a/experimental/pipe/SkPipeCanvas.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkPipeCanvas_DEFINED -#define SkPipeCanvas_DEFINED - -#include "SkCanvasVirtualEnforcer.h" -#include "SkDeduper.h" -#include "SkImage.h" -#include "SkNoDrawCanvas.h" -#include "SkPipe.h" -#include "SkTypeface.h" -#include "SkWriteBuffer.h" - -class SkPipeCanvas; -class SkPipeWriter; - -template <typename T> class SkTIndexSet { -public: - void reset() { fArray.reset(); } - - // returns the found index or 0 - int find(const T& key) const { - const Rec* stop = fArray.end(); - for (const Rec* curr = fArray.begin(); curr < stop; ++curr) { - if (key == curr->fKey) { - return curr->fIndex; - } - } - return 0; - } - - // returns the new index - int add(const T& key) { - Rec* rec = fArray.append(); - rec->fKey = key; - rec->fIndex = fNextIndex++; - return rec->fIndex; - } - -private: - struct Rec { - T fKey; - int fIndex; - }; - - SkTDArray<Rec> fArray; - int fNextIndex = 1; -}; - -class SkPipeDeduper : public SkDeduper { -public: - void resetCaches() { - fImages.reset(); - fPictures.reset(); - fTypefaces.reset(); - fFactories.reset(); - } - - void setCanvas(SkPipeCanvas* canvas) { fPipeCanvas = canvas; } - void setStream(SkWStream* stream) { fStream = stream; } - void setSerialProcs(const SkSerialProcs& procs) { fProcs = procs; } - - // returns 0 if not found - int findImage(SkImage* image) const { return fImages.find(image->uniqueID()); } - int findPicture(SkPicture* picture) const { return fPictures.find(picture->uniqueID()); } - - int findOrDefineImage(SkImage*) override; - int findOrDefinePicture(SkPicture*) override; - int findOrDefineTypeface(SkTypeface*) override; - int findOrDefineFactory(SkFlattenable*) override; - -private: - SkPipeCanvas* fPipeCanvas = nullptr; - SkWStream* fStream = nullptr; - SkSerialProcs fProcs; - - // All our keys (at the moment) are 32bit uniqueIDs - SkTIndexSet<uint32_t> fImages; - SkTIndexSet<uint32_t> fPictures; - SkTIndexSet<uint32_t> fTypefaces; - SkTIndexSet<SkFlattenable::Factory> fFactories; -}; - - -class SkPipeCanvas : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> { -public: - SkPipeCanvas(const SkRect& cull, SkPipeDeduper*, SkWStream*); - ~SkPipeCanvas() override; - -protected: - void willSave() override; - SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override; - void willRestore() override; - - void didConcat(const SkMatrix&) override; - void didSetMatrix(const SkMatrix&) override; - - void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, - const SkPaint&) override; - void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], - int count, SkBlendMode, const SkRect* cull, const SkPaint*) override; - void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; - void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, - const SkPaint&) override; - void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], - const SkPaint&) override; - void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], - SkScalar constY, const SkPaint&) override; - void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint&) override; - void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], - const SkRect* cull, const SkPaint& paint) override; - void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], - SkBlendMode, const SkPaint&) override; - - void onDrawPaint(const SkPaint&) override; - void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; - void onDrawRect(const SkRect&, const SkPaint&) override; - void onDrawOval(const SkRect&, const SkPaint&) override; - void onDrawRegion(const SkRegion&, const SkPaint&) override; - void onDrawRRect(const SkRRect&, const SkPaint&) override; - void onDrawPath(const SkPath&, const SkPaint&) override; - void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override; - - void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; - void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, - const SkPaint*, SrcRectConstraint) override; - void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, - const SkPaint*) override; - void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst, - const SkPaint*) override; - void onDrawImageSet(const ImageSetEntry[], int count, float alpha, SkFilterQuality, - SkBlendMode) override; - void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount, - SkBlendMode, const SkPaint&) override; - - void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override; - void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override; - void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override; - void onClipRegion(const SkRegion&, SkClipOp) override; - - void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; - void onDrawAnnotation(const SkRect&, const char[], SkData*) override; - void onDrawDrawable(SkDrawable*, const SkMatrix*) override; - - // These we turn into images - void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; - void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, - SrcRectConstraint) override; - void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, - const SkPaint*) override; - void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst, - const SkPaint*) override; - -private: - SkPipeDeduper* fDeduper; - SkWStream* fStream; - - friend class SkPipeWriter; - - typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED; -}; - - -#endif diff --git a/experimental/pipe/SkPipeFormat.h b/experimental/pipe/SkPipeFormat.h deleted file mode 100644 index f9c5f58942..0000000000 --- a/experimental/pipe/SkPipeFormat.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkPipeFormat_DEFINED -#define SkPipeFormat_DEFINED - -#include "SkTypes.h" - -#define kDefinePicture_ExtPipeVerb SkSetFourByteTag('s', 'k', 'p', 'i') - -enum class SkPipeVerb : uint8_t { - kSave, // extra == 0 - kSaveLayer, - kRestore, // extra == 0 - kConcat, // extra == SkMatrix::MaskType - - kClipRect, // extra == (SkRegion::Op << 1) | isAntiAlias:1 - kClipRRect, // extra == (SkRegion::Op << 1) | isAntiAlias:1 - kClipPath, // extra == (SkRegion::Op << 1) | isAntiAlias:1 - kClipRegion, // extra == (SkRegion::Op << 1) - - kDrawArc, // extra == useCenter - kDrawAtlas, // extra == has_colors | has_cull | has_paint | mode - kDrawDRRect, - kDrawText, // extra == byteLength:24 else next 32 - kDrawPosText, // extra == byteLength:24 else next 32 - kDrawPosTextH, // extra == byteLength:24 else next 32 - kDrawRegion, // extra == size:24 of region, or 0 means next 32 - kDrawTextBlob, - kDrawTextRSXform, // extra == (byteLength:23 << 1) else next 32 | has_cull_rect:1 - kDrawPatch, - kDrawPaint, // extra == 0 - kDrawPoints, // extra == PointMode - kDrawRect, // extra == 0 - kDrawPath, // extra == 0 - kDrawShadowRec, // extra == 0 - kDrawOval, // extra == 0 - kDrawRRect, // extra == 0 - - kDrawImage, // extra == has_paint:1 - kDrawImageRect, // extra == constraint | has_src_rect | has_paint - kDrawImageNine, // extra == has_paint:1 - kDrawImageLattice, // extra == has_paint:1 - kDrawImageSet, // extra == 0 - - kDrawVertices, - - kDrawPicture, // extra == picture_index - kDrawAnnotation, // extra == (key_len_plus_1:23 << 1) else next 32 | has_data:1 - - kDefineImage, // extra == image_index - kDefineTypeface, - kDefineFactory, // extra == factory_index (followed by padded getTypeName string) - kDefinePicture, // extra == 0 or forget_index + 1 (0 means we're defining a new picture) - kEndPicture, // extra == picture_index - kWriteImage, // extra == image_index - kWritePicture, // extra == picture_index -}; - -enum PaintUsage { - kText_PaintUsage = 1 << 0, - kTextBlob_PaintUsage = 1 << 1, - kGeometry_PaintUsage = 1 << 2, - kImage_PaintUsage = 1 << 3, - kSaveLayer_PaintUsage = 1 << 4, - kDrawPaint_PaintUsage = 1 << 5, - kVertices_PaintUsage = 1 << 6, - kRespectsStroke_PaintUsage = 1 << 7, - kUnknown_PaintUsage = 0xFF, -}; - -// must sum to <= 32 -enum BitsPerField { - kFlags_BPF = 16, - kFilter_BPF = 2, - kStyle_BPF = 2, - kCaps_BPF = 2, - kJoins_BPF = 2, - kHint_BPF = 2, - kAlign_BPF = 2, - kEncoding_BPF = 2, -}; - -enum { - kTextSize_NonDef = 1 << 0, - kTextScaleX_NonDef = 1 << 1, - kTextSkewX_NonDef = 1 << 2, - kStrokeWidth_NonDef = 1 << 3, - kStrokeMiter_NonDef = 1 << 4, - kColor_NonDef = 1 << 5, - kTypeface_NonDef = 1 << 6, - kPathEffect_NonDef = 1 << 7, - kShader_NonDef = 1 << 8, - kMaskFilter_NonDef = 1 << 9, - kColorFilter_NonDef = 1 << 10, - kRasterizer_NonDef = 1 << 11, - kImageFilter_NonDef = 1 << 12, - kDrawLooper_NonDef = 1 << 13, -}; - -enum { - kFlags_SaveLayerMask = 0xFF, - kHasBounds_SaveLayerMask = 1 << 8, - kHasPaint_SaveLayerMask = 1 << 9, - kHasBackdrop_SaveLayerMask = 1 << 10, - kDontClipToLayer_SaveLayerMask = 1 << 11, - kHasClipMask_SaveLayerMask = 1 << 12, - kHasClipMatrix_SaveLayerMask = 1 << 13, -}; - -enum { - kObjectDefinitionBits = 20, - kIndex_ObjectDefinitionMask = ((1 << kObjectDefinitionBits) - 1), - kUser_ObjectDefinitionMask = 0x7 << kObjectDefinitionBits, - kUndef_ObjectDefinitionMask = 1 << 23, - // (Undef:1 | User:3 | Index:20) must fit in extra:24 -}; - -enum { - kTypeMask_ConcatMask = 0xF, - kSetMatrix_ConcatMask = 1 << 4, -}; - -enum { - kMode_DrawAtlasMask = 0xFF, - kHasColors_DrawAtlasMask = 1 << 8, - kHasCull_DrawAtlasMask = 1 << 9, - kHasPaint_DrawAtlasMask = 1 << 10, -}; - -enum { - kHasPaint_DrawImageMask = 1 << 0, -}; - -enum { - kConstraint_DrawImageRectMask = 1 << 0, - kHasPaint_DrawImageRectMask = 1 << 1, - kHasSrcRect_DrawImageRectMask = 1 << 2, -}; - -enum { - kHasPaint_DrawImageNineMask = 1 << 0, -}; - -enum { - // picture_index takes the first kObjectDefinitionBits bits - kHasMatrix_DrawPictureExtra = 1 << 21, - kHasPaint_DrawPictureExtra = 1 << 22, -}; - -enum { - kIndex_DefineFactoryExtraBits = 10, - kNameLength_DefineFactoryExtraBits = 14, // includes trailing 0 - kNameLength_DefineFactoryExtraMask = (1 << kNameLength_DefineFactoryExtraBits) - 1, -}; - -enum { - kModeEnum_DrawPatchExtraMask = 0xFF, - kExplicitXfer_DrawPatchExtraValue = 0xFF, - kHasColors_DrawPatchExtraMask = 0x100, - kHasTexture_DrawPatchExtraMask = 0x200, -}; - -enum { - // if we store a zero for VCount, then read an int after the packedverb for the vcount - kVCount_DrawVerticesMask = (1 << 11) - 1, - - kVMode_DrawVerticesShift = 11, - kVMode_DrawVerticesMask = 3 << kVMode_DrawVerticesShift, - - kXMode_DrawVerticesShift = 13, - kXMode_DrawVerticesMask = 0xFF << kXMode_DrawVerticesShift, - - kHasTex_DrawVerticesMask = 1 << 21, - kHasColors_DrawVerticesMask = 1 << 22, - kHasIndices_DrawVerticesMask = 1 << 23, -}; - -enum { - kHasPaint_DrawImageLatticeMask = 1 << 0, - kHasFlags_DrawImageLatticeMask = 1 << 1, - kXCount_DrawImageLatticeShift = 2, // bits 2:9 are xcount or FF means 32bits follow - kYCount_DrawImageLatticeShift = 10, // bits 10:17 are ycount or FF means 32bits follow - kCount_DrawImageLatticeMask = 0xFF, // sentinel for 32bits follow, - // thus max inline count is 254 -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static inline bool fits_in(int value, int bits) { - return value >= 0 && value < (1 << bits); -} - -static inline void ASSERT_FITS_IN(int value, int bits) { - SkASSERT(fits_in(value, bits)); -} - -static inline uint32_t pack_verb(SkPipeVerb verb, unsigned extra = 0) { - //SkDebugf("pack [%d] %d\n", verb, extra); - ASSERT_FITS_IN((unsigned)verb, 8); - ASSERT_FITS_IN(extra, 24); - return ((uint32_t)verb << 24) | extra; -} - -static inline SkPipeVerb unpack_verb(uint32_t data) { - return (SkPipeVerb)(data >> 24); -} - -static inline unsigned unpack_verb_extra(uint32_t data) { - return data & 0xFFFFFF; -} - -#endif diff --git a/experimental/pipe/SkPipeReader.cpp b/experimental/pipe/SkPipeReader.cpp deleted file mode 100644 index 385119fb07..0000000000 --- a/experimental/pipe/SkPipeReader.cpp +++ /dev/null @@ -1,905 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkCanvas.h" -#include "SkCanvasPriv.h" -#include "SkDeduper.h" -#include "SkDrawShadowInfo.h" -#include "SkPicture.h" -#include "SkPictureRecorder.h" -#include "SkPipe.h" -#include "SkPipeFormat.h" -#include "SkReadBuffer.h" -#include "SkRefSet.h" -#include "SkRSXform.h" -#include "SkTextBlobPriv.h" -#include "SkTypeface.h" -#include "SkVertices.h" - -class SkPipeReader; - -static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex = nullptr); - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -class SkPipeInflator : public SkInflator { -public: - SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures, - SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Factory>* factories, - const SkDeserialProcs& procs) - : fImages(images) - , fPictures(pictures) - , fTypefaces(typefaces) - , fFactories(factories) - , fProcs(procs) - {} - - SkImage* getImage(int index) override { - return index ? fImages->get(index - 1) : nullptr; - } - SkPicture* getPicture(int index) override { - return index ? fPictures->get(index - 1) : nullptr; - } - SkTypeface* getTypeface(int index) override { - return fTypefaces->get(index - 1); - } - SkFlattenable::Factory getFactory(int index) override { - return index ? fFactories->getAt(index - 1) : nullptr; - } - - bool setImage(int index, sk_sp<SkImage> img) { - return fImages->set(index - 1, std::move(img)); - } - bool setPicture(int index, sk_sp<SkPicture> pic) { - return fPictures->set(index - 1, std::move(pic)); - } - bool setTypeface(int index, sk_sp<SkTypeface> face) { - return fTypefaces->set(index - 1, std::move(face)); - } - bool setFactory(int index, SkFlattenable::Factory factory) { - SkASSERT(index > 0); - SkASSERT(factory); - index -= 1; - if ((unsigned)index < (unsigned)fFactories->count()) { - (*fFactories)[index] = factory; - return true; - } - if (fFactories->count() == index) { - *fFactories->append() = factory; - return true; - } - SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories->count()); - return false; - } - - void setDeserialProcs(const SkDeserialProcs& procs) { - fProcs = procs; - } - - sk_sp<SkTypeface> makeTypeface(const void* data, size_t size); - sk_sp<SkImage> makeImage(const sk_sp<SkData>&); - -private: - SkRefSet<SkImage>* fImages; - SkRefSet<SkPicture>* fPictures; - SkRefSet<SkTypeface>* fTypefaces; - SkTDArray<SkFlattenable::Factory>* fFactories; - SkDeserialProcs fProcs; -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -static SkRRect read_rrect(SkReadBuffer& reader) { - SkRRect rrect; - rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMemory); - return rrect; -} - -static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) { - SkMatrix matrix; - matrix.reset(); - - if (tm & SkMatrix::kPerspective_Mask) { - matrix.set9(reader.skipT<SkScalar>(9)); - } else if (tm & SkMatrix::kAffine_Mask) { - const SkScalar* tmp = reader.skipT<SkScalar>(6); - matrix[SkMatrix::kMScaleX] = tmp[0]; - matrix[SkMatrix::kMSkewX] = tmp[1]; - matrix[SkMatrix::kMTransX] = tmp[2]; - matrix[SkMatrix::kMScaleY] = tmp[3]; - matrix[SkMatrix::kMSkewY] = tmp[4]; - matrix[SkMatrix::kMTransY] = tmp[5]; - } else if (tm & SkMatrix::kScale_Mask) { - const SkScalar* tmp = reader.skipT<SkScalar>(4); - matrix[SkMatrix::kMScaleX] = tmp[0]; - matrix[SkMatrix::kMTransX] = tmp[1]; - matrix[SkMatrix::kMScaleY] = tmp[2]; - matrix[SkMatrix::kMTransY] = tmp[3]; - } else if (tm & SkMatrix::kTranslate_Mask) { - const SkScalar* tmp = reader.skipT<SkScalar>(2); - matrix[SkMatrix::kMTransX] = tmp[0]; - matrix[SkMatrix::kMTransY] = tmp[1]; - } - // else read nothing for Identity - return matrix; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -#define CHECK_SET_SCALAR(Field) \ - do { if (nondef & k##Field##_NonDef) { \ - paint.set##Field(reader.readScalar()); \ - }} while (0) - -#define CHECK_SET_FLATTENABLE(Field) \ - do { if (nondef & k##Field##_NonDef) { \ - paint.set##Field(reader.read##Field()); \ - }} while (0) - -/* - * Header: - * paint flags : 32 - * non_def bits : 16 - * xfermode enum : 8 - * pad zeros : 8 - */ -static SkPaint read_paint(SkReadBuffer& reader) { - SkPaint paint; - - uint32_t packedFlags = reader.read32(); - uint32_t extra = reader.read32(); - unsigned nondef = extra >> 16; - paint.setBlendMode(SkBlendMode((extra >> 8) & 0xFF)); - SkASSERT((extra & 0xFF) == 0); // zero pad byte - - packedFlags >>= 2; // currently unused - paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3)); packedFlags >>= 2; - paint.setTextAlign((SkPaint::Align)(packedFlags & 3)); packedFlags >>= 2; - paint.setHinting((SkPaint::Hinting)(packedFlags & 3)); packedFlags >>= 2; - paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3)); packedFlags >>= 2; - paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3)); packedFlags >>= 2; - paint.setStyle((SkPaint::Style)(packedFlags & 3)); packedFlags >>= 2; - paint.setFilterQuality((SkFilterQuality)(packedFlags & 3)); packedFlags >>= 2; - paint.setFlags(packedFlags); - - CHECK_SET_SCALAR(TextSize); - CHECK_SET_SCALAR(TextScaleX); - CHECK_SET_SCALAR(TextSkewX); - CHECK_SET_SCALAR(StrokeWidth); - CHECK_SET_SCALAR(StrokeMiter); - - if (nondef & kColor_NonDef) { - paint.setColor(reader.read32()); - } - - CHECK_SET_FLATTENABLE(Typeface); - CHECK_SET_FLATTENABLE(PathEffect); - CHECK_SET_FLATTENABLE(Shader); - CHECK_SET_FLATTENABLE(MaskFilter); - CHECK_SET_FLATTENABLE(ColorFilter); - CHECK_SET_FLATTENABLE(ImageFilter); - CHECK_SET_FLATTENABLE(DrawLooper); - - return paint; -} - -class SkPipeReader : public SkReadBuffer { -public: - SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size) - : SkReadBuffer(data, size) - , fSink(sink) - {} - - SkPipeDeserializer* fSink; - - SkFlattenable::Factory findFactory(const char name[]) { - SkFlattenable::Factory factory; - // Check if a custom Factory has been specified for this flattenable. - if (!(factory = this->getCustomFactory(SkString(name)))) { - // If there is no custom Factory, check for a default. - factory = SkFlattenable::NameToFactory(name); - } - return factory; - } - - bool readPaint(SkPaint* paint) override { - *paint = read_paint(*this); - return this->isValid(); - } -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*); - -static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb)); - canvas->save(); -} - -static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb)); - unsigned extra = unpack_verb_extra(packedVerb); - const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? reader.skipT<SkRect>() : nullptr; - SkPaint paintStorage, *paint = nullptr; - if (extra & kHasPaint_SaveLayerMask) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - sk_sp<SkImageFilter> backdrop; - if (extra & kHasBackdrop_SaveLayerMask) { - backdrop = reader.readImageFilter(); - } - sk_sp<SkImage> clipMask; - if (extra & kHasClipMask_SaveLayerMask) { - clipMask = reader.readImage(); - } - SkMatrix clipMatrix; - if (extra & kHasClipMatrix_SaveLayerMask) { - reader.readMatrix(&clipMatrix); - } - SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_SaveLayerMask); - - // unremap this wacky flag - if (extra & kDontClipToLayer_SaveLayerMask) { - flags |= SkCanvasPriv::kDontClipToLayer_SaveLayerFlag; - } - - canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), clipMask.get(), - (extra & kHasClipMatrix_SaveLayerMask) ? &clipMatrix : nullptr, flags)); -} - -static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb)); - canvas->restore(); -} - -static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb)); - SkMatrix::TypeMask tm = (SkMatrix::TypeMask)(packedVerb & kTypeMask_ConcatMask); - const SkMatrix matrix = read_sparse_matrix(reader, tm); - if (packedVerb & kSetMatrix_ConcatMask) { - canvas->setMatrix(matrix); - } else { - canvas->concat(matrix); - } -} - -static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb)); - SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1); - bool isAA = unpack_verb_extra(packedVerb) & 1; - canvas->clipRect(*reader.skipT<SkRect>(), op, isAA); -} - -static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb)); - SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1); - bool isAA = unpack_verb_extra(packedVerb) & 1; - canvas->clipRRect(read_rrect(reader), op, isAA); -} - -static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb)); - SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1); - bool isAA = unpack_verb_extra(packedVerb) & 1; - SkPath path; - reader.readPath(&path); - canvas->clipPath(path, op, isAA); -} - -static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb)); - SkClipOp op = (SkClipOp)(unpack_verb_extra(packedVerb) >> 1); - SkRegion region; - reader.readRegion(®ion); - canvas->clipRegion(region, op); -} - -static void drawArc_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawArc == unpack_verb(packedVerb)); - const bool useCenter = (bool)(unpack_verb_extra(packedVerb) & 1); - const SkScalar* scalars = reader.skipT<SkScalar>(6); // bounds[0..3], start[4], sweep[5] - const SkRect* bounds = (const SkRect*)scalars; - canvas->drawArc(*bounds, scalars[4], scalars[5], useCenter, read_paint(reader)); -} - -static void drawAtlas_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawAtlas == unpack_verb(packedVerb)); - SkBlendMode mode = (SkBlendMode)(packedVerb & kMode_DrawAtlasMask); - sk_sp<SkImage> image(reader.readImage()); - int count = reader.read32(); - const SkRSXform* xform = reader.skipT<SkRSXform>(count); - const SkRect* rect = reader.skipT<SkRect>(count); - const SkColor* color = nullptr; - if (packedVerb & kHasColors_DrawAtlasMask) { - color = reader.skipT<SkColor>(count); - } - const SkRect* cull = nullptr; - if (packedVerb & kHasCull_DrawAtlasMask) { - cull = reader.skipT<SkRect>(); - } - SkPaint paintStorage, *paint = nullptr; - if (packedVerb & kHasPaint_DrawAtlasMask) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - canvas->drawAtlas(image, xform, rect, color, count, mode, cull, paint); -} - -static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb)); - const SkRRect outer = read_rrect(reader); - const SkRRect inner = read_rrect(reader); - canvas->drawDRRect(outer, inner, read_paint(reader)); -} - -static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb)); - uint32_t len = unpack_verb_extra(packedVerb); - if (0 == len) { - len = reader.read32(); - } - const void* text = reader.skip(SkAlign4(len)); - SkScalar x = reader.readScalar(); - SkScalar y = reader.readScalar(); - canvas->drawText(text, len, x, y, read_paint(reader)); -} - -static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb)); - uint32_t len = unpack_verb_extra(packedVerb); - if (0 == len) { - len = reader.read32(); - } - const void* text = reader.skip(SkAlign4(len)); - int count = reader.read32(); - const SkPoint* pos = reader.skipT<SkPoint>(count); - SkPaint paint = read_paint(reader); - SkASSERT(paint.countText(text, len) == count); - canvas->drawPosText(text, len, pos, paint); -} - -static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb)); - uint32_t len = unpack_verb_extra(packedVerb); - if (0 == len) { - len = reader.read32(); - } - const void* text = reader.skip(SkAlign4(len)); - int count = reader.read32(); - const SkScalar* xpos = reader.skipT<SkScalar>(count); - SkScalar constY = reader.readScalar(); - SkPaint paint = read_paint(reader); - SkASSERT(paint.countText(text, len) == count); - canvas->drawPosTextH(text, len, xpos, constY, paint); -} - -static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - sk_sp<SkTextBlob> tb = SkTextBlobPriv::MakeFromBuffer(reader); - SkScalar x = reader.readScalar(); - SkScalar y = reader.readScalar(); - canvas->drawTextBlob(tb, x, y, read_paint(reader)); -} - -static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb)); - uint32_t len = unpack_verb_extra(packedVerb) >> 1; - if (0 == len) { - len = reader.read32(); - } - const void* text = reader.skip(SkAlign4(len)); - int count = reader.read32(); - const SkRSXform* xform = reader.skipT<SkRSXform>(count); - const SkRect* cull = (packedVerb & 1) ? reader.skipT<SkRect>() : nullptr; - SkPaint paint = read_paint(reader); - SkASSERT(paint.countText(text, len) == count); - canvas->drawTextRSXform(text, len, xform, cull, paint); -} - -static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb)); - const SkColor* colors = nullptr; - const SkPoint* tex = nullptr; - const SkPoint* cubics = reader.skipT<SkPoint>(12); - if (packedVerb & kHasColors_DrawPatchExtraMask) { - colors = reader.skipT<SkColor>(4); - } - if (packedVerb & kHasTexture_DrawPatchExtraMask) { - tex = reader.skipT<SkPoint>(4); - } - SkBlendMode mode = (SkBlendMode)(packedVerb & kModeEnum_DrawPatchExtraMask); - canvas->drawPatch(cubics, colors, tex, mode, read_paint(reader)); -} - -static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb)); - canvas->drawPaint(read_paint(reader)); -} - -static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb)); - const SkRect* rect = reader.skipT<SkRect>(); - canvas->drawRect(*rect, read_paint(reader)); -} - -static void drawRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawRegion == unpack_verb(packedVerb)); - size_t size = unpack_verb_extra(packedVerb); - if (0 == size) { - size = reader.read32(); - } - SkRegion region; - region.readFromMemory(reader.skipT<char>(size), size); - canvas->drawRegion(region, read_paint(reader)); -} - -static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb)); - const SkRect* rect = reader.skipT<SkRect>(); - canvas->drawOval(*rect, read_paint(reader)); -} - -static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb)); - SkRRect rrect = read_rrect(reader); - canvas->drawRRect(rrect, read_paint(reader)); -} - -static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb)); - SkPath path; - reader.readPath(&path); - canvas->drawPath(path, read_paint(reader)); -} - -static void drawShadowRec_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawShadowRec == unpack_verb(packedVerb)); - SkPath path; - reader.readPath(&path); - SkDrawShadowRec rec; - reader.readPad32(&rec, sizeof(rec)); - canvas->private_draw_shadow_rec(path, rec); -} - -static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb)); - SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb); - int count = reader.read32(); - const SkPoint* points = reader.skipT<SkPoint>(count); - canvas->drawPoints(mode, count, points, read_paint(reader)); -} - -static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb)); - sk_sp<SkImage> image(reader.readImage()); - SkScalar x = reader.readScalar(); - SkScalar y = reader.readScalar(); - SkPaint paintStorage, *paint = nullptr; - if (packedVerb & kHasPaint_DrawImageMask) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - canvas->drawImage(image, x, y, paint); -} - -static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb)); - sk_sp<SkImage> image(reader.readImage()); - SkCanvas::SrcRectConstraint constraint = - (SkCanvas::SrcRectConstraint)(packedVerb & kConstraint_DrawImageRectMask); - const SkRect* src = (packedVerb & kHasSrcRect_DrawImageRectMask) ? - reader.skipT<SkRect>() : nullptr; - const SkRect* dst = reader.skipT<SkRect>(); - SkPaint paintStorage, *paint = nullptr; - if (packedVerb & kHasPaint_DrawImageRectMask) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - if (src) { - canvas->drawImageRect(image, *src, *dst, paint, constraint); - } else { - canvas->drawImageRect(image, *dst, paint); - } -} - -static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb)); - sk_sp<SkImage> image(reader.readImage()); - const SkIRect* center = reader.skipT<SkIRect>(); - const SkRect* dst = reader.skipT<SkRect>(); - SkPaint paintStorage, *paint = nullptr; - if (packedVerb & kHasPaint_DrawImageNineMask) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - canvas->drawImageNine(image, *center, *dst, paint); -} - -static void drawImageLattice_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawImageLattice == unpack_verb(packedVerb)); - sk_sp<SkImage> image(reader.readImage()); - - SkCanvas::Lattice lattice; - if (!SkCanvasPriv::ReadLattice(reader, &lattice)) { - return; - } - const SkRect* dst = reader.skipT<SkRect>(); - - SkPaint paintStorage, *paint = nullptr; - if (packedVerb & kHasPaint_DrawImageLatticeMask) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - canvas->drawImageLattice(image.get(), lattice, *dst, paint); -} - -static void drawImageSet_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawImageSet == unpack_verb(packedVerb)); - - int cnt = reader.readInt(); - float alpha = SkScalarToFloat(reader.readScalar()); - SkFilterQuality filterQuality = (SkFilterQuality)reader.readInt(); - SkBlendMode mode = (SkBlendMode)reader.readInt(); - SkAutoTArray<SkCanvas::ImageSetEntry> set(cnt); - for (int i = 0; i < cnt; ++i) { - set[i].fImage = reader.readImage(); - reader.readRect(&set[i].fSrcRect); - reader.readRect(&set[i].fDstRect); - set[i].fAAFlags = reader.readUInt(); - } - canvas->experimental_DrawImageSetV0(set.get(), cnt, alpha, filterQuality, mode); -} - -static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb)); - SkBlendMode bmode = (SkBlendMode)unpack_verb_extra(packedVerb); - sk_sp<SkVertices> vertices = nullptr; - if (sk_sp<SkData> data = reader.readByteArrayAsData()) { - vertices = SkVertices::Decode(data->data(), data->size()); - } - int boneCount = reader.read32(); - const SkVertices::Bone* bones = boneCount ? reader.skipT<SkVertices::Bone>(boneCount) : nullptr; - if (vertices) { - canvas->drawVertices(vertices, bones, boneCount, bmode, read_paint(reader)); - } -} - -static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb)); - unsigned extra = unpack_verb_extra(packedVerb); - int index = extra & kIndex_ObjectDefinitionMask; - SkPicture* pic = reader.getInflator()->getPicture(index); - SkMatrix matrixStorage, *matrix = nullptr; - SkPaint paintStorage, *paint = nullptr; - if (extra & kHasMatrix_DrawPictureExtra) { - reader.readMatrix(&matrixStorage); - matrix = &matrixStorage; - } - if (extra & kHasPaint_DrawPictureExtra) { - paintStorage = read_paint(reader); - paint = &paintStorage; - } - canvas->drawPicture(pic, matrix, paint); -} - -static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb)); - const SkRect* rect = reader.skipT<SkRect>(); - - // len includes the key's trailing 0 - uint32_t len = unpack_verb_extra(packedVerb) >> 1; - if (0 == len) { - len = reader.read32(); - } - const char* key = reader.skipT<char>(len); - sk_sp<SkData> data; - if (packedVerb & 1) { - uint32_t size = reader.read32(); - data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size); - } - canvas->drawAnnotation(*rect, key, data); -} - -#if 0 - stream.write("skiacodc", 8); - stream.write32(pmap.width()); - stream.write32(pmap.height()); - stream.write16(pmap.colorType()); - stream.write16(pmap.alphaType()); - stream.write32(0); // no colorspace for now - for (int y = 0; y < pmap.height(); ++y) { - stream.write(pmap.addr8(0, y), pmap.width()); - } -#endif - -sk_sp<SkImage> SkPipeInflator::makeImage(const sk_sp<SkData>& data) { - if (fProcs.fImageProc) { - return fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx); - } - return SkImage::MakeFromEncoded(data); -} - - -static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas*) { - SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb)); - SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); - uint32_t extra = unpack_verb_extra(packedVerb); - int index = extra & kIndex_ObjectDefinitionMask; - - if (extra & kUndef_ObjectDefinitionMask) { - // zero-index means we are "forgetting" that cache entry - inflator->setImage(index, nullptr); - } else { - // we are defining a new image - sk_sp<SkData> data = reader.readByteArrayAsData(); - sk_sp<SkImage> image = data ? inflator->makeImage(data) : nullptr; - if (!image) { - SkDebugf("-- failed to decode\n"); - } - inflator->setImage(index, std::move(image)); - } -} - -sk_sp<SkTypeface> SkPipeInflator::makeTypeface(const void* data, size_t size) { - if (fProcs.fTypefaceProc) { - return fProcs.fTypefaceProc(data, size, fProcs.fTypefaceCtx); - } - SkMemoryStream stream(data, size, false); - return SkTypeface::MakeDeserialize(&stream); -} - -static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb)); - SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); - uint32_t extra = unpack_verb_extra(packedVerb); - int index = extra & kIndex_ObjectDefinitionMask; - - if (extra & kUndef_ObjectDefinitionMask) { - // zero-index means we are "forgetting" that cache entry - inflator->setTypeface(index, nullptr); - } else { - // we are defining a new image - sk_sp<SkData> data = reader.readByteArrayAsData(); - // TODO: seems like we could "peek" to see the array, and not need to copy it. - sk_sp<SkTypeface> tf = data ? inflator->makeTypeface(data->data(), data->size()) : nullptr; - inflator->setTypeface(index, std::move(tf)); - } -} - -static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb)); - SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); - uint32_t extra = unpack_verb_extra(packedVerb); - int index = extra >> kNameLength_DefineFactoryExtraBits; - size_t len = extra & kNameLength_DefineFactoryExtraMask; - // +1 for the trailing null char - const char* name = (const char*)reader.skip(SkAlign4(len + 1)); - SkFlattenable::Factory factory = reader.findFactory(name); - if (factory) { - inflator->setFactory(index, factory); - } -} - -static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)); - int deleteIndex = unpack_verb_extra(packedVerb); - - SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); - - if (deleteIndex) { - inflator->setPicture(deleteIndex - 1, nullptr); - } else { - SkPictureRecorder recorder; - int pictureIndex = -1; // invalid - const SkRect* cull = reader.skipT<SkRect>(); - if (!cull) { - return; - } - do_playback(reader, recorder.beginRecording(*cull), &pictureIndex); - SkASSERT(pictureIndex > 0); - sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); - inflator->setPicture(pictureIndex, std::move(picture)); - } -} - -static void endPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { - SK_ABORT("not reached"); // never call me -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -struct HandlerRec { - SkPipeHandler fProc; - const char* fName; -}; - -#define HANDLER(name) { name##_handler, #name } -const HandlerRec gPipeHandlers[] = { - HANDLER(save), - HANDLER(saveLayer), - HANDLER(restore), - HANDLER(concat), - - HANDLER(clipRect), - HANDLER(clipRRect), - HANDLER(clipPath), - HANDLER(clipRegion), - - HANDLER(drawArc), - HANDLER(drawAtlas), - HANDLER(drawDRRect), - HANDLER(drawText), - HANDLER(drawPosText), - HANDLER(drawPosTextH), - HANDLER(drawRegion), - HANDLER(drawTextBlob), - HANDLER(drawTextRSXform), - HANDLER(drawPatch), - HANDLER(drawPaint), - HANDLER(drawPoints), - HANDLER(drawRect), - HANDLER(drawPath), - HANDLER(drawShadowRec), - HANDLER(drawOval), - HANDLER(drawRRect), - - HANDLER(drawImage), - HANDLER(drawImageRect), - HANDLER(drawImageNine), - HANDLER(drawImageLattice), - HANDLER(drawImageSet), - - HANDLER(drawVertices), - - HANDLER(drawPicture), - HANDLER(drawAnnotation), - - HANDLER(defineImage), - HANDLER(defineTypeface), - HANDLER(defineFactory), - HANDLER(definePicture), - HANDLER(endPicture), // handled special -- should never be called -}; -#undef HANDLER - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -class SkPipeDeserializer::Impl { -public: - SkRefSet<SkImage> fImages; - SkRefSet<SkPicture> fPictures; - SkRefSet<SkTypeface> fTypefaces; - SkTDArray<SkFlattenable::Factory> fFactories; - SkDeserialProcs fProcs; -}; - -SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {} -SkPipeDeserializer::~SkPipeDeserializer() {} - -void SkPipeDeserializer::setDeserialProcs(const SkDeserialProcs& procs) { - fImpl->fProcs = procs; -} - -sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) { - if (size < sizeof(uint32_t)) { - SkDebugf("-------- data length too short for readImage %d\n", size); - return nullptr; - } - - const uint32_t* ptr = (const uint32_t*)data; - uint32_t packedVerb = *ptr++; - size -= 4; - - if (SkPipeVerb::kDefineImage == unpack_verb(packedVerb)) { - SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, - &fImpl->fTypefaces, &fImpl->fFactories, - fImpl->fProcs); - SkPipeReader reader(this, ptr, size); - reader.setInflator(&inflator); - defineImage_handler(reader, packedVerb, nullptr); - packedVerb = reader.read32(); // read the next verb - } - if (SkPipeVerb::kWriteImage != unpack_verb(packedVerb)) { - SkDebugf("-------- unexpected verb for readImage %d\n", unpack_verb(packedVerb)); - return nullptr; - } - int index = unpack_verb_extra(packedVerb); - if (0 == index) { - return nullptr; // writer failed - } - return sk_ref_sp(fImpl->fImages.get(index - 1)); -} - -sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) { - if (size < sizeof(uint32_t)) { - SkDebugf("-------- data length too short for readPicture %d\n", size); - return nullptr; - } - - const uint32_t* ptr = (const uint32_t*)data; - uint32_t packedVerb = *ptr++; - size -= 4; - - if (SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)) { - SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, - &fImpl->fTypefaces, &fImpl->fFactories, - fImpl->fProcs); - SkPipeReader reader(this, ptr, size); - reader.setInflator(&inflator); - definePicture_handler(reader, packedVerb, nullptr); - packedVerb = reader.read32(); // read the next verb - } - if (SkPipeVerb::kWritePicture != unpack_verb(packedVerb)) { - SkDebugf("-------- unexpected verb for readPicture %d\n", unpack_verb(packedVerb)); - return nullptr; - } - int index = unpack_verb_extra(packedVerb); - if (0 == index) { - return nullptr; // writer failed - } - return sk_ref_sp(fImpl->fPictures.get(index - 1)); -} - -static bool do_playback(SkPipeReader& reader, SkCanvas* canvas, int* endPictureIndex) { - int indent = 0; - - const bool showEachVerb = false; - int counter = 0; - while (!reader.eof()) { - uint32_t prevOffset = reader.offset(); - uint32_t packedVerb = reader.read32(); - SkPipeVerb verb = unpack_verb(packedVerb); - if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) { - SkDebugf("------- bad verb %d\n", verb); - return false; - } - if (SkPipeVerb::kRestore == verb) { - indent -= 1; - SkASSERT(indent >= 0); - } - - if (SkPipeVerb::kEndPicture == verb) { - if (endPictureIndex) { - *endPictureIndex = unpack_verb_extra(packedVerb); - } - return true; - } - HandlerRec rec = gPipeHandlers[(unsigned)verb]; - rec.fProc(reader, packedVerb, canvas); - if (showEachVerb) { - for (int i = 0; i < indent; ++i) { - SkDebugf(" "); - } - SkDebugf("%d [%d] %s %d\n", prevOffset, counter++, rec.fName, reader.offset() - prevOffset); - } - if (!reader.isValid()) { - SkDebugf("-------- bad reader\n"); - return false; - } - - switch (verb) { - case SkPipeVerb::kSave: - case SkPipeVerb::kSaveLayer: - indent += 1; - break; - default: - break; - } - } - return true; -} - -bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canvas) { - SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, - &fImpl->fTypefaces, &fImpl->fFactories, - fImpl->fProcs); - SkPipeReader reader(this, data, size); - reader.setInflator(&inflator); - return do_playback(reader, canvas); -} - diff --git a/experimental/pipe/SkRefSet.h b/experimental/pipe/SkRefSet.h deleted file mode 100644 index e556196ced..0000000000 --- a/experimental/pipe/SkRefSet.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2016 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkRefSet_DEFINED -#define SkRefSet_DEFINED - -#include "SkRefCnt.h" -#include "SkTArray.h" - -template <typename T> class SkRefSet { -public: - T* get(int index) const { - SkASSERT((unsigned)index < (unsigned)fArray.count()); - return fArray[index].get(); - } - - bool set(int index, sk_sp<T> value) { - if (index < fArray.count()) { - fArray[index] = std::move(value); - return true; - } - if (fArray.count() == index && value) { - fArray.emplace_back(std::move(value)); - return true; - } - SkDebugf("SkRefSet: index [%d] out of range %d\n", index, fArray.count()); - return false; - } - -private: - SkTArray<sk_sp<T>> fArray; -}; - -#endif |