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" 14b7425173f96e93b090787e2386ba5f022b6c2869fmalita#include "SkTextBlob.h" 15b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkTSearch.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define HEAP_BLOCK_SIZE 4096 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 194e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.orgenum { 20d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // just need a value that save or getSaveCount would never return 214e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org kNoInitialSave = -1, 224e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org}; 234e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org 242ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com// A lot of basic types get stored as a uint32_t: bools, ints, paint indices, etc. 252ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.comstatic int const kUInt32Size = 4; 262ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 275f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitastatic const uint32_t kSaveSize = kUInt32Size; 288e12656096fceeed8b3cc4284d57dea04893b455mtklein#ifdef SK_DEBUG 29e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.comstatic const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; 30e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.comstatic const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect); 318e12656096fceeed8b3cc4284d57dea04893b455mtklein#endif//SK_DEBUG 32e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 330bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillipsSkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags) 3419fafef9784fe7c644540ffd0ee9f6da1914a038commit-bot@chromium.org : INHERITED(dimensions.width(), dimensions.height()) 3571a236370792416b367a7d2d6b8e471b06b331cdmtklein , fRecordFlags(flags) 3671a236370792416b367a7d2d6b8e471b06b331cdmtklein , fInitialSaveCount(kNoInitialSave) { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkPictureRecord::~SkPictureRecord() { 4021830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com fPictureRefs.unrefAll(); 41b7425173f96e93b090787e2386ba5f022b6c2869fmalita fTextBlobRefs.unrefAll(); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 468e12656096fceeed8b3cc4284d57dea04893b455mtklein#ifdef SK_DEBUG 47e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com// Return the offset of the paint inside a given op's byte stream. A zero 48e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com// return value means there is no paint (and you really shouldn't be calling 49e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com// this method) 508e12656096fceeed8b3cc4284d57dea04893b455mtkleinstatic inline size_t get_paint_offset(DrawType op, size_t opSize) { 51e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com // These offsets are where the paint would be if the op size doesn't overflow 529f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita static const uint8_t gPaintOffsets[] = { 53e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // UNUSED - no paint 54e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // CLIP_PATH - no paint 55e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // CLIP_REGION - no paint 56e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // CLIP_RECT - no paint 57e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // CLIP_RRECT - no paint 58e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // CONCAT - no paint 59e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_BITMAP - right after op code 60c54d8db4d169ea5f2af2a9a2349df007bd428475Florin Malita 1, // DRAW_BITMAP_MATRIX - right after op code, deprecated 61e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_BITMAP_NINE - right after op code 62e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_BITMAP_RECT_TO_RECT - right after op code 63e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // DRAW_CLEAR - no paint 64e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // DRAW_DATA - no paint 65e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_OVAL - right after op code 66e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_PAINT - right after op code 67e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_PATH - right after op code 68e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // DRAW_PICTURE - no paint 69e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_POINTS - right after op code 70e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_POS_TEXT - right after op code 71e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_POS_TEXT_TOP_BOTTOM - right after op code 72e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_POS_TEXT_H - right after op code 73e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_POS_TEXT_H_TOP_BOTTOM - right after op code 74e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_RECT - right after op code 75e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_RRECT - right after op code 76e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_SPRITE - right after op code 77e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_TEXT - right after op code 78e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_TEXT_ON_PATH - right after op code 79e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_TEXT_TOP_BOTTOM - right after op code 80e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1, // DRAW_VERTICES - right after op code 81e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // RESTORE - no paint 82e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // ROTATE - no paint 83e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // SAVE - no paint 84f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com 0, // SAVE_LAYER - see below - this paint's location varies 85e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // SCALE - no paint 86e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // SET_MATRIX - no paint 87e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // SKEW - no paint 88e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // TRANSLATE - no paint 89e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 0, // NOOP - no paint 900a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 0, // BEGIN_GROUP - no paint 910a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 0, // COMMENT - no paint 920a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 0, // END_GROUP - no paint 93ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 1, // DRAWDRRECT - right after op code 94210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 0, // PUSH_CULL - no paint 95210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 0, // POP_CULL - no paint 96963137b75c0a1fe91f35e9826742f36309f5e65ddandov 1, // DRAW_PATCH - right after op code 979f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita 1, // DRAW_PICTURE_MATRIX_PAINT - right after op code 98b7425173f96e93b090787e2386ba5f022b6c2869fmalita 1, // DRAW_TEXT_BLOB- right after op code 99f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com }; 100e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 101ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, 102ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org need_to_be_in_sync); 103e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); 104e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 105e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com int overflow = 0; 106e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com if (0 != (opSize & ~MASK_24) || opSize == MASK_24) { 107e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com // This op's size overflows so an extra uint32_t will be written 108e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com // after the op code 109e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com overflow = sizeof(uint32_t); 110e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com } 111e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 112e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com if (SAVE_LAYER == op) { 113e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com static const uint32_t kSaveLayerNoBoundsPaintOffset = 2 * kUInt32Size; 114e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com static const uint32_t kSaveLayerWithBoundsPaintOffset = 2 * kUInt32Size + sizeof(SkRect); 115e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 116e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com if (kSaveLayerNoBoundsSize == opSize) { 117e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com return kSaveLayerNoBoundsPaintOffset + overflow; 118e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com } else { 119e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com SkASSERT(kSaveLayerWithBoundsSize == opSize); 120e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com return kSaveLayerWithBoundsPaintOffset + overflow; 121e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com } 122e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com } 123e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 124e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com SkASSERT(0 != gPaintOffsets[op]); // really shouldn't be calling this method 125e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com return gPaintOffsets[op] * sizeof(uint32_t) + overflow; 126e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com} 1278e12656096fceeed8b3cc4284d57dea04893b455mtklein#endif//SK_DEBUG 128e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1295f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitavoid SkPictureRecord::willSave() { 130ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // record the offset to us, making it non-positive to distinguish a save 131ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // from a clip entry. 1324469938e92d779dff05e745559e67907bbf21e78reed@google.com fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); 1335f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita this->recordSave(); 134e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 1355f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita this->INHERITED::willSave(); 1365a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 13711f869277c81a232fd4e40eca41e6f71b95b4b17skia.committer@gmail.com 1385f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malitavoid SkPictureRecord::recordSave() { 139c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips fContentInfo.onSave(); 140c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips 1415f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita // op only 142dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = kSaveSize; 1438b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SAVE, &size); 14482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 1458b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 148e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgSkCanvas::SaveLayerStrategy SkPictureRecord::willSaveLayer(const SkRect* bounds, 149e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org const SkPaint* paint, SaveFlags flags) { 150ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // record the offset to us, making it non-positive to distinguish a save 151ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com // from a clip entry. 1524469938e92d779dff05e745559e67907bbf21e78reed@google.com fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); 1535a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com this->recordSaveLayer(bounds, paint, flags); 15411f869277c81a232fd4e40eca41e6f71b95b4b17skia.committer@gmail.com 155e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->INHERITED::willSaveLayer(bounds, paint, flags); 156e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org /* No need for a (potentially very big) layer which we don't actually need 1575a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com at this time (and may not be able to afford since during record our 1585a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com clip starts out the size of the picture, which is often much larger 1595a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com than the size of the actual device we'll use during playback). 1605a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com */ 161e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org return kNoLayer_SaveLayerStrategy; 1625a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 1635a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 1645a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comvoid SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint, 165105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com SaveFlags flags) { 166c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips fContentInfo.onSaveLayer(); 167c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips 1682ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + bool for 'bounds' 169dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size; 17049f085dddff10473b6ebf832a974288300224e60bsalomon if (bounds) { 1712ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += sizeof(*bounds); // + rect 1722ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 1732ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // + paint index + flags 1742ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += 2 * kUInt32Size; 1752ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 176e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com SkASSERT(kSaveLayerNoBoundsSize == size || kSaveLayerWithBoundsSize == size); 177e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.com 1788b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SAVE_LAYER, &size); 179cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRectPtr(bounds); 1808e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(SAVE_LAYER, size) == fWriter.bytesWritten()); 181cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 182cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(flags); 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1848b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 187210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org#ifdef SK_DEBUG 188210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org/* 1892ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com * Read the op code from 'offset' in 'writer' and extract the size too. 1902ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com */ 191dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgstatic DrawType peek_op_and_size(SkWriter32* writer, size_t offset, uint32_t* size) { 192536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org uint32_t peek = writer->readTAt<uint32_t>(offset); 1932ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 1942ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com uint32_t op; 195c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org UNPACK_8_24(peek, op, *size); 1962ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (MASK_24 == *size) { 1972ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // size required its own slot right after the op code 198536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org *size = writer->readTAt<uint32_t>(offset + kUInt32Size); 1992ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 2002ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com return (DrawType) op; 201ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com} 20246616af01b412ea984a516fda1ed8ec08e689f29mtklein#endif//SK_DEBUG 2034b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org 204e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.orgvoid SkPictureRecord::willRestore() { 2054e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org // FIXME: SkDeferredCanvas needs to be refactored to respect 2064e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org // save/restore balancing so that the following test can be 2074e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org // turned on permanently. 2084e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org#if 0 2094e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org SkASSERT(fRestoreOffsetStack.count() > 1); 2104e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org#endif 2114e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org 212b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com // check for underflow 213b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com if (fRestoreOffsetStack.count() == 0) { 214b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com return; 215b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com } 216b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com 21746616af01b412ea984a516fda1ed8ec08e689f29mtklein this->recordRestore(); 218ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com 219b4e22d62da422f3599ef9bd5091c5f4b7709d27ereed@android.com fRestoreOffsetStack.pop(); 22032a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com 221e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org this->INHERITED::willRestore(); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 224105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.comvoid SkPictureRecord::recordRestore(bool fillInSkips) { 225c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips fContentInfo.onRestore(); 226c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips 227105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com if (fillInSkips) { 228105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com this->fillRestoreOffsetPlaceholdersForCurrentStackLevel((uint32_t)fWriter.bytesWritten()); 229105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com } 230dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size; // RESTORE consists solely of 1 op code 231dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t initialOffset = this->addDraw(RESTORE, &size); 2325a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com this->validate(initialOffset, size); 2335a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 2345a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 235d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.orgvoid SkPictureRecord::recordTranslate(const SkMatrix& m) { 236d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkASSERT(SkMatrix::kTranslate_Mask == m.getType()); 237d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org 2382ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + dx + dy 239dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 2408b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(TRANSLATE, &size); 241d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getTranslateX()); 242d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getTranslateY()); 2438b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 246d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.orgvoid SkPictureRecord::recordScale(const SkMatrix& m) { 247d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org SkASSERT(SkMatrix::kScale_Mask == m.getType()); 248105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com 2492ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + sx + sy 250dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + 2 * sizeof(SkScalar); 2518b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SCALE, &size); 252d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getScaleX()); 253d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->addScalar(m.getScaleY()); 2548b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25744c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.orgvoid SkPictureRecord::didConcat(const SkMatrix& matrix) { 258d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org switch (matrix.getType()) { 259d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org case SkMatrix::kTranslate_Mask: 260d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->recordTranslate(matrix); 261d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org break; 262d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org case SkMatrix::kScale_Mask: 263d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->recordScale(matrix); 264d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org break; 265d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org default: 266d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org this->recordConcat(matrix); 267d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org break; 268d9ea09e1f29b303e6fa36079e99729d2951925b9commit-bot@chromium.org } 26944c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->INHERITED::didConcat(matrix); 2705a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 2715a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 2725a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comvoid SkPictureRecord::recordConcat(const SkMatrix& matrix) { 2734469938e92d779dff05e745559e67907bbf21e78reed@google.com this->validate(fWriter.bytesWritten(), 0); 274fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + matrix 275dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = kUInt32Size + matrix.writeToMemory(NULL); 2768b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CONCAT, &size); 277cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addMatrix(matrix); 2788b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.orgvoid SkPictureRecord::didSetMatrix(const SkMatrix& matrix) { 2824469938e92d779dff05e745559e67907bbf21e78reed@google.com this->validate(fWriter.bytesWritten(), 0); 283fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + matrix 284dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = kUInt32Size + matrix.writeToMemory(NULL); 2858b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(SET_MATRIX, &size); 286cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addMatrix(matrix); 2878b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 28844c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org this->INHERITED::didSetMatrix(matrix); 2896e073b9e2b70d6bbf8a06050fff1364827204f08reed@android.com} 2906e073b9e2b70d6bbf8a06050fff1364827204f08reed@android.com 29145482d1d2b97de185df137a1db40cbe5a62313a5reed@google.comstatic bool regionOpExpands(SkRegion::Op op) { 29245482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com switch (op) { 29345482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kUnion_Op: 29445482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kXOR_Op: 29545482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kReverseDifference_Op: 29645482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kReplace_Op: 29745482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com return true; 29845482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kIntersect_Op: 29945482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com case SkRegion::kDifference_Op: 30045482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com return false; 30145482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com default: 3020c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown region op"); 30345482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com return false; 30445482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com } 30545482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com} 30645482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com 307e37ad358b7219e45323a79c484ea67a5c59f34c2robertphillips@google.comvoid SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset) { 308ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com int32_t offset = fRestoreOffsetStack.top(); 309ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com while (offset > 0) { 310536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org uint32_t peek = fWriter.readTAt<uint32_t>(offset); 311536ac5e20c2ec2008993c0677ba8cbc5ae0f34cfcommit-bot@chromium.org fWriter.overwriteTAt(offset, restoreOffset); 312c6d3c444ca76feba5a8937dbc80626ade5347275commit-bot@chromium.org offset = peek; 313e3dbedb44cad6c7b7e5c9aae5224d0b0abec9bf4junov@chromium.org } 31411f869277c81a232fd4e40eca41e6f71b95b4b17skia.committer@gmail.com 315ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com#ifdef SK_DEBUG 3162ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // offset of 0 has been disabled, so we skip it 3172ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed if (offset > 0) { 3182ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // assert that the final offset value points to a save verb 3192ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed uint32_t opSize; 3202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); 3212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp); 3222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed } 323ffacd3c56d73c03d3fe53b47a49ea6be2ca4748freed@google.com#endif 324e3dbedb44cad6c7b7e5c9aae5224d0b0abec9bf4junov@chromium.org} 325e3dbedb44cad6c7b7e5c9aae5224d0b0abec9bf4junov@chromium.org 326d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.comvoid SkPictureRecord::beginRecording() { 327d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // we have to call this *after* our constructor, to ensure that it gets 328d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // recorded. This is balanced by restoreToCount() call from endRecording, 329d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com // which in-turn calls our overridden restore(), so those get recorded too. 330091a594dbc4116ec2e54724432472bf37dae794acommit-bot@chromium.org fInitialSaveCount = this->save(); 331d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com} 332d86e7ab6044e4aba017cb126a26dd378eec9fcbareed@google.com 333a6c9e0e02be390d36b80f4872c628edb3594208ejunov@chromium.orgvoid SkPictureRecord::endRecording() { 3344e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org SkASSERT(kNoInitialSave != fInitialSaveCount); 3354e6dfa51525e174d79cb88800d8e5f2c88291270junov@chromium.org this->restoreToCount(fInitialSaveCount); 336a6c9e0e02be390d36b80f4872c628edb3594208ejunov@chromium.org} 337a6c9e0e02be390d36b80f4872c628edb3594208ejunov@chromium.org 338dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { 33921b519d56f9838c2e6e7abe704d3313e03f6f754reed@google.com if (fRestoreOffsetStack.isEmpty()) { 3405a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return -1; 34121b519d56f9838c2e6e7abe704d3313e03f6f754reed@google.com } 34221b519d56f9838c2e6e7abe704d3313e03f6f754reed@google.com 343d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // The RestoreOffset field is initially filled with a placeholder 344d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // value that points to the offset of the previous RestoreOffset 345d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // in the current stack level, thus forming a linked list so that 346d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // the restore offsets can be filled in when the corresponding 347d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // restore command is recorded. 348d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com int32_t prevOffset = fRestoreOffsetStack.top(); 349d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com 35045482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com if (regionOpExpands(op)) { 35145482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // Run back through any previous clip ops, and mark their offset to 35245482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // be 0, disabling their ability to trigger a jump-to-restore, otherwise 35345482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // they could hide this clips ability to expand the clip (i.e. go from 35445482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com // empty to non-empty). 355cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->fillRestoreOffsetPlaceholdersForCurrentStackLevel(0); 356d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com 357d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // Reset the pointer back to the previous clip so that subsequent 358d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com // restores don't overwrite the offsets we just cleared. 359d0f1a4fb28057de42d116005d82166b2302d28e9fmalita@google.com prevOffset = 0; 36045482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com } 36174b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org 3624469938e92d779dff05e745559e67907bbf21e78reed@google.com size_t offset = fWriter.bytesWritten(); 363cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(prevOffset); 364dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org fRestoreOffsetStack.top() = SkToU32(offset); 3655a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 36645482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com} 36745482d1d2b97de185df137a1db40cbe5a62313a5reed@google.com 3688f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 3698f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); 3708f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->INHERITED::onClipRect(rect, op, edgeStyle); 3715a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 3725a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 373dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 374f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // id + rect + clip params 375dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + sizeof(rect) + 1 * kUInt32Size; 3764310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 377f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 378f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 379f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 380f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 3818b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_RECT, &size); 382cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(rect); 383cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, doAA)); 384dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = this->recordRestoreOffsetPlaceholder(op); 385306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 3868b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 3875a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 38868d61ed83ec7b6e98e9623c2f5c9e7b1a32d25bbreed@google.com} 38968d61ed83ec7b6e98e9623c2f5c9e7b1a32d25bbreed@google.com 3908f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 3918f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); 392d954498c01ccf0417feacf89e45d0c62a06a813breed this->INHERITED::onClipRRect(rrect, op, edgeStyle); 3935a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 3945a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 395dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { 396f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // op + rrect + clip params 397dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size + SkRRect::kSizeInMemory + 1 * kUInt32Size; 3984310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 399f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 400f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 401f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 402f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 4038b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_RRECT, &size); 404cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRRect(rrect); 405cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, doAA)); 406dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = recordRestoreOffsetPlaceholder(op); 4078b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4085a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 4094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 4104ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 4118f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { 4125a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com int pathID = this->addPathToHeap(path); 4138f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle); 414d954498c01ccf0417feacf89e45d0c62a06a813breed this->INHERITED::onClipPath(path, op, edgeStyle); 4155a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 4165a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 417dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) { 418f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // op + path index + clip params 419dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size; 4204310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 421f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 422f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 423f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 424f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 4258b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_PATH, &size); 426cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(pathID); 427cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, doAA)); 428dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = recordRestoreOffsetPlaceholder(op); 4298b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4305a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comvoid SkPictureRecord::onClipRegion(const SkRegion& region, SkRegion::Op op) { 4345a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com this->recordClipRegion(region, op); 4358f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com this->INHERITED::onClipRegion(region, op); 4365a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 4375a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 438dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.orgsize_t SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op) { 439fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + clip params + region 440dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + region.writeToMemory(NULL); 4414310c66ed4bb67c96ec65d8b499b8a9c4deab2edrobertphillips@google.com // recordRestoreOffsetPlaceholder doesn't always write an offset 442f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com if (!fRestoreOffsetStack.isEmpty()) { 443f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com // + restore offset 444f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com size += kUInt32Size; 445f92915089fa914843ca63594efc47a80b8f971bcrobertphillips@google.com } 4468b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(CLIP_REGION, &size); 447cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRegion(region); 448cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(ClipParams_pack(op, false)); 449dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t offset = this->recordRestoreOffsetPlaceholder(op); 45082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 4518b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4525a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com return offset; 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45541af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawPaint(const SkPaint& paint) { 4562ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index 457dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size; 4588b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_PAINT, &size); 4598e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_PAINT, size) == fWriter.bytesWritten()); 460cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 4618b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 46441af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[], 46541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 466afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onDrawPoints(count, paint); 467105a4a584c4c2c84c24e102112326b15683673f5robertphillips@google.com 4682ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + mode + count + point data 469dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 4 * kUInt32Size + count * sizeof(SkPoint); 4708b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_POINTS, &size); 4718e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_POINTS, size) == fWriter.bytesWritten()); 472cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 473afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw 474cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(mode); 475dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org this->addInt(SkToInt(count)); 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(pts, count * sizeof(SkPoint)); 4778b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 48041af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawOval(const SkRect& oval, const SkPaint& paint) { 4812ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + rect 482dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + sizeof(oval); 4838b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_OVAL, &size); 4848e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_OVAL, size) == fWriter.bytesWritten()); 485cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 486cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(oval); 4878b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 4894ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 49041af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawRect(const SkRect& rect, const SkPaint& paint) { 4912ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + rect 492dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + sizeof(rect); 4938b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_RECT, &size); 4948e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_RECT, size) == fWriter.bytesWritten()); 495cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 496cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(rect); 4978b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50041af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { 50146616af01b412ea984a516fda1ed8ec08e689f29mtklein // op + paint index + rrect 50246616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory; 50346616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t initialOffset = this->addDraw(DRAW_RRECT, &size); 5048e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_RRECT, size) == fWriter.bytesWritten()); 50546616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 50646616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addRRect(rrect); 50746616af01b412ea984a516fda1ed8ec08e689f29mtklein this->validate(initialOffset, size); 5084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 5094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 510ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, 511ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org const SkPaint& paint) { 512ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org // op + paint index + rrects 513dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2; 514dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t initialOffset = this->addDraw(DRAW_DRRECT, &size); 5158e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_DRRECT, size) == fWriter.bytesWritten()); 516ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->addPaint(paint); 517ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->addRRect(outer); 518ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->addRRect(inner); 519ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org this->validate(initialOffset, size); 520ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org} 521ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org 52241af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawPath(const SkPath& path, const SkPaint& paint) { 523afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onDrawPath(path, paint); 524e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org 5252ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + path index 526dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size; 5278b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_PATH, &size); 5288e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_PATH, size) == fWriter.bytesWritten()); 529cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 530cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPath(path); 5318b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 53441af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, 53541af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 5362ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + bitmap index + left + top 537dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 5388b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_BITMAP, &size); 5398e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_BITMAP, size) == fWriter.bytesWritten()); 540cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 541f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 542cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(left); 543cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(top); 5448b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54741af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, 54841af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint, DrawBitmapRectFlags flags) { 549eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org // id + paint index + bitmap index + bool for 'src' + flags 550dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 5 * kUInt32Size; 55149f085dddff10473b6ebf832a974288300224e60bsalomon if (src) { 5522ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += sizeof(*src); // + rect 5532ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 5542ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += sizeof(dst); // + rect 5552ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 5568b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_BITMAP_RECT_TO_RECT, &size); 5578e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_BITMAP_RECT_TO_RECT, size) 55850b393a768c0311b3210f723325fd27bf161136bcommit-bot@chromium.org == fWriter.bytesWritten()); 559cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 560f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 561cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRectPtr(src); // may be null 562cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(dst); 563cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(flags); 5648b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 567a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkPictureRecord::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, 568a85d4d0814818e4ddabb9237da209d61d6cd5854reed const SkPaint* paint) { 569a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkBitmap bm; 570a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (as_IB(image)->getROPixels(&bm)) { 571a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->SkPictureRecord::onDrawBitmap(bm, x, y, paint); 572a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 573a85d4d0814818e4ddabb9237da209d61d6cd5854reed} 574a85d4d0814818e4ddabb9237da209d61d6cd5854reed 575a85d4d0814818e4ddabb9237da209d61d6cd5854reedvoid SkPictureRecord::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 576a85d4d0814818e4ddabb9237da209d61d6cd5854reed const SkPaint* paint) { 577a85d4d0814818e4ddabb9237da209d61d6cd5854reed SkBitmap bm; 578a85d4d0814818e4ddabb9237da209d61d6cd5854reed if (as_IB(image)->getROPixels(&bm)) { 579a85d4d0814818e4ddabb9237da209d61d6cd5854reed this->SkPictureRecord::onDrawBitmapRect(bm, src, dst, paint, kNone_DrawBitmapRectFlag); 580a85d4d0814818e4ddabb9237da209d61d6cd5854reed } 581a85d4d0814818e4ddabb9237da209d61d6cd5854reed} 582a85d4d0814818e4ddabb9237da209d61d6cd5854reed 58341af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 58441af966ab338e95eee81ab618ab28195075338f7reed const SkRect& dst, const SkPaint* paint) { 5852ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + bitmap id + center + dst rect 586dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + sizeof(center) + sizeof(dst); 5878b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); 5888e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_BITMAP_NINE, size) == fWriter.bytesWritten()); 589cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 590f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 591cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addIRect(center); 592cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addRect(dst); 5938b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 594f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com} 595f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com 59641af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawSprite(const SkBitmap& bitmap, int left, int top, 59741af966ab338e95eee81ab618ab28195075338f7reed const SkPaint* paint) { 5982ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + bitmap index + left + top 599dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 5 * kUInt32Size; 6008b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_SPRITE, &size); 6018e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_SPRITE, size) == fWriter.bytesWritten()); 602cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaintPtr(paint); 603f6a5afb66b661c884cd308577431b7abf025b182commit-bot@chromium.org this->addBitmap(bitmap); 604cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(left); 605cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(top); 6068b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 609e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 610e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 6112ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + length + 'length' worth of chars + x + y 612dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 2 * sizeof(SkScalar); 6132ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 61446616af01b412ea984a516fda1ed8ec08e689f29mtklein DrawType op = DRAW_TEXT; 6158b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(op, &size); 6168e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(op, size) == fWriter.bytesWritten()); 61746616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 618cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 619cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(x); 620cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(y); 6218b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 624e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 625e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkPaint& paint) { 626dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org int points = paint.countText(text, byteLength); 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62846616af01b412ea984a516fda1ed8ec08e689f29mtklein // op + paint index + length + 'length' worth of data + num points + x&y point data 62946616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + points * sizeof(SkPoint); 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 63146616af01b412ea984a516fda1ed8ec08e689f29mtklein DrawType op = DRAW_POS_TEXT; 6322ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 6338b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(op, &size); 6348e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(op, size) == fWriter.bytesWritten()); 63546616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 636cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 637cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(points); 63846616af01b412ea984a516fda1ed8ec08e689f29mtklein fWriter.writeMul4(pos, points * sizeof(SkPoint)); 6398b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 642e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 643e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SkScalar constY, const SkPaint& paint) { 644dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org int points = paint.countText(text, byteLength); 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6462ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + length + 'length' worth of data + num points 647dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; 6482ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // + y + the actual points 6492ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += 1 * kUInt32Size + points * sizeof(SkScalar); 650cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org 65146616af01b412ea984a516fda1ed8ec08e689f29mtklein size_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size); 65246616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addPaint(paint); 653cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 654cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(points); 655cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addScalar(constY); 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(xpos, points * sizeof(SkScalar)); 6578b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 660e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkPictureRecord::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 661e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com const SkMatrix* matrix, const SkPaint& paint) { 662fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // op + paint index + length + 'length' worth of data + path index + matrix 663fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org const SkMatrix& m = matrix ? *matrix : SkMatrix::I(); 664dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + m.writeToMemory(NULL); 6658b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_TEXT_ON_PATH, &size); 6668e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_TEXT_ON_PATH, size) == fWriter.bytesWritten()); 667cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 668cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addText(text, byteLength); 669cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPath(path); 670cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addMatrix(m); 6718b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 674b7425173f96e93b090787e2386ba5f022b6c2869fmalitavoid SkPictureRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 675b7425173f96e93b090787e2386ba5f022b6c2869fmalita const SkPaint& paint) { 676b7425173f96e93b090787e2386ba5f022b6c2869fmalita 677b7425173f96e93b090787e2386ba5f022b6c2869fmalita // op + paint index + blob index + x/y 678b7425173f96e93b090787e2386ba5f022b6c2869fmalita size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar); 679b7425173f96e93b090787e2386ba5f022b6c2869fmalita size_t initialOffset = this->addDraw(DRAW_TEXT_BLOB, &size); 6808e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset + get_paint_offset(DRAW_TEXT_BLOB, size) == fWriter.bytesWritten()); 681b7425173f96e93b090787e2386ba5f022b6c2869fmalita 682b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addPaint(paint); 683b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addTextBlob(blob); 684b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addScalar(x); 685b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addScalar(y); 686b7425173f96e93b090787e2386ba5f022b6c2869fmalita 687b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->validate(initialOffset, size); 688b7425173f96e93b090787e2386ba5f022b6c2869fmalita} 689b7425173f96e93b090787e2386ba5f022b6c2869fmalita 690d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reedvoid SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, 691d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkPaint* paint) { 6922ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + picture index 693dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size; 694d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed size_t initialOffset; 695d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed 696d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed if (NULL == matrix && NULL == paint) { 697d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed initialOffset = this->addDraw(DRAW_PICTURE, &size); 698d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->addPicture(picture); 699d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } else { 700d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed const SkMatrix& m = matrix ? *matrix : SkMatrix::I(); 701d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed size += m.writeToMemory(NULL) + kUInt32Size; // matrix + paint 702d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed initialOffset = this->addDraw(DRAW_PICTURE_MATRIX_PAINT, &size); 7038e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset + get_paint_offset(DRAW_PICTURE_MATRIX_PAINT, size) 7049f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita == fWriter.bytesWritten()); 705d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed this->addPaintPtr(paint); 7069f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita this->addMatrix(m); 7079f49cfdbf6493b953775890d7f9c97a1dce0d341fmalita this->addPicture(picture); 708d5fa1a455aad61f3e99081fe7a9b065cb3b115c6reed } 7098b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 71241af966ab338e95eee81ab618ab28195075338f7reedvoid SkPictureRecord::onDrawVertices(VertexMode vmode, int vertexCount, 71341af966ab338e95eee81ab618ab28195075338f7reed const SkPoint vertices[], const SkPoint texs[], 71441af966ab338e95eee81ab618ab28195075338f7reed const SkColor colors[], SkXfermode* xfer, 71541af966ab338e95eee81ab618ab28195075338f7reed const uint16_t indices[], int indexCount, 71641af966ab338e95eee81ab618ab28195075338f7reed const SkPaint& paint) { 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t flags = 0; 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (texs) { 7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= DRAW_VERTICES_HAS_TEXS; 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (colors) { 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= DRAW_VERTICES_HAS_COLORS; 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (indexCount > 0) { 7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= DRAW_VERTICES_HAS_INDICES; 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 72749f085dddff10473b6ebf832a974288300224e60bsalomon if (xfer) { 72885e143c33c214e54187aa28146aa7666961a0d17reed@google.com SkXfermode::Mode mode; 72985e143c33c214e54187aa28146aa7666961a0d17reed@google.com if (xfer->asMode(&mode) && SkXfermode::kModulate_Mode != mode) { 73085e143c33c214e54187aa28146aa7666961a0d17reed@google.com flags |= DRAW_VERTICES_HAS_XFER; 73185e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 73285e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7342ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // op + paint index + flags + vmode + vCount + vertices 735dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 5 * kUInt32Size + vertexCount * sizeof(SkPoint); 7362ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (flags & DRAW_VERTICES_HAS_TEXS) { 7372ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += vertexCount * sizeof(SkPoint); // + uvs 7382ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 7392ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (flags & DRAW_VERTICES_HAS_COLORS) { 7402ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += vertexCount * sizeof(SkColor); // + vert colors 7412ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 7422ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com if (flags & DRAW_VERTICES_HAS_INDICES) { 7432ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com // + num indices + indices 7442ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com size += 1 * kUInt32Size + SkAlign4(indexCount * sizeof(uint16_t)); 7452ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com } 74685e143c33c214e54187aa28146aa7666961a0d17reed@google.com if (flags & DRAW_VERTICES_HAS_XFER) { 74785e143c33c214e54187aa28146aa7666961a0d17reed@google.com size += kUInt32Size; // mode enum 74885e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 7492ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com 7508b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(DRAW_VERTICES, &size); 7518e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_VERTICES, size) == fWriter.bytesWritten()); 752cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPaint(paint); 753cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(flags); 754cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(vmode); 755cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(vertexCount); 756cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPoints(vertices, vertexCount); 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & DRAW_VERTICES_HAS_TEXS) { 758cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addPoints(texs, vertexCount); 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & DRAW_VERTICES_HAS_COLORS) { 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(colors, vertexCount * sizeof(SkColor)); 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags & DRAW_VERTICES_HAS_INDICES) { 764cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(indexCount); 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writePad(indices, indexCount * sizeof(uint16_t)); 7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 76785e143c33c214e54187aa28146aa7666961a0d17reed@google.com if (flags & DRAW_VERTICES_HAS_XFER) { 76885e143c33c214e54187aa28146aa7666961a0d17reed@google.com SkXfermode::Mode mode = SkXfermode::kModulate_Mode; 76985e143c33c214e54187aa28146aa7666961a0d17reed@google.com (void)xfer->asMode(&mode); 770cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(mode); 77185e143c33c214e54187aa28146aa7666961a0d17reed@google.com } 7728b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 775b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 776b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPoint texCoords[4], SkXfermode* xmode, 777b3c9d1c33caf325aada244204215eb790c228c12dandov const SkPaint& paint) { 778b3c9d1c33caf325aada244204215eb790c228c12dandov // op + paint index + patch 12 control points + flag + patch 4 colors + 4 texture coordinates 779b3c9d1c33caf325aada244204215eb790c228c12dandov size_t size = 2 * kUInt32Size + SkPatchUtils::kNumCtrlPts * sizeof(SkPoint) + kUInt32Size; 780b3c9d1c33caf325aada244204215eb790c228c12dandov uint32_t flag = 0; 78149f085dddff10473b6ebf832a974288300224e60bsalomon if (colors) { 782b3c9d1c33caf325aada244204215eb790c228c12dandov flag |= DRAW_VERTICES_HAS_COLORS; 783b3c9d1c33caf325aada244204215eb790c228c12dandov size += SkPatchUtils::kNumCorners * sizeof(SkColor); 784b3c9d1c33caf325aada244204215eb790c228c12dandov } 78549f085dddff10473b6ebf832a974288300224e60bsalomon if (texCoords) { 786b3c9d1c33caf325aada244204215eb790c228c12dandov flag |= DRAW_VERTICES_HAS_TEXS; 787b3c9d1c33caf325aada244204215eb790c228c12dandov size += SkPatchUtils::kNumCorners * sizeof(SkPoint); 788b3c9d1c33caf325aada244204215eb790c228c12dandov } 78949f085dddff10473b6ebf832a974288300224e60bsalomon if (xmode) { 790b3c9d1c33caf325aada244204215eb790c228c12dandov SkXfermode::Mode mode; 791b3c9d1c33caf325aada244204215eb790c228c12dandov if (xmode->asMode(&mode) && SkXfermode::kModulate_Mode != mode) { 792b3c9d1c33caf325aada244204215eb790c228c12dandov flag |= DRAW_VERTICES_HAS_XFER; 793b3c9d1c33caf325aada244204215eb790c228c12dandov size += kUInt32Size; 794b3c9d1c33caf325aada244204215eb790c228c12dandov } 795b3c9d1c33caf325aada244204215eb790c228c12dandov } 79646616af01b412ea984a516fda1ed8ec08e689f29mtklein 797963137b75c0a1fe91f35e9826742f36309f5e65ddandov size_t initialOffset = this->addDraw(DRAW_PATCH, &size); 7988e12656096fceeed8b3cc4284d57dea04893b455mtklein SkASSERT(initialOffset+get_paint_offset(DRAW_PATCH, size) == fWriter.bytesWritten()); 799963137b75c0a1fe91f35e9826742f36309f5e65ddandov this->addPaint(paint); 800b3c9d1c33caf325aada244204215eb790c228c12dandov this->addPatch(cubics); 801b3c9d1c33caf325aada244204215eb790c228c12dandov this->addInt(flag); 80246616af01b412ea984a516fda1ed8ec08e689f29mtklein 803b3c9d1c33caf325aada244204215eb790c228c12dandov // write optional parameters 80449f085dddff10473b6ebf832a974288300224e60bsalomon if (colors) { 805b3c9d1c33caf325aada244204215eb790c228c12dandov fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor)); 806b3c9d1c33caf325aada244204215eb790c228c12dandov } 80749f085dddff10473b6ebf832a974288300224e60bsalomon if (texCoords) { 808b3c9d1c33caf325aada244204215eb790c228c12dandov fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint)); 809b3c9d1c33caf325aada244204215eb790c228c12dandov } 810b3c9d1c33caf325aada244204215eb790c228c12dandov if (flag & DRAW_VERTICES_HAS_XFER) { 811b3c9d1c33caf325aada244204215eb790c228c12dandov SkXfermode::Mode mode = SkXfermode::kModulate_Mode; 812b3c9d1c33caf325aada244204215eb790c228c12dandov xmode->asMode(&mode); 813b3c9d1c33caf325aada244204215eb790c228c12dandov this->addInt(mode); 814b3c9d1c33caf325aada244204215eb790c228c12dandov } 815963137b75c0a1fe91f35e9826742f36309f5e65ddandov this->validate(initialOffset, size); 816963137b75c0a1fe91f35e9826742f36309f5e65ddandov} 817963137b75c0a1fe91f35e9826742f36309f5e65ddandov 8180a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.comvoid SkPictureRecord::beginCommentGroup(const char* description) { 8190a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com // op/size + length of string + \0 terminated chars 820dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t length = strlen(description); 821dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 2 * kUInt32Size + SkAlign4(length + 1); 8228b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(BEGIN_COMMENT_GROUP, &size); 8230a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com fWriter.writeString(description, length); 8248b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 8250a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com} 8260a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 8270a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.comvoid SkPictureRecord::addComment(const char* kywd, const char* value) { 8280a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com // op/size + 2x length of string + 2x \0 terminated chars 829dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t kywdLen = strlen(kywd); 830dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t valueLen = strlen(value); 831dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 3 * kUInt32Size + SkAlign4(kywdLen + 1) + SkAlign4(valueLen + 1); 8328b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(COMMENT, &size); 8330a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com fWriter.writeString(kywd, kywdLen); 8340a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com fWriter.writeString(value, valueLen); 8358b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 8360a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com} 8370a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 8380a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.comvoid SkPictureRecord::endCommentGroup() { 8390a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com // op/size 840dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org size_t size = 1 * kUInt32Size; 8418b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com size_t initialOffset = this->addDraw(END_COMMENT_GROUP, &size); 8428b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com this->validate(initialOffset, size); 8430a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com} 8440a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 84682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 8474a8126e7f81384526629b1e21bf89b632ea13cd9reedSkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) { 848cae54f1f211e3c293ef9afb968067d06ca0ea23dcommit-bot@chromium.org return NULL; 84976f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com} 85076f10a3bd936af7dbe2b5873d5a7eedd73cdc5dareed@google.com 851e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein// If we already have a stored, can we reuse it instead of also storing b? 852e069400cabd0edd3db52bbf1958063d3ed12ef28mtkleinstatic bool equivalent(const SkBitmap& a, const SkBitmap& b) { 853e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (a.info() != b.info() || a.pixelRefOrigin() != b.pixelRefOrigin()) { 854e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // Requiring a.info() == b.info() may be overkill in some cases (alphatype mismatch), 855e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // but it sure makes things easier to reason about below. 856e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; 857e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 858e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (a.pixelRef() == b.pixelRef()) { 859e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return true; // Same shape and same pixels -> same bitmap. 860e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 861e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 862e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // From here down we're going to have to look at the bitmap data, so we require pixelRefs(). 863e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (!a.pixelRef() || !b.pixelRef()) { 864e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; 865e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 866e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 867e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // If the bitmaps have encoded data, check first before locking pixels so they don't decode. 868e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkAutoTUnref<SkData> encA(a.pixelRef()->refEncodedData()), 869e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein encB(b.pixelRef()->refEncodedData()); 870e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (encA && encB) { 871e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return encA->equals(encB); 872e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } else if (encA || encB) { 873e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; // One has encoded data but the other does not. 874e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 875e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 876e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // As a last resort, we have to look at the pixels. This will read back textures. 877e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkAutoLockPixels al(a), bl(b); 878e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const char* ap = (const char*)a.getPixels(); 879e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const char* bp = (const char*)b.getPixels(); 880e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (ap && bp) { 881e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // We check row by row; row bytes might differ. 882e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkASSERT(a.info() == b.info()); // We checked this above. 883e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein SkASSERT(a.info().bytesPerPixel() > 0); // If we have pixelRefs, this better be true. 884e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const SkImageInfo info = a.info(); 885e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein const size_t bytesToCompare = info.width() * info.bytesPerPixel(); 886e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein for (int row = 0; row < info.height(); row++) { 887e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (0 != memcmp(ap, bp, bytesToCompare)) { 888e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; 889e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 890e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein ap += a.rowBytes(); 891e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein bp += b.rowBytes(); 892e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 893e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return true; 894e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 895e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return false; // Couldn't get pixels for both bitmaps. 896e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein} 897e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein 898e069400cabd0edd3db52bbf1958063d3ed12ef28mtkleinvoid SkPictureRecord::addBitmap(const SkBitmap& bitmap) { 899e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // First see if we already have this bitmap. This deduplication should really 900e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // only be important for our tests, where bitmaps tend not to be tagged immutable. 901e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // In Chrome (and hopefully Android?) they're typically immutable. 902e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein for (int i = 0; i < fBitmaps.count(); i++) { 903e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein if (equivalent(fBitmaps[i], bitmap)) { 904e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein this->addInt(i); // Unlike the rest, bitmap indices are 0-based. 905e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein return; 906e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 907e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein } 908e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // Don't have it. We'll add it to our list, making sure it's tagged as immutable. 90971a236370792416b367a7d2d6b8e471b06b331cdmtklein if (bitmap.isImmutable()) { 910e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // Shallow copies of bitmaps are cheap, so immutable == fast. 91171a236370792416b367a7d2d6b8e471b06b331cdmtklein fBitmaps.push_back(bitmap); 91271a236370792416b367a7d2d6b8e471b06b331cdmtklein } else { 913e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein // If you see this block on a memory profile, it's a good opportunity to reduce RAM usage. 91471a236370792416b367a7d2d6b8e471b06b331cdmtklein SkBitmap copy; 91571a236370792416b367a7d2d6b8e471b06b331cdmtklein bitmap.copyTo(©); 91671a236370792416b367a7d2d6b8e471b06b331cdmtklein copy.setImmutable(); 91771a236370792416b367a7d2d6b8e471b06b331cdmtklein fBitmaps.push_back(copy); 91871a236370792416b367a7d2d6b8e471b06b331cdmtklein } 919e069400cabd0edd3db52bbf1958063d3ed12ef28mtklein this->addInt(fBitmaps.count()-1); // Remember, 0-based. 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addMatrix(const SkMatrix& matrix) { 923fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org fWriter.writeMatrix(matrix); 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 92646616af01b412ea984a516fda1ed8ec08e689f29mtkleinvoid SkPictureRecord::addPaintPtr(const SkPaint* paint) { 927afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onAddPaintPtr(paint); 928e2cb12a82ad924f7b134a9459b190213485c6a50commit-bot@chromium.org 92946616af01b412ea984a516fda1ed8ec08e689f29mtklein if (paint) { 930a74ce853c824c5ae30e219ddf46a61d91cc0ab2amtklein fPaints.push_back(*paint); 931a74ce853c824c5ae30e219ddf46a61d91cc0ab2amtklein this->addInt(fPaints.count()); 93246616af01b412ea984a516fda1ed8ec08e689f29mtklein } else { 93346616af01b412ea984a516fda1ed8ec08e689f29mtklein this->addInt(0); 93446616af01b412ea984a516fda1ed8ec08e689f29mtklein } 935cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org} 936cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org 9375a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comint SkPictureRecord::addPathToHeap(const SkPath& path) { 93871a236370792416b367a7d2d6b8e471b06b331cdmtklein fPaths.push_back(path); 93971a236370792416b367a7d2d6b8e471b06b331cdmtklein return fPaths.count(); 9405a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com} 9415a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.com 9425a63f24558b84610e93c6d7b67d849b5ab435e51robertphillips@google.comvoid SkPictureRecord::addPath(const SkPath& path) { 943cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(this->addPathToHeap(path)); 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 946b3c9d1c33caf325aada244204215eb790c228c12dandovvoid SkPictureRecord::addPatch(const SkPoint cubics[12]) { 947b3c9d1c33caf325aada244204215eb790c228c12dandov fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint)); 948963137b75c0a1fe91f35e9826742f36309f5e65ddandov} 949963137b75c0a1fe91f35e9826742f36309f5e65ddandov 9509b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkPictureRecord::addPicture(const SkPicture* picture) { 9519b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips int index = fPictureRefs.find(picture); 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (index < 0) { // not found 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com index = fPictureRefs.count(); 9549b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips *fPictureRefs.append() = picture; 9559b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips picture->ref(); 9568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // follow the convention of recording a 1-based index 958cb6adecd4d37ae23c89a473a5f648584e0428520robertphillips@google.com this->addInt(index + 1); 9598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addPoint(const SkPoint& point) { 9628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writePoint(point); 9638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 96482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 9658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addPoints(const SkPoint pts[], int count) { 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeMul4(pts, count * sizeof(SkPoint)); 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 96968250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.orgvoid SkPictureRecord::addNoOp() { 97068250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org size_t size = kUInt32Size; // op 97168250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org this->addDraw(NOOP, &size); 97268250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org} 97368250c8e7c2bf5d669397c849259c3bcad40237esenorblanco@chromium.org 9748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addRect(const SkRect& rect) { 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeRect(rect); 9768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addRectPtr(const SkRect* rect) { 9798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fWriter.writeBool(rect != NULL)) { 9808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writeRect(*rect); 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 984f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.comvoid SkPictureRecord::addIRect(const SkIRect& rect) { 985f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com fWriter.write(&rect, sizeof(rect)); 986f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com} 987f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addIRectPtr(const SkIRect* rect) { 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fWriter.writeBool(rect != NULL)) { 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(SkIRect*)fWriter.reserve(sizeof(SkIRect)) = *rect; 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comvoid SkPictureRecord::addRRect(const SkRRect& rrect) { 9954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com fWriter.writeRRect(rrect); 9964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com} 9974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addRegion(const SkRegion& region) { 999fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org fWriter.writeRegion(region); 10008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPictureRecord::addText(const void* text, size_t byteLength) { 1003afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw fContentInfo.onDrawText(); 1004dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org addInt(SkToInt(byteLength)); 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWriter.writePad(text, byteLength); 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008b7425173f96e93b090787e2386ba5f022b6c2869fmalitavoid SkPictureRecord::addTextBlob(const SkTextBlob *blob) { 1009dd1e9f75969c72da53657e58a080c47b30f64140jbroman int index = fTextBlobRefs.count(); 1010dd1e9f75969c72da53657e58a080c47b30f64140jbroman *fTextBlobRefs.append() = blob; 1011dd1e9f75969c72da53657e58a080c47b30f64140jbroman blob->ref(); 1012b7425173f96e93b090787e2386ba5f022b6c2869fmalita // follow the convention of recording a 1-based index 1013b7425173f96e93b090787e2386ba5f022b6c2869fmalita this->addInt(index + 1); 1014b7425173f96e93b090787e2386ba5f022b6c2869fmalita} 1015b7425173f96e93b090787e2386ba5f022b6c2869fmalita 10168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 10178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1018