| OLD | NEW |
| (Empty) |
| 1 | |
| 2 /* | |
| 3 * Copyright 2011 Google Inc. | |
| 4 * | |
| 5 * Use of this source code is governed by a BSD-style license that can be | |
| 6 * found in the LICENSE file. | |
| 7 */ | |
| 8 | |
| 9 | |
| 10 #include "SkBitmapHeap.h" | |
| 11 #include "SkCanvas.h" | |
| 12 #include "SkPaint.h" | |
| 13 #include "SkGPipe.h" | |
| 14 #include "SkGPipePriv.h" | |
| 15 #include "SkReader32.h" | |
| 16 #include "SkStream.h" | |
| 17 | |
| 18 #include "SkAnnotation.h" | |
| 19 #include "SkColorFilter.h" | |
| 20 #include "SkDrawLooper.h" | |
| 21 #include "SkImageFilter.h" | |
| 22 #include "SkMaskFilter.h" | |
| 23 #include "SkPatchUtils.h" | |
| 24 #include "SkPathEffect.h" | |
| 25 #include "SkRasterizer.h" | |
| 26 #include "SkReadBuffer.h" | |
| 27 #include "SkRRect.h" | |
| 28 #include "SkRSXform.h" | |
| 29 #include "SkShader.h" | |
| 30 #include "SkTextBlob.h" | |
| 31 #include "SkTypeface.h" | |
| 32 #include "SkXfermode.h" | |
| 33 | |
| 34 static SkFlattenable::Type paintflat_to_flattype(PaintFlats pf) { | |
| 35 static const uint8_t gEffectTypesInPaintFlatsOrder[] = { | |
| 36 SkFlattenable::kSkColorFilter_Type, | |
| 37 SkFlattenable::kSkDrawLooper_Type, | |
| 38 SkFlattenable::kSkImageFilter_Type, | |
| 39 SkFlattenable::kSkMaskFilter_Type, | |
| 40 SkFlattenable::kSkPathEffect_Type, | |
| 41 SkFlattenable::kSkRasterizer_Type, | |
| 42 SkFlattenable::kSkShader_Type, | |
| 43 SkFlattenable::kSkXfermode_Type, | |
| 44 }; | |
| 45 | |
| 46 SkASSERT((size_t)pf < SK_ARRAY_COUNT(gEffectTypesInPaintFlatsOrder)); | |
| 47 return (SkFlattenable::Type)gEffectTypesInPaintFlatsOrder[pf]; | |
| 48 } | |
| 49 | |
| 50 static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat
) { | |
| 51 SkASSERT(paintFlat < kCount_PaintFlats); | |
| 52 switch (paintFlat) { | |
| 53 case kColorFilter_PaintFlat: | |
| 54 paint->setColorFilter((SkColorFilter*)obj); | |
| 55 break; | |
| 56 case kDrawLooper_PaintFlat: | |
| 57 paint->setLooper((SkDrawLooper*)obj); | |
| 58 break; | |
| 59 case kMaskFilter_PaintFlat: | |
| 60 paint->setMaskFilter((SkMaskFilter*)obj); | |
| 61 break; | |
| 62 case kPathEffect_PaintFlat: | |
| 63 paint->setPathEffect((SkPathEffect*)obj); | |
| 64 break; | |
| 65 case kRasterizer_PaintFlat: | |
| 66 paint->setRasterizer((SkRasterizer*)obj); | |
| 67 break; | |
| 68 case kShader_PaintFlat: | |
| 69 paint->setShader((SkShader*)obj); | |
| 70 break; | |
| 71 case kImageFilter_PaintFlat: | |
| 72 paint->setImageFilter((SkImageFilter*)obj); | |
| 73 break; | |
| 74 case kXfermode_PaintFlat: | |
| 75 paint->setXfermode((SkXfermode*)obj); | |
| 76 break; | |
| 77 default: | |
| 78 SkDEBUGFAIL("never gets here"); | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 template <typename T> class SkRefCntTDArray : public SkTDArray<T> { | |
| 83 public: | |
| 84 ~SkRefCntTDArray() { this->unrefAll(); } | |
| 85 }; | |
| 86 | |
| 87 static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) { | |
| 88 return cond ? bits | mask : bits & ~mask; | |
| 89 } | |
| 90 | |
| 91 class SkGPipeState : public SkBitmapHeapReader { | |
| 92 public: | |
| 93 SkGPipeState(); | |
| 94 ~SkGPipeState(); | |
| 95 | |
| 96 void setSilent(bool silent) { | |
| 97 fSilent = silent; | |
| 98 } | |
| 99 | |
| 100 bool shouldDraw() { | |
| 101 return !fSilent; | |
| 102 } | |
| 103 | |
| 104 void setFlags(unsigned flags) { | |
| 105 if (fFlags != flags) { | |
| 106 fFlags = flags; | |
| 107 this->updateReader(); | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 unsigned getFlags() const { | |
| 112 return fFlags; | |
| 113 } | |
| 114 | |
| 115 void setReader(SkReadBuffer* reader) { | |
| 116 fReader = reader; | |
| 117 this->updateReader(); | |
| 118 } | |
| 119 | |
| 120 const SkPaint& paint() const { return fPaint; } | |
| 121 SkPaint* editPaint() { return &fPaint; } | |
| 122 | |
| 123 SkFlattenable* getFlat(unsigned index) const { | |
| 124 if (0 == index) { | |
| 125 return nullptr; | |
| 126 } | |
| 127 return fFlatArray[index - 1]; | |
| 128 } | |
| 129 | |
| 130 void defFlattenable(PaintFlats pf, int index) { | |
| 131 index--; | |
| 132 SkFlattenable* obj = fReader->readFlattenable(paintflat_to_flattype(pf))
; | |
| 133 if (fFlatArray.count() == index) { | |
| 134 *fFlatArray.append() = obj; | |
| 135 } else { | |
| 136 SkSafeUnref(fFlatArray[index]); | |
| 137 fFlatArray[index] = obj; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 void defFactory(const char* name) { | |
| 142 SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name); | |
| 143 if (factory) { | |
| 144 SkASSERT(fFactoryArray.find(factory) < 0); | |
| 145 *fFactoryArray.append() = factory; | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 /** | |
| 150 * Add a bitmap to the array of bitmaps, or replace an existing one. | |
| 151 * This is only used when in cross process mode without a shared heap. | |
| 152 */ | |
| 153 void addBitmap(int index) { | |
| 154 SkASSERT(shouldFlattenBitmaps(fFlags)); | |
| 155 SkBitmap* bm; | |
| 156 if(fBitmaps.count() == index) { | |
| 157 bm = new SkBitmap; | |
| 158 *fBitmaps.append() = bm; | |
| 159 } else { | |
| 160 bm = fBitmaps[index]; | |
| 161 } | |
| 162 fReader->readBitmap(bm); | |
| 163 } | |
| 164 | |
| 165 /** | |
| 166 * Override of SkBitmapHeapReader, so that SkReadBuffer can use | |
| 167 * these SkBitmaps for bitmap shaders. Used only in cross process mode | |
| 168 * without a shared heap. | |
| 169 */ | |
| 170 SkBitmap* getBitmap(int32_t index) const override { | |
| 171 SkASSERT(shouldFlattenBitmaps(fFlags)); | |
| 172 return fBitmaps[index]; | |
| 173 } | |
| 174 | |
| 175 /** | |
| 176 * Needed to be a non-abstract subclass of SkBitmapHeapReader. | |
| 177 */ | |
| 178 void releaseRef(int32_t) override {} | |
| 179 | |
| 180 void setSharedHeap(SkBitmapHeap* heap) { | |
| 181 SkASSERT(!shouldFlattenBitmaps(fFlags) || nullptr == heap); | |
| 182 SkRefCnt_SafeAssign(fSharedHeap, heap); | |
| 183 this->updateReader(); | |
| 184 } | |
| 185 | |
| 186 void setImageHeap(SkImageHeap* heap) { | |
| 187 fImageHeap.reset(SkRef(heap)); | |
| 188 } | |
| 189 | |
| 190 /** | |
| 191 * Access the shared heap. Only used in the case when bitmaps are not | |
| 192 * flattened. | |
| 193 */ | |
| 194 SkBitmapHeap* getSharedHeap() const { | |
| 195 SkASSERT(!shouldFlattenBitmaps(fFlags)); | |
| 196 return fSharedHeap; | |
| 197 } | |
| 198 | |
| 199 void addTypeface() { | |
| 200 size_t size = fReader->read32(); | |
| 201 const void* data = fReader->skip(SkAlign4(size)); | |
| 202 SkMemoryStream stream(data, size, false); | |
| 203 *fTypefaces.append() = SkTypeface::Deserialize(&stream); | |
| 204 } | |
| 205 | |
| 206 SkTypeface* getTypeface(unsigned id) const { | |
| 207 return id ? fTypefaces[id - 1] : nullptr; | |
| 208 } | |
| 209 | |
| 210 const SkImage* getImage(int32_t slot) const { | |
| 211 return fImageHeap->get(slot); | |
| 212 } | |
| 213 | |
| 214 private: | |
| 215 void updateReader() { | |
| 216 if (nullptr == fReader) { | |
| 217 return; | |
| 218 } | |
| 219 bool crossProcess = SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag)
; | |
| 220 fReader->setFlags(set_clear_mask(fReader->getFlags(), crossProcess, | |
| 221 SkReadBuffer::kCrossProcess_Flag)); | |
| 222 if (crossProcess) { | |
| 223 fReader->setFactoryArray(&fFactoryArray); | |
| 224 } else { | |
| 225 fReader->setFactoryArray(nullptr); | |
| 226 } | |
| 227 | |
| 228 if (shouldFlattenBitmaps(fFlags)) { | |
| 229 fReader->setBitmapStorage(this); | |
| 230 } else { | |
| 231 fReader->setBitmapStorage(fSharedHeap); | |
| 232 } | |
| 233 } | |
| 234 SkReadBuffer* fReader; | |
| 235 SkPaint fPaint; | |
| 236 SkTDArray<SkFlattenable*> fFlatArray; | |
| 237 SkTDArray<SkTypeface*> fTypefaces; | |
| 238 SkTDArray<SkFlattenable::Factory> fFactoryArray; | |
| 239 SkTDArray<SkBitmap*> fBitmaps; | |
| 240 bool fSilent; | |
| 241 // Only used when sharing bitmaps with the writer. | |
| 242 SkBitmapHeap* fSharedHeap; | |
| 243 SkAutoTUnref<SkImageHeap> fImageHeap; | |
| 244 unsigned fFlags; | |
| 245 }; | |
| 246 | |
| 247 /////////////////////////////////////////////////////////////////////////////// | |
| 248 | |
| 249 template <typename T> const T* skip(SkReader32* reader, size_t count = 1) { | |
| 250 size_t size = sizeof(T) * count; | |
| 251 SkASSERT(SkAlign4(size) == size); | |
| 252 return reinterpret_cast<const T*>(reader->skip(size)); | |
| 253 } | |
| 254 | |
| 255 template <typename T> const T* skipAlign(SkReader32* reader, size_t count = 1) { | |
| 256 size_t size = SkAlign4(sizeof(T) * count); | |
| 257 return reinterpret_cast<const T*>(reader->skip(size)); | |
| 258 } | |
| 259 | |
| 260 /////////////////////////////////////////////////////////////////////////////// | |
| 261 /////////////////////////////////////////////////////////////////////////////// | |
| 262 | |
| 263 static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 264 SkGPipeState* state) { | |
| 265 SkPath path; | |
| 266 reader->readPath(&path); | |
| 267 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFla
g); | |
| 268 canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), doAA); | |
| 269 } | |
| 270 | |
| 271 static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 272 SkGPipeState* state) { | |
| 273 SkRegion rgn; | |
| 274 reader->readRegion(&rgn); | |
| 275 canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32)); | |
| 276 } | |
| 277 | |
| 278 static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 279 SkGPipeState* state) { | |
| 280 const SkRect* rect = skip<SkRect>(reader); | |
| 281 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFla
g); | |
| 282 canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA); | |
| 283 } | |
| 284 | |
| 285 static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 286 SkGPipeState* state) { | |
| 287 SkRRect rrect; | |
| 288 reader->readRRect(&rrect); | |
| 289 bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFla
g); | |
| 290 canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA); | |
| 291 } | |
| 292 | |
| 293 /////////////////////////////////////////////////////////////////////////////// | |
| 294 | |
| 295 static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 296 SkGPipeState* state) { | |
| 297 SkMatrix matrix; | |
| 298 reader->readMatrix(&matrix); | |
| 299 canvas->setMatrix(matrix); | |
| 300 } | |
| 301 | |
| 302 static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 303 SkGPipeState* state) { | |
| 304 SkMatrix matrix; | |
| 305 reader->readMatrix(&matrix); | |
| 306 canvas->concat(matrix); | |
| 307 } | |
| 308 | |
| 309 static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 310 SkGPipeState* state) { | |
| 311 const SkScalar* param = skip<SkScalar>(reader, 2); | |
| 312 canvas->scale(param[0], param[1]); | |
| 313 } | |
| 314 | |
| 315 static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 316 SkGPipeState* state) { | |
| 317 const SkScalar* param = skip<SkScalar>(reader, 2); | |
| 318 canvas->skew(param[0], param[1]); | |
| 319 } | |
| 320 | |
| 321 static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 322 SkGPipeState* state) { | |
| 323 canvas->rotate(reader->readScalar()); | |
| 324 } | |
| 325 | |
| 326 static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 327 SkGPipeState* state) { | |
| 328 const SkScalar* param = skip<SkScalar>(reader, 2); | |
| 329 canvas->translate(param[0], param[1]); | |
| 330 } | |
| 331 | |
| 332 /////////////////////////////////////////////////////////////////////////////// | |
| 333 | |
| 334 static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 335 SkGPipeState* state) { | |
| 336 canvas->save(); | |
| 337 } | |
| 338 | |
| 339 static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 340 SkGPipeState* state) { | |
| 341 unsigned flags = DrawOp_unpackFlags(op32); | |
| 342 SkCanvas::SaveLayerFlags saveLayerFlags = DrawOp_unpackData(op32); | |
| 343 | |
| 344 const SkRect* bounds = nullptr; | |
| 345 if (flags & kSaveLayer_HasBounds_DrawOpFlag) { | |
| 346 bounds = skip<SkRect>(reader); | |
| 347 } | |
| 348 const SkPaint* paint = nullptr; | |
| 349 if (flags & kSaveLayer_HasPaint_DrawOpFlag) { | |
| 350 paint = &state->paint(); | |
| 351 } | |
| 352 canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, saveLayerFlags)); | |
| 353 } | |
| 354 | |
| 355 static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 356 SkGPipeState* state) { | |
| 357 canvas->restore(); | |
| 358 } | |
| 359 | |
| 360 /////////////////////////////////////////////////////////////////////////////// | |
| 361 | |
| 362 static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 363 SkGPipeState* state) { | |
| 364 if (state->shouldDraw()) { | |
| 365 canvas->drawPaint(state->paint()); | |
| 366 } | |
| 367 } | |
| 368 | |
| 369 static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 370 SkGPipeState* state) { | |
| 371 SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32); | |
| 372 size_t count = reader->readU32(); | |
| 373 const SkPoint* pts = skip<SkPoint>(reader, count); | |
| 374 if (state->shouldDraw()) { | |
| 375 canvas->drawPoints(mode, count, pts, state->paint()); | |
| 376 } | |
| 377 } | |
| 378 | |
| 379 static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 380 SkGPipeState* state) { | |
| 381 const SkRect* rect = skip<SkRect>(reader); | |
| 382 if (state->shouldDraw()) { | |
| 383 canvas->drawOval(*rect, state->paint()); | |
| 384 } | |
| 385 } | |
| 386 | |
| 387 static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 388 SkGPipeState* state) { | |
| 389 const SkRect* rect = skip<SkRect>(reader); | |
| 390 if (state->shouldDraw()) { | |
| 391 canvas->drawRect(*rect, state->paint()); | |
| 392 } | |
| 393 } | |
| 394 | |
| 395 static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 396 SkGPipeState* state) { | |
| 397 SkRRect rrect; | |
| 398 reader->readRRect(&rrect); | |
| 399 if (state->shouldDraw()) { | |
| 400 canvas->drawRRect(rrect, state->paint()); | |
| 401 } | |
| 402 } | |
| 403 | |
| 404 static void drawDRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 405 SkGPipeState* state) { | |
| 406 SkRRect outer, inner; | |
| 407 reader->readRRect(&outer); | |
| 408 reader->readRRect(&inner); | |
| 409 if (state->shouldDraw()) { | |
| 410 canvas->drawDRRect(outer, inner, state->paint()); | |
| 411 } | |
| 412 } | |
| 413 | |
| 414 static void drawPatch_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 415 SkGPipeState* state) { | |
| 416 | |
| 417 unsigned flags = DrawOp_unpackFlags(op32); | |
| 418 | |
| 419 const SkPoint* cubics = skip<SkPoint>(reader, SkPatchUtils::kNumCtrlPts); | |
| 420 | |
| 421 const SkColor* colors = nullptr; | |
| 422 if (flags & kDrawVertices_HasColors_DrawOpFlag) { | |
| 423 colors = skip<SkColor>(reader, SkPatchUtils::kNumCorners); | |
| 424 } | |
| 425 const SkPoint* texCoords = nullptr; | |
| 426 if (flags & kDrawVertices_HasTexs_DrawOpFlag) { | |
| 427 texCoords = skip<SkPoint>(reader, SkPatchUtils::kNumCorners); | |
| 428 } | |
| 429 SkAutoTUnref<SkXfermode> xfer; | |
| 430 if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { | |
| 431 int mode = reader->readInt(); | |
| 432 if (mode < 0 || mode > SkXfermode::kLastMode) { | |
| 433 mode = SkXfermode::kModulate_Mode; | |
| 434 } | |
| 435 xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode)); | |
| 436 } | |
| 437 if (state->shouldDraw()) { | |
| 438 canvas->drawPatch(cubics, colors, texCoords, xfer, state->paint()); | |
| 439 } | |
| 440 } | |
| 441 | |
| 442 static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 443 SkGPipeState* state) { | |
| 444 SkPath path; | |
| 445 reader->readPath(&path); | |
| 446 if (state->shouldDraw()) { | |
| 447 canvas->drawPath(path, state->paint()); | |
| 448 } | |
| 449 } | |
| 450 | |
| 451 static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 452 SkGPipeState* state) { | |
| 453 unsigned flags = DrawOp_unpackFlags(op32); | |
| 454 | |
| 455 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readU32(); | |
| 456 int vertexCount = reader->readU32(); | |
| 457 const SkPoint* verts = skip<SkPoint>(reader, vertexCount); | |
| 458 | |
| 459 const SkPoint* texs = nullptr; | |
| 460 if (flags & kDrawVertices_HasTexs_DrawOpFlag) { | |
| 461 texs = skip<SkPoint>(reader, vertexCount); | |
| 462 } | |
| 463 | |
| 464 const SkColor* colors = nullptr; | |
| 465 if (flags & kDrawVertices_HasColors_DrawOpFlag) { | |
| 466 colors = skip<SkColor>(reader, vertexCount); | |
| 467 } | |
| 468 | |
| 469 SkAutoTUnref<SkXfermode> xfer; | |
| 470 if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { | |
| 471 SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32(); | |
| 472 xfer.reset(SkXfermode::Create(mode)); | |
| 473 } | |
| 474 | |
| 475 int indexCount = 0; | |
| 476 const uint16_t* indices = nullptr; | |
| 477 if (flags & kDrawVertices_HasIndices_DrawOpFlag) { | |
| 478 indexCount = reader->readU32(); | |
| 479 indices = skipAlign<uint16_t>(reader, indexCount); | |
| 480 } | |
| 481 if (state->shouldDraw()) { | |
| 482 canvas->drawVertices(vmode, vertexCount, verts, texs, colors, xfer, | |
| 483 indices, indexCount, state->paint()); | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 static void drawAtlas_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, Sk
GPipeState* state) { | |
| 488 unsigned flags = DrawOp_unpackFlags(op32); | |
| 489 | |
| 490 const SkPaint* paint = nullptr; | |
| 491 if (flags & kDrawAtlas_HasPaint_DrawOpFlag) { | |
| 492 paint = &state->paint(); | |
| 493 } | |
| 494 const int slot = reader->readU32(); | |
| 495 const SkImage* atlas = state->getImage(slot); | |
| 496 const int count = reader->readU32(); | |
| 497 SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32(); | |
| 498 const SkRSXform* xform = skip<SkRSXform>(reader, count); | |
| 499 const SkRect* tex = skip<SkRect>(reader, count); | |
| 500 const SkColor* colors = nullptr; | |
| 501 if (flags & kDrawAtlas_HasColors_DrawOpFlag) { | |
| 502 colors = skip<SkColor>(reader, count); | |
| 503 } | |
| 504 const SkRect* cull = nullptr; | |
| 505 if (flags & kDrawAtlas_HasCull_DrawOpFlag) { | |
| 506 cull = skip<SkRect>(reader, 1); | |
| 507 } | |
| 508 | |
| 509 if (state->shouldDraw()) { | |
| 510 canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); | |
| 511 } | |
| 512 } | |
| 513 | |
| 514 /////////////////////////////////////////////////////////////////////////////// | |
| 515 | |
| 516 static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 517 SkGPipeState* state) { | |
| 518 size_t len = reader->readU32(); | |
| 519 const void* text = reader->skip(SkAlign4(len)); | |
| 520 const SkScalar* xy = skip<SkScalar>(reader, 2); | |
| 521 if (state->shouldDraw()) { | |
| 522 canvas->drawText(text, len, xy[0], xy[1], state->paint()); | |
| 523 } | |
| 524 } | |
| 525 | |
| 526 static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 527 SkGPipeState* state) { | |
| 528 size_t len = reader->readU32(); | |
| 529 const void* text = reader->skip(SkAlign4(len)); | |
| 530 size_t posCount = reader->readU32(); // compute by our writer | |
| 531 const SkPoint* pos = skip<SkPoint>(reader, posCount); | |
| 532 if (state->shouldDraw()) { | |
| 533 canvas->drawPosText(text, len, pos, state->paint()); | |
| 534 } | |
| 535 } | |
| 536 | |
| 537 static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 538 SkGPipeState* state) { | |
| 539 size_t len = reader->readU32(); | |
| 540 const void* text = reader->skip(SkAlign4(len)); | |
| 541 size_t posCount = reader->readU32(); // compute by our writer | |
| 542 const SkScalar* xpos = skip<SkScalar>(reader, posCount); | |
| 543 SkScalar constY = reader->readScalar(); | |
| 544 if (state->shouldDraw()) { | |
| 545 canvas->drawPosTextH(text, len, xpos, constY, state->paint()); | |
| 546 } | |
| 547 } | |
| 548 | |
| 549 static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op3
2, | |
| 550 SkGPipeState* state) { | |
| 551 size_t len = reader->readU32(); | |
| 552 const void* text = reader->skip(SkAlign4(len)); | |
| 553 | |
| 554 SkPath path; | |
| 555 reader->readPath(&path); | |
| 556 | |
| 557 SkMatrix matrixStorage; | |
| 558 const SkMatrix* matrix = nullptr; | |
| 559 if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) { | |
| 560 reader->readMatrix(&matrixStorage); | |
| 561 matrix = &matrixStorage; | |
| 562 } | |
| 563 if (state->shouldDraw()) { | |
| 564 canvas->drawTextOnPath(text, len, path, matrix, state->paint()); | |
| 565 } | |
| 566 } | |
| 567 | |
| 568 /////////////////////////////////////////////////////////////////////////////// | |
| 569 | |
| 570 class BitmapHolder : SkNoncopyable { | |
| 571 public: | |
| 572 BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state); | |
| 573 ~BitmapHolder() { | |
| 574 if (fHeapEntry != nullptr) { | |
| 575 fHeapEntry->releaseRef(); | |
| 576 } | |
| 577 } | |
| 578 const SkBitmap* getBitmap() { | |
| 579 return fBitmap; | |
| 580 } | |
| 581 private: | |
| 582 SkBitmapHeapEntry* fHeapEntry; | |
| 583 const SkBitmap* fBitmap; | |
| 584 SkBitmap fBitmapStorage; | |
| 585 }; | |
| 586 | |
| 587 BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32, | |
| 588 SkGPipeState* state) { | |
| 589 const unsigned flags = state->getFlags(); | |
| 590 const unsigned index = DrawOp_unpackData(op32); | |
| 591 if (shouldFlattenBitmaps(flags)) { | |
| 592 fHeapEntry = nullptr; | |
| 593 fBitmap = state->getBitmap(index); | |
| 594 } else { | |
| 595 SkBitmapHeapEntry* entry = state->getSharedHeap()->getEntry(index); | |
| 596 if (SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)) { | |
| 597 // Make a shallow copy for thread safety. Each thread will point to
the same SkPixelRef, | |
| 598 // which is thread safe. | |
| 599 fBitmapStorage = *entry->getBitmap(); | |
| 600 fBitmap = &fBitmapStorage; | |
| 601 // Release the ref on the bitmap now, since we made our own copy. | |
| 602 entry->releaseRef(); | |
| 603 fHeapEntry = nullptr; | |
| 604 } else { | |
| 605 SkASSERT(!shouldFlattenBitmaps(flags)); | |
| 606 SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)
); | |
| 607 fHeapEntry = entry; | |
| 608 fBitmap = fHeapEntry->getBitmap(); | |
| 609 } | |
| 610 } | |
| 611 } | |
| 612 | |
| 613 static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 614 SkGPipeState* state) { | |
| 615 BitmapHolder holder(reader, op32, state); | |
| 616 bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_Dra
wOpFlag); | |
| 617 SkScalar left = reader->readScalar(); | |
| 618 SkScalar top = reader->readScalar(); | |
| 619 const SkBitmap* bitmap = holder.getBitmap(); | |
| 620 if (state->shouldDraw()) { | |
| 621 canvas->drawBitmap(*bitmap, left, top, hasPaint ? &state->paint() : null
ptr); | |
| 622 } | |
| 623 } | |
| 624 | |
| 625 static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader, | |
| 626 uint32_t op32, SkGPipeState* state) { | |
| 627 BitmapHolder holder(reader, op32, state); | |
| 628 bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_Dra
wOpFlag); | |
| 629 const SkIRect* center = skip<SkIRect>(reader); | |
| 630 const SkRect* dst = skip<SkRect>(reader); | |
| 631 const SkBitmap* bitmap = holder.getBitmap(); | |
| 632 if (state->shouldDraw()) { | |
| 633 canvas->drawBitmapNine(*bitmap, *center, *dst, | |
| 634 hasPaint ? &state->paint() : nullptr); | |
| 635 } | |
| 636 } | |
| 637 | |
| 638 static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, | |
| 639 uint32_t op32, SkGPipeState* state) { | |
| 640 BitmapHolder holder(reader, op32, state); | |
| 641 unsigned flags = DrawOp_unpackFlags(op32); | |
| 642 bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); | |
| 643 bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag); | |
| 644 const SkRect* src; | |
| 645 if (hasSrc) { | |
| 646 src = skip<SkRect>(reader); | |
| 647 } else { | |
| 648 src = nullptr; | |
| 649 } | |
| 650 SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint
; | |
| 651 if (flags & kDrawBitmap_Bleed_DrawOpFlag) { | |
| 652 constraint = SkCanvas::kFast_SrcRectConstraint; | |
| 653 } | |
| 654 const SkRect* dst = skip<SkRect>(reader); | |
| 655 const SkBitmap* bitmap = holder.getBitmap(); | |
| 656 if (state->shouldDraw()) { | |
| 657 canvas->legacy_drawBitmapRect(*bitmap, src, *dst, hasPaint ? &state->pai
nt() : nullptr, constraint); | |
| 658 } | |
| 659 } | |
| 660 | |
| 661 static void drawImage_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, Sk
GPipeState* state) { | |
| 662 unsigned slot = DrawOp_unpackData(op32); | |
| 663 unsigned flags = DrawOp_unpackFlags(op32); | |
| 664 bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); | |
| 665 SkScalar x = reader->readScalar(); | |
| 666 SkScalar y = reader->readScalar(); | |
| 667 const SkImage* image = state->getImage(slot); | |
| 668 if (state->shouldDraw()) { | |
| 669 canvas->drawImage(image, x, y, hasPaint ? &state->paint() : nullptr); | |
| 670 } | |
| 671 } | |
| 672 | |
| 673 static void drawImageRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32
, | |
| 674 SkGPipeState* state) { | |
| 675 unsigned slot = DrawOp_unpackData(op32); | |
| 676 unsigned flags = DrawOp_unpackFlags(op32); | |
| 677 bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); | |
| 678 bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag); | |
| 679 const SkRect* src = nullptr; | |
| 680 if (hasSrc) { | |
| 681 src = skip<SkRect>(reader); | |
| 682 } | |
| 683 const SkRect* dst = skip<SkRect>(reader); | |
| 684 SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader
->readInt(); | |
| 685 | |
| 686 const SkImage* image = state->getImage(slot); | |
| 687 if (state->shouldDraw()) { | |
| 688 canvas->legacy_drawImageRect(image, src, *dst, hasPaint ? &state->paint(
) : nullptr, constraint); | |
| 689 } | |
| 690 } | |
| 691 | |
| 692 static void drawImageNine_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32
, | |
| 693 SkGPipeState* state) { | |
| 694 unsigned slot = DrawOp_unpackData(op32); | |
| 695 unsigned flags = DrawOp_unpackFlags(op32); | |
| 696 bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); | |
| 697 const SkIRect* center = skip<SkIRect>(reader); | |
| 698 const SkRect* dst = skip<SkRect>(reader); | |
| 699 const SkImage* image = state->getImage(slot); | |
| 700 if (state->shouldDraw()) { | |
| 701 canvas->drawImageNine(image, *center, *dst, hasPaint ? &state->paint() :
nullptr); | |
| 702 } | |
| 703 } | |
| 704 | |
| 705 /////////////////////////////////////////////////////////////////////////////// | |
| 706 | |
| 707 static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 708 SkGPipeState* state) { | |
| 709 UNIMPLEMENTED | |
| 710 } | |
| 711 | |
| 712 static void drawTextBlob_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, | |
| 713 SkGPipeState* state) { | |
| 714 SkScalar x = reader->readScalar(); | |
| 715 SkScalar y = reader->readScalar(); | |
| 716 | |
| 717 int typefaceCount = reader->readU32(); | |
| 718 SkAutoSTMalloc<16, SkTypeface*> typefaceArray(typefaceCount); | |
| 719 if (state->getFlags() & SkGPipeWriter::kCrossProcess_Flag) { | |
| 720 for (int i = 0; i < typefaceCount; ++i) { | |
| 721 typefaceArray[i] = state->getTypeface(reader->readU32()); | |
| 722 } | |
| 723 } else { | |
| 724 reader->read(typefaceArray.get(), typefaceCount * sizeof(SkTypeface*)); | |
| 725 } | |
| 726 | |
| 727 size_t blobSize = reader->readU32(); | |
| 728 const void* data = reader->skip(SkAlign4(blobSize)); | |
| 729 | |
| 730 if (state->shouldDraw()) { | |
| 731 SkReadBuffer blobBuffer(data, blobSize); | |
| 732 blobBuffer.setTypefaceArray(typefaceArray.get(), typefaceCount); | |
| 733 SkAutoTUnref<const SkTextBlob> blob(SkTextBlob::CreateFromBuffer(blobBuf
fer)); | |
| 734 SkASSERT(blob.get()); | |
| 735 | |
| 736 canvas->drawTextBlob(blob, x, y, state->paint()); | |
| 737 } | |
| 738 } | |
| 739 /////////////////////////////////////////////////////////////////////////////// | |
| 740 | |
| 741 static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, | |
| 742 SkGPipeState* state) { | |
| 743 size_t offset = reader->offset(); | |
| 744 size_t stop = offset + PaintOp_unpackData(op32); | |
| 745 SkPaint* p = state->editPaint(); | |
| 746 | |
| 747 do { | |
| 748 uint32_t p32 = reader->readU32(); | |
| 749 unsigned op = PaintOp_unpackOp(p32); | |
| 750 unsigned data = PaintOp_unpackData(p32); | |
| 751 | |
| 752 // SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data); | |
| 753 | |
| 754 switch (op) { | |
| 755 case kReset_PaintOp: p->reset(); break; | |
| 756 case kFlags_PaintOp: p->setFlags(data); break; | |
| 757 case kColor_PaintOp: p->setColor(reader->readU32()); break; | |
| 758 case kFilterLevel_PaintOp: p->setFilterQuality((SkFilterQuality)data
); break; | |
| 759 case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break; | |
| 760 case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break; | |
| 761 case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break; | |
| 762 case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break; | |
| 763 case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break; | |
| 764 case kEncoding_PaintOp: | |
| 765 p->setTextEncoding((SkPaint::TextEncoding)data); | |
| 766 break; | |
| 767 case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break; | |
| 768 case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break; | |
| 769 case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break; | |
| 770 case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); br
eak; | |
| 771 case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); brea
k; | |
| 772 | |
| 773 case kFlatIndex_PaintOp: { | |
| 774 PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32); | |
| 775 unsigned index = data; | |
| 776 set_paintflat(p, state->getFlat(index), pf); | |
| 777 break; | |
| 778 } | |
| 779 | |
| 780 case kTypeface_PaintOp: | |
| 781 SkASSERT(SkToBool(state->getFlags() & | |
| 782 SkGPipeWriter::kCrossProcess_Flag)); | |
| 783 p->setTypeface(state->getTypeface(data)); | |
| 784 break; | |
| 785 default: SkDEBUGFAIL("bad paintop"); return; | |
| 786 } | |
| 787 SkASSERT(reader->offset() <= stop); | |
| 788 } while (reader->offset() < stop); | |
| 789 } | |
| 790 | |
| 791 static void typeface_rp(SkCanvas*, SkReader32* reader, uint32_t, | |
| 792 SkGPipeState* state) { | |
| 793 SkASSERT(!SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag)); | |
| 794 SkPaint* p = state->editPaint(); | |
| 795 p->setTypeface(static_cast<SkTypeface*>(reader->readPtr())); | |
| 796 } | |
| 797 | |
| 798 static void annotation_rp(SkCanvas*, SkReader32* reader, uint32_t op32, | |
| 799 SkGPipeState* state) { | |
| 800 SkPaint* p = state->editPaint(); | |
| 801 | |
| 802 const size_t size = DrawOp_unpackData(op32); | |
| 803 if (size > 0) { | |
| 804 SkReadBuffer buffer(reader->skip(size), size); | |
| 805 p->setAnnotation(SkAnnotation::Create(buffer))->unref(); | |
| 806 SkASSERT(buffer.offset() == size); | |
| 807 } else { | |
| 808 p->setAnnotation(nullptr); | |
| 809 } | |
| 810 } | |
| 811 | |
| 812 /////////////////////////////////////////////////////////////////////////////// | |
| 813 | |
| 814 static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* stat
e) { | |
| 815 state->addTypeface(); | |
| 816 } | |
| 817 | |
| 818 static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32, | |
| 819 SkGPipeState* state) { | |
| 820 PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32); | |
| 821 unsigned index = DrawOp_unpackData(op32); | |
| 822 state->defFlattenable(pf, index); | |
| 823 } | |
| 824 | |
| 825 static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32, | |
| 826 SkGPipeState* state) { | |
| 827 unsigned index = DrawOp_unpackData(op32); | |
| 828 state->addBitmap(index); | |
| 829 } | |
| 830 | |
| 831 static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t, | |
| 832 SkGPipeState* state) { | |
| 833 state->defFactory(reader->readString()); | |
| 834 } | |
| 835 | |
| 836 /////////////////////////////////////////////////////////////////////////////// | |
| 837 | |
| 838 static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*)
{ | |
| 839 size_t bytes = DrawOp_unpackData(op32); | |
| 840 (void)reader->skip(bytes); | |
| 841 } | |
| 842 | |
| 843 static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32, | |
| 844 SkGPipeState* state) { | |
| 845 unsigned flags = DrawOp_unpackFlags(op32); | |
| 846 state->setFlags(flags); | |
| 847 } | |
| 848 | |
| 849 static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t, | |
| 850 SkGPipeState* state) { | |
| 851 state->setSharedHeap(static_cast<SkBitmapHeap*>(reader->readPtr())); | |
| 852 } | |
| 853 | |
| 854 static void shareImageHeap_rp(SkCanvas*, SkReader32* reader, uint32_t, SkGPipeSt
ate* state) { | |
| 855 state->setImageHeap(static_cast<SkImageHeap*>(reader->readPtr())); | |
| 856 } | |
| 857 | |
| 858 static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {} | |
| 859 | |
| 860 typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*); | |
| 861 | |
| 862 static const ReadProc gReadTable[] = { | |
| 863 skip_rp, | |
| 864 clipPath_rp, | |
| 865 clipRegion_rp, | |
| 866 clipRect_rp, | |
| 867 clipRRect_rp, | |
| 868 concat_rp, | |
| 869 drawAtlas_rp, | |
| 870 drawBitmap_rp, | |
| 871 drawBitmapNine_rp, | |
| 872 drawBitmapRect_rp, | |
| 873 drawDRRect_rp, | |
| 874 drawImage_rp, | |
| 875 drawImageRect_rp, | |
| 876 drawImageNine_rp, | |
| 877 drawOval_rp, | |
| 878 drawPaint_rp, | |
| 879 drawPatch_rp, | |
| 880 drawPath_rp, | |
| 881 drawPicture_rp, | |
| 882 drawPoints_rp, | |
| 883 drawPosText_rp, | |
| 884 drawPosTextH_rp, | |
| 885 drawRect_rp, | |
| 886 drawRRect_rp, | |
| 887 drawText_rp, | |
| 888 drawTextBlob_rp, | |
| 889 drawTextOnPath_rp, | |
| 890 drawVertices_rp, | |
| 891 restore_rp, | |
| 892 rotate_rp, | |
| 893 save_rp, | |
| 894 saveLayer_rp, | |
| 895 scale_rp, | |
| 896 setMatrix_rp, | |
| 897 skew_rp, | |
| 898 translate_rp, | |
| 899 | |
| 900 paintOp_rp, | |
| 901 typeface_rp, | |
| 902 annotation_rp, | |
| 903 | |
| 904 def_Typeface_rp, | |
| 905 def_PaintFlat_rp, | |
| 906 def_Bitmap_rp, | |
| 907 def_Factory_rp, | |
| 908 | |
| 909 reportFlags_rp, | |
| 910 shareBitmapHeap_rp, | |
| 911 shareImageHeap_rp, | |
| 912 done_rp | |
| 913 }; | |
| 914 | |
| 915 /////////////////////////////////////////////////////////////////////////////// | |
| 916 | |
| 917 SkGPipeState::SkGPipeState() | |
| 918 : fReader(0) | |
| 919 , fSilent(false) | |
| 920 , fSharedHeap(nullptr) | |
| 921 , fFlags(0) { | |
| 922 | |
| 923 } | |
| 924 | |
| 925 SkGPipeState::~SkGPipeState() { | |
| 926 fTypefaces.safeUnrefAll(); | |
| 927 fFlatArray.safeUnrefAll(); | |
| 928 fBitmaps.deleteAll(); | |
| 929 SkSafeUnref(fSharedHeap); | |
| 930 } | |
| 931 | |
| 932 /////////////////////////////////////////////////////////////////////////////// | |
| 933 | |
| 934 #include "SkGPipe.h" | |
| 935 | |
| 936 SkGPipeReader::SkGPipeReader() { | |
| 937 fCanvas = nullptr; | |
| 938 fState = nullptr; | |
| 939 fProc = nullptr; | |
| 940 } | |
| 941 | |
| 942 SkGPipeReader::SkGPipeReader(SkCanvas* target) { | |
| 943 fCanvas = nullptr; | |
| 944 this->setCanvas(target); | |
| 945 fState = nullptr; | |
| 946 fProc = nullptr; | |
| 947 } | |
| 948 | |
| 949 void SkGPipeReader::setCanvas(SkCanvas *target) { | |
| 950 SkRefCnt_SafeAssign(fCanvas, target); | |
| 951 } | |
| 952 | |
| 953 SkGPipeReader::~SkGPipeReader() { | |
| 954 SkSafeUnref(fCanvas); | |
| 955 delete fState; | |
| 956 } | |
| 957 | |
| 958 SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length, | |
| 959 uint32_t playbackFlags, size_t* by
tesRead) { | |
| 960 if (nullptr == fCanvas) { | |
| 961 return kError_Status; | |
| 962 } | |
| 963 | |
| 964 if (nullptr == fState) { | |
| 965 fState = new SkGPipeState; | |
| 966 } | |
| 967 | |
| 968 fState->setSilent(playbackFlags & kSilent_PlaybackFlag); | |
| 969 | |
| 970 SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1)); | |
| 971 | |
| 972 const ReadProc* table = gReadTable; | |
| 973 SkReadBuffer reader(data, length); | |
| 974 reader.setBitmapDecoder(fProc); | |
| 975 SkCanvas* canvas = fCanvas; | |
| 976 Status status = kEOF_Status; | |
| 977 | |
| 978 fState->setReader(&reader); | |
| 979 while (!reader.eof()) { | |
| 980 uint32_t op32 = reader.readUInt(); | |
| 981 unsigned op = DrawOp_unpackOp(op32); | |
| 982 // SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;) | |
| 983 | |
| 984 if (op >= SK_ARRAY_COUNT(gReadTable)) { | |
| 985 SkDebugf("---- bad op during GPipeState::playback\n"); | |
| 986 status = kError_Status; | |
| 987 break; | |
| 988 } | |
| 989 if (kDone_DrawOp == op) { | |
| 990 status = kDone_Status; | |
| 991 break; | |
| 992 } | |
| 993 table[op](canvas, reader.getReader32(), op32, fState); | |
| 994 if ((playbackFlags & kReadAtom_PlaybackFlag) && | |
| 995 (table[op] != paintOp_rp && | |
| 996 table[op] != def_Typeface_rp && | |
| 997 table[op] != def_PaintFlat_rp && | |
| 998 table[op] != def_Bitmap_rp | |
| 999 )) { | |
| 1000 status = kReadAtom_Status; | |
| 1001 break; | |
| 1002 } | |
| 1003 } | |
| 1004 | |
| 1005 if (bytesRead) { | |
| 1006 *bytesRead = reader.offset(); | |
| 1007 } | |
| 1008 return status; | |
| 1009 } | |
| OLD | NEW |