1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkPictureRecord.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkRRect.h" 11cb93a386Sopenharmony_ci#include "include/core/SkRSXform.h" 12cb93a386Sopenharmony_ci#include "include/core/SkTextBlob.h" 13cb93a386Sopenharmony_ci#include "include/private/SkTo.h" 14cb93a386Sopenharmony_ci#include "src/core/SkCanvasPriv.h" 15cb93a386Sopenharmony_ci#include "src/core/SkDrawShadowInfo.h" 16cb93a386Sopenharmony_ci#include "src/core/SkMatrixPriv.h" 17cb93a386Sopenharmony_ci#include "src/core/SkSamplingPriv.h" 18cb93a386Sopenharmony_ci#include "src/core/SkTSearch.h" 19cb93a386Sopenharmony_ci#include "src/image/SkImage_Base.h" 20cb93a386Sopenharmony_ci#include "src/utils/SkPatchUtils.h" 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci#define HEAP_BLOCK_SIZE 4096 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_cienum { 25cb93a386Sopenharmony_ci // just need a value that save or getSaveCount would never return 26cb93a386Sopenharmony_ci kNoInitialSave = -1, 27cb93a386Sopenharmony_ci}; 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci// A lot of basic types get stored as a uint32_t: bools, ints, paint indices, etc. 30cb93a386Sopenharmony_cistatic int const kUInt32Size = 4; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciSkPictureRecord::SkPictureRecord(const SkIRect& dimensions, uint32_t flags) 33cb93a386Sopenharmony_ci : INHERITED(dimensions) 34cb93a386Sopenharmony_ci , fRecordFlags(flags) 35cb93a386Sopenharmony_ci , fInitialSaveCount(kNoInitialSave) { 36cb93a386Sopenharmony_ci} 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciSkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags) 39cb93a386Sopenharmony_ci : SkPictureRecord(SkIRect::MakeSize(dimensions), flags) {} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_civoid SkPictureRecord::onFlush() { 44cb93a386Sopenharmony_ci size_t size = sizeof(kUInt32Size); 45cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(FLUSH, &size); 46cb93a386Sopenharmony_ci this->validate(initialOffset, size); 47cb93a386Sopenharmony_ci} 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_civoid SkPictureRecord::willSave() { 50cb93a386Sopenharmony_ci // record the offset to us, making it non-positive to distinguish a save 51cb93a386Sopenharmony_ci // from a clip entry. 52cb93a386Sopenharmony_ci fRestoreOffsetStack.push_back(-(int32_t)fWriter.bytesWritten()); 53cb93a386Sopenharmony_ci this->recordSave(); 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci this->INHERITED::willSave(); 56cb93a386Sopenharmony_ci} 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_civoid SkPictureRecord::recordSave() { 59cb93a386Sopenharmony_ci // op only 60cb93a386Sopenharmony_ci size_t size = sizeof(kUInt32Size); 61cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(SAVE, &size); 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci this->validate(initialOffset, size); 64cb93a386Sopenharmony_ci} 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_civoid SkPictureRecord::onMarkCTM(const char* name) { 67cb93a386Sopenharmony_ci size_t nameLen = SkWriter32::WriteStringSize(name); 68cb93a386Sopenharmony_ci size_t size = sizeof(kUInt32Size) + nameLen; // op + name 69cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(MARK_CTM, &size); 70cb93a386Sopenharmony_ci fWriter.writeString(name); 71cb93a386Sopenharmony_ci this->validate(initialOffset, size); 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci this->INHERITED::onMarkCTM(name); 74cb93a386Sopenharmony_ci} 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ciSkCanvas::SaveLayerStrategy SkPictureRecord::getSaveLayerStrategy(const SaveLayerRec& rec) { 77cb93a386Sopenharmony_ci // record the offset to us, making it non-positive to distinguish a save 78cb93a386Sopenharmony_ci // from a clip entry. 79cb93a386Sopenharmony_ci fRestoreOffsetStack.push_back(-(int32_t)fWriter.bytesWritten()); 80cb93a386Sopenharmony_ci this->recordSaveLayer(rec); 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci (void)this->INHERITED::getSaveLayerStrategy(rec); 83cb93a386Sopenharmony_ci /* No need for a (potentially very big) layer which we don't actually need 84cb93a386Sopenharmony_ci at this time (and may not be able to afford since during record our 85cb93a386Sopenharmony_ci clip starts out the size of the picture, which is often much larger 86cb93a386Sopenharmony_ci than the size of the actual device we'll use during playback). 87cb93a386Sopenharmony_ci */ 88cb93a386Sopenharmony_ci return kNoLayer_SaveLayerStrategy; 89cb93a386Sopenharmony_ci} 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_cibool SkPictureRecord::onDoSaveBehind(const SkRect* subset) { 92cb93a386Sopenharmony_ci fRestoreOffsetStack.push_back(-(int32_t)fWriter.bytesWritten()); 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci size_t size = sizeof(kUInt32Size) + sizeof(uint32_t); // op + flags 95cb93a386Sopenharmony_ci uint32_t flags = 0; 96cb93a386Sopenharmony_ci if (subset) { 97cb93a386Sopenharmony_ci flags |= SAVEBEHIND_HAS_SUBSET; 98cb93a386Sopenharmony_ci size += sizeof(*subset); 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(SAVE_BEHIND, &size); 102cb93a386Sopenharmony_ci this->addInt(flags); 103cb93a386Sopenharmony_ci if (subset) { 104cb93a386Sopenharmony_ci this->addRect(*subset); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci this->validate(initialOffset, size); 108cb93a386Sopenharmony_ci return false; 109cb93a386Sopenharmony_ci} 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_civoid SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) { 112cb93a386Sopenharmony_ci // op + flatflags 113cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size; 114cb93a386Sopenharmony_ci uint32_t flatFlags = 0; 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci if (rec.fBounds) { 117cb93a386Sopenharmony_ci flatFlags |= SAVELAYERREC_HAS_BOUNDS; 118cb93a386Sopenharmony_ci size += sizeof(*rec.fBounds); 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci if (rec.fPaint) { 121cb93a386Sopenharmony_ci flatFlags |= SAVELAYERREC_HAS_PAINT; 122cb93a386Sopenharmony_ci size += sizeof(uint32_t); // index 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci if (rec.fBackdrop) { 125cb93a386Sopenharmony_ci flatFlags |= SAVELAYERREC_HAS_BACKDROP; 126cb93a386Sopenharmony_ci size += sizeof(uint32_t); // (paint) index 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci if (rec.fSaveLayerFlags) { 129cb93a386Sopenharmony_ci flatFlags |= SAVELAYERREC_HAS_FLAGS; 130cb93a386Sopenharmony_ci size += sizeof(uint32_t); 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci if (SkCanvasPriv::GetBackdropScaleFactor(rec) != 1.f) { 133cb93a386Sopenharmony_ci flatFlags |= SAVELAYERREC_HAS_BACKDROP_SCALE; 134cb93a386Sopenharmony_ci size += sizeof(SkScalar); 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci const size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERREC, &size); 138cb93a386Sopenharmony_ci this->addInt(flatFlags); 139cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_BOUNDS) { 140cb93a386Sopenharmony_ci this->addRect(*rec.fBounds); 141cb93a386Sopenharmony_ci } 142cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_PAINT) { 143cb93a386Sopenharmony_ci this->addPaintPtr(rec.fPaint); 144cb93a386Sopenharmony_ci } 145cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_BACKDROP) { 146cb93a386Sopenharmony_ci // overkill, but we didn't already track single flattenables, so using a paint for that 147cb93a386Sopenharmony_ci SkPaint paint; 148cb93a386Sopenharmony_ci paint.setImageFilter(sk_ref_sp(const_cast<SkImageFilter*>(rec.fBackdrop))); 149cb93a386Sopenharmony_ci this->addPaint(paint); 150cb93a386Sopenharmony_ci } 151cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_FLAGS) { 152cb93a386Sopenharmony_ci this->addInt(rec.fSaveLayerFlags); 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci if (flatFlags & SAVELAYERREC_HAS_BACKDROP_SCALE) { 155cb93a386Sopenharmony_ci this->addScalar(SkCanvasPriv::GetBackdropScaleFactor(rec)); 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci this->validate(initialOffset, size); 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ci#ifdef SK_DEBUG 161cb93a386Sopenharmony_ci/* 162cb93a386Sopenharmony_ci * Read the op code from 'offset' in 'writer' and extract the size too. 163cb93a386Sopenharmony_ci */ 164cb93a386Sopenharmony_cistatic DrawType peek_op_and_size(SkWriter32* writer, size_t offset, uint32_t* size) { 165cb93a386Sopenharmony_ci uint32_t peek = writer->readTAt<uint32_t>(offset); 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ci uint32_t op; 168cb93a386Sopenharmony_ci UNPACK_8_24(peek, op, *size); 169cb93a386Sopenharmony_ci if (MASK_24 == *size) { 170cb93a386Sopenharmony_ci // size required its own slot right after the op code 171cb93a386Sopenharmony_ci *size = writer->readTAt<uint32_t>(offset + kUInt32Size); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci return (DrawType) op; 174cb93a386Sopenharmony_ci} 175cb93a386Sopenharmony_ci#endif//SK_DEBUG 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_civoid SkPictureRecord::willRestore() { 178cb93a386Sopenharmony_ci#if 0 179cb93a386Sopenharmony_ci SkASSERT(fRestoreOffsetStack.count() > 1); 180cb93a386Sopenharmony_ci#endif 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci // check for underflow 183cb93a386Sopenharmony_ci if (fRestoreOffsetStack.count() == 0) { 184cb93a386Sopenharmony_ci return; 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci this->recordRestore(); 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ci fRestoreOffsetStack.pop(); 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_ci this->INHERITED::willRestore(); 192cb93a386Sopenharmony_ci} 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_civoid SkPictureRecord::recordRestore(bool fillInSkips) { 195cb93a386Sopenharmony_ci if (fillInSkips) { 196cb93a386Sopenharmony_ci this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten()); 197cb93a386Sopenharmony_ci } 198cb93a386Sopenharmony_ci size_t size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code 199cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(RESTORE, &size); 200cb93a386Sopenharmony_ci this->validate(initialOffset, size); 201cb93a386Sopenharmony_ci} 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_civoid SkPictureRecord::recordTranslate(const SkMatrix& m) { 204cb93a386Sopenharmony_ci SkASSERT(SkMatrix::kTranslate_Mask == m.getType()); 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci // op + dx + dy 207cb93a386Sopenharmony_ci size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 208cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(TRANSLATE, &size); 209cb93a386Sopenharmony_ci this->addScalar(m.getTranslateX()); 210cb93a386Sopenharmony_ci this->addScalar(m.getTranslateY()); 211cb93a386Sopenharmony_ci this->validate(initialOffset, size); 212cb93a386Sopenharmony_ci} 213cb93a386Sopenharmony_ci 214cb93a386Sopenharmony_civoid SkPictureRecord::recordScale(const SkMatrix& m) { 215cb93a386Sopenharmony_ci SkASSERT(SkMatrix::kScale_Mask == m.getType()); 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci // op + sx + sy 218cb93a386Sopenharmony_ci size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 219cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(SCALE, &size); 220cb93a386Sopenharmony_ci this->addScalar(m.getScaleX()); 221cb93a386Sopenharmony_ci this->addScalar(m.getScaleY()); 222cb93a386Sopenharmony_ci this->validate(initialOffset, size); 223cb93a386Sopenharmony_ci} 224cb93a386Sopenharmony_ci 225cb93a386Sopenharmony_civoid SkPictureRecord::didConcat44(const SkM44& m) { 226cb93a386Sopenharmony_ci this->validate(fWriter.bytesWritten(), 0); 227cb93a386Sopenharmony_ci // op + matrix 228cb93a386Sopenharmony_ci size_t size = kUInt32Size + 16 * sizeof(SkScalar); 229cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CONCAT44, &size); 230cb93a386Sopenharmony_ci fWriter.write(SkMatrixPriv::M44ColMajor(m), 16 * sizeof(SkScalar)); 231cb93a386Sopenharmony_ci this->validate(initialOffset, size); 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_ci this->INHERITED::didConcat44(m); 234cb93a386Sopenharmony_ci} 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_civoid SkPictureRecord::didSetM44(const SkM44& m) { 237cb93a386Sopenharmony_ci this->validate(fWriter.bytesWritten(), 0); 238cb93a386Sopenharmony_ci // op + matrix 239cb93a386Sopenharmony_ci size_t size = kUInt32Size + 16 * sizeof(SkScalar); 240cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(SET_M44, &size); 241cb93a386Sopenharmony_ci fWriter.write(SkMatrixPriv::M44ColMajor(m), 16 * sizeof(SkScalar)); 242cb93a386Sopenharmony_ci this->validate(initialOffset, size); 243cb93a386Sopenharmony_ci this->INHERITED::didSetM44(m); 244cb93a386Sopenharmony_ci} 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_civoid SkPictureRecord::didScale(SkScalar x, SkScalar y) { 247cb93a386Sopenharmony_ci this->didConcat44(SkM44::Scale(x, y)); 248cb93a386Sopenharmony_ci} 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_civoid SkPictureRecord::didTranslate(SkScalar x, SkScalar y) { 251cb93a386Sopenharmony_ci this->didConcat44(SkM44::Translate(x, y)); 252cb93a386Sopenharmony_ci} 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_civoid SkPictureRecord::recordConcat(const SkMatrix& matrix) { 255cb93a386Sopenharmony_ci this->validate(fWriter.bytesWritten(), 0); 256cb93a386Sopenharmony_ci // op + matrix 257cb93a386Sopenharmony_ci size_t size = kUInt32Size + SkMatrixPriv::WriteToMemory(matrix, nullptr); 258cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CONCAT, &size); 259cb93a386Sopenharmony_ci this->addMatrix(matrix); 260cb93a386Sopenharmony_ci this->validate(initialOffset, size); 261cb93a386Sopenharmony_ci} 262cb93a386Sopenharmony_ci 263cb93a386Sopenharmony_civoid SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) { 264cb93a386Sopenharmony_ci int32_t offset = fRestoreOffsetStack.top(); 265cb93a386Sopenharmony_ci while (offset > 0) { 266cb93a386Sopenharmony_ci uint32_t peek = fWriter.readTAt<uint32_t>(offset); 267cb93a386Sopenharmony_ci fWriter.overwriteTAt(offset, restoreOffset); 268cb93a386Sopenharmony_ci offset = peek; 269cb93a386Sopenharmony_ci } 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_ci#ifdef SK_DEBUG 272cb93a386Sopenharmony_ci // offset of 0 has been disabled, so we skip it 273cb93a386Sopenharmony_ci if (offset > 0) { 274cb93a386Sopenharmony_ci // assert that the final offset value points to a save verb 275cb93a386Sopenharmony_ci uint32_t opSize; 276cb93a386Sopenharmony_ci DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); 277cb93a386Sopenharmony_ci SkASSERT(SAVE == drawOp || SAVE_LAYER_SAVELAYERREC == drawOp); 278cb93a386Sopenharmony_ci } 279cb93a386Sopenharmony_ci#endif 280cb93a386Sopenharmony_ci} 281cb93a386Sopenharmony_ci 282cb93a386Sopenharmony_civoid SkPictureRecord::beginRecording() { 283cb93a386Sopenharmony_ci // we have to call this *after* our constructor, to ensure that it gets 284cb93a386Sopenharmony_ci // recorded. This is balanced by restoreToCount() call from endRecording, 285cb93a386Sopenharmony_ci // which in-turn calls our overridden restore(), so those get recorded too. 286cb93a386Sopenharmony_ci fInitialSaveCount = this->save(); 287cb93a386Sopenharmony_ci} 288cb93a386Sopenharmony_ci 289cb93a386Sopenharmony_civoid SkPictureRecord::endRecording() { 290cb93a386Sopenharmony_ci SkASSERT(kNoInitialSave != fInitialSaveCount); 291cb93a386Sopenharmony_ci this->restoreToCount(fInitialSaveCount); 292cb93a386Sopenharmony_ci} 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_cisize_t SkPictureRecord::recordRestoreOffsetPlaceholder() { 295cb93a386Sopenharmony_ci if (fRestoreOffsetStack.isEmpty()) { 296cb93a386Sopenharmony_ci return -1; 297cb93a386Sopenharmony_ci } 298cb93a386Sopenharmony_ci 299cb93a386Sopenharmony_ci // The RestoreOffset field is initially filled with a placeholder 300cb93a386Sopenharmony_ci // value that points to the offset of the previous RestoreOffset 301cb93a386Sopenharmony_ci // in the current stack level, thus forming a linked list so that 302cb93a386Sopenharmony_ci // the restore offsets can be filled in when the corresponding 303cb93a386Sopenharmony_ci // restore command is recorded. 304cb93a386Sopenharmony_ci int32_t prevOffset = fRestoreOffsetStack.top(); 305cb93a386Sopenharmony_ci 306cb93a386Sopenharmony_ci size_t offset = fWriter.bytesWritten(); 307cb93a386Sopenharmony_ci this->addInt(prevOffset); 308cb93a386Sopenharmony_ci fRestoreOffsetStack.top() = SkToU32(offset); 309cb93a386Sopenharmony_ci return offset; 310cb93a386Sopenharmony_ci} 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_civoid SkPictureRecord::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) { 313cb93a386Sopenharmony_ci this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); 314cb93a386Sopenharmony_ci this->INHERITED::onClipRect(rect, op, edgeStyle); 315cb93a386Sopenharmony_ci} 316cb93a386Sopenharmony_ci 317cb93a386Sopenharmony_cisize_t SkPictureRecord::recordClipRect(const SkRect& rect, SkClipOp op, bool doAA) { 318cb93a386Sopenharmony_ci // id + rect + clip params 319cb93a386Sopenharmony_ci size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; 320cb93a386Sopenharmony_ci // recordRestoreOffsetPlaceholder doesn't always write an offset 321cb93a386Sopenharmony_ci if (!fRestoreOffsetStack.isEmpty()) { 322cb93a386Sopenharmony_ci // + restore offset 323cb93a386Sopenharmony_ci size += kUInt32Size; 324cb93a386Sopenharmony_ci } 325cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CLIP_RECT, &size); 326cb93a386Sopenharmony_ci this->addRect(rect); 327cb93a386Sopenharmony_ci this->addInt(ClipParams_pack(op, doAA)); 328cb93a386Sopenharmony_ci size_t offset = this->recordRestoreOffsetPlaceholder(); 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_ci this->validate(initialOffset, size); 331cb93a386Sopenharmony_ci return offset; 332cb93a386Sopenharmony_ci} 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_civoid SkPictureRecord::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) { 335cb93a386Sopenharmony_ci this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); 336cb93a386Sopenharmony_ci this->INHERITED::onClipRRect(rrect, op, edgeStyle); 337cb93a386Sopenharmony_ci} 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_cisize_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) { 340cb93a386Sopenharmony_ci // op + rrect + clip params 341cb93a386Sopenharmony_ci size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; 342cb93a386Sopenharmony_ci // recordRestoreOffsetPlaceholder doesn't always write an offset 343cb93a386Sopenharmony_ci if (!fRestoreOffsetStack.isEmpty()) { 344cb93a386Sopenharmony_ci // + restore offset 345cb93a386Sopenharmony_ci size += kUInt32Size; 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CLIP_RRECT, &size); 348cb93a386Sopenharmony_ci this->addRRect(rrect); 349cb93a386Sopenharmony_ci this->addInt(ClipParams_pack(op, doAA)); 350cb93a386Sopenharmony_ci size_t offset = recordRestoreOffsetPlaceholder(); 351cb93a386Sopenharmony_ci this->validate(initialOffset, size); 352cb93a386Sopenharmony_ci return offset; 353cb93a386Sopenharmony_ci} 354cb93a386Sopenharmony_ci 355cb93a386Sopenharmony_civoid SkPictureRecord::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) { 356cb93a386Sopenharmony_ci int pathID = this->addPathToHeap(path); 357cb93a386Sopenharmony_ci this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle); 358cb93a386Sopenharmony_ci this->INHERITED::onClipPath(path, op, edgeStyle); 359cb93a386Sopenharmony_ci} 360cb93a386Sopenharmony_ci 361cb93a386Sopenharmony_cisize_t SkPictureRecord::recordClipPath(int pathID, SkClipOp op, bool doAA) { 362cb93a386Sopenharmony_ci // op + path index + clip params 363cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size; 364cb93a386Sopenharmony_ci // recordRestoreOffsetPlaceholder doesn't always write an offset 365cb93a386Sopenharmony_ci if (!fRestoreOffsetStack.isEmpty()) { 366cb93a386Sopenharmony_ci // + restore offset 367cb93a386Sopenharmony_ci size += kUInt32Size; 368cb93a386Sopenharmony_ci } 369cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CLIP_PATH, &size); 370cb93a386Sopenharmony_ci this->addInt(pathID); 371cb93a386Sopenharmony_ci this->addInt(ClipParams_pack(op, doAA)); 372cb93a386Sopenharmony_ci size_t offset = recordRestoreOffsetPlaceholder(); 373cb93a386Sopenharmony_ci this->validate(initialOffset, size); 374cb93a386Sopenharmony_ci return offset; 375cb93a386Sopenharmony_ci} 376cb93a386Sopenharmony_ci 377cb93a386Sopenharmony_civoid SkPictureRecord::onClipShader(sk_sp<SkShader> cs, SkClipOp op) { 378cb93a386Sopenharmony_ci // Overkill to store a whole paint, but we don't have an existing structure to just store 379cb93a386Sopenharmony_ci // shaders. If size becomes an issue in the future, we can optimize this. 380cb93a386Sopenharmony_ci SkPaint paint; 381cb93a386Sopenharmony_ci paint.setShader(cs); 382cb93a386Sopenharmony_ci 383cb93a386Sopenharmony_ci // op + paint index + clipop 384cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size; 385cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CLIP_SHADER_IN_PAINT, &size); 386cb93a386Sopenharmony_ci this->addPaint(paint); 387cb93a386Sopenharmony_ci this->addInt((int)op); 388cb93a386Sopenharmony_ci this->validate(initialOffset, size); 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ci this->INHERITED::onClipShader(std::move(cs), op); 391cb93a386Sopenharmony_ci} 392cb93a386Sopenharmony_ci 393cb93a386Sopenharmony_civoid SkPictureRecord::onClipRegion(const SkRegion& region, SkClipOp op) { 394cb93a386Sopenharmony_ci this->recordClipRegion(region, op); 395cb93a386Sopenharmony_ci this->INHERITED::onClipRegion(region, op); 396cb93a386Sopenharmony_ci} 397cb93a386Sopenharmony_ci 398cb93a386Sopenharmony_cisize_t SkPictureRecord::recordClipRegion(const SkRegion& region, SkClipOp op) { 399cb93a386Sopenharmony_ci // op + clip params + region 400cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + region.writeToMemory(nullptr); 401cb93a386Sopenharmony_ci // recordRestoreOffsetPlaceholder doesn't always write an offset 402cb93a386Sopenharmony_ci if (!fRestoreOffsetStack.isEmpty()) { 403cb93a386Sopenharmony_ci // + restore offset 404cb93a386Sopenharmony_ci size += kUInt32Size; 405cb93a386Sopenharmony_ci } 406cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(CLIP_REGION, &size); 407cb93a386Sopenharmony_ci this->addRegion(region); 408cb93a386Sopenharmony_ci this->addInt(ClipParams_pack(op, false)); 409cb93a386Sopenharmony_ci size_t offset = this->recordRestoreOffsetPlaceholder(); 410cb93a386Sopenharmony_ci 411cb93a386Sopenharmony_ci this->validate(initialOffset, size); 412cb93a386Sopenharmony_ci return offset; 413cb93a386Sopenharmony_ci} 414cb93a386Sopenharmony_ci 415cb93a386Sopenharmony_civoid SkPictureRecord::onResetClip() { 416cb93a386Sopenharmony_ci if (!fRestoreOffsetStack.isEmpty()) { 417cb93a386Sopenharmony_ci // Run back through any previous clip ops, and mark their offset to 418cb93a386Sopenharmony_ci // be 0, disabling their ability to trigger a jump-to-restore, otherwise 419cb93a386Sopenharmony_ci // they could hide this expansion of the clip. 420cb93a386Sopenharmony_ci this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); 421cb93a386Sopenharmony_ci } 422cb93a386Sopenharmony_ci size_t size = sizeof(kUInt32Size); 423cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(RESET_CLIP, &size); 424cb93a386Sopenharmony_ci this->validate(initialOffset, size); 425cb93a386Sopenharmony_ci this->INHERITED::onResetClip(); 426cb93a386Sopenharmony_ci} 427cb93a386Sopenharmony_ci 428cb93a386Sopenharmony_civoid SkPictureRecord::onDrawPaint(const SkPaint& paint) { 429cb93a386Sopenharmony_ci // op + paint index 430cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size; 431cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_PAINT, &size); 432cb93a386Sopenharmony_ci this->addPaint(paint); 433cb93a386Sopenharmony_ci this->validate(initialOffset, size); 434cb93a386Sopenharmony_ci} 435cb93a386Sopenharmony_ci 436cb93a386Sopenharmony_civoid SkPictureRecord::onDrawBehind(const SkPaint& paint) { 437cb93a386Sopenharmony_ci // logically the same as drawPaint, but with a diff enum 438cb93a386Sopenharmony_ci // op + paint index 439cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size; 440cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_BEHIND_PAINT, &size); 441cb93a386Sopenharmony_ci this->addPaint(paint); 442cb93a386Sopenharmony_ci this->validate(initialOffset, size); 443cb93a386Sopenharmony_ci} 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_civoid SkPictureRecord::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 446cb93a386Sopenharmony_ci const SkPaint& paint) { 447cb93a386Sopenharmony_ci // op + paint index + mode + count + point data 448cb93a386Sopenharmony_ci size_t size = 4 * kUInt32Size + count * sizeof(SkPoint); 449cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_POINTS, &size); 450cb93a386Sopenharmony_ci this->addPaint(paint); 451cb93a386Sopenharmony_ci 452cb93a386Sopenharmony_ci this->addInt(mode); 453cb93a386Sopenharmony_ci this->addInt(SkToInt(count)); 454cb93a386Sopenharmony_ci fWriter.writeMul4(pts, count * sizeof(SkPoint)); 455cb93a386Sopenharmony_ci this->validate(initialOffset, size); 456cb93a386Sopenharmony_ci} 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_civoid SkPictureRecord::onDrawOval(const SkRect& oval, const SkPaint& paint) { 459cb93a386Sopenharmony_ci // op + paint index + rect 460cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + sizeof(oval); 461cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_OVAL, &size); 462cb93a386Sopenharmony_ci this->addPaint(paint); 463cb93a386Sopenharmony_ci this->addRect(oval); 464cb93a386Sopenharmony_ci this->validate(initialOffset, size); 465cb93a386Sopenharmony_ci} 466cb93a386Sopenharmony_ci 467cb93a386Sopenharmony_civoid SkPictureRecord::onDrawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 468cb93a386Sopenharmony_ci bool useCenter, const SkPaint& paint) { 469cb93a386Sopenharmony_ci // op + paint index + rect + start + sweep + bool (as int) 470cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + sizeof(oval) + sizeof(startAngle) + sizeof(sweepAngle) + 471cb93a386Sopenharmony_ci sizeof(int); 472cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_ARC, &size); 473cb93a386Sopenharmony_ci this->addPaint(paint); 474cb93a386Sopenharmony_ci this->addRect(oval); 475cb93a386Sopenharmony_ci this->addScalar(startAngle); 476cb93a386Sopenharmony_ci this->addScalar(sweepAngle); 477cb93a386Sopenharmony_ci this->addInt(useCenter); 478cb93a386Sopenharmony_ci this->validate(initialOffset, size); 479cb93a386Sopenharmony_ci} 480cb93a386Sopenharmony_ci 481cb93a386Sopenharmony_civoid SkPictureRecord::onDrawRect(const SkRect& rect, const SkPaint& paint) { 482cb93a386Sopenharmony_ci // op + paint index + rect 483cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + sizeof(rect); 484cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_RECT, &size); 485cb93a386Sopenharmony_ci this->addPaint(paint); 486cb93a386Sopenharmony_ci this->addRect(rect); 487cb93a386Sopenharmony_ci this->validate(initialOffset, size); 488cb93a386Sopenharmony_ci} 489cb93a386Sopenharmony_ci 490cb93a386Sopenharmony_civoid SkPictureRecord::onDrawRegion(const SkRegion& region, const SkPaint& paint) { 491cb93a386Sopenharmony_ci // op + paint index + region 492cb93a386Sopenharmony_ci size_t regionBytes = region.writeToMemory(nullptr); 493cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + regionBytes; 494cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_REGION, &size); 495cb93a386Sopenharmony_ci this->addPaint(paint); 496cb93a386Sopenharmony_ci fWriter.writeRegion(region); 497cb93a386Sopenharmony_ci this->validate(initialOffset, size); 498cb93a386Sopenharmony_ci} 499cb93a386Sopenharmony_ci 500cb93a386Sopenharmony_civoid SkPictureRecord::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 501cb93a386Sopenharmony_ci // op + paint index + rrect 502cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory; 503cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_RRECT, &size); 504cb93a386Sopenharmony_ci this->addPaint(paint); 505cb93a386Sopenharmony_ci this->addRRect(rrect); 506cb93a386Sopenharmony_ci this->validate(initialOffset, size); 507cb93a386Sopenharmony_ci} 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_civoid SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 510cb93a386Sopenharmony_ci const SkPaint& paint) { 511cb93a386Sopenharmony_ci // op + paint index + rrects 512cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2; 513cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_DRRECT, &size); 514cb93a386Sopenharmony_ci this->addPaint(paint); 515cb93a386Sopenharmony_ci this->addRRect(outer); 516cb93a386Sopenharmony_ci this->addRRect(inner); 517cb93a386Sopenharmony_ci this->validate(initialOffset, size); 518cb93a386Sopenharmony_ci} 519cb93a386Sopenharmony_ci 520cb93a386Sopenharmony_civoid SkPictureRecord::onDrawPath(const SkPath& path, const SkPaint& paint) { 521cb93a386Sopenharmony_ci // op + paint index + path index 522cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size; 523cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_PATH, &size); 524cb93a386Sopenharmony_ci this->addPaint(paint); 525cb93a386Sopenharmony_ci this->addPath(path); 526cb93a386Sopenharmony_ci this->validate(initialOffset, size); 527cb93a386Sopenharmony_ci} 528cb93a386Sopenharmony_ci 529cb93a386Sopenharmony_civoid SkPictureRecord::onDrawImage2(const SkImage* image, SkScalar x, SkScalar y, 530cb93a386Sopenharmony_ci const SkSamplingOptions& sampling, const SkPaint* paint) { 531cb93a386Sopenharmony_ci // op + paint_index + image_index + x + y 532cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar) + SkSamplingPriv::kFlatSize; 533cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_IMAGE2, &size); 534cb93a386Sopenharmony_ci this->addPaintPtr(paint); 535cb93a386Sopenharmony_ci this->addImage(image); 536cb93a386Sopenharmony_ci this->addScalar(x); 537cb93a386Sopenharmony_ci this->addScalar(y); 538cb93a386Sopenharmony_ci this->addSampling(sampling); 539cb93a386Sopenharmony_ci this->validate(initialOffset, size); 540cb93a386Sopenharmony_ci} 541cb93a386Sopenharmony_ci 542cb93a386Sopenharmony_civoid SkPictureRecord::onDrawImageRect2(const SkImage* image, const SkRect& src, const SkRect& dst, 543cb93a386Sopenharmony_ci const SkSamplingOptions& sampling, const SkPaint* paint, 544cb93a386Sopenharmony_ci SrcRectConstraint constraint) { 545cb93a386Sopenharmony_ci // id + paint_index + image_index + constraint 546cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size + 2 * sizeof(dst) + SkSamplingPriv::kFlatSize + kUInt32Size; 547cb93a386Sopenharmony_ci 548cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_IMAGE_RECT2, &size); 549cb93a386Sopenharmony_ci this->addPaintPtr(paint); 550cb93a386Sopenharmony_ci this->addImage(image); 551cb93a386Sopenharmony_ci this->addRect(src); 552cb93a386Sopenharmony_ci this->addRect(dst); 553cb93a386Sopenharmony_ci this->addSampling(sampling); 554cb93a386Sopenharmony_ci this->addInt(constraint); 555cb93a386Sopenharmony_ci this->validate(initialOffset, size); 556cb93a386Sopenharmony_ci} 557cb93a386Sopenharmony_ci 558cb93a386Sopenharmony_civoid SkPictureRecord::onDrawImageLattice2(const SkImage* image, const Lattice& lattice, 559cb93a386Sopenharmony_ci const SkRect& dst, SkFilterMode filter, 560cb93a386Sopenharmony_ci const SkPaint* paint) { 561cb93a386Sopenharmony_ci size_t latticeSize = SkCanvasPriv::WriteLattice(nullptr, lattice); 562cb93a386Sopenharmony_ci // op + paint index + image index + lattice + dst rect 563cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size + latticeSize + sizeof(dst) + sizeof(uint32_t); // filter 564cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_IMAGE_LATTICE2, &size); 565cb93a386Sopenharmony_ci this->addPaintPtr(paint); 566cb93a386Sopenharmony_ci this->addImage(image); 567cb93a386Sopenharmony_ci (void)SkCanvasPriv::WriteLattice(fWriter.reservePad(latticeSize), lattice); 568cb93a386Sopenharmony_ci this->addRect(dst); 569cb93a386Sopenharmony_ci this->addInt(static_cast<uint32_t>(filter)); 570cb93a386Sopenharmony_ci this->validate(initialOffset, size); 571cb93a386Sopenharmony_ci} 572cb93a386Sopenharmony_ci 573cb93a386Sopenharmony_civoid SkPictureRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 574cb93a386Sopenharmony_ci const SkPaint& paint) { 575cb93a386Sopenharmony_ci 576cb93a386Sopenharmony_ci // op + paint index + blob index + x/y 577cb93a386Sopenharmony_ci size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 578cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_TEXT_BLOB, &size); 579cb93a386Sopenharmony_ci 580cb93a386Sopenharmony_ci this->addPaint(paint); 581cb93a386Sopenharmony_ci this->addTextBlob(blob); 582cb93a386Sopenharmony_ci this->addScalar(x); 583cb93a386Sopenharmony_ci this->addScalar(y); 584cb93a386Sopenharmony_ci 585cb93a386Sopenharmony_ci this->validate(initialOffset, size); 586cb93a386Sopenharmony_ci} 587cb93a386Sopenharmony_ci 588cb93a386Sopenharmony_civoid SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 589cb93a386Sopenharmony_ci const SkPaint* paint) { 590cb93a386Sopenharmony_ci // op + picture index 591cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size; 592cb93a386Sopenharmony_ci size_t initialOffset; 593cb93a386Sopenharmony_ci 594cb93a386Sopenharmony_ci if (nullptr == matrix && nullptr == paint) { 595cb93a386Sopenharmony_ci initialOffset = this->addDraw(DRAW_PICTURE, &size); 596cb93a386Sopenharmony_ci this->addPicture(picture); 597cb93a386Sopenharmony_ci } else { 598cb93a386Sopenharmony_ci const SkMatrix& m = matrix ? *matrix : SkMatrix::I(); 599cb93a386Sopenharmony_ci size += SkMatrixPriv::WriteToMemory(m, nullptr) + kUInt32Size; // matrix + paint 600cb93a386Sopenharmony_ci initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size); 601cb93a386Sopenharmony_ci this->addPaintPtr(paint); 602cb93a386Sopenharmony_ci this->addMatrix(m); 603cb93a386Sopenharmony_ci this->addPicture(picture); 604cb93a386Sopenharmony_ci } 605cb93a386Sopenharmony_ci this->validate(initialOffset, size); 606cb93a386Sopenharmony_ci} 607cb93a386Sopenharmony_ci 608cb93a386Sopenharmony_civoid SkPictureRecord::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) { 609cb93a386Sopenharmony_ci // op + drawable index 610cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size; 611cb93a386Sopenharmony_ci size_t initialOffset; 612cb93a386Sopenharmony_ci 613cb93a386Sopenharmony_ci if (nullptr == matrix) { 614cb93a386Sopenharmony_ci initialOffset = this->addDraw(DRAW_DRAWABLE, &size); 615cb93a386Sopenharmony_ci this->addDrawable(drawable); 616cb93a386Sopenharmony_ci } else { 617cb93a386Sopenharmony_ci size += SkMatrixPriv::WriteToMemory(*matrix, nullptr); // matrix 618cb93a386Sopenharmony_ci initialOffset = this->addDraw(DRAW_DRAWABLE_MATRIX, &size); 619cb93a386Sopenharmony_ci this->addMatrix(*matrix); 620cb93a386Sopenharmony_ci this->addDrawable(drawable); 621cb93a386Sopenharmony_ci } 622cb93a386Sopenharmony_ci this->validate(initialOffset, size); 623cb93a386Sopenharmony_ci} 624cb93a386Sopenharmony_ci 625cb93a386Sopenharmony_civoid SkPictureRecord::onDrawVerticesObject(const SkVertices* vertices, 626cb93a386Sopenharmony_ci SkBlendMode mode, const SkPaint& paint) { 627cb93a386Sopenharmony_ci // op + paint index + vertices index + zero_bones + mode 628cb93a386Sopenharmony_ci size_t size = 5 * kUInt32Size; 629cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_VERTICES_OBJECT, &size); 630cb93a386Sopenharmony_ci 631cb93a386Sopenharmony_ci this->addPaint(paint); 632cb93a386Sopenharmony_ci this->addVertices(vertices); 633cb93a386Sopenharmony_ci this->addInt(0); // legacy bone count 634cb93a386Sopenharmony_ci this->addInt(static_cast<uint32_t>(mode)); 635cb93a386Sopenharmony_ci 636cb93a386Sopenharmony_ci this->validate(initialOffset, size); 637cb93a386Sopenharmony_ci} 638cb93a386Sopenharmony_ci 639cb93a386Sopenharmony_civoid SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 640cb93a386Sopenharmony_ci const SkPoint texCoords[4], SkBlendMode bmode, 641cb93a386Sopenharmony_ci const SkPaint& paint) { 642cb93a386Sopenharmony_ci // op + paint index + patch 12 control points + flag + patch 4 colors + 4 texture coordinates 643cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + SkPatchUtils::kNumCtrlPts * sizeof(SkPoint) + kUInt32Size; 644cb93a386Sopenharmony_ci uint32_t flag = 0; 645cb93a386Sopenharmony_ci if (colors) { 646cb93a386Sopenharmony_ci flag |= DRAW_VERTICES_HAS_COLORS; 647cb93a386Sopenharmony_ci size += SkPatchUtils::kNumCorners * sizeof(SkColor); 648cb93a386Sopenharmony_ci } 649cb93a386Sopenharmony_ci if (texCoords) { 650cb93a386Sopenharmony_ci flag |= DRAW_VERTICES_HAS_TEXS; 651cb93a386Sopenharmony_ci size += SkPatchUtils::kNumCorners * sizeof(SkPoint); 652cb93a386Sopenharmony_ci } 653cb93a386Sopenharmony_ci if (SkBlendMode::kModulate != bmode) { 654cb93a386Sopenharmony_ci flag |= DRAW_VERTICES_HAS_XFER; 655cb93a386Sopenharmony_ci size += kUInt32Size; 656cb93a386Sopenharmony_ci } 657cb93a386Sopenharmony_ci 658cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_PATCH, &size); 659cb93a386Sopenharmony_ci this->addPaint(paint); 660cb93a386Sopenharmony_ci this->addPatch(cubics); 661cb93a386Sopenharmony_ci this->addInt(flag); 662cb93a386Sopenharmony_ci 663cb93a386Sopenharmony_ci // write optional parameters 664cb93a386Sopenharmony_ci if (colors) { 665cb93a386Sopenharmony_ci fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor)); 666cb93a386Sopenharmony_ci } 667cb93a386Sopenharmony_ci if (texCoords) { 668cb93a386Sopenharmony_ci fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint)); 669cb93a386Sopenharmony_ci } 670cb93a386Sopenharmony_ci if (flag & DRAW_VERTICES_HAS_XFER) { 671cb93a386Sopenharmony_ci this->addInt((int)bmode); 672cb93a386Sopenharmony_ci } 673cb93a386Sopenharmony_ci this->validate(initialOffset, size); 674cb93a386Sopenharmony_ci} 675cb93a386Sopenharmony_ci 676cb93a386Sopenharmony_civoid SkPictureRecord::onDrawAtlas2(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 677cb93a386Sopenharmony_ci const SkColor colors[], int count, SkBlendMode mode, 678cb93a386Sopenharmony_ci const SkSamplingOptions& sampling, const SkRect* cull, 679cb93a386Sopenharmony_ci const SkPaint* paint) { 680cb93a386Sopenharmony_ci // [op + paint-index + atlas-index + flags + count] + [xform] + [tex] + [*colors + mode] + cull 681cb93a386Sopenharmony_ci size_t size = 5 * kUInt32Size + count * sizeof(SkRSXform) + count * sizeof(SkRect); 682cb93a386Sopenharmony_ci size += SkSamplingPriv::kFlatSize; 683cb93a386Sopenharmony_ci uint32_t flags = 0; 684cb93a386Sopenharmony_ci if (colors) { 685cb93a386Sopenharmony_ci flags |= DRAW_ATLAS_HAS_COLORS; 686cb93a386Sopenharmony_ci size += count * sizeof(SkColor); 687cb93a386Sopenharmony_ci size += sizeof(uint32_t); // xfermode::mode 688cb93a386Sopenharmony_ci } 689cb93a386Sopenharmony_ci if (cull) { 690cb93a386Sopenharmony_ci flags |= DRAW_ATLAS_HAS_CULL; 691cb93a386Sopenharmony_ci size += sizeof(SkRect); 692cb93a386Sopenharmony_ci } 693cb93a386Sopenharmony_ci flags |= DRAW_ATLAS_HAS_SAMPLING; 694cb93a386Sopenharmony_ci 695cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_ATLAS, &size); 696cb93a386Sopenharmony_ci this->addPaintPtr(paint); 697cb93a386Sopenharmony_ci this->addImage(atlas); 698cb93a386Sopenharmony_ci this->addInt(flags); 699cb93a386Sopenharmony_ci this->addInt(count); 700cb93a386Sopenharmony_ci fWriter.write(xform, count * sizeof(SkRSXform)); 701cb93a386Sopenharmony_ci fWriter.write(tex, count * sizeof(SkRect)); 702cb93a386Sopenharmony_ci 703cb93a386Sopenharmony_ci // write optional parameters 704cb93a386Sopenharmony_ci if (colors) { 705cb93a386Sopenharmony_ci fWriter.write(colors, count * sizeof(SkColor)); 706cb93a386Sopenharmony_ci this->addInt((int)mode); 707cb93a386Sopenharmony_ci } 708cb93a386Sopenharmony_ci if (cull) { 709cb93a386Sopenharmony_ci fWriter.write(cull, sizeof(SkRect)); 710cb93a386Sopenharmony_ci } 711cb93a386Sopenharmony_ci this->addSampling(sampling); 712cb93a386Sopenharmony_ci this->validate(initialOffset, size); 713cb93a386Sopenharmony_ci} 714cb93a386Sopenharmony_ci 715cb93a386Sopenharmony_civoid SkPictureRecord::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) { 716cb93a386Sopenharmony_ci // op + path index + zParams + lightPos + lightRadius + spot/ambient alphas + color + flags 717cb93a386Sopenharmony_ci size_t size = 2 * kUInt32Size + 2 * sizeof(SkPoint3) + 1 * sizeof(SkScalar) + 3 * kUInt32Size; 718cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_SHADOW_REC, &size); 719cb93a386Sopenharmony_ci 720cb93a386Sopenharmony_ci this->addPath(path); 721cb93a386Sopenharmony_ci 722cb93a386Sopenharmony_ci fWriter.writePoint3(rec.fZPlaneParams); 723cb93a386Sopenharmony_ci fWriter.writePoint3(rec.fLightPos); 724cb93a386Sopenharmony_ci fWriter.writeScalar(rec.fLightRadius); 725cb93a386Sopenharmony_ci fWriter.write32(rec.fAmbientColor); 726cb93a386Sopenharmony_ci fWriter.write32(rec.fSpotColor); 727cb93a386Sopenharmony_ci fWriter.write32(rec.fFlags); 728cb93a386Sopenharmony_ci 729cb93a386Sopenharmony_ci this->validate(initialOffset, size); 730cb93a386Sopenharmony_ci} 731cb93a386Sopenharmony_ci 732cb93a386Sopenharmony_civoid SkPictureRecord::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) { 733cb93a386Sopenharmony_ci size_t keyLen = SkWriter32::WriteStringSize(key); 734cb93a386Sopenharmony_ci size_t valueLen = SkWriter32::WriteDataSize(value); 735cb93a386Sopenharmony_ci size_t size = 4 + sizeof(SkRect) + keyLen + valueLen; 736cb93a386Sopenharmony_ci 737cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_ANNOTATION, &size); 738cb93a386Sopenharmony_ci this->addRect(rect); 739cb93a386Sopenharmony_ci fWriter.writeString(key); 740cb93a386Sopenharmony_ci fWriter.writeData(value); 741cb93a386Sopenharmony_ci this->validate(initialOffset, size); 742cb93a386Sopenharmony_ci} 743cb93a386Sopenharmony_ci 744cb93a386Sopenharmony_civoid SkPictureRecord::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4], 745cb93a386Sopenharmony_ci SkCanvas::QuadAAFlags aa, const SkColor4f& color, 746cb93a386Sopenharmony_ci SkBlendMode mode) { 747cb93a386Sopenharmony_ci 748cb93a386Sopenharmony_ci // op + rect + aa flags + color + mode + hasClip(as int) + clipCount*points 749cb93a386Sopenharmony_ci size_t size = 4 * kUInt32Size + sizeof(SkColor4f) + sizeof(rect) + 750cb93a386Sopenharmony_ci (clip ? 4 : 0) * sizeof(SkPoint); 751cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_EDGEAA_QUAD, &size); 752cb93a386Sopenharmony_ci this->addRect(rect); 753cb93a386Sopenharmony_ci this->addInt((int) aa); 754cb93a386Sopenharmony_ci fWriter.write(&color, sizeof(SkColor4f)); 755cb93a386Sopenharmony_ci this->addInt((int) mode); 756cb93a386Sopenharmony_ci this->addInt(clip != nullptr); 757cb93a386Sopenharmony_ci if (clip) { 758cb93a386Sopenharmony_ci this->addPoints(clip, 4); 759cb93a386Sopenharmony_ci } 760cb93a386Sopenharmony_ci this->validate(initialOffset, size); 761cb93a386Sopenharmony_ci} 762cb93a386Sopenharmony_ci 763cb93a386Sopenharmony_civoid SkPictureRecord::onDrawEdgeAAImageSet2(const SkCanvas::ImageSetEntry set[], int count, 764cb93a386Sopenharmony_ci const SkPoint dstClips[], 765cb93a386Sopenharmony_ci const SkMatrix preViewMatrices[], 766cb93a386Sopenharmony_ci const SkSamplingOptions& sampling, 767cb93a386Sopenharmony_ci const SkPaint* paint, 768cb93a386Sopenharmony_ci SkCanvas::SrcRectConstraint constraint) { 769cb93a386Sopenharmony_ci static constexpr size_t kMatrixSize = 9 * sizeof(SkScalar); // *not* sizeof(SkMatrix) 770cb93a386Sopenharmony_ci // op + count + paint + constraint + (image index, src rect, dst rect, alpha, aa flags, 771cb93a386Sopenharmony_ci // hasClip(int), matrixIndex) * cnt + totalClipCount + dstClips + totalMatrixCount + matrices 772cb93a386Sopenharmony_ci int totalDstClipCount, totalMatrixCount; 773cb93a386Sopenharmony_ci SkCanvasPriv::GetDstClipAndMatrixCounts(set, count, &totalDstClipCount, &totalMatrixCount); 774cb93a386Sopenharmony_ci 775cb93a386Sopenharmony_ci size_t size = 6 * kUInt32Size + sizeof(SkPoint) * totalDstClipCount + 776cb93a386Sopenharmony_ci kMatrixSize * totalMatrixCount + 777cb93a386Sopenharmony_ci (4 * kUInt32Size + 2 * sizeof(SkRect) + sizeof(SkScalar)) * count + 778cb93a386Sopenharmony_ci SkSamplingPriv::kFlatSize; 779cb93a386Sopenharmony_ci size_t initialOffset = this->addDraw(DRAW_EDGEAA_IMAGE_SET2, &size); 780cb93a386Sopenharmony_ci this->addInt(count); 781cb93a386Sopenharmony_ci this->addPaintPtr(paint); 782cb93a386Sopenharmony_ci this->addSampling(sampling); 783cb93a386Sopenharmony_ci this->addInt((int) constraint); 784cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 785cb93a386Sopenharmony_ci this->addImage(set[i].fImage.get()); 786cb93a386Sopenharmony_ci this->addRect(set[i].fSrcRect); 787cb93a386Sopenharmony_ci this->addRect(set[i].fDstRect); 788cb93a386Sopenharmony_ci this->addInt(set[i].fMatrixIndex); 789cb93a386Sopenharmony_ci this->addScalar(set[i].fAlpha); 790cb93a386Sopenharmony_ci this->addInt((int)set[i].fAAFlags); 791cb93a386Sopenharmony_ci this->addInt(set[i].fHasClip); 792cb93a386Sopenharmony_ci } 793cb93a386Sopenharmony_ci this->addInt(totalDstClipCount); 794cb93a386Sopenharmony_ci this->addPoints(dstClips, totalDstClipCount); 795cb93a386Sopenharmony_ci this->addInt(totalMatrixCount); 796cb93a386Sopenharmony_ci for (int i = 0; i < totalMatrixCount; ++i) { 797cb93a386Sopenharmony_ci this->addMatrix(preViewMatrices[i]); 798cb93a386Sopenharmony_ci } 799cb93a386Sopenharmony_ci this->validate(initialOffset, size); 800cb93a386Sopenharmony_ci} 801cb93a386Sopenharmony_ci 802cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 803cb93a386Sopenharmony_ci 804cb93a386Sopenharmony_ci// De-duping helper. 805cb93a386Sopenharmony_ci 806cb93a386Sopenharmony_citemplate <typename T> 807cb93a386Sopenharmony_cistatic bool equals(T* a, T* b) { return a->uniqueID() == b->uniqueID(); } 808cb93a386Sopenharmony_ci 809cb93a386Sopenharmony_citemplate <> 810cb93a386Sopenharmony_cibool equals(SkDrawable* a, SkDrawable* b) { 811cb93a386Sopenharmony_ci // SkDrawable's generationID is not a stable unique identifier. 812cb93a386Sopenharmony_ci return a == b; 813cb93a386Sopenharmony_ci} 814cb93a386Sopenharmony_ci 815cb93a386Sopenharmony_citemplate <typename T> 816cb93a386Sopenharmony_cistatic int find_or_append(SkTArray<sk_sp<T>>& array, T* obj) { 817cb93a386Sopenharmony_ci for (int i = 0; i < array.count(); i++) { 818cb93a386Sopenharmony_ci if (equals(array[i].get(), obj)) { 819cb93a386Sopenharmony_ci return i; 820cb93a386Sopenharmony_ci } 821cb93a386Sopenharmony_ci } 822cb93a386Sopenharmony_ci 823cb93a386Sopenharmony_ci array.push_back(sk_ref_sp(obj)); 824cb93a386Sopenharmony_ci 825cb93a386Sopenharmony_ci return array.count() - 1; 826cb93a386Sopenharmony_ci} 827cb93a386Sopenharmony_ci 828cb93a386Sopenharmony_cisk_sp<SkSurface> SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) { 829cb93a386Sopenharmony_ci return nullptr; 830cb93a386Sopenharmony_ci} 831cb93a386Sopenharmony_ci 832cb93a386Sopenharmony_civoid SkPictureRecord::addImage(const SkImage* image) { 833cb93a386Sopenharmony_ci // convention for images is 0-based index 834cb93a386Sopenharmony_ci this->addInt(find_or_append(fImages, image)); 835cb93a386Sopenharmony_ci} 836cb93a386Sopenharmony_ci 837cb93a386Sopenharmony_civoid SkPictureRecord::addMatrix(const SkMatrix& matrix) { 838cb93a386Sopenharmony_ci fWriter.writeMatrix(matrix); 839cb93a386Sopenharmony_ci} 840cb93a386Sopenharmony_ci 841cb93a386Sopenharmony_civoid SkPictureRecord::addPaintPtr(const SkPaint* paint) { 842cb93a386Sopenharmony_ci if (paint) { 843cb93a386Sopenharmony_ci fPaints.push_back(*paint); 844cb93a386Sopenharmony_ci this->addInt(fPaints.count()); 845cb93a386Sopenharmony_ci } else { 846cb93a386Sopenharmony_ci this->addInt(0); 847cb93a386Sopenharmony_ci } 848cb93a386Sopenharmony_ci} 849cb93a386Sopenharmony_ci 850cb93a386Sopenharmony_ciint SkPictureRecord::addPathToHeap(const SkPath& path) { 851cb93a386Sopenharmony_ci if (int* n = fPaths.find(path)) { 852cb93a386Sopenharmony_ci return *n; 853cb93a386Sopenharmony_ci } 854cb93a386Sopenharmony_ci int n = fPaths.count() + 1; // 0 is reserved for null / error. 855cb93a386Sopenharmony_ci fPaths.set(path, n); 856cb93a386Sopenharmony_ci return n; 857cb93a386Sopenharmony_ci} 858cb93a386Sopenharmony_ci 859cb93a386Sopenharmony_civoid SkPictureRecord::addPath(const SkPath& path) { 860cb93a386Sopenharmony_ci this->addInt(this->addPathToHeap(path)); 861cb93a386Sopenharmony_ci} 862cb93a386Sopenharmony_ci 863cb93a386Sopenharmony_civoid SkPictureRecord::addPatch(const SkPoint cubics[12]) { 864cb93a386Sopenharmony_ci fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint)); 865cb93a386Sopenharmony_ci} 866cb93a386Sopenharmony_ci 867cb93a386Sopenharmony_civoid SkPictureRecord::addPicture(const SkPicture* picture) { 868cb93a386Sopenharmony_ci // follow the convention of recording a 1-based index 869cb93a386Sopenharmony_ci this->addInt(find_or_append(fPictures, picture) + 1); 870cb93a386Sopenharmony_ci} 871cb93a386Sopenharmony_ci 872cb93a386Sopenharmony_civoid SkPictureRecord::addDrawable(SkDrawable* drawable) { 873cb93a386Sopenharmony_ci // follow the convention of recording a 1-based index 874cb93a386Sopenharmony_ci this->addInt(find_or_append(fDrawables, drawable) + 1); 875cb93a386Sopenharmony_ci} 876cb93a386Sopenharmony_ci 877cb93a386Sopenharmony_civoid SkPictureRecord::addPoint(const SkPoint& point) { 878cb93a386Sopenharmony_ci fWriter.writePoint(point); 879cb93a386Sopenharmony_ci} 880cb93a386Sopenharmony_ci 881cb93a386Sopenharmony_civoid SkPictureRecord::addPoints(const SkPoint pts[], int count) { 882cb93a386Sopenharmony_ci fWriter.writeMul4(pts, count * sizeof(SkPoint)); 883cb93a386Sopenharmony_ci} 884cb93a386Sopenharmony_ci 885cb93a386Sopenharmony_civoid SkPictureRecord::addNoOp() { 886cb93a386Sopenharmony_ci size_t size = kUInt32Size; // op 887cb93a386Sopenharmony_ci this->addDraw(NOOP, &size); 888cb93a386Sopenharmony_ci} 889cb93a386Sopenharmony_ci 890cb93a386Sopenharmony_civoid SkPictureRecord::addRect(const SkRect& rect) { 891cb93a386Sopenharmony_ci fWriter.writeRect(rect); 892cb93a386Sopenharmony_ci} 893cb93a386Sopenharmony_ci 894cb93a386Sopenharmony_civoid SkPictureRecord::addRectPtr(const SkRect* rect) { 895cb93a386Sopenharmony_ci if (fWriter.writeBool(rect != nullptr)) { 896cb93a386Sopenharmony_ci fWriter.writeRect(*rect); 897cb93a386Sopenharmony_ci } 898cb93a386Sopenharmony_ci} 899cb93a386Sopenharmony_ci 900cb93a386Sopenharmony_civoid SkPictureRecord::addIRect(const SkIRect& rect) { 901cb93a386Sopenharmony_ci fWriter.write(&rect, sizeof(rect)); 902cb93a386Sopenharmony_ci} 903cb93a386Sopenharmony_ci 904cb93a386Sopenharmony_civoid SkPictureRecord::addIRectPtr(const SkIRect* rect) { 905cb93a386Sopenharmony_ci if (fWriter.writeBool(rect != nullptr)) { 906cb93a386Sopenharmony_ci *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect; 907cb93a386Sopenharmony_ci } 908cb93a386Sopenharmony_ci} 909cb93a386Sopenharmony_ci 910cb93a386Sopenharmony_civoid SkPictureRecord::addRRect(const SkRRect& rrect) { 911cb93a386Sopenharmony_ci fWriter.writeRRect(rrect); 912cb93a386Sopenharmony_ci} 913cb93a386Sopenharmony_ci 914cb93a386Sopenharmony_civoid SkPictureRecord::addRegion(const SkRegion& region) { 915cb93a386Sopenharmony_ci fWriter.writeRegion(region); 916cb93a386Sopenharmony_ci} 917cb93a386Sopenharmony_ci 918cb93a386Sopenharmony_civoid SkPictureRecord::addSampling(const SkSamplingOptions& sampling) { 919cb93a386Sopenharmony_ci fWriter.writeBool(sampling.useCubic); 920cb93a386Sopenharmony_ci if (sampling.useCubic) { 921cb93a386Sopenharmony_ci fWriter.writeScalar(sampling.cubic.B); 922cb93a386Sopenharmony_ci fWriter.writeScalar(sampling.cubic.C); 923cb93a386Sopenharmony_ci } else { 924cb93a386Sopenharmony_ci fWriter.writeInt(static_cast<uint32_t>(sampling.filter)); 925cb93a386Sopenharmony_ci fWriter.writeInt(static_cast<uint32_t>(sampling.mipmap)); 926cb93a386Sopenharmony_ci } 927cb93a386Sopenharmony_ci} 928cb93a386Sopenharmony_ci 929cb93a386Sopenharmony_civoid SkPictureRecord::addText(const void* text, size_t byteLength) { 930cb93a386Sopenharmony_ci addInt(SkToInt(byteLength)); 931cb93a386Sopenharmony_ci fWriter.writePad(text, byteLength); 932cb93a386Sopenharmony_ci} 933cb93a386Sopenharmony_ci 934cb93a386Sopenharmony_civoid SkPictureRecord::addTextBlob(const SkTextBlob* blob) { 935cb93a386Sopenharmony_ci // follow the convention of recording a 1-based index 936cb93a386Sopenharmony_ci this->addInt(find_or_append(fTextBlobs, blob) + 1); 937cb93a386Sopenharmony_ci} 938cb93a386Sopenharmony_ci 939cb93a386Sopenharmony_civoid SkPictureRecord::addVertices(const SkVertices* vertices) { 940cb93a386Sopenharmony_ci // follow the convention of recording a 1-based index 941cb93a386Sopenharmony_ci this->addInt(find_or_append(fVertices, vertices) + 1); 942cb93a386Sopenharmony_ci} 943cb93a386Sopenharmony_ci 944cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 945