1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 776f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPictureRecord.h" 9d575eed3549dcb943ae84cfeb0a31463d6edad34junov@chromium.org#include "SkDevice.h" 10a85d4d0814818e4ddabb9237da209d61d6cd5854reed#include "SkImage_Base.h" 11b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h" 12b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPixelRef.h" 13b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkRRect.h" 1471c3c760a83123ee0b3127b8c65c6394ce541c50reed#include "SkRSXform.h" 15b7425173f96e93b090787e2386ba5f022b6c2869fmalita#include "SkTextBlob.h" 16b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkTSearch.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define HEAP_BLOCK_SIZE 4096 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 204e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.orgenum { 21d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // just need a value that save or getSaveCount would never return 224e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org kNoInitialSave = -1, 234e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org}; 244e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org 252ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com// A lot of basic types get stored as a uint32_t: bools, ints, paint indices, etc. 262ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.comstatic int const kUInt32Size = 4; 272ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 280bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillipsSkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags) 2919fafef9784fe7c644540ffd0ee9f6da1914a038commit-bot@chromium.org : INHERITED(dimensions.width(), dimensions.height()) 3071a236370792416b367a7d2d6b8e471b06b331cdmtklein , fRecordFlags(flags) 3171a236370792416b367a7d2d6b8e471b06b331cdmtklein , fInitialSaveCount(kNoInitialSave) { 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkPictureRecord::~SkPictureRecord() { 355351aad9bc5b2e3101472248967e3dc1f84d24eerobertphillips fImageRefs.unrefAll(); 3621830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com fPictureRefs.unrefAll(); 37b7425173f96e93b090787e2386ba5f022b6c2869fmalita fTextBlobRefs.unrefAll(); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 425f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitavoid SkPictureRecord::willSave() { 43ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // record the offset to us, making it non-positive to distinguish a save 44ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // from a clip entry. 454469938e92d779dff05e745559e67907bbf21e78reed@google.com fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); 465f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita this->recordSave(); 47e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 485f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita this->INHERITED::willSave(); 495a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 5011f869277c81a232fd4e40eca41e6f71b95b4b17skia.committer@gmail.com 515f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitavoid SkPictureRecord::recordSave() { 52c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips fContentInfo.onSave(); 53c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips 545f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita // op only 55512f3e3b2592097a39bde9331829b38d16c0f85dreed size_t size = sizeof(kUInt32Size); 568b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SAVE, &size); 5782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 588b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 614960eeec4a1f2a772654883d7f3615d47bcd5dc3reedSkCanvas::SaveLayerStrategy SkPictureRecord::getSaveLayerStrategy(const SaveLayerRec& rec) { 62ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // record the offset to us, making it non-positive to distinguish a save 63ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // from a clip entry. 644469938e92d779dff05e745559e67907bbf21e78reed@google.com fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); 654960eeec4a1f2a772654883d7f3615d47bcd5dc3reed this->recordSaveLayer(rec); 6611f869277c81a232fd4e40eca41e6f71b95b4b17skia.committer@gmail.com 674960eeec4a1f2a772654883d7f3615d47bcd5dc3reed (void)this->INHERITED::getSaveLayerStrategy(rec); 68e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org /* No need for a (potentially very big) layer which we don't actually need 695a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com at this time (and may not be able to afford since during record our 705a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com clip starts out the size of the picture, which is often much larger 715a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com than the size of the actual device we'll use during playback). 725a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com */ 73e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return kNoLayer_SaveLayerStrategy; 745a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 755a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 764960eeec4a1f2a772654883d7f3615d47bcd5dc3reedvoid SkPictureRecord::recordSaveLayer(const SaveLayerRec& rec) { 77c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips fContentInfo.onSaveLayer(); 78c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips 79bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed // op + flatflags 80dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size; 81bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed uint32_t flatFlags = 0; 82bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed 834960eeec4a1f2a772654883d7f3615d47bcd5dc3reed if (rec.fBounds) { 84bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed flatFlags |= SAVELAYERREC_HAS_BOUNDS; 85bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed size += sizeof(*rec.fBounds); 86bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 87bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (rec.fPaint) { 88bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed flatFlags |= SAVELAYERREC_HAS_PAINT; 89bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed size += sizeof(uint32_t); // index 90bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 91bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (rec.fBackdrop) { 92bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed flatFlags |= SAVELAYERREC_HAS_BACKDROP; 93bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed size += sizeof(uint32_t); // (paint) index 94bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 95bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (rec.fSaveLayerFlags) { 96bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed flatFlags |= SAVELAYERREC_HAS_FLAGS; 97bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed size += sizeof(uint32_t); 982ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 100bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed const size_t initialOffset = this->addDraw(SAVE_LAYER_SAVELAYERREC, &size); 101bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed this->addInt(flatFlags); 102bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (flatFlags & SAVELAYERREC_HAS_BOUNDS) { 103bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed this->addRect(*rec.fBounds); 104bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 105bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (flatFlags & SAVELAYERREC_HAS_PAINT) { 106bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed this->addPaintPtr(rec.fPaint); 107bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 108bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (flatFlags & SAVELAYERREC_HAS_BACKDROP) { 109bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed // overkill, but we didn't already track single flattenables, so using a paint for that 110bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkPaint paint; 111bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed paint.setImageFilter(const_cast<SkImageFilter*>(rec.fBackdrop)); 112bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed this->addPaint(paint); 113bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 114bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed if (flatFlags & SAVELAYERREC_HAS_FLAGS) { 115bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed this->addInt(rec.fSaveLayerFlags); 116bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed } 1178b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 120210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org#ifdef SK_DEBUG 121210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org/* 1222ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com * Read the op code from 'offset' in 'writer' and extract the size too. 1232ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com */ 124dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgstatic DrawType peek_op_and_size(SkWriter32* writer, size_t offset, uint32_t* size) { 125536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org uint32_t peek = writer->readTAt<uint32_t>(offset); 1262ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 1272ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com uint32_t op; 128c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org UNPACK_8_24(peek, op, *size); 1292ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (MASK_24 == *size) { 1302ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // size required its own slot right after the op code 131536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org *size = writer->readTAt<uint32_t>(offset + kUInt32Size); 1322ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 1332ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com return (DrawType) op; 134ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com} 13546616af01b412ea984a516fda1ed8ec08e689f29mtklein#endif//SK_DEBUG 1364b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org 137e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgvoid SkPictureRecord::willRestore() { 1384e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org#if 0 1394e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org SkASSERT(fRestoreOffsetStack.count() > 1); 1404e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org#endif 1414e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org 142b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com // check for underflow 143b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com if (fRestoreOffsetStack.count() == 0) { 144b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com return; 145b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com } 146b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com 14746616af01b412ea984a516fda1ed8ec08e689f29mtklein this->recordRestore(); 148ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com 149b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com fRestoreOffsetStack.pop(); 15032a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com 151e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->INHERITED::willRestore(); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 154105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.comvoid SkPictureRecord::recordRestore(bool fillInSkips) { 155c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips fContentInfo.onRestore(); 156c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips 157105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com if (fillInSkips) { 158105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten()); 159105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com } 160dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code 161dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t initialOffset = this->addDraw(RESTORE, &size); 1625a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com this->validate(initialOffset, size); 1635a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 1645a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 165d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.orgvoid SkPictureRecord::recordTranslate(const SkMatrix& m) { 166d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkASSERT(SkMatrix::kTranslate_Mask == m.getType()); 167d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 1682ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + dx + dy 169dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 1708b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(TRANSLATE, &size); 171d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getTranslateX()); 172d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getTranslateY()); 1738b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 176d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.orgvoid SkPictureRecord::recordScale(const SkMatrix& m) { 177d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkASSERT(SkMatrix::kScale_Mask == m.getType()); 178105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com 1792ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + sx + sy 180dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 1818b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SCALE, &size); 182d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getScaleX()); 183d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getScaleY()); 1848b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.orgvoid SkPictureRecord::didConcat(const SkMatrix& matrix) { 188d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org switch (matrix.getType()) { 189d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org case SkMatrix::kTranslate_Mask: 190d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->recordTranslate(matrix); 191d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org break; 192d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org case SkMatrix::kScale_Mask: 193d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->recordScale(matrix); 194d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org break; 195d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org default: 196d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->recordConcat(matrix); 197d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org break; 198d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 19944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->INHERITED::didConcat(matrix); 2005a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 2015a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 2025a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comvoid SkPictureRecord::recordConcat(const SkMatrix& matrix) { 2034469938e92d779dff05e745559e67907bbf21e78reed@google.com this->validate(fWriter.bytesWritten(), 0); 204fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + matrix 20596fcdcc219d2a0d3579719b84b28bede76efba64halcanary size_t size = kUInt32Size + matrix.writeToMemory(nullptr); 2068b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CONCAT, &size); 207cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addMatrix(matrix); 2088b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.orgvoid SkPictureRecord::didSetMatrix(const SkMatrix& matrix) { 2124469938e92d779dff05e745559e67907bbf21e78reed@google.com this->validate(fWriter.bytesWritten(), 0); 213fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + matrix 21496fcdcc219d2a0d3579719b84b28bede76efba64halcanary size_t size = kUInt32Size + matrix.writeToMemory(nullptr); 2158b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SET_MATRIX, &size); 216cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addMatrix(matrix); 2178b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 21844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->INHERITED::didSetMatrix(matrix); 2196e073b9e2b70d6bbf8a06050fff1364827204f08reed@android.com} 2206e073b9e2b70d6bbf8a06050fff1364827204f08reed@android.com 22145482d1d2b97de185df137a1db40cbe5a62313a5reed@google.comstatic bool regionOpExpands(SkRegion::Op op) { 22245482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com switch (op) { 22345482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kUnion_Op: 22445482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kXOR_Op: 22545482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kReverseDifference_Op: 22645482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kReplace_Op: 22745482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com return true; 22845482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kIntersect_Op: 22945482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kDifference_Op: 23045482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com return false; 23145482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com default: 2320c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown region op"); 23345482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com return false; 23445482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com } 23545482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com} 23645482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com 237e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.comvoid SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) { 238ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com int32_t offset = fRestoreOffsetStack.top(); 239ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com while (offset > 0) { 240536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org uint32_t peek = fWriter.readTAt<uint32_t>(offset); 241536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org fWriter.overwriteTAt(offset, restoreOffset); 242c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org offset = peek; 243e3dbedb44cad6c7b7e5c9aae5224d0b0abec9bf4junov@chromium.org } 24411f869277c81a232fd4e40eca41e6f71b95b4b17skia.committer@gmail.com 245ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com#ifdef SK_DEBUG 2462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // offset of 0 has been disabled, so we skip it 2472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (offset > 0) { 2482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // assert that the final offset value points to a save verb 2492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed uint32_t opSize; 2502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); 2514960eeec4a1f2a772654883d7f3615d47bcd5dc3reed SkASSERT(SAVE_LAYER_SAVEFLAGS_DEPRECATED != drawOp); 252bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkASSERT(SAVE_LAYER_SAVELAYERFLAGS_DEPRECATED_JAN_2016 != drawOp); 253bfd5f171e6a3eccd7c4bede652a85fd76bcbce2areed SkASSERT(SAVE == drawOp || SAVE_LAYER_SAVELAYERREC == drawOp); 2542ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 255ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com#endif 256e3dbedb44cad6c7b7e5c9aae5224d0b0abec9bf4junov@chromium.org} 257e3dbedb44cad6c7b7e5c9aae5224d0b0abec9bf4junov@chromium.org 258d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.comvoid SkPictureRecord::beginRecording() { 259d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // we have to call this *after* our constructor, to ensure that it gets 260d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // recorded. This is balanced by restoreToCount() call from endRecording, 261d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // which in-turn calls our overridden restore(), so those get recorded too. 262091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org fInitialSaveCount = this->save(); 263d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com} 264d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com 265a6c9e0e02be390d36b80f4872c628edb3594208ejunov@chromium.orgvoid SkPictureRecord::endRecording() { 2664e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org SkASSERT(kNoInitialSave != fInitialSaveCount); 2674e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org this->restoreToCount(fInitialSaveCount); 268a6c9e0e02be390d36b80f4872c628edb3594208ejunov@chromium.org} 269a6c9e0e02be390d36b80f4872c628edb3594208ejunov@chromium.org 270dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { 27121b519d56f9838c2e6e7abe704d3313e03f6f754reed@google.com if (fRestoreOffsetStack.isEmpty()) { 2725a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return -1; 27321b519d56f9838c2e6e7abe704d3313e03f6f754reed@google.com } 27421b519d56f9838c2e6e7abe704d3313e03f6f754reed@google.com 275d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // The RestoreOffset field is initially filled with a placeholder 276d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // value that points to the offset of the previous RestoreOffset 277d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // in the current stack level, thus forming a linked list so that 278d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // the restore offsets can be filled in when the corresponding 279d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // restore command is recorded. 280d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com int32_t prevOffset = fRestoreOffsetStack.top(); 281d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com 28245482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com if (regionOpExpands(op)) { 28345482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // Run back through any previous clip ops, and mark their offset to 28445482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // be 0, disabling their ability to trigger a jump-to-restore, otherwise 28545482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // they could hide this clips ability to expand the clip (i.e. go from 28645482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // empty to non-empty). 287cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); 288d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com 289d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // Reset the pointer back to the previous clip so that subsequent 290d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // restores don't overwrite the offsets we just cleared. 291d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com prevOffset = 0; 29245482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com } 29374b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 2944469938e92d779dff05e745559e67907bbf21e78reed@google.com size_t offset = fWriter.bytesWritten(); 295cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(prevOffset); 296dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org fRestoreOffsetStack.top() = SkToU32(offset); 2975a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 29845482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com} 29945482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com 3008f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 3018f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); 3028f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->INHERITED::onClipRect(rect, op, edgeStyle); 3035a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 3045a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 305dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 306f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // id + rect + clip params 307dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; 3084310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 309f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 310f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 311f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 312f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 3138b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_RECT, &size); 314cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(rect); 315cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, doAA)); 316dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = this->recordRestoreOffsetPlaceholder(op); 317306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 3188b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 3195a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 32068d61ed83ec7b6e98e9623c2f5c9e7b1a32d25bbreed@google.com} 32168d61ed83ec7b6e98e9623c2f5c9e7b1a32d25bbreed@google.com 3228f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 3238f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); 324d954498c01ccf0417feacf89e45d0c62a06a813breed this->INHERITED::onClipRRect(rrect, op, edgeStyle); 3255a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 3265a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 327dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 328f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // op + rrect + clip params 329dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; 3304310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 331f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 332f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 333f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 334f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 3358b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_RRECT, &size); 336cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRRect(rrect); 337cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, doAA)); 338dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = recordRestoreOffsetPlaceholder(op); 3398b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 3405a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 3414ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 3424ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 3438f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 3445a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com int pathID = this->addPathToHeap(path); 3458f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle); 346d954498c01ccf0417feacf89e45d0c62a06a813breed this->INHERITED::onClipPath(path, op, edgeStyle); 3475a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 3485a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 349dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) { 350f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // op + path index + clip params 351dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size; 3524310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 353f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 354f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 355f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 356f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 3578b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_PATH, &size); 358cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(pathID); 359cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, doAA)); 360dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = recordRestoreOffsetPlaceholder(op); 3618b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 3625a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipRegion(const SkRegion& region, SkRegion::Op op) { 3665a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com this->recordClipRegion(region, op); 3678f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->INHERITED::onClipRegion(region, op); 3685a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 3695a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 370dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op) { 371fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + clip params + region 37296fcdcc219d2a0d3579719b84b28bede76efba64halcanary size_t size = 2 * kUInt32Size + region.writeToMemory(nullptr); 3734310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 374f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 375f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 376f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 377f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 3788b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_REGION, &size); 379cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRegion(region); 380cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, false)); 381dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = this->recordRestoreOffsetPlaceholder(op); 38282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 3838b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 3845a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 38741af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawPaint(const SkPaint& paint) { 3882ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index 389dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size; 3908b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_PAINT, &size); 391cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 3928b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 39541af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 39641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 397afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onDrawPoints(count, paint); 398105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com 3992ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + mode + count + point data 400dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 4 * kUInt32Size + count * sizeof(SkPoint); 4018b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_POINTS, &size); 402cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 403afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw 404cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(mode); 405dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org this->addInt(SkToInt(count)); 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(pts, count * sizeof(SkPoint)); 4078b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 41041af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawOval(const SkRect& oval, const SkPaint& paint) { 4112ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + rect 412dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + sizeof(oval); 4138b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_OVAL, &size); 414cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 415cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(oval); 4168b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 4184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 41941af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawRect(const SkRect& rect, const SkPaint& paint) { 4202ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + rect 421dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + sizeof(rect); 4228b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_RECT, &size); 423cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 424cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(rect); 4258b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42841af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 42946616af01b412ea984a516fda1ed8ec08e689f29mtklein // op + paint index + rrect 43046616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory; 43146616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t initialOffset = this->addDraw(DRAW_RRECT, &size); 43246616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 43346616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addRRect(rrect); 43446616af01b412ea984a516fda1ed8ec08e689f29mtklein this->validate(initialOffset, size); 4354ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 4364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 437ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 438ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 439ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // op + paint index + rrects 440dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2; 441dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t initialOffset = this->addDraw(DRAW_DRRECT, &size); 442ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->addPaint(paint); 443ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->addRRect(outer); 444ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->addRRect(inner); 445ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->validate(initialOffset, size); 446ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 447ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 44841af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawPath(const SkPath& path, const SkPaint& paint) { 449afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onDrawPath(path, paint); 450e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org 4512ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + path index 452dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size; 4538b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_PATH, &size); 454cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 455cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPath(path); 4568b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45941af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 46041af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 4612ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + bitmap index + left + top 462dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 4638b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_BITMAP, &size); 464cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 465f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 466cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(left); 467cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(top); 4688b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 47141af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 472562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 473eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org // id + paint index + bitmap index + bool for 'src' + flags 474dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 5 * kUInt32Size; 47549f085dddff10473b6ebf832a974288300224e60bsalomon if (src) { 4762ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += sizeof(*src); // + rect 4772ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 4782ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += sizeof(dst); // + rect 4792ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 480a5517e2b190a8083b38964972b031c13e99f1012reed size_t initialOffset = this->addDraw(DRAW_BITMAP_RECT, &size); 481cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 482f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 483cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRectPtr(src); // may be null 484cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(dst); 485a5517e2b190a8083b38964972b031c13e99f1012reed this->addInt(constraint); 4868b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 489a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkPictureRecord::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, 490a85d4d0814818e4ddabb9237da209d61d6cd5854reed const SkPaint* paint) { 491871872f3f247f6b699617f6d9ef50ef5da6fbe74reed // op + paint_index + image_index + x + y 492871872f3f247f6b699617f6d9ef50ef5da6fbe74reed size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 493871872f3f247f6b699617f6d9ef50ef5da6fbe74reed size_t initialOffset = this->addDraw(DRAW_IMAGE, &size); 494871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addPaintPtr(paint); 495871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addImage(image); 496871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addScalar(x); 497871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addScalar(y); 498871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->validate(initialOffset, size); 499a85d4d0814818e4ddabb9237da209d61d6cd5854reed} 500a85d4d0814818e4ddabb9237da209d61d6cd5854reed 501a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkPictureRecord::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 502562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint constraint) { 503a5517e2b190a8083b38964972b031c13e99f1012reed // id + paint_index + image_index + bool_for_src + constraint 504a5517e2b190a8083b38964972b031c13e99f1012reed size_t size = 5 * kUInt32Size; 505871872f3f247f6b699617f6d9ef50ef5da6fbe74reed if (src) { 506871872f3f247f6b699617f6d9ef50ef5da6fbe74reed size += sizeof(*src); // + rect 507a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 508871872f3f247f6b699617f6d9ef50ef5da6fbe74reed size += sizeof(dst); // + rect 509c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein 510871872f3f247f6b699617f6d9ef50ef5da6fbe74reed size_t initialOffset = this->addDraw(DRAW_IMAGE_RECT, &size); 511871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addPaintPtr(paint); 512871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addImage(image); 513871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addRectPtr(src); // may be null 514871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addRect(dst); 515a5517e2b190a8083b38964972b031c13e99f1012reed this->addInt(constraint); 516871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->validate(initialOffset, size); 517a85d4d0814818e4ddabb9237da209d61d6cd5854reed} 518a85d4d0814818e4ddabb9237da209d61d6cd5854reed 5194c21dc5ddf3b482293ed34eead876d8d61a662c3reedvoid SkPictureRecord::onDrawImageNine(const SkImage* img, const SkIRect& center, const SkRect& dst, 5204c21dc5ddf3b482293ed34eead876d8d61a662c3reed const SkPaint* paint) { 5214c21dc5ddf3b482293ed34eead876d8d61a662c3reed // id + paint_index + image_index + center + dst 5224c21dc5ddf3b482293ed34eead876d8d61a662c3reed size_t size = 3 * kUInt32Size + sizeof(SkIRect) + sizeof(SkRect); 523c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein 5244c21dc5ddf3b482293ed34eead876d8d61a662c3reed size_t initialOffset = this->addDraw(DRAW_IMAGE_NINE, &size); 5254c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->addPaintPtr(paint); 5264c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->addImage(img); 5274c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->addIRect(center); 5284c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->addRect(dst); 5294c21dc5ddf3b482293ed34eead876d8d61a662c3reed this->validate(initialOffset, size); 5304c21dc5ddf3b482293ed34eead876d8d61a662c3reed} 5314c21dc5ddf3b482293ed34eead876d8d61a662c3reed 53241af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 53341af966ab338e95eee81ab618ab28195075338f7reed const SkRect& dst, const SkPaint* paint) { 5342ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + bitmap id + center + dst rect 535dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); 5368b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); 537cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 538f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 539cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addIRect(center); 540cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(dst); 5418b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 542f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com} 543f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com 544e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 545e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 5462ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + length + 'length' worth of chars + x + y 547dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar); 5482ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 54946616af01b412ea984a516fda1ed8ec08e689f29mtklein DrawType op = DRAW_TEXT; 5508b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(op, &size); 55146616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 552cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 553cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(x); 554cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(y); 5558b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 558e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 559e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 560dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org int points = paint.countText(text, byteLength); 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56246616af01b412ea984a516fda1ed8ec08e689f29mtklein // op + paint index + length + 'length' worth of data + num points + x&y point data 56346616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + points * sizeof(SkPoint); 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56546616af01b412ea984a516fda1ed8ec08e689f29mtklein DrawType op = DRAW_POS_TEXT; 5662ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 5678b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(op, &size); 56846616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 569cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 570cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(points); 57146616af01b412ea984a516fda1ed8ec08e689f29mtklein fWriter.writeMul4(pos, points * sizeof(SkPoint)); 5728b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 575e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 576e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 577dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org int points = paint.countText(text, byteLength); 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5792ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + length + 'length' worth of data + num points 580dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 5812ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // + y + the actual points 5822ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += 1 * kUInt32Size + points * sizeof(SkScalar); 583cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org 58446616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size); 58546616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 586cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 587cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(points); 588cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(constY); 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(xpos, points * sizeof(SkScalar)); 5908b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 593e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 594e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 595fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + paint index + length + 'length' worth of data + path index + matrix 596fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org const SkMatrix& m = matrix ? *matrix : SkMatrix::I(); 59796fcdcc219d2a0d3579719b84b28bede76efba64halcanary size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + m.writeToMemory(nullptr); 5988b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); 599cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 600cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 601cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPath(path); 602cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addMatrix(m); 6038b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 606b7425173f96e93b090787e2386ba5f022b6c2869fmalitavoid SkPictureRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 607b7425173f96e93b090787e2386ba5f022b6c2869fmalita const SkPaint& paint) { 608b7425173f96e93b090787e2386ba5f022b6c2869fmalita 609b7425173f96e93b090787e2386ba5f022b6c2869fmalita // op + paint index + blob index + x/y 610b7425173f96e93b090787e2386ba5f022b6c2869fmalita size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 611b7425173f96e93b090787e2386ba5f022b6c2869fmalita size_t initialOffset = this->addDraw(DRAW_TEXT_BLOB, &size); 612b7425173f96e93b090787e2386ba5f022b6c2869fmalita 613b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addPaint(paint); 614b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addTextBlob(blob); 615b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addScalar(x); 616b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addScalar(y); 617b7425173f96e93b090787e2386ba5f022b6c2869fmalita 618b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->validate(initialOffset, size); 619b7425173f96e93b090787e2386ba5f022b6c2869fmalita} 620b7425173f96e93b090787e2386ba5f022b6c2869fmalita 621d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 622d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 6232ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + picture index 624dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size; 625d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed size_t initialOffset; 626d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 62796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == matrix && nullptr == paint) { 628d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed initialOffset = this->addDraw(DRAW_PICTURE, &size); 629d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->addPicture(picture); 630d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } else { 631d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkMatrix& m = matrix ? *matrix : SkMatrix::I(); 63296fcdcc219d2a0d3579719b84b28bede76efba64halcanary size += m.writeToMemory(nullptr) + kUInt32Size; // matrix + paint 633d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size); 634d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->addPaintPtr(paint); 6359f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita this->addMatrix(m); 6369f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita this->addPicture(picture); 637d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 6388b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64141af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawVertices(VertexMode vmode, int vertexCount, 64241af966ab338e95eee81ab618ab28195075338f7reed const SkPoint vertices[], const SkPoint texs[], 64341af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xfer, 64441af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 64541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t flags = 0; 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (texs) { 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= DRAW_VERTICES_HAS_TEXS; 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (colors) { 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= DRAW_VERTICES_HAS_COLORS; 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (indexCount > 0) { 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= DRAW_VERTICES_HAS_INDICES; 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 65649f085dddff10473b6ebf832a974288300224e60bsalomon if (xfer) { 65785e143c33c214e54187aa28146aa7666961a0d17reed@google.com SkXfermode::Mode mode; 65885e143c33c214e54187aa28146aa7666961a0d17reed@google.com if (xfer->asMode(&mode) && SkXfermode::kModulate_Mode != mode) { 65985e143c33c214e54187aa28146aa7666961a0d17reed@google.com flags |= DRAW_VERTICES_HAS_XFER; 66085e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 66185e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6632ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + flags + vmode + vCount + vertices 664dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 5 * kUInt32Size + vertexCount * sizeof(SkPoint); 6652ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (flags & DRAW_VERTICES_HAS_TEXS) { 6662ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += vertexCount * sizeof(SkPoint); // + uvs 6672ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 6682ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (flags & DRAW_VERTICES_HAS_COLORS) { 6692ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += vertexCount * sizeof(SkColor); // + vert colors 6702ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 6712ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (flags & DRAW_VERTICES_HAS_INDICES) { 6722ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // + num indices + indices 6732ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); 6742ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 67585e143c33c214e54187aa28146aa7666961a0d17reed@google.com if (flags & DRAW_VERTICES_HAS_XFER) { 67685e143c33c214e54187aa28146aa7666961a0d17reed@google.com size += kUInt32Size; // mode enum 67785e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 6782ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 6798b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_VERTICES, &size); 680cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 681cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(flags); 682cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(vmode); 683cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(vertexCount); 684cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPoints(vertices, vertexCount); 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & DRAW_VERTICES_HAS_TEXS) { 686cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPoints(texs, vertexCount); 6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & DRAW_VERTICES_HAS_COLORS) { 6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); 6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & DRAW_VERTICES_HAS_INDICES) { 692cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(indexCount); 6938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 69585e143c33c214e54187aa28146aa7666961a0d17reed@google.com if (flags & DRAW_VERTICES_HAS_XFER) { 69685e143c33c214e54187aa28146aa7666961a0d17reed@google.com SkXfermode::Mode mode = SkXfermode::kModulate_Mode; 69785e143c33c214e54187aa28146aa7666961a0d17reed@google.com (void)xfer->asMode(&mode); 698cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(mode); 69985e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 7008b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 703b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 704b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, 705b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPaint& paint) { 706b3c9d1c33caf325aada244204215eb790c228c12dandov // op + paint index + patch 12 control points + flag + patch 4 colors + 4 texture coordinates 707b3c9d1c33caf325aada244204215eb790c228c12dandov size_t size = 2 * kUInt32Size + SkPatchUtils::kNumCtrlPts * sizeof(SkPoint) + kUInt32Size; 708b3c9d1c33caf325aada244204215eb790c228c12dandov uint32_t flag = 0; 70949f085dddff10473b6ebf832a974288300224e60bsalomon if (colors) { 710b3c9d1c33caf325aada244204215eb790c228c12dandov flag |= DRAW_VERTICES_HAS_COLORS; 711b3c9d1c33caf325aada244204215eb790c228c12dandov size += SkPatchUtils::kNumCorners * sizeof(SkColor); 712b3c9d1c33caf325aada244204215eb790c228c12dandov } 71349f085dddff10473b6ebf832a974288300224e60bsalomon if (texCoords) { 714b3c9d1c33caf325aada244204215eb790c228c12dandov flag |= DRAW_VERTICES_HAS_TEXS; 715b3c9d1c33caf325aada244204215eb790c228c12dandov size += SkPatchUtils::kNumCorners * sizeof(SkPoint); 716b3c9d1c33caf325aada244204215eb790c228c12dandov } 71749f085dddff10473b6ebf832a974288300224e60bsalomon if (xmode) { 718b3c9d1c33caf325aada244204215eb790c228c12dandov SkXfermode::Mode mode; 719b3c9d1c33caf325aada244204215eb790c228c12dandov if (xmode->asMode(&mode) && SkXfermode::kModulate_Mode != mode) { 720b3c9d1c33caf325aada244204215eb790c228c12dandov flag |= DRAW_VERTICES_HAS_XFER; 721b3c9d1c33caf325aada244204215eb790c228c12dandov size += kUInt32Size; 722b3c9d1c33caf325aada244204215eb790c228c12dandov } 723b3c9d1c33caf325aada244204215eb790c228c12dandov } 72446616af01b412ea984a516fda1ed8ec08e689f29mtklein 725963137b75c0a1fe91f35e9826742f36309f5e65ddandov size_t initialOffset = this->addDraw(DRAW_PATCH, &size); 726963137b75c0a1fe91f35e9826742f36309f5e65ddandov this->addPaint(paint); 727b3c9d1c33caf325aada244204215eb790c228c12dandov this->addPatch(cubics); 728b3c9d1c33caf325aada244204215eb790c228c12dandov this->addInt(flag); 72946616af01b412ea984a516fda1ed8ec08e689f29mtklein 730b3c9d1c33caf325aada244204215eb790c228c12dandov // write optional parameters 73149f085dddff10473b6ebf832a974288300224e60bsalomon if (colors) { 732b3c9d1c33caf325aada244204215eb790c228c12dandov fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor)); 733b3c9d1c33caf325aada244204215eb790c228c12dandov } 73449f085dddff10473b6ebf832a974288300224e60bsalomon if (texCoords) { 735b3c9d1c33caf325aada244204215eb790c228c12dandov fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint)); 736b3c9d1c33caf325aada244204215eb790c228c12dandov } 737b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_XFER) { 738b3c9d1c33caf325aada244204215eb790c228c12dandov SkXfermode::Mode mode = SkXfermode::kModulate_Mode; 739b3c9d1c33caf325aada244204215eb790c228c12dandov xmode->asMode(&mode); 740b3c9d1c33caf325aada244204215eb790c228c12dandov this->addInt(mode); 741b3c9d1c33caf325aada244204215eb790c228c12dandov } 742963137b75c0a1fe91f35e9826742f36309f5e65ddandov this->validate(initialOffset, size); 743963137b75c0a1fe91f35e9826742f36309f5e65ddandov} 744963137b75c0a1fe91f35e9826742f36309f5e65ddandov 74571c3c760a83123ee0b3127b8c65c6394ce541c50reedvoid SkPictureRecord::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], 74671c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkColor colors[], int count, SkXfermode::Mode mode, 74771c3c760a83123ee0b3127b8c65c6394ce541c50reed const SkRect* cull, const SkPaint* paint) { 74871c3c760a83123ee0b3127b8c65c6394ce541c50reed // [op + paint-index + atlas-index + flags + count] + [xform] + [tex] + [*colors + mode] + cull 74971c3c760a83123ee0b3127b8c65c6394ce541c50reed size_t size = 5 * kUInt32Size + count * sizeof(SkRSXform) + count * sizeof(SkRect); 75071c3c760a83123ee0b3127b8c65c6394ce541c50reed uint32_t flags = 0; 75171c3c760a83123ee0b3127b8c65c6394ce541c50reed if (colors) { 75271c3c760a83123ee0b3127b8c65c6394ce541c50reed flags |= DRAW_ATLAS_HAS_COLORS; 75371c3c760a83123ee0b3127b8c65c6394ce541c50reed size += count * sizeof(SkColor); 75471c3c760a83123ee0b3127b8c65c6394ce541c50reed size += sizeof(uint32_t); // xfermode::mode 75571c3c760a83123ee0b3127b8c65c6394ce541c50reed } 75671c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull) { 75771c3c760a83123ee0b3127b8c65c6394ce541c50reed flags |= DRAW_ATLAS_HAS_CULL; 75871c3c760a83123ee0b3127b8c65c6394ce541c50reed size += sizeof(SkRect); 75971c3c760a83123ee0b3127b8c65c6394ce541c50reed } 760c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein 76171c3c760a83123ee0b3127b8c65c6394ce541c50reed size_t initialOffset = this->addDraw(DRAW_ATLAS, &size); 76271c3c760a83123ee0b3127b8c65c6394ce541c50reed this->addPaintPtr(paint); 76371c3c760a83123ee0b3127b8c65c6394ce541c50reed this->addImage(atlas); 76471c3c760a83123ee0b3127b8c65c6394ce541c50reed this->addInt(flags); 76571c3c760a83123ee0b3127b8c65c6394ce541c50reed this->addInt(count); 76671c3c760a83123ee0b3127b8c65c6394ce541c50reed fWriter.write(xform, count * sizeof(SkRSXform)); 76771c3c760a83123ee0b3127b8c65c6394ce541c50reed fWriter.write(tex, count * sizeof(SkRect)); 76871c3c760a83123ee0b3127b8c65c6394ce541c50reed 76971c3c760a83123ee0b3127b8c65c6394ce541c50reed // write optional parameters 77071c3c760a83123ee0b3127b8c65c6394ce541c50reed if (colors) { 77171c3c760a83123ee0b3127b8c65c6394ce541c50reed fWriter.write(colors, count * sizeof(SkColor)); 77271c3c760a83123ee0b3127b8c65c6394ce541c50reed this->addInt(mode); 77371c3c760a83123ee0b3127b8c65c6394ce541c50reed } 77471c3c760a83123ee0b3127b8c65c6394ce541c50reed if (cull) { 77571c3c760a83123ee0b3127b8c65c6394ce541c50reed fWriter.write(cull, sizeof(SkRect)); 77671c3c760a83123ee0b3127b8c65c6394ce541c50reed } 77771c3c760a83123ee0b3127b8c65c6394ce541c50reed this->validate(initialOffset, size); 77871c3c760a83123ee0b3127b8c65c6394ce541c50reed} 77971c3c760a83123ee0b3127b8c65c6394ce541c50reed 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 78182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 7824a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) { 78396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 78476f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 78576f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 786e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein// If we already have a stored, can we reuse it instead of also storing b? 787e069400cabd0edd3db52bbf1958063d3ed12ef28mtkleinstatic bool equivalent(const SkBitmap& a, const SkBitmap& b) { 788e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (a.info() != b.info() || a.pixelRefOrigin() != b.pixelRefOrigin()) { 789e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // Requiring a.info() == b.info() may be overkill in some cases (alphatype mismatch), 790e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // but it sure makes things easier to reason about below. 791e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; 792e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 793e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (a.pixelRef() == b.pixelRef()) { 794e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return true; // Same shape and same pixels -> same bitmap. 795e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 796e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 797e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // From here down we're going to have to look at the bitmap data, so we require pixelRefs(). 798e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (!a.pixelRef() || !b.pixelRef()) { 799e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; 800e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 801e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 802e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // If the bitmaps have encoded data, check first before locking pixels so they don't decode. 803e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkAutoTUnref<SkData> encA(a.pixelRef()->refEncodedData()), 804e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein encB(b.pixelRef()->refEncodedData()); 805e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (encA && encB) { 806e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return encA->equals(encB); 807e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } else if (encA || encB) { 808e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; // One has encoded data but the other does not. 809e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 810e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 811e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // As a last resort, we have to look at the pixels. This will read back textures. 812e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkAutoLockPixels al(a), bl(b); 813e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const char* ap = (const char*)a.getPixels(); 814e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const char* bp = (const char*)b.getPixels(); 815e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (ap && bp) { 816e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // We check row by row; row bytes might differ. 817e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkASSERT(a.info() == b.info()); // We checked this above. 818e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkASSERT(a.info().bytesPerPixel() > 0); // If we have pixelRefs, this better be true. 819e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const SkImageInfo info = a.info(); 820e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const size_t bytesToCompare = info.width() * info.bytesPerPixel(); 821e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein for (int row = 0; row < info.height(); row++) { 822e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (0 != memcmp(ap, bp, bytesToCompare)) { 823e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; 824e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 825e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein ap += a.rowBytes(); 826e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein bp += b.rowBytes(); 827e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 828e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return true; 829e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 830e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; // Couldn't get pixels for both bitmaps. 831e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein} 832e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 833e069400cabd0edd3db52bbf1958063d3ed12ef28mtkleinvoid SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 834e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // First see if we already have this bitmap. This deduplication should really 835e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // only be important for our tests, where bitmaps tend not to be tagged immutable. 836e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // In Chrome (and hopefully Android?) they're typically immutable. 837e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein for (int i = 0; i < fBitmaps.count(); i++) { 838e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (equivalent(fBitmaps[i], bitmap)) { 839e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein this->addInt(i); // Unlike the rest, bitmap indices are 0-based. 840e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return; 841e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 842e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 843e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // Don't have it. We'll add it to our list, making sure it's tagged as immutable. 84471a236370792416b367a7d2d6b8e471b06b331cdmtklein if (bitmap.isImmutable()) { 845e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // Shallow copies of bitmaps are cheap, so immutable == fast. 84671a236370792416b367a7d2d6b8e471b06b331cdmtklein fBitmaps.push_back(bitmap); 84771a236370792416b367a7d2d6b8e471b06b331cdmtklein } else { 848e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // If you see this block on a memory profile, it's a good opportunity to reduce RAM usage. 84971a236370792416b367a7d2d6b8e471b06b331cdmtklein SkBitmap copy; 85071a236370792416b367a7d2d6b8e471b06b331cdmtklein bitmap.copyTo(©); 85171a236370792416b367a7d2d6b8e471b06b331cdmtklein copy.setImmutable(); 85271a236370792416b367a7d2d6b8e471b06b331cdmtklein fBitmaps.push_back(copy); 85371a236370792416b367a7d2d6b8e471b06b331cdmtklein } 854e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein this->addInt(fBitmaps.count()-1); // Remember, 0-based. 8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 857871872f3f247f6b699617f6d9ef50ef5da6fbe74reedvoid SkPictureRecord::addImage(const SkImage* image) { 858871872f3f247f6b699617f6d9ef50ef5da6fbe74reed int index = fImageRefs.find(image); 859871872f3f247f6b699617f6d9ef50ef5da6fbe74reed if (index >= 0) { 860871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addInt(index); 861871872f3f247f6b699617f6d9ef50ef5da6fbe74reed } else { 862871872f3f247f6b699617f6d9ef50ef5da6fbe74reed *fImageRefs.append() = SkRef(image); 863871872f3f247f6b699617f6d9ef50ef5da6fbe74reed this->addInt(fImageRefs.count()-1); 864871872f3f247f6b699617f6d9ef50ef5da6fbe74reed } 865871872f3f247f6b699617f6d9ef50ef5da6fbe74reed} 866871872f3f247f6b699617f6d9ef50ef5da6fbe74reed 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addMatrix(const SkMatrix& matrix) { 868fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org fWriter.writeMatrix(matrix); 8698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 87146616af01b412ea984a516fda1ed8ec08e689f29mtkleinvoid SkPictureRecord::addPaintPtr(const SkPaint* paint) { 872afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onAddPaintPtr(paint); 873e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org 87446616af01b412ea984a516fda1ed8ec08e689f29mtklein if (paint) { 875a74ce853c824c5ae30e219ddf46a61d91cc0ab2amtklein fPaints.push_back(*paint); 876a74ce853c824c5ae30e219ddf46a61d91cc0ab2amtklein this->addInt(fPaints.count()); 87746616af01b412ea984a516fda1ed8ec08e689f29mtklein } else { 87846616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addInt(0); 87946616af01b412ea984a516fda1ed8ec08e689f29mtklein } 880cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org} 881cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org 8825a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comint SkPictureRecord::addPathToHeap(const SkPath& path) { 883c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein if (int* n = fPaths.find(path)) { 884c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein return *n; 885c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein } 886c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein int n = fPaths.count() + 1; // 0 is reserved for null / error. 887c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein fPaths.set(path, n); 888c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein return n; 8895a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 8905a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 8915a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comvoid SkPictureRecord::addPath(const SkPath& path) { 892cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(this->addPathToHeap(path)); 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 895b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkPictureRecord::addPatch(const SkPoint cubics[12]) { 896b3c9d1c33caf325aada244204215eb790c228c12dandov fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint)); 897963137b75c0a1fe91f35e9826742f36309f5e65ddandov} 898963137b75c0a1fe91f35e9826742f36309f5e65ddandov 8999b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkPictureRecord::addPicture(const SkPicture* picture) { 9009b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips int index = fPictureRefs.find(picture); 9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (index < 0) { // not found 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index = fPictureRefs.count(); 9039b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips *fPictureRefs.append() = picture; 9049b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips picture->ref(); 9058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // follow the convention of recording a 1-based index 907cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(index + 1); 9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addPoint(const SkPoint& point) { 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writePoint(point); 9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 91382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 9148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addPoints(const SkPoint pts[], int count) { 9158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(pts, count * sizeof(SkPoint)); 9168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 91868250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.orgvoid SkPictureRecord::addNoOp() { 91968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org size_t size = kUInt32Size; // op 92068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org this->addDraw(NOOP, &size); 92168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org} 92268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addRect(const SkRect& rect) { 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeRect(rect); 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addRectPtr(const SkRect* rect) { 92896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (fWriter.writeBool(rect != nullptr)) { 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeRect(*rect); 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 933f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.comvoid SkPictureRecord::addIRect(const SkIRect& rect) { 934f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com fWriter.write(&rect, sizeof(rect)); 935f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com} 936f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addIRectPtr(const SkIRect* rect) { 93896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (fWriter.writeBool(rect != nullptr)) { 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect; 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9434ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkPictureRecord::addRRect(const SkRRect& rrect) { 9444ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com fWriter.writeRRect(rrect); 9454ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 9464ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 9478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addRegion(const SkRegion& region) { 948fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org fWriter.writeRegion(region); 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addText(const void* text, size_t byteLength) { 952afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onDrawText(); 953dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org addInt(SkToInt(byteLength)); 9548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writePad(text, byteLength); 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 957b7425173f96e93b090787e2386ba5f022b6c2869fmalitavoid SkPictureRecord::addTextBlob(const SkTextBlob *blob) { 958dd1e9f75969c72da53657e58a080c47b30f64140jbroman int index = fTextBlobRefs.count(); 959dd1e9f75969c72da53657e58a080c47b30f64140jbroman *fTextBlobRefs.append() = blob; 960dd1e9f75969c72da53657e58a080c47b30f64140jbroman blob->ref(); 961b7425173f96e93b090787e2386ba5f022b6c2869fmalita // follow the convention of recording a 1-based index 962b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addInt(index + 1); 963b7425173f96e93b090787e2386ba5f022b6c2869fmalita} 964b7425173f96e93b090787e2386ba5f022b6c2869fmalita 9658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 967