Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2016 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "SkCanvas.h" | |
| 9 #include "SkDeduper.h" | |
| 10 #include "SkPicture.h" | |
| 11 #include "SkPictureRecorder.h" | |
| 12 #include "SkPipe.h" | |
| 13 #include "SkPipeFormat.h" | |
| 14 #include "SkReadBuffer.h" | |
| 15 #include "SkRefSet.h" | |
| 16 #include "SkRSXform.h" | |
| 17 #include "SkTextBlob.h" | |
| 18 #include "SkTypeface.h" | |
| 19 | |
| 20 class SkPipeReader; | |
| 21 | |
| 22 static bool do_playback(SkPipeReader& reader, SkCanvas* canvas); | |
| 23 | |
| 24 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 25 | |
| 26 class SkPipeInflator : public SkInflator { | |
| 27 public: | |
| 28 SkPipeInflator(SkRefSet<SkImage>* images, SkRefSet<SkPicture>* pictures, | |
| 29 SkRefSet<SkTypeface>* typefaces, SkTDArray<SkFlattenable::Fac tory>* factories) | |
| 30 : fImages(images) | |
| 31 , fPictures(pictures) | |
| 32 , fTypefaces(typefaces) | |
| 33 , fFactories(factories) | |
| 34 {} | |
| 35 | |
| 36 SkImage* getImage(int index) override { | |
| 37 return index ? fImages->get(index - 1) : nullptr; | |
| 38 } | |
| 39 SkPicture* getPicture(int index) override { | |
| 40 return index ? fPictures->get(index - 1) : nullptr; | |
| 41 } | |
| 42 SkTypeface* getTypeface(int index) override { return fTypefaces->get(index); } | |
| 43 SkFlattenable::Factory getFactory(int index) override { | |
| 44 return index ? fFactories->getAt(index - 1) : nullptr; | |
| 45 } | |
| 46 | |
| 47 bool setImage(int index, SkImage* img) { | |
| 48 return fImages->set(index - 1, img); | |
| 49 } | |
| 50 bool setPicture(int index, SkPicture* pic) { | |
| 51 return fPictures->set(index - 1, pic); | |
| 52 } | |
| 53 bool setTypeface(int index, SkTypeface* face) { | |
| 54 return fTypefaces->set(index - 1, face); | |
| 55 } | |
| 56 bool setFactory(int index, SkFlattenable::Factory factory) { | |
| 57 SkASSERT(index > 0); | |
| 58 SkASSERT(factory); | |
| 59 index -= 1; | |
| 60 if ((unsigned)index < (unsigned)fFactories->count()) { | |
| 61 (*fFactories)[index] = factory; | |
| 62 return true; | |
| 63 } | |
| 64 if (fFactories->count() == index) { | |
| 65 *fFactories->append() = factory; | |
| 66 return true; | |
| 67 } | |
| 68 SkDebugf("setFactory: index [%d] out of range %d\n", index, fFactories-> count()); | |
| 69 return false; | |
| 70 } | |
| 71 | |
| 72 private: | |
| 73 SkRefSet<SkImage>* fImages; | |
| 74 SkRefSet<SkPicture>* fPictures; | |
| 75 SkRefSet<SkTypeface>* fTypefaces; | |
| 76 SkTDArray<SkFlattenable::Factory>* fFactories; | |
| 77 }; | |
| 78 | |
| 79 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 80 | |
| 81 template <typename T> const T* skip(SkReadBuffer& reader, int count = 1) { | |
| 82 return (const T*)reader.skip(count * sizeof(T)); | |
| 83 } | |
| 84 | |
| 85 static SkRRect read_rrect(SkReadBuffer& reader) { | |
| 86 SkRRect rrect; | |
| 87 rrect.readFromMemory(reader.skip(SkRRect::kSizeInMemory), SkRRect::kSizeInMe mory); | |
| 88 return rrect; | |
| 89 } | |
| 90 | |
| 91 static SkMatrix read_sparse_matrix(SkReadBuffer& reader, SkMatrix::TypeMask tm) { | |
| 92 SkMatrix matrix; | |
| 93 matrix.reset(); | |
| 94 | |
| 95 if (tm & SkMatrix::kPerspective_Mask) { | |
| 96 matrix.set9(skip<SkScalar>(reader, 9)); | |
| 97 } else if (tm & SkMatrix::kAffine_Mask) { | |
| 98 const SkScalar* tmp = skip<SkScalar>(reader, 6); | |
| 99 matrix[SkMatrix::kMScaleX] = tmp[0]; | |
| 100 matrix[SkMatrix::kMSkewX] = tmp[1]; | |
| 101 matrix[SkMatrix::kMTransX] = tmp[2]; | |
| 102 matrix[SkMatrix::kMScaleY] = tmp[3]; | |
| 103 matrix[SkMatrix::kMSkewY] = tmp[4]; | |
| 104 matrix[SkMatrix::kMTransY] = tmp[5]; | |
| 105 } else if (tm & SkMatrix::kScale_Mask) { | |
| 106 const SkScalar* tmp = skip<SkScalar>(reader, 4); | |
| 107 matrix[SkMatrix::kMScaleX] = tmp[0]; | |
| 108 matrix[SkMatrix::kMTransX] = tmp[1]; | |
| 109 matrix[SkMatrix::kMScaleY] = tmp[2]; | |
| 110 matrix[SkMatrix::kMTransY] = tmp[3]; | |
| 111 } else if (tm & SkMatrix::kTranslate_Mask) { | |
| 112 const SkScalar* tmp = skip<SkScalar>(reader, 2); | |
| 113 matrix[SkMatrix::kMTransX] = tmp[0]; | |
| 114 matrix[SkMatrix::kMTransY] = tmp[1]; | |
| 115 } | |
| 116 // else read nothing for Identity | |
| 117 return matrix; | |
| 118 } | |
| 119 | |
| 120 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 121 | |
| 122 #define CHECK_SET_SCALAR(Field) \ | |
| 123 do { if (nondef & k##Field##_NonDef) { \ | |
| 124 paint.set##Field(reader.readScalar()); \ | |
| 125 }} while (0) | |
| 126 | |
| 127 #define CHECK_SET_FLATTENABLE(Field) \ | |
| 128 do { if (nondef & k##Field##_NonDef) { \ | |
| 129 paint.set##Field(reader.read##Field()); \ | |
| 130 }} while (0) | |
| 131 | |
| 132 /* | |
| 133 * Header: | |
| 134 * paint flags : 32 | |
| 135 * non_def bits : 16 | |
| 136 * xfermode enum : 8 | |
| 137 * pad zeros : 8 | |
| 138 */ | |
| 139 static SkPaint read_paint(SkReadBuffer& reader) { | |
| 140 uint32_t packedFlags = reader.read32(); | |
| 141 uint32_t extra = reader.read32(); | |
| 142 unsigned nondef = extra >> 16; | |
| 143 SkXfermode::Mode mode = (SkXfermode::Mode)((extra >> 8) & 0xFF); | |
| 144 SkASSERT((extra & 0xFF) == 0); | |
| 145 | |
| 146 SkPaint paint; | |
| 147 | |
| 148 packedFlags >>= 2; | |
| 149 paint.setTextEncoding((SkPaint::TextEncoding)(packedFlags & 3)); packedFl ags >>= 2; | |
| 150 paint.setTextAlign((SkPaint::Align)(packedFlags & 3)); packedFl ags >>= 2; | |
| 151 paint.setHinting((SkPaint::Hinting)(packedFlags & 2)); packedFl ags >>= 2; | |
| 152 paint.setStrokeJoin((SkPaint::Join)(packedFlags & 3)); packedFl ags >>= 2; | |
| 153 paint.setStrokeCap((SkPaint::Cap)(packedFlags & 3)); packedFl ags >>= 2; | |
| 154 paint.setStyle((SkPaint::Style)(packedFlags & 3)); packedFl ags >>= 2; | |
| 155 paint.setFilterQuality((SkFilterQuality)(packedFlags & 3)); packedFl ags >>= 2; | |
| 156 paint.setFlags(packedFlags); | |
| 157 | |
| 158 CHECK_SET_SCALAR(TextSize); | |
| 159 CHECK_SET_SCALAR(TextScaleX); | |
| 160 CHECK_SET_SCALAR(TextSkewX); | |
| 161 CHECK_SET_SCALAR(StrokeWidth); | |
| 162 CHECK_SET_SCALAR(StrokeMiter); | |
| 163 | |
| 164 if (nondef & kColor_NonDef) { | |
| 165 paint.setColor(reader.read32()); | |
| 166 } | |
| 167 if (nondef & kTypeface_NonDef) { | |
|
mtklein
2016/08/26 18:43:23
:|
| |
| 168 } | |
| 169 | |
| 170 CHECK_SET_FLATTENABLE(PathEffect); | |
| 171 CHECK_SET_FLATTENABLE(Shader); | |
| 172 CHECK_SET_FLATTENABLE(Xfermode); | |
| 173 CHECK_SET_FLATTENABLE(MaskFilter); | |
| 174 CHECK_SET_FLATTENABLE(ColorFilter); | |
| 175 CHECK_SET_FLATTENABLE(Rasterizer); | |
| 176 CHECK_SET_FLATTENABLE(ImageFilter); | |
| 177 | |
| 178 if (!(nondef & kXfermode_NonDef)) { | |
| 179 paint.setXfermodeMode(mode); | |
| 180 } | |
| 181 | |
| 182 return paint; | |
| 183 } | |
| 184 | |
| 185 class SkPipeReader : public SkReadBuffer { | |
| 186 public: | |
| 187 SkPipeReader(SkPipeDeserializer* sink, const void* data, size_t size) | |
| 188 : SkReadBuffer(data, size) | |
| 189 , fSink(sink) | |
| 190 {} | |
| 191 | |
| 192 SkPipeDeserializer* fSink; | |
| 193 | |
| 194 SkFlattenable::Factory findFactory(const char name[]) { | |
| 195 SkFlattenable::Factory factory; | |
| 196 // Check if a custom Factory has been specified for this flattenable. | |
| 197 if (!(factory = this->getCustomFactory(SkString(name)))) { | |
| 198 // If there is no custom Factory, check for a default. | |
| 199 factory = SkFlattenable::NameToFactory(name); | |
| 200 } | |
| 201 return factory; | |
| 202 } | |
| 203 | |
| 204 void readPaint(SkPaint* paint) override { | |
| 205 *paint = read_paint(*this); | |
| 206 } | |
| 207 }; | |
| 208 | |
| 209 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 210 | |
| 211 typedef void (*SkPipeHandler)(SkPipeReader&, uint32_t packedVerb, SkCanvas*); | |
| 212 | |
| 213 static void save_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* ca nvas) { | |
| 214 SkASSERT(SkPipeVerb::kSave == unpack_verb(packedVerb)); | |
| 215 canvas->save(); | |
| 216 } | |
| 217 | |
| 218 static void saveLayer_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
| 219 SkASSERT(SkPipeVerb::kSaveLayer == unpack_verb(packedVerb)); | |
| 220 unsigned extra = unpack_verb_extra(packedVerb); | |
| 221 const SkRect* bounds = (extra & kHasBounds_SaveLayerMask) ? skip<SkRect>(rea der) : nullptr; | |
| 222 SkPaint paintStorage, *paint = nullptr; | |
| 223 if (extra & kHasPaint_SaveLayerMask) { | |
| 224 paintStorage = read_paint(reader); | |
| 225 paint = &paintStorage; | |
| 226 } | |
| 227 sk_sp<SkImageFilter> backdrop; | |
| 228 if (extra & kHasBackdrop_SaveLayerMask) { | |
| 229 backdrop = reader.readImageFilter(); | |
| 230 } | |
| 231 SkCanvas::SaveLayerFlags flags = (SkCanvas::SaveLayerFlags)(extra & kFlags_S aveLayerMask); | |
| 232 canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, backdrop.get(), flag s)); | |
| 233 } | |
| 234 | |
| 235 static void restore_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { | |
| 236 SkASSERT(SkPipeVerb::kRestore == unpack_verb(packedVerb)); | |
| 237 canvas->restore(); | |
| 238 } | |
| 239 | |
| 240 static void concat_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas* canvas) { | |
| 241 SkASSERT(SkPipeVerb::kConcat == unpack_verb(packedVerb)); | |
| 242 SkMatrix::TypeMask tm = (SkMatrix::TypeMask)unpack_verb_extra(packedVerb); | |
| 243 canvas->concat(read_sparse_matrix(reader, tm)); | |
| 244 } | |
| 245 | |
| 246 static void clipRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
| 247 SkASSERT(SkPipeVerb::kClipRect == unpack_verb(packedVerb)); | |
| 248 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
| 249 bool isAA = unpack_verb_extra(packedVerb) & 1; | |
| 250 canvas->clipRect(*skip<SkRect>(reader), op, isAA); | |
| 251 } | |
| 252 | |
| 253 static void clipRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
| 254 SkASSERT(SkPipeVerb::kClipRRect == unpack_verb(packedVerb)); | |
| 255 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
| 256 bool isAA = unpack_verb_extra(packedVerb) & 1; | |
| 257 canvas->clipRRect(read_rrect(reader), op, isAA); | |
| 258 } | |
| 259 | |
| 260 static void clipPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
| 261 SkASSERT(SkPipeVerb::kClipPath == unpack_verb(packedVerb)); | |
| 262 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
| 263 bool isAA = unpack_verb_extra(packedVerb) & 1; | |
| 264 SkPath path; | |
| 265 reader.readPath(&path); | |
| 266 canvas->clipPath(path, op, isAA); | |
| 267 } | |
| 268 | |
| 269 static void clipRegion_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanv as* canvas) { | |
| 270 SkASSERT(SkPipeVerb::kClipRegion == unpack_verb(packedVerb)); | |
| 271 SkRegion::Op op = (SkRegion::Op)(unpack_verb_extra(packedVerb) >> 1); | |
| 272 SkRegion region; | |
| 273 reader.readRegion(®ion); | |
| 274 canvas->clipRegion(region, op); | |
| 275 } | |
| 276 | |
| 277 static void drawDRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanv as* canvas) { | |
| 278 SkASSERT(SkPipeVerb::kDrawDRRect == unpack_verb(packedVerb)); | |
| 279 const SkRRect outer = read_rrect(reader); | |
| 280 const SkRRect inner = read_rrect(reader); | |
| 281 canvas->drawDRRect(outer, inner, read_paint(reader)); | |
| 282 } | |
| 283 | |
| 284 static void drawText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
| 285 SkASSERT(SkPipeVerb::kDrawText == unpack_verb(packedVerb)); | |
| 286 uint32_t len = unpack_verb_extra(packedVerb); | |
| 287 if (0 == len) { | |
| 288 len = reader.read32(); | |
| 289 } | |
| 290 const void* text = reader.skip(SkAlign4(len)); | |
| 291 SkScalar x = reader.readScalar(); | |
| 292 SkScalar y = reader.readScalar(); | |
| 293 canvas->drawText(text, len, x, y, read_paint(reader)); | |
| 294 } | |
| 295 | |
| 296 static void drawPosText_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan vas* canvas) { | |
| 297 SkASSERT(SkPipeVerb::kDrawPosText == unpack_verb(packedVerb)); | |
| 298 uint32_t len = unpack_verb_extra(packedVerb); | |
| 299 if (0 == len) { | |
| 300 len = reader.read32(); | |
| 301 } | |
| 302 const void* text = reader.skip(SkAlign4(len)); | |
| 303 int count = reader.read32(); | |
| 304 const SkPoint* pos = skip<SkPoint>(reader, count); | |
| 305 SkPaint paint = read_paint(reader); | |
| 306 SkASSERT(paint.countText(text, len) == count); | |
| 307 canvas->drawPosText(text, len, pos, paint); | |
| 308 } | |
| 309 | |
| 310 static void drawPosTextH_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa nvas* canvas) { | |
| 311 SkASSERT(SkPipeVerb::kDrawPosTextH == unpack_verb(packedVerb)); | |
| 312 uint32_t len = unpack_verb_extra(packedVerb); | |
| 313 if (0 == len) { | |
| 314 len = reader.read32(); | |
| 315 } | |
| 316 const void* text = reader.skip(SkAlign4(len)); | |
| 317 int count = reader.read32(); | |
| 318 const SkScalar* xpos = skip<SkScalar>(reader, count); | |
| 319 SkScalar constY = reader.readScalar(); | |
| 320 SkPaint paint = read_paint(reader); | |
| 321 SkASSERT(paint.countText(text, len) == count); | |
| 322 canvas->drawPosTextH(text, len, xpos, constY, paint); | |
| 323 } | |
| 324 | |
| 325 static void drawTextOnPath_handler(SkPipeReader& reader, uint32_t packedVerb, Sk Canvas* canvas) { | |
| 326 SkASSERT(SkPipeVerb::kDrawTextOnPath == unpack_verb(packedVerb)); | |
| 327 uint32_t byteLength = packedVerb & kTextLength_DrawTextOnPathMask; | |
| 328 SkMatrix::TypeMask tm = (SkMatrix::TypeMask) | |
| 329 ((packedVerb & kMatrixType_DrawTextOnPathMask) >> kMatrixType_DrawTe xtOnPathShift); | |
| 330 | |
| 331 if (0 == byteLength) { | |
| 332 byteLength = reader.read32(); | |
| 333 } | |
| 334 const void* text = reader.skip(SkAlign4(byteLength)); | |
| 335 SkPath path; | |
| 336 reader.readPath(&path); | |
| 337 const SkMatrix* matrix = nullptr; | |
| 338 SkMatrix matrixStorage; | |
| 339 if (tm != SkMatrix::kIdentity_Mask) { | |
| 340 matrixStorage = read_sparse_matrix(reader, tm); | |
| 341 matrix = &matrixStorage; | |
| 342 } | |
| 343 canvas->drawTextOnPath(text, byteLength, path, matrix, read_paint(reader)); | |
| 344 } | |
| 345 | |
| 346 static void drawTextBlob_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa nvas* canvas) { | |
| 347 sk_sp<SkTextBlob> tb = SkTextBlob::MakeFromBuffer(reader); | |
| 348 SkScalar x = reader.readScalar(); | |
| 349 SkScalar y = reader.readScalar(); | |
| 350 canvas->drawTextBlob(tb, x, y, read_paint(reader)); | |
| 351 } | |
| 352 | |
| 353 static void drawTextRSXform_handler(SkPipeReader& reader, uint32_t packedVerb, S kCanvas* canvas) { | |
| 354 SkASSERT(SkPipeVerb::kDrawTextRSXform == unpack_verb(packedVerb)); | |
| 355 uint32_t len = unpack_verb_extra(packedVerb) >> 1; | |
| 356 if (0 == len) { | |
| 357 len = reader.read32(); | |
| 358 } | |
| 359 const void* text = reader.skip(SkAlign4(len)); | |
| 360 int count = reader.read32(); | |
| 361 const SkRSXform* xform = skip<SkRSXform>(reader, count); | |
| 362 const SkRect* cull = (packedVerb & 1) ? skip<SkRect>(reader) : nullptr; | |
| 363 SkPaint paint = read_paint(reader); | |
| 364 SkASSERT(paint.countText(text, len) == count); | |
| 365 canvas->drawTextRSXform(text, len, xform, cull, paint); | |
| 366 } | |
| 367 | |
| 368 static void drawPatch_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
| 369 SkASSERT(SkPipeVerb::kDrawPatch == unpack_verb(packedVerb)); | |
| 370 const SkColor* colors = nullptr; | |
| 371 const SkPoint* tex = nullptr; | |
| 372 const SkPoint* cubics = skip<SkPoint>(reader, 12); | |
| 373 if (packedVerb & kHasColors_DrawPatchExtraMask) { | |
| 374 colors = skip<SkColor>(reader, 4); | |
| 375 } | |
| 376 if (packedVerb & kHasTexture_DrawPatchExtraMask) { | |
| 377 tex = skip<SkPoint>(reader, 4); | |
| 378 } | |
| 379 sk_sp<SkXfermode> xfer; | |
| 380 unsigned mode = packedVerb & kModeEnum_DrawPatchExtraMask; | |
| 381 if (kExplicitXfer_DrawPatchExtraValue == mode) { | |
| 382 xfer = reader.readXfermode(); | |
| 383 } else { | |
| 384 if (mode != SkXfermode::kSrcOver_Mode) { | |
| 385 xfer = SkXfermode::Make((SkXfermode::Mode)mode); | |
| 386 } | |
| 387 } | |
| 388 canvas->drawPatch(cubics, colors, tex, xfer.get(), read_paint(reader)); | |
| 389 } | |
| 390 | |
| 391 static void drawPaint_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
| 392 SkASSERT(SkPipeVerb::kDrawPaint == unpack_verb(packedVerb)); | |
| 393 canvas->drawPaint(read_paint(reader)); | |
| 394 } | |
| 395 | |
| 396 static void drawRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
| 397 SkASSERT(SkPipeVerb::kDrawRect == unpack_verb(packedVerb)); | |
| 398 const SkRect* rect = skip<SkRect>(reader); | |
| 399 canvas->drawRect(*rect, read_paint(reader)); | |
| 400 } | |
| 401 | |
| 402 static void drawOval_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
| 403 SkASSERT(SkPipeVerb::kDrawOval == unpack_verb(packedVerb)); | |
| 404 const SkRect* rect = skip<SkRect>(reader); | |
| 405 canvas->drawOval(*rect, read_paint(reader)); | |
| 406 } | |
| 407 | |
| 408 static void drawRRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
| 409 SkASSERT(SkPipeVerb::kDrawRRect == unpack_verb(packedVerb)); | |
| 410 SkRRect rrect = read_rrect(reader); | |
| 411 canvas->drawRRect(rrect, read_paint(reader)); | |
| 412 } | |
| 413 | |
| 414 static void drawPath_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanvas * canvas) { | |
| 415 SkASSERT(SkPipeVerb::kDrawPath == unpack_verb(packedVerb)); | |
| 416 SkPath path; | |
| 417 reader.readPath(&path); | |
| 418 canvas->drawPath(path, read_paint(reader)); | |
| 419 } | |
| 420 | |
| 421 static void drawPoints_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanv as* canvas) { | |
| 422 SkASSERT(SkPipeVerb::kDrawPoints == unpack_verb(packedVerb)); | |
| 423 SkCanvas::PointMode mode = (SkCanvas::PointMode)unpack_verb_extra(packedVerb ); | |
| 424 int count = reader.read32(); | |
| 425 const SkPoint* points = skip<SkPoint>(reader, count); | |
| 426 canvas->drawPoints(mode, count, points, read_paint(reader)); | |
| 427 } | |
| 428 | |
| 429 static void drawImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCanva s* canvas) { | |
| 430 SkASSERT(SkPipeVerb::kDrawImage == unpack_verb(packedVerb)); | |
| 431 sk_sp<SkImage> image(reader.readImage()); | |
| 432 SkScalar x = reader.readScalar(); | |
| 433 SkScalar y = reader.readScalar(); | |
| 434 SkPaint paintStorage, *paint = nullptr; | |
| 435 if (packedVerb & 1) { | |
| 436 paintStorage = read_paint(reader); | |
| 437 paint = &paintStorage; | |
| 438 } | |
| 439 canvas->drawImage(image, x, y, paint); | |
| 440 } | |
| 441 | |
| 442 static void drawImageRect_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
| 443 SkASSERT(SkPipeVerb::kDrawImageRect == unpack_verb(packedVerb)); | |
| 444 sk_sp<SkImage> image(reader.readImage()); | |
| 445 const SkRect* src = (packedVerb & 2) ? skip<SkRect>(reader) : nullptr; | |
| 446 const SkRect* dst = skip<SkRect>(reader); | |
| 447 SkPaint paintStorage, *paint = nullptr; | |
| 448 if (packedVerb & 1) { | |
| 449 paintStorage = read_paint(reader); | |
| 450 paint = &paintStorage; | |
| 451 } | |
| 452 if (src) { | |
| 453 canvas->drawImageRect(image, *src, *dst, paint); | |
| 454 } else { | |
| 455 canvas->drawImageRect(image, *dst, paint); | |
| 456 } | |
| 457 } | |
| 458 | |
| 459 static void drawImageNine_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
| 460 SkASSERT(SkPipeVerb::kDrawImageNine == unpack_verb(packedVerb)); | |
| 461 sk_sp<SkImage> image(reader.readImage()); | |
| 462 const SkIRect* center = skip<SkIRect>(reader); | |
| 463 const SkRect* dst = skip<SkRect>(reader); | |
| 464 SkPaint paintStorage, *paint = nullptr; | |
| 465 if (packedVerb & 1) { | |
| 466 paintStorage = read_paint(reader); | |
| 467 paint = &paintStorage; | |
| 468 } | |
| 469 canvas->drawImageNine(image, *center, *dst, paint); | |
| 470 } | |
| 471 | |
| 472 static void drawVertices_handler(SkPipeReader& reader, uint32_t packedVerb, SkCa nvas* canvas) { | |
| 473 SkASSERT(SkPipeVerb::kDrawVertices == unpack_verb(packedVerb)); | |
| 474 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode) | |
| 475 ((packedVerb & kVMode_DrawVerticesMask) >> kVMode_DrawVerticesShift) ; | |
| 476 int vertexCount = packedVerb & kVCount_DrawVerticesMask; | |
| 477 if (0 == vertexCount) { | |
| 478 vertexCount = reader.read32(); | |
| 479 } | |
| 480 sk_sp<SkXfermode> xfer; | |
| 481 unsigned xmode = (packedVerb & kVMode_DrawVerticesMask) >> kVMode_DrawVertic esShift; | |
| 482 if (0xFF == xmode) { | |
| 483 xfer = reader.readXfermode(); | |
| 484 } else { | |
| 485 xfer = SkXfermode::Make((SkXfermode::Mode)xmode); | |
| 486 } | |
| 487 const SkPoint* vertices = skip<SkPoint>(reader, vertexCount); | |
| 488 const SkPoint* texs = nullptr; | |
| 489 if (packedVerb & kHasTex_DrawVerticesMask) { | |
| 490 texs = skip<SkPoint>(reader, vertexCount); | |
| 491 } | |
| 492 const SkColor* colors = nullptr; | |
| 493 if (packedVerb & kHasColors_DrawVerticesMask) { | |
| 494 colors = skip<SkColor>(reader, vertexCount); | |
| 495 } | |
| 496 int indexCount = 0; | |
| 497 const uint16_t* indices = nullptr; | |
| 498 if (packedVerb & kHasIndices_DrawVerticesMask) { | |
| 499 indexCount = reader.read32(); | |
| 500 indices = skip<uint16_t>(reader, indexCount); | |
| 501 } | |
| 502 | |
| 503 canvas->drawVertices(vmode, vertexCount, vertices, texs, colors, xfer.get(), | |
| 504 indices, indexCount, read_paint(reader)); | |
| 505 } | |
| 506 | |
| 507 static void drawPicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan vas* canvas) { | |
| 508 SkASSERT(SkPipeVerb::kDrawPicture == unpack_verb(packedVerb)); | |
| 509 unsigned extra = unpack_verb_extra(packedVerb); | |
| 510 int index = extra & kIndex_DefineObjectMask; | |
| 511 SkPicture* pic = reader.getInflator()->getPicture(index); | |
| 512 SkMatrix matrixStorage, *matrix = nullptr; | |
| 513 SkPaint paintStorage, *paint = nullptr; | |
| 514 if (extra & kHasMatrix_DrawPictureExtra) { | |
| 515 reader.readMatrix(&matrixStorage); | |
| 516 matrix = &matrixStorage; | |
| 517 } | |
| 518 if (extra & kHasPaint_DrawPictureExtra) { | |
| 519 paintStorage = read_paint(reader); | |
| 520 paint = &paintStorage; | |
| 521 } | |
| 522 canvas->drawPicture(pic, matrix, paint); | |
| 523 } | |
| 524 | |
| 525 static void drawAnnotation_handler(SkPipeReader& reader, uint32_t packedVerb, Sk Canvas* canvas) { | |
| 526 SkASSERT(SkPipeVerb::kDrawAnnotation == unpack_verb(packedVerb)); | |
| 527 const SkRect* rect = skip<SkRect>(reader); | |
| 528 | |
| 529 // len includes the key's trailing 0 | |
| 530 uint32_t len = unpack_verb_extra(packedVerb) >> 1; | |
| 531 if (0 == len) { | |
| 532 len = reader.read32(); | |
| 533 } | |
| 534 const char* key = skip<char>(reader, len); | |
| 535 sk_sp<SkData> data; | |
| 536 if (packedVerb & 1) { | |
| 537 uint32_t size = reader.read32(); | |
| 538 data = SkData::MakeWithCopy(reader.skip(SkAlign4(size)), size); | |
| 539 } | |
| 540 canvas->drawAnnotation(*rect, key, data); | |
| 541 } | |
| 542 | |
| 543 static void defineImage_handler(SkPipeReader& reader, uint32_t packedVerb, SkCan vas* canvas) { | |
| 544 SkASSERT(SkPipeVerb::kDefineImage == unpack_verb(packedVerb)); | |
| 545 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); | |
| 546 uint32_t extra = unpack_verb_extra(packedVerb); | |
| 547 int index = extra & kIndex_DefineObjectMask; | |
| 548 | |
| 549 if (extra & kForget_DefineObjectMask) { | |
| 550 // zero-index means we are "forgetting" that cache entry | |
| 551 inflator->setImage(index, nullptr); | |
| 552 } else { | |
| 553 // we are defining a new image | |
| 554 sk_sp<SkData> data = reader.readByteArrayAsData(); | |
| 555 sk_sp<SkImage> image = SkImage::MakeFromEncoded(data); | |
| 556 inflator->setImage(index, image.get()); | |
| 557 } | |
| 558 } | |
| 559 | |
| 560 static void definePicture_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
| 561 SkASSERT(SkPipeVerb::kDefinePicture == unpack_verb(packedVerb)); | |
| 562 uint32_t extra = unpack_verb_extra(packedVerb); | |
| 563 // we expect our caller to notice the "kEnd" and not call us | |
| 564 SkASSERT(0 == (extra & kEnd_DefinePictureMask)); | |
| 565 | |
| 566 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); | |
| 567 int index = extra & kIndex_DefineObjectMask; | |
| 568 | |
| 569 if (extra & kForget_DefineObjectMask) { | |
| 570 // zero-index means we are "forgetting" that cache entry | |
| 571 inflator->setPicture(index, nullptr); | |
| 572 } else { | |
| 573 SkPictureRecorder recorder; | |
| 574 do_playback(reader, recorder.beginRecording(9999, 9999)); | |
| 575 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); | |
| 576 inflator->setPicture(index, picture.get()); | |
| 577 } | |
| 578 } | |
| 579 | |
| 580 static void defineTypeface_handler(SkPipeReader& reader, uint32_t packedVerb, Sk Canvas* canvas) { | |
| 581 SkASSERT(SkPipeVerb::kDefineTypeface == unpack_verb(packedVerb)); | |
| 582 } | |
| 583 | |
| 584 static void defineFactory_handler(SkPipeReader& reader, uint32_t packedVerb, SkC anvas* canvas) { | |
| 585 SkASSERT(SkPipeVerb::kDefineFactory == unpack_verb(packedVerb)); | |
| 586 SkPipeInflator* inflator = (SkPipeInflator*)reader.getInflator(); | |
| 587 uint32_t extra = unpack_verb_extra(packedVerb); | |
| 588 int index = extra >> kNameLength_DefineFactoryExtraBits; | |
| 589 size_t len = extra & kNameLength_DefineFactoryExtraMask; | |
| 590 | |
| 591 const char* name = (const char*)reader.skip(SkAlign4(len)); | |
| 592 SkFlattenable::Factory factory = reader.findFactory(name); | |
| 593 if (factory) { | |
| 594 inflator->setFactory(index, factory); | |
| 595 } | |
| 596 } | |
| 597 | |
| 598 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 599 | |
| 600 struct HandlerRec { | |
| 601 SkPipeHandler fProc; | |
| 602 const char* fName; | |
| 603 }; | |
| 604 | |
| 605 #define HANDLER(name) { name##_handler, #name } | |
| 606 const HandlerRec gPipeHandlers[] = { | |
| 607 HANDLER(save), | |
| 608 HANDLER(saveLayer), | |
| 609 HANDLER(restore), | |
| 610 HANDLER(concat), | |
| 611 | |
| 612 HANDLER(clipRect), | |
| 613 HANDLER(clipRRect), | |
| 614 HANDLER(clipPath), | |
| 615 HANDLER(clipRegion), | |
| 616 | |
| 617 HANDLER(drawDRRect), | |
| 618 HANDLER(drawText), | |
| 619 HANDLER(drawPosText), | |
| 620 HANDLER(drawPosTextH), | |
| 621 HANDLER(drawTextOnPath), | |
| 622 HANDLER(drawTextBlob), | |
| 623 HANDLER(drawTextRSXform), | |
| 624 HANDLER(drawPatch), | |
| 625 HANDLER(drawPaint), | |
| 626 HANDLER(drawPoints), | |
| 627 HANDLER(drawRect), | |
| 628 HANDLER(drawPath), | |
| 629 HANDLER(drawOval), | |
| 630 HANDLER(drawRRect), | |
| 631 | |
| 632 HANDLER(drawImage), | |
| 633 HANDLER(drawImageRect), | |
| 634 HANDLER(drawImageNine), | |
| 635 | |
| 636 HANDLER(drawVertices), | |
| 637 | |
| 638 HANDLER(drawPicture), | |
| 639 HANDLER(drawAnnotation), | |
| 640 | |
| 641 HANDLER(defineImage), | |
| 642 HANDLER(definePicture), | |
| 643 HANDLER(defineTypeface), | |
| 644 HANDLER(defineFactory), | |
| 645 }; | |
| 646 #undef HANDLER | |
| 647 | |
| 648 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 649 | |
| 650 class SkPipeDeserializer::Impl { | |
| 651 public: | |
| 652 SkRefSet<SkImage> fImages; | |
| 653 SkRefSet<SkPicture> fPictures; | |
| 654 SkRefSet<SkTypeface> fTypefaces; | |
| 655 SkTDArray<SkFlattenable::Factory> fFactories; | |
| 656 }; | |
| 657 | |
| 658 SkPipeDeserializer::SkPipeDeserializer() : fImpl(new Impl) {} | |
| 659 SkPipeDeserializer::~SkPipeDeserializer() { delete fImpl; } | |
| 660 | |
| 661 sk_sp<SkPicture> SkPipeDeserializer::readPicture(const void* data, size_t size) { | |
| 662 if (size < sizeof(uint32_t) + sizeof(SkRect)) { | |
| 663 return nullptr; | |
| 664 } | |
| 665 | |
| 666 uint32_t header; | |
| 667 memcpy(&header, data, 4); size -= 4; data = (const char*)data + 4; | |
| 668 if (kDefinePicture_ExtPipeVerb != header) { | |
| 669 return nullptr; | |
| 670 } | |
| 671 SkRect cull; | |
| 672 memcpy(&cull, data, sizeof(SkRect)); | |
| 673 size -= sizeof(SkRect); data = (const char*)data + sizeof(SkRect); | |
| 674 | |
| 675 SkPictureRecorder recorder; | |
| 676 this->playback(data, size, recorder.beginRecording(cull)); | |
| 677 return recorder.finishRecordingAsPicture(); | |
| 678 } | |
| 679 | |
| 680 sk_sp<SkImage> SkPipeDeserializer::readImage(const void* data, size_t size) { | |
| 681 if (size < sizeof(uint32_t)) { | |
| 682 return nullptr; | |
| 683 } | |
| 684 | |
| 685 uint32_t header; | |
| 686 memcpy(&header, data, 4); size -= 4; data = (const char*)data + 4; | |
| 687 if (kDefineImage_ExtPipeVerb != header) { | |
| 688 return nullptr; | |
| 689 } | |
| 690 | |
| 691 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, | |
| 692 &fImpl->fTypefaces, &fImpl->fFactories); | |
| 693 SkPipeReader reader(this, data, size); | |
| 694 reader.setInflator(&inflator); | |
| 695 return sk_sp<SkImage>(reader.readImage()); | |
| 696 } | |
| 697 | |
| 698 static bool do_playback(SkPipeReader& reader, SkCanvas* canvas) { | |
| 699 const bool showEachVerb = true; | |
| 700 int counter = 0; | |
| 701 while (!reader.eof()) { | |
| 702 uint32_t prevOffset = reader.offset(); | |
| 703 uint32_t packedVerb = reader.read32(); | |
| 704 SkPipeVerb verb = unpack_verb(packedVerb); | |
| 705 if ((unsigned)verb >= SK_ARRAY_COUNT(gPipeHandlers)) { | |
| 706 SkDebugf("------- bad verb %d\n", verb); | |
| 707 return false; | |
| 708 } | |
| 709 | |
| 710 if (SkPipeVerb::kDefinePicture == verb && (packedVerb & kEnd_DefinePictu reMask)) { | |
| 711 return true; | |
| 712 } | |
| 713 HandlerRec rec = gPipeHandlers[(unsigned)verb]; | |
| 714 rec.fProc(reader, packedVerb, canvas); | |
| 715 if (showEachVerb) { | |
| 716 SkDebugf("[%d] %s %d\n", counter++, rec.fName, reader.offset() - pre vOffset); | |
| 717 } | |
| 718 if (!reader.isValid()) { | |
| 719 SkDebugf("-------- bad reader\n"); | |
| 720 return false; | |
| 721 } | |
| 722 } | |
| 723 return true; | |
| 724 } | |
| 725 | |
| 726 bool SkPipeDeserializer::playback(const void* data, size_t size, SkCanvas* canva s) { | |
| 727 SkPipeInflator inflator(&fImpl->fImages, &fImpl->fPictures, | |
| 728 &fImpl->fTypefaces, &fImpl->fFactories); | |
| 729 SkPipeReader reader(this, data, size); | |
| 730 reader.setInflator(&inflator); | |
| 731 return do_playback(reader, canvas); | |
| 732 } | |
| 733 | |
| OLD | NEW |