SkPictureData.cpp revision db539905bb3af7bd05839a7d2558e97d5cb51ca2
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 */
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <new>
88515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com#include "SkBBoxHierarchy.h"
9c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein#include "SkDrawPictureCallback.h"
10db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#include "SkPictureData.h"
118016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkPictureRecord.h"
128515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com#include "SkPictureStateTree.h"
138016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkReadBuffer.h"
148016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkTypeface.h"
158515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com#include "SkTSort.h"
168016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkWriteBuffer.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#if SK_SUPPORT_GPU
1912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#include "GrContext.h"
2012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#endif
2112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
22f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.comtemplate <typename T> int SafeCount(const T* obj) {
23f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    return obj ? obj->count() : 0;
24f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com}
25f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com
26ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com/*  Define this to spew out a debug statement whenever we skip the remainder of
27ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    a save/restore block because a clip... command returned false (empty).
28ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com */
29ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#define SPEW_CLIP_SKIPPINGx
30ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com
31db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::PlaybackReplacements::ReplacementInfo*
32db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::PlaybackReplacements::push() {
33beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    SkDEBUGCODE(this->validate());
34b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com    return fReplacements.push();
35beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com}
36beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
37db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::PlaybackReplacements::freeAll() {
38beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    for (int i = 0; i < fReplacements.count(); ++i) {
39beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        SkDELETE(fReplacements[i].fBM);
40beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
41beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    fReplacements.reset();
42beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com}
43beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
44beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com#ifdef SK_DEBUG
45db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::PlaybackReplacements::validate() const {
46beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // Check that the ranges are monotonically increasing and non-overlapping
47beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    if (fReplacements.count() > 0) {
48beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
49beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
50beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        for (int i = 1; i < fReplacements.count(); ++i) {
51beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
52beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            SkASSERT(fReplacements[i-1].fStop < fReplacements[i].fStart);
53beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
54beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
55beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com}
56beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com#endif
57beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
58db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictInfo& info)
59e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(info) {
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->init();
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
63db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::initForPlayback() const {
64e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    // ensure that the paths bounds are pre-computed
65e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    if (NULL != fPathHeap.get()) {
66e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        for (int i = 0; i < fPathHeap->count(); i++) {
67e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips            (*fPathHeap.get())[i].updateBoundsCache();
68e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        }
69e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    }
70e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips}
71e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips
72db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictureRecord& record,
739058d602d0303c4d601bea260929367a8be37f04robertphillips                                     const SkPictInfo& info,
749058d602d0303c4d601bea260929367a8be37f04robertphillips                                     bool deepCopyOps)
75e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(info) {
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG_SIZE
7782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    size_t overallBytes, bitmapBytes, matricesBytes,
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    paintBytes, pathBytes, pictureBytes, regionBytes;
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int bitmaps = record.bitmaps(&bitmapBytes);
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int matrices = record.matrices(&matricesBytes);
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int paints = record.paints(&paintBytes);
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int paths = record.paths(&pathBytes);
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int pictures = record.pictures(&pictureBytes);
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int regions = record.regions(&regionBytes);
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("picture record mem used %zd (stream %zd) ", record.size(),
868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com             record.streamlen());
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bitmaps != 0)
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (matrices != 0)
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("matrices size %zd (matrices:%d) ", matricesBytes, matrices);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (paints != 0)
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (paths != 0)
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (pictures != 0)
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (regions != 0)
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (record.fPointWrites != 0)
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("points size %zd (points:%d) ", record.fPointBytes, record.fPointWrites);
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (record.fRectWrites != 0)
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("rects size %zd (rects:%d) ", record.fRectBytes, record.fRectWrites);
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (record.fTextWrites != 0)
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("text size %zd (text strings:%d) ", record.fTextBytes, record.fTextWrites);
10582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("\n");
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG_DUMP
1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    record.dumpMatrices();
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    record.dumpPaints();
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
11370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    this->init();
1140bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
1150bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    fOpData = record.opData(deepCopyOps);
11682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1178515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    fBoundingHierarchy = record.fBoundingHierarchy;
1188515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    fStateTree = record.fStateTree;
1198515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
1208515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkSafeRef(fBoundingHierarchy);
1218515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkSafeRef(fStateTree);
1220bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    fContentInfo.set(record.fContentInfo);
1238515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
1248515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    if (NULL != fBoundingHierarchy) {
1258515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com        fBoundingHierarchy->flushDeferredInserts();
1268515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    }
1278515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // copy over the refcnt dictionary to our reader
12921830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    record.fFlattenableHeap.setupPlaybacks();
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
131c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    fBitmaps = record.fBitmapHeap->extractBitmaps();
13221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    fPaints = record.fPaints.unflattenToArray();
13321830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com
134c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap));
135e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    fPathHeap.reset(SkSafeRef(record.pathHeap()));
136c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
137e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    this->initForPlayback();
1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1399b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPictureCount = pictures.count();
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPictureCount > 0) {
1429b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips        fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = 0; i < fPictureCount; i++) {
1446de27127c4d50ef90b5435aefaeef47fa84b819drobertphillips            fPictureRefs[i] = pictures[i];
1456de27127c4d50ef90b5435aefaeef47fa84b819drobertphillips            fPictureRefs[i]->ref();
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
14882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG_SIZE
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int overall = fPlayback->size(&overallBytes);
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bitmaps = fPlayback->bitmaps(&bitmapBytes);
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    paints = fPlayback->paints(&paintBytes);
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    paths = fPlayback->paths(&pathBytes);
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    pictures = fPlayback->pictures(&pictureBytes);
1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    regions = fPlayback->regions(&regionBytes);
1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall);
1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (bitmaps != 0)
1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (paints != 0)
1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (paths != 0)
1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (pictures != 0)
1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (regions != 0)
1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("\n");
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
171d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
172db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictureData& src, SkPictCopyInfo* deepCopyInfo)
173e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(src.fInfo) {
1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->init();
1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
176c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
177e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
178c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
179c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    fOpData = SkSafeRef(src.fOpData);
1801d225f2b3352bb8f24661f62d2bd1cc7386a2f86skia.committer@gmail.com
1818515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    fBoundingHierarchy = src.fBoundingHierarchy;
1828515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    fStateTree = src.fStateTree;
1830bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    fContentInfo.set(src.fContentInfo);
1848515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
1858515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkSafeRef(fBoundingHierarchy);
1868515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkSafeRef(fStateTree);
187c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
188c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    if (deepCopyInfo) {
18966ec1e4c6179915a50bea74fad4b8cc14e63a4cfcommit-bot@chromium.org        SkASSERT(deepCopyInfo->initialized);
19066ec1e4c6179915a50bea74fad4b8cc14e63a4cfcommit-bot@chromium.org
19194f20dc89a55483ba63db01829332065e6e1b2acjunov@chromium.org        int paintCount = SafeCount(src.fPaints);
192c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
193c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        if (src.fBitmaps) {
194c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com            fBitmaps = SkTRefArray<SkBitmap>::Create(src.fBitmaps->begin(), src.fBitmaps->count());
195c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        }
196c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
19794f20dc89a55483ba63db01829332065e6e1b2acjunov@chromium.org        fPaints = SkTRefArray<SkPaint>::Create(paintCount);
19894f20dc89a55483ba63db01829332065e6e1b2acjunov@chromium.org        SkASSERT(deepCopyInfo->paintData.count() == paintCount);
199dee54be428017a81f13519291a03baac11d61602reed@google.com        SkBitmapHeap* bmHeap = deepCopyInfo->controller.getBitmapHeap();
200dee54be428017a81f13519291a03baac11d61602reed@google.com        SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePlayback();
20194f20dc89a55483ba63db01829332065e6e1b2acjunov@chromium.org        for (int i = 0; i < paintCount; i++) {
202dee54be428017a81f13519291a03baac11d61602reed@google.com            if (deepCopyInfo->paintData[i]) {
203aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org                deepCopyInfo->paintData[i]->unflatten<SkPaint::FlatteningTraits>(
204aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org                    &fPaints->writableAt(i), bmHeap, tfPlayback);
205dee54be428017a81f13519291a03baac11d61602reed@google.com            } else {
206dee54be428017a81f13519291a03baac11d61602reed@google.com                // needs_deep_copy was false, so just need to assign
207dee54be428017a81f13519291a03baac11d61602reed@google.com                fPaints->writableAt(i) = src.fPaints->at(i);
208dee54be428017a81f13519291a03baac11d61602reed@google.com            }
209c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        }
210c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
211c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    } else {
212c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        fBitmaps = SkSafeRef(src.fBitmaps);
213c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        fPaints = SkSafeRef(src.fPaints);
214c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    }
2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPictureCount = src.fPictureCount;
2179b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < fPictureCount; i++) {
219c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        if (deepCopyInfo) {
220c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com            fPictureRefs[i] = src.fPictureRefs[i]->clone();
221c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        } else {
222c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com            fPictureRefs[i] = src.fPictureRefs[i];
223c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com            fPictureRefs[i]->ref();
224c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com        }
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
227d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#else
228db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictureData& src) : fInfo(src.fInfo) {
229d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    this->init();
230d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein
231d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fBitmapHeap.reset(SkSafeRef(src.fBitmapHeap.get()));
232d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fPathHeap.reset(SkSafeRef(src.fPathHeap.get()));
233d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein
234d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fOpData = SkSafeRef(src.fOpData);
235d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein
236d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fBoundingHierarchy = src.fBoundingHierarchy;
237d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fStateTree = src.fStateTree;
238d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fContentInfo.set(src.fContentInfo);
239d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein
240d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    SkSafeRef(fBoundingHierarchy);
241d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    SkSafeRef(fStateTree);
242d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein
243d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fBitmaps = SkSafeRef(src.fBitmaps);
244d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fPaints = SkSafeRef(src.fPaints);
245d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein
246d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fPictureCount = src.fPictureCount;
247d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
248d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    for (int i = 0; i < fPictureCount; i++) {
249d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein        fPictureRefs[i] = SkRef(src.fPictureRefs[i]);
250d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein    }
251d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein}
252d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#endif//SK_SUPPORT_LEGACY_PICTURE_CLONE
2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
254db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::init() {
2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fBitmaps = NULL;
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPaints = NULL;
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPictureRefs = NULL;
258f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    fPictureCount = 0;
259ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    fOpData = NULL;
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fFactoryPlayback = NULL;
2618515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    fBoundingHierarchy = NULL;
2628515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    fStateTree = NULL;
26370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    fCachedActiveOps = NULL;
26475cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org    fCurOffset = 0;
265beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    fUseBBH = true;
266beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    fStart = 0;
267beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    fStop = 0;
268beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    fReplacements = NULL;
2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
271db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::~SkPictureData() {
2729e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org    SkSafeUnref(fOpData);
2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
274f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    SkSafeUnref(fBitmaps);
275f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    SkSafeUnref(fPaints);
2768515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkSafeUnref(fBoundingHierarchy);
2778515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkSafeUnref(fStateTree);
27882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
27970512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    SkDELETE(fCachedActiveOps);
28070512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < fPictureCount; i++) {
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPictureRefs[i]->unref();
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDELETE_ARRAY(fPictureRefs);
28582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDELETE(fFactoryPlayback);
2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
289db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpSize() const {
2908f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] paints=%d [%d]\n",
291ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com             fOpData->size(),
292f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com             SafeCount(fBitmaps), SafeCount(fBitmaps) * sizeof(SkBitmap),
2938f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org             SafeCount(fPaints), SafeCount(fPaints) * sizeof(SkPaint));
294e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    SkDebugf("--- picture size: paths=%d\n",
295e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips             SafeCount(fPathHeap.get()));
2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::containsBitmaps() const {
299381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    if (fBitmaps && fBitmaps->count() > 0) {
300381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        return true;
301381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    }
302381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    for (int i = 0; i < fPictureCount; ++i) {
303381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        if (fPictureRefs[i]->willPlayBackBitmaps()) {
304381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com            return true;
305381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        }
306381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    }
307381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    return false;
308381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com}
309381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com
3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
315dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.orgstatic size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
316dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    size_t size = 4;  // for 'count'
317dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
318dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    for (int i = 0; i < count; i++) {
319dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        const char* name = SkFlattenable::FactoryToName(array[i]);
320dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        if (NULL == name || 0 == *name) {
321dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += SkWStream::SizeOfPackedUInt(0);
322dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        } else {
323dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size_t len = strlen(name);
324dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += SkWStream::SizeOfPackedUInt(len);
325dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += len;
326dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        }
327dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    }
328dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
329dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    return size;
330dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org}
33182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
332db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
333dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    int count = rec.count();
33482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
337e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    rec.copyToArray(array);
33882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
339dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    size_t size = compute_chunk_size(array, count);
340dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
341dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    // TODO: write_tag_size should really take a size_t
3428f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    SkPicture::WriteTagSize(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
34306e975252112eb5ca62ebacd484118a640c19168commit-bot@chromium.org    SkDEBUGCODE(size_t start = stream->bytesWritten());
344dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    stream->write32(count);
345dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const char* name = SkFlattenable::FactoryToName(array[i]);
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//        SkDebugf("---- write factories [%d] %p <%s>\n", i, array[i], name);
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (NULL == name || 0 == *name) {
3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->writePackedUInt(0);
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
3522cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org            size_t len = strlen(name);
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->writePackedUInt(len);
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->write(name, len);
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
357dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
35806e975252112eb5ca62ebacd484118a640c19168commit-bot@chromium.org    SkASSERT(size == (stream->bytesWritten() - start));
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
361db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count = rec.count();
36382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3648f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    SkPicture::WriteTagSize(stream, SK_PICT_TYPEFACE_TAG, count);
36582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkTypeface*> storage(count);
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkTypeface** array = (SkTypeface**)storage.get();
368e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    rec.copyToArray((SkRefCnt**)array);
36982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        array[i]->serialize(stream);
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
375db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
376f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    int i, n;
37782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
378f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    if ((n = SafeCount(fBitmaps)) > 0) {
3798f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        SkPicture::WriteTagSize(buffer, SK_PICT_BITMAP_BUFFER_TAG, n);
380f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com        for (i = 0; i < n; i++) {
381c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com            buffer.writeBitmap((*fBitmaps)[i]);
3826756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        }
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
384fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
385f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    if ((n = SafeCount(fPaints)) > 0) {
3868f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        SkPicture::WriteTagSize(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
387f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com        for (i = 0; i < n; i++) {
388c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com            buffer.writePaint((*fPaints)[i]);
3896756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        }
3906756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    }
391a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
392e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    if ((n = SafeCount(fPathHeap.get())) > 0) {
393e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        SkPicture::WriteTagSize(buffer, SK_PICT_PATH_BUFFER_TAG, n);
394e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        fPathHeap->flatten(buffer);
395e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    }
3966756209ee0a0103d395ac908edbdcf5268b920dareed@google.com}
3976756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
398db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::serialize(SkWStream* stream,
39932ef131f5279da0850f865dece4935aeddddb40ascroggo@google.com                                  SkPicture::EncodeBitmap encoder) const {
4008f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    SkPicture::WriteTagSize(stream, SK_PICT_READER_TAG, fOpData->size());
401ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    stream->write(fOpData->bytes(), fOpData->size());
40282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
4036756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    if (fPictureCount > 0) {
4048f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        SkPicture::WriteTagSize(stream, SK_PICT_PICTURE_TAG, fPictureCount);
4056756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        for (int i = 0; i < fPictureCount; i++) {
406f8d7d2731318cdf510ab68e6b3f5ec68ab22c8e2scroggo@google.com            fPictureRefs[i]->serialize(stream, encoder);
4076756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        }
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
40982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
4106756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    // Write some of our data into a writebuffer, and then serialize that
4116756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    // into our stream
4126756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    {
4136756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        SkRefCntSet  typefaceSet;
4146756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        SkFactorySet factSet;
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
416a2bd2d12ad9504583e9311404fcd82b40df49d30commit-bot@chromium.org        SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag);
4176756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        buffer.setTypefaceRecorder(&typefaceSet);
4186756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        buffer.setFactoryRecorder(&factSet);
4195a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com        buffer.setBitmapEncoder(encoder);
42034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
4216756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        this->flattenToBuffer(buffer);
42282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
423dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        // We have to write these two sets into the stream *before* we write
4246756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        // the buffer, since parsing that buffer will require that we already
4256756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        // have these sets available to use.
4268f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        WriteFactories(stream, factSet);
4278f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        WriteTypefaces(stream, typefaceSet);
4286756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
4298f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        SkPicture::WriteTagSize(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
4306756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        buffer.writeToStream(stream);
4316756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    }
432ed38495c7cf5bdeb2843b6f1f090579fbefe497dreed@google.com
4336f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    stream->write32(SK_PICT_EOF_TAG);
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
436db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::flatten(SkWriteBuffer& buffer) const {
4378f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    SkPicture::WriteTagSize(buffer, SK_PICT_READER_TAG, fOpData->size());
4385e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    buffer.writeByteArray(fOpData->bytes(), fOpData->size());
4395e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
4405e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    if (fPictureCount > 0) {
4418f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org        SkPicture::WriteTagSize(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
4425e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        for (int i = 0; i < fPictureCount; i++) {
4435e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            fPictureRefs[i]->flatten(buffer);
4445e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
4455e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
4465e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
4475e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    // Write this picture playback's data into a writebuffer
4485e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    this->flattenToBuffer(buffer);
4496f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    buffer.write32(SK_PICT_EOF_TAG);
4505e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
4515e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
45434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com/**
4558b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *  Return the corresponding SkReadBuffer flags, given a set of
45634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com *  SkPictInfo flags.
45734342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com */
45834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.comstatic uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
45934342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    static const struct {
46034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        uint32_t    fSrc;
46134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        uint32_t    fDst;
46234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    } gSD[] = {
4638b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kCrossProcess_Flag,   SkReadBuffer::kCrossProcess_Flag },
4648b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kScalarIsFloat_Flag,  SkReadBuffer::kScalarIsFloat_Flag },
4658b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kPtrIs64Bit_Flag,     SkReadBuffer::kPtrIs64Bit_Flag },
46634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    };
467fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
46834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    uint32_t rbMask = 0;
46934342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
47034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        if (pictInfoFlags & gSD[i].fSrc) {
47134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com            rbMask |= gSD[i].fDst;
47234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        }
47334342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    }
47434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    return rbMask;
47534342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com}
47634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
477db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseStreamTag(SkStream* stream,
4780943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org                                       uint32_t tag,
479dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org                                       uint32_t size,
4800943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org                                       SkPicture::InstallPixelRefProc proc) {
4816756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    /*
4826756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
4836756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
4846756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  but if they are present, they need to have been seen before the buffer.
4856756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *
4866756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  We assert that if/when we see either of these, that we have not yet seen
4876756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  the buffer tag, because if we have, then its too-late to deal with the
4886756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  factories or typefaces.
4896756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     */
490c4dc831f7be430dc8a7d68fd9eb84bfda8a1c519scroggo@google.com    SkDEBUGCODE(bool haveBuffer = false;)
4916756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
4926756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    switch (tag) {
4936f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_READER_TAG: {
49412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            SkAutoMalloc storage(size);
49512705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            if (stream->read(storage.get(), size) != size) {
49612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
49712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
498ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com            SkASSERT(NULL == fOpData);
49912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            fOpData = SkData::NewFromMalloc(storage.detach(), size);
5006756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5016f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_FACTORY_TAG: {
5026756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkASSERT(!haveBuffer);
503dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        // Remove this code when v21 and below are no longer supported. At the
504dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        // same time add a new 'count' variable and use it rather then reusing 'size'.
505dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#ifndef DISABLE_V21_COMPATIBILITY_CODE
5060943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org            if (fInfo.fVersion >= 22) {
507dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                // in v22 this tag's size represents the size of the chunk in bytes
508dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                // and the number of factory strings is written out separately
509dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#endif
510dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org                size = stream->readU32();
511dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#ifndef DISABLE_V21_COMPATIBILITY_CODE
512dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            }
513dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org#endif
5146756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size));
5156756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            for (size_t i = 0; i < size; i++) {
5166756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                SkString str;
51712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                const size_t len = stream->readPackedUInt();
5186756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                str.resize(len);
51912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                if (stream->read(str.writable_str(), len) != len) {
52012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    return false;
52112705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
5226756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
5236756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
5246756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5256f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_TYPEFACE_TAG: {
5266756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkASSERT(!haveBuffer);
527dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
528dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            fTFPlayback.setCount(count);
529dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; i++) {
53073c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                SkAutoTUnref<SkTypeface> tf(SkTypeface::Deserialize(stream));
53173c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                if (!tf.get()) {    // failed to deserialize
53273c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    // fTFPlayback asserts it never has a null, so we plop in
53373c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    // the default here.
53473c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    tf.reset(SkTypeface::RefDefault());
53573c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                }
53673c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                fTFPlayback.set(i, tf);
5376756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
5386756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5396f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PICTURE_TAG: {
5406756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            fPictureCount = size;
5419b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
54212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            bool success = true;
54312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            int i = 0;
54412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            for ( ; i < fPictureCount; i++) {
545f1754ec69131801c1a6ed3c704501a9400bbf324scroggo@google.com                fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc);
54612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                if (NULL == fPictureRefs[i]) {
54712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    success = false;
54812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    break;
54912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
55012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
55112705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            if (!success) {
55212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                // Delete all of the pictures that were already created (up to but excluding i):
55312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                for (int j = 0; j < i; j++) {
55412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    fPictureRefs[j]->unref();
55512705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
55612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                // Delete the array
55712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                SkDELETE_ARRAY(fPictureRefs);
55812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                fPictureCount = 0;
55912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
5606756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
5616756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5626f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_BUFFER_SIZE_TAG: {
5636756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkAutoMalloc storage(size);
56412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            if (stream->read(storage.get(), size) != size) {
56512705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
56612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
567fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
5688b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org            SkReadBuffer buffer(storage.get(), size);
5690943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org            buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
5707ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org            buffer.setVersion(fInfo.fVersion);
57134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
5726756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            fFactoryPlayback->setupBuffer(buffer);
5736756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            fTFPlayback.setupBuffer(buffer);
574f8d7d2731318cdf510ab68e6b3f5ec68ab22c8e2scroggo@google.com            buffer.setBitmapDecoder(proc);
575fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
5766756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            while (!buffer.eof()) {
577c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                tag = buffer.readUInt();
578c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                size = buffer.readUInt();
579e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips                if (!this->parseBufferTag(buffer, tag, size)) {
58012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    return false;
58112705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
5826756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
583c4dc831f7be430dc8a7d68fd9eb84bfda8a1c519scroggo@google.com            SkDEBUGCODE(haveBuffer = true;)
5846756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
58612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;    // success
5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
589db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseBufferTag(SkReadBuffer& buffer,
590dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org                                       uint32_t tag, uint32_t size) {
5916756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    switch (tag) {
5926f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_BITMAP_BUFFER_TAG: {
593dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
594f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com            fBitmaps = SkTRefArray<SkBitmap>::Create(size);
595dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; ++i) {
596c52295f9ddc5592260b8adfce3d2778d4a21c9f2reed@google.com                SkBitmap* bm = &fBitmaps->writableAt(i);
597c52295f9ddc5592260b8adfce3d2778d4a21c9f2reed@google.com                buffer.readBitmap(bm);
598c52295f9ddc5592260b8adfce3d2778d4a21c9f2reed@google.com                bm->setImmutable();
5996756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
6006756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
6016f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PAINT_BUFFER_TAG: {
602dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
603f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com            fPaints = SkTRefArray<SkPaint>::Create(size);
604dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; ++i) {
605c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                buffer.readPaint(&fPaints->writableAt(i));
6066756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
6076756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
6086f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PATH_BUFFER_TAG:
609e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips            if (size > 0) {
610e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips                fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
611e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips            }
6126756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            break;
6139e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        case SK_PICT_READER_TAG: {
6149e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            SkAutoMalloc storage(size);
6159e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            if (!buffer.readByteArray(storage.get(), size) ||
6169e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                !buffer.validate(NULL == fOpData)) {
6179e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
6189e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
6199e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            SkASSERT(NULL == fOpData);
6209e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            fOpData = SkData::NewFromMalloc(storage.detach(), size);
6219e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        } break;
6229e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        case SK_PICT_PICTURE_TAG: {
6239e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            if (!buffer.validate((0 == fPictureCount) && (NULL == fPictureRefs))) {
6249e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
6259e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
6269e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            fPictureCount = size;
6279b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips            fPictureRefs = SkNEW_ARRAY(const SkPicture*, fPictureCount);
6289e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            bool success = true;
6299e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            int i = 0;
6309e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            for ( ; i < fPictureCount; i++) {
6319e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                fPictureRefs[i] = SkPicture::CreateFromBuffer(buffer);
6329e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                if (NULL == fPictureRefs[i]) {
6339e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                    success = false;
6349e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                    break;
6359e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                }
6369e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
6379e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            if (!success) {
6389e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                // Delete all of the pictures that were already created (up to but excluding i):
6399e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                for (int j = 0; j < i; j++) {
6409e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                    fPictureRefs[j]->unref();
6419e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                }
6429e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                // Delete the array
6439e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                SkDELETE_ARRAY(fPictureRefs);
6449e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                fPictureCount = 0;
6459e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
6469e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
6479e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        } break;
64812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        default:
64912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            // The tag was invalid.
65012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            return false;
6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
65212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;    // success
6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
655db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
656db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               const SkPictInfo& info,
657db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               SkPicture::InstallPixelRefProc proc) {
658db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info)));
65912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com
660db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    if (!data->parseStream(stream, proc)) {
66112705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        return NULL;
66212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    }
663db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    return data.detach();
66412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com}
6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
666db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer,
667db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               const SkPictInfo& info) {
668db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info)));
6697ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org    buffer.setVersion(info.fVersion);
6705e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
671db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    if (!data->parseBuffer(buffer)) {
6725e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        return NULL;
6735e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
674db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    return data.detach();
6755e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
6765e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
677db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseStream(SkStream* stream,
678db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                SkPicture::InstallPixelRefProc proc) {
6796756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    for (;;) {
6806756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        uint32_t tag = stream->readU32();
6816f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
6826756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            break;
683ed38495c7cf5bdeb2843b6f1f090579fbefe497dreed@google.com        }
6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6856756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        uint32_t size = stream->readU32();
686e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        if (!this->parseStreamTag(stream, tag, size, proc)) {
68712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            return false; // we're invalid
68812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        }
6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
69012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;
6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
693db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseBuffer(SkReadBuffer& buffer) {
6945e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    for (;;) {
6955e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        uint32_t tag = buffer.readUInt();
6966f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
6975e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            break;
6985e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
6995e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
7005e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        uint32_t size = buffer.readUInt();
701e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        if (!this->parseBufferTag(buffer, tag, size)) {
7025e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            return false; // we're invalid
7035e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
7045e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
7055e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    return true;
7065e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
7075e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
711ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#ifdef SPEW_CLIP_SKIPPING
712ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.comstruct SkipClipRec {
713ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    int     fCount;
714ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    size_t  fSize;
71582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
716ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    SkipClipRec() {
717ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com        fCount = 0;
718ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com        fSize = 0;
719ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    }
72082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
721ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    void recordSkip(size_t bytes) {
722ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com        fCount += 1;
723ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com        fSize += bytes;
724ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    }
725ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com};
726ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#endif
727ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com
7283f7137250c8558dedd1f08ed2e5f61d3665c19cbrobertphillips@google.com#ifdef SK_DEVELOPER
729db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::preDraw(int opIndex, int type) {
7306d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com    return false;
7316f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com}
7326f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com
733db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::postDraw(int opIndex) {
7346f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com}
7356f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com#endif
7366f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com
7372ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com/*
738e4ce5b82627d7ef7cab34b808ff88dc208aef7bcrobertphillips@google.com * Read the next op code and chunk size from 'reader'. The returned size
739ce8343d7dde40e509317708de239be1fa72b28f9skia.committer@gmail.com * is the entire size of the chunk (including the opcode). Thus, the
740e4ce5b82627d7ef7cab34b808ff88dc208aef7bcrobertphillips@google.com * offset just prior to calling read_op_and_size + 'size' is the offset
741ce8343d7dde40e509317708de239be1fa72b28f9skia.committer@gmail.com * to the next chunk's op code. This also means that the size of a chunk
742e4ce5b82627d7ef7cab34b808ff88dc208aef7bcrobertphillips@google.com * with no arguments (just an opcode) will be 4.
7432ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com */
7442ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.comstatic DrawType read_op_and_size(SkReader32* reader, uint32_t* size) {
7452ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com    uint32_t temp = reader->readInt();
7462ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com    uint32_t op;
7472ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com    if (((uint8_t) temp) == temp) {
7482ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        // old skp file - no size information
7492ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        op = temp;
7502ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        *size = 0;
7512ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com    } else {
7522ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        UNPACK_8_24(temp, op, *size);
7532ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        if (MASK_24 == *size) {
7542ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com            *size = reader->readInt();
7552ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        }
7562ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com    }
7572ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com    return (DrawType) op;
7582ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com}
7592ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com
760db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsuint32_t SkPictureData::CachedOperationList::offset(int index) const {
76170512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    SkASSERT(index < fOps.count());
76270512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    return ((SkPictureStateTree::Draw*)fOps[index])->fOffset;
76370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org}
76470512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
765db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsconst SkMatrix& SkPictureData::CachedOperationList::matrix(int index) const {
76670512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    SkASSERT(index < fOps.count());
76770512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    return *((SkPictureStateTree::Draw*)fOps[index])->fMatrix;
76870512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org}
76970512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
770db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsconst SkPicture::OperationList& SkPictureData::getActiveOps(const SkIRect& query) {
77170512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    if (NULL == fStateTree || NULL == fBoundingHierarchy) {
77270512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org        return SkPicture::OperationList::InvalidList();
77370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    }
77470512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
77570512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    if (NULL == fCachedActiveOps) {
77670512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org        fCachedActiveOps = SkNEW(CachedOperationList);
77770512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    }
77870512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
77970512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    if (query == fCachedActiveOps->fCacheQueryRect) {
78070512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org        return *fCachedActiveOps;
78170512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    }
78270512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
78370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    fCachedActiveOps->fOps.rewind();
78470512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
78570512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    fBoundingHierarchy->search(query, &(fCachedActiveOps->fOps));
78670512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    if (0 != fCachedActiveOps->fOps.count()) {
78770512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org        SkTQSort<SkPictureStateTree::Draw>(
78870512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org            reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps.begin()),
78970512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org            reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps.end()-1));
79070512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    }
79170512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
79270512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    fCachedActiveOps->fCacheQueryRect = query;
79370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    return *fCachedActiveOps;
79470512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org}
79570512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org
79675cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.orgclass SkAutoResetOpID {
79775cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.orgpublic:
798db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    SkAutoResetOpID(SkPictureData* data) : fData(data) { }
79975cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org    ~SkAutoResetOpID() {
800db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips        if (NULL != fData) {
801db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips            fData->resetOpID();
80275cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org        }
80375cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org    }
80475cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org
80575cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.orgprivate:
806db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    SkPictureData* fData;
80775cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org};
80875cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org
809beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com// TODO: Replace with hash or pass in "lastLookedUp" hint
810db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::PlaybackReplacements::ReplacementInfo*
811db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::PlaybackReplacements::lookupByStart(size_t start) {
812beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    SkDEBUGCODE(this->validate());
813beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    for (int i = 0; i < fReplacements.count(); ++i) {
814beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        if (start == fReplacements[i].fStart) {
815beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            return &fReplacements[i];
816beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        } else if (start < fReplacements[i].fStart) {
817beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            return NULL;  // the ranges are monotonically increasing and non-overlapping
818beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
819beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
820beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
821beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    return NULL;
822beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com}
823beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
824db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
82575cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org    SkAutoResetOpID aroi(this);
82675cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org    SkASSERT(0 == fCurOffset);
82775cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org
8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef ENABLE_TIME_DRAW
8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoTime  at("SkPicture::draw", 50);
8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
83182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
832ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#ifdef SPEW_CLIP_SKIPPING
833210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org    SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull;
834210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org    int opCount = 0;
835ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#endif
8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
83756c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
838f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    SkAutoMutexAcquire autoMutex(fDrawMutex);
839f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif
840f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com
8415f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com    // kDrawComplete will be the signal that we have reached the end of
8425f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com    // the command stream
8435f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com    static const uint32_t kDrawComplete = SK_MaxU32;
8445f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com
845ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    SkReader32 reader(fOpData->bytes(), fOpData->size());
8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    TextContainer text;
84770512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    const SkTDArray<void*>* activeOps = NULL;
8488515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
849beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // When draw limits are enabled (i.e., 0 != fStart || 0 != fStop) the state
850beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    // tree isn't used to pick and choose the draw operations
851beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    if (0 == fStart && 0 == fStop) {
852beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        if (fUseBBH && NULL != fStateTree && NULL != fBoundingHierarchy) {
853beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            SkRect clipBounds;
854beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            if (canvas.getClipBounds(&clipBounds)) {
855beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkIRect query;
856beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                clipBounds.roundOut(&query);
857beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
858beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                const SkPicture::OperationList& activeOpsList = this->getActiveOps(query);
859beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (activeOpsList.valid()) {
860beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    if (0 == activeOpsList.numOps()) {
861beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                        return;     // nothing to draw
862beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    }
863beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
864beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // Since the opList is valid we know it is our derived class
865beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    activeOps = &((const CachedOperationList&)activeOpsList).fOps;
86670512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org                }
8671c6307e36fd96894bd11727c995f9cf9991a7be1rileya@google.com            }
8688515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com        }
8698515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    }
8708515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
87170512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    SkPictureStateTree::Iterator it = (NULL == activeOps) ?
8728515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com        SkPictureStateTree::Iterator() :
87370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org        fStateTree->getIterator(*activeOps, &canvas);
8748515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
875beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    if (0 != fStart || 0 != fStop) {
876beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        reader.setOffset(fStart);
877beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        uint32_t size;
878beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
879beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        SkASSERT(SAVE_LAYER == op);
880beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        reader.setOffset(fStart+size);
881beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com    }
882beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
8838515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    if (it.isValid()) {
884a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org        uint32_t skipTo = it.nextDraw();
8855f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com        if (kDrawComplete == skipTo) {
8861c6307e36fd96894bd11727c995f9cf9991a7be1rileya@google.com            return;
8871c6307e36fd96894bd11727c995f9cf9991a7be1rileya@google.com        }
8885f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com        reader.setOffset(skipTo);
8898515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    }
8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
891b4c2819671757044857ec477156699163025a353reed@google.com    // Record this, so we can concat w/ it if we encounter a setMatrix()
892b4c2819671757044857ec477156699163025a353reed@google.com    SkMatrix initialMatrix = canvas.getTotalMatrix();
893821650655be1519039ae9a4a4c2e5873c02ba354commit-bot@chromium.org
894821650655be1519039ae9a4a4c2e5873c02ba354commit-bot@chromium.org    SkAutoCanvasRestore acr(&canvas, false);
895b4c2819671757044857ec477156699163025a353reed@google.com
896d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
897d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com    fAbortCurrentPlayback = false;
898d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com#endif
899d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com
9006d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com#ifdef SK_DEVELOPER
9016d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com    int opIndex = -1;
9026d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com#endif
9036d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com
904ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    while (!reader.eof()) {
90574babdfce524f478b9177834fe51d0394e42de6areed@google.com        if (callback && callback->abortDrawing()) {
90674babdfce524f478b9177834fe51d0394e42de6areed@google.com            return;
90774babdfce524f478b9177834fe51d0394e42de6areed@google.com        }
908d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
909d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com        if (fAbortCurrentPlayback) {
910d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com            return;
911d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com        }
912d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com#endif
913beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        if (0 != fStart || 0 != fStop) {
914beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            size_t offset = reader.offset() ;
915beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            if (offset >= fStop) {
916beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                uint32_t size;
917beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
918beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkASSERT(RESTORE == op);
919beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                return;
920beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            }
921beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
922beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
923beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        if (NULL != fReplacements) {
924beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            // Potentially replace a block of operations with a single drawBitmap call
925db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips            SkPictureData::PlaybackReplacements::ReplacementInfo* temp =
926beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                                            fReplacements->lookupByStart(reader.offset());
927beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            if (NULL != temp) {
928beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkASSERT(NULL != temp->fBM);
929beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkASSERT(NULL != temp->fPaint);
930f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                canvas.save();
931f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                canvas.setMatrix(initialMatrix);
932952841bf41a81228c23d16c7204b458abe0d7136robertphillips                SkRect src = SkRect::Make(temp->fSrcRect);
933952841bf41a81228c23d16c7204b458abe0d7136robertphillips                SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
934952841bf41a81228c23d16c7204b458abe0d7136robertphillips                                              temp->fSrcRect.width(),
935952841bf41a81228c23d16c7204b458abe0d7136robertphillips                                              temp->fSrcRect.height());
936952841bf41a81228c23d16c7204b458abe0d7136robertphillips                canvas.drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint);
937f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                canvas.restore();
938beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
939beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                if (it.isValid()) {
940beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // This save is needed since the BBH will automatically issue
941beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // a restore to balanced the saveLayer we're skipping
942beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    canvas.save();
943beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
944beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // At this point we know that the PictureStateTree was aiming
945beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // for some draw op within temp's saveLayer (although potentially
946beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // in a separate saveLayer nested inside it).
947beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // We need to skip all the operations inside temp's range
948b2c82c99f891e4e846e4959c811661bf68fa43d6skia.committer@gmail.com                    // along with all the associated state changes but update
949beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    // the state tree to the first operation outside temp's range.
950beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
951f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                    uint32_t skipTo;
952f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                    do {
953f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                        skipTo = it.nextDraw();
954f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                        if (kDrawComplete == skipTo) {
955f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            break;
956f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                        }
957f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org
958f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                        if (skipTo <= temp->fStop) {
959f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            reader.setOffset(skipTo);
960f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            uint32_t size;
961f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            DrawType op = read_op_and_size(&reader, &size);
962f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            // Since we are relying on the normal SkPictureStateTree
963f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            // playback we need to convert any nested saveLayer calls
964f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            // it may issue into saves (so that all its internal
965f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            // restores will be balanced).
966f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            if (SAVE_LAYER == op) {
967f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                                canvas.save();
968f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                            }
969f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                        }
970f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                    } while (skipTo <= temp->fStop);
971f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org
972f97d65dc256111f1de6bbf3521c7cd3cf3e70f60commit-bot@chromium.org                    if (kDrawComplete == skipTo) {
973beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                        break;
974beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    }
975beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
976beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    reader.setOffset(skipTo);
977beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                } else {
978beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    reader.setOffset(temp->fStop);
979beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    uint32_t size;
980beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
981beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                    SkASSERT(RESTORE == op);
982beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                }
983beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                continue;
984beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com            }
985beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com        }
986d9b0f480be398cb37c447605109c419e8314cf61djsollen@google.com
987210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org#ifdef SPEW_CLIP_SKIPPING
988210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org        opCount++;
989210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org#endif
990210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org
99175cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org        fCurOffset = reader.offset();
9922ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        uint32_t size;
9932ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        DrawType op = read_op_and_size(&reader, &size);
9944b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org        size_t skipTo = 0;
9956d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com        if (NOOP == op) {
996e4ce5b82627d7ef7cab34b808ff88dc208aef7bcrobertphillips@google.com            // NOOPs are to be ignored - do not propagate them any further
99775cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org            skipTo = fCurOffset + size;
9986d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com#ifdef SK_DEVELOPER
9996d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com        } else {
10006d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com            opIndex++;
10016d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com            if (this->preDraw(opIndex, op)) {
100275cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org                skipTo = fCurOffset + size;
10036d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com            }
10046d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com#endif
1005e4ce5b82627d7ef7cab34b808ff88dc208aef7bcrobertphillips@google.com        }
1006e4ce5b82627d7ef7cab34b808ff88dc208aef7bcrobertphillips@google.com
10075f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com        if (0 != skipTo) {
10084b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org            if (it.isValid()) {
10094b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org                // If using a bounding box hierarchy, advance the state tree
10104b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org                // iterator until at or after skipTo
10114b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org                uint32_t adjustedSkipTo;
10124b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org                do {
1013a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org                    adjustedSkipTo = it.nextDraw();
10144b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org                } while (adjustedSkipTo < skipTo);
10154b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org                skipTo = adjustedSkipTo;
10164b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org            }
10175f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com            if (kDrawComplete == skipTo) {
10185f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com                break;
10195f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com            }
10205f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com            reader.setOffset(skipTo);
10215f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com            continue;
10225f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com        }
10234b32bd53c63b245707822ae83e3215863303bf43commit-bot@chromium.org
10242ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com        switch (op) {
10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CLIP_PATH: {
1026ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkPath& path = getPath(reader);
1027ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                uint32_t packed = reader.readInt();
10282ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
102983ab49556ffc83fd3b2c1142db264362d21e6b19reed@google.com                bool doAA = ClipParams_unpackDoAA(packed);
1030ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t offsetToRestore = reader.readInt();
10319fa4d0cca9b27d4ffb510096b37a69d78f88dfc6junov@chromium.org                SkASSERT(!offsetToRestore || \
1032ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    offsetToRestore >= reader.offset());
10338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                canvas.clipPath(path, regionOp, doAA);
10348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                if (canvas.isClipEmpty() && offsetToRestore) {
1035ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#ifdef SPEW_CLIP_SKIPPING
1036ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    skipPath.recordSkip(offsetToRestore - reader.offset());
1037ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#endif
1038ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    reader.setOffset(offsetToRestore);
10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CLIP_REGION: {
1042fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                SkRegion region;
1043fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                this->getRegion(reader, &region);
1044ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                uint32_t packed = reader.readInt();
10452ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
1046ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t offsetToRestore = reader.readInt();
10479fa4d0cca9b27d4ffb510096b37a69d78f88dfc6junov@chromium.org                SkASSERT(!offsetToRestore || \
1048ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    offsetToRestore >= reader.offset());
10498f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                canvas.clipRegion(region, regionOp);
10508f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                if (canvas.isClipEmpty() && offsetToRestore) {
1051ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#ifdef SPEW_CLIP_SKIPPING
1052ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    skipRegion.recordSkip(offsetToRestore - reader.offset());
1053ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#endif
1054ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    reader.setOffset(offsetToRestore);
10558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
10578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CLIP_RECT: {
1058ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkRect& rect = reader.skipT<SkRect>();
1059ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                uint32_t packed = reader.readInt();
10602ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
106183ab49556ffc83fd3b2c1142db264362d21e6b19reed@google.com                bool doAA = ClipParams_unpackDoAA(packed);
1062ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t offsetToRestore = reader.readInt();
10639fa4d0cca9b27d4ffb510096b37a69d78f88dfc6junov@chromium.org                SkASSERT(!offsetToRestore || \
10644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                         offsetToRestore >= reader.offset());
10658f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                canvas.clipRect(rect, regionOp, doAA);
10668f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                if (canvas.isClipEmpty() && offsetToRestore) {
1067ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#ifdef SPEW_CLIP_SKIPPING
1068ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    skipRect.recordSkip(offsetToRestore - reader.offset());
1069ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#endif
1070ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    reader.setOffset(offsetToRestore);
10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
10734ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com            case CLIP_RRECT: {
10744ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                SkRRect rrect;
10754ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                reader.readRRect(&rrect);
10764ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                uint32_t packed = reader.readInt();
10772ca1aaaa442290b8262e1ca3ec64ebe46a191211robertphillips@google.com                SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
10784ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                bool doAA = ClipParams_unpackDoAA(packed);
10794ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                size_t offsetToRestore = reader.readInt();
1080beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com                SkASSERT(!offsetToRestore || offsetToRestore >= reader.offset());
10818f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                canvas.clipRRect(rrect, regionOp, doAA);
10828f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com                if (canvas.isClipEmpty() && offsetToRestore) {
10834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#ifdef SPEW_CLIP_SKIPPING
10844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                    skipRRect.recordSkip(offsetToRestore - reader.offset());
10854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#endif
10864ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                    reader.setOffset(offsetToRestore);
10874ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                }
10884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com            } break;
1089210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org            case PUSH_CULL: {
1090210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                const SkRect& cullRect = reader.skipT<SkRect>();
1091210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                size_t offsetToRestore = reader.readInt();
1092210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                if (offsetToRestore && canvas.quickReject(cullRect)) {
1093210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org#ifdef SPEW_CLIP_SKIPPING
1094210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                    skipCull.recordSkip(offsetToRestore - reader.offset());
1095210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org#endif
1096210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                    reader.setOffset(offsetToRestore);
1097210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                } else {
1098210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                    canvas.pushCull(cullRect);
1099210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                }
1100210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org            } break;
1101210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org            case POP_CULL:
1102210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                canvas.popCull();
1103210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                break;
1104fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org            case CONCAT: {
1105fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                SkMatrix matrix;
1106fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                this->getMatrix(reader, &matrix);
1107fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                canvas.concat(matrix);
11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
1109fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org            }
11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_BITMAP: {
1111d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint* paint = this->getPaint(reader);
1112d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkBitmap& bitmap = this->getBitmap(reader);
1113ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkPoint& loc = reader.skipT<SkPoint>();
1114a5adf5385dc6958bda4dad47f59c1c45bd98c627reed@google.com                canvas.drawBitmap(bitmap, loc.fX, loc.fY, paint);
11158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
11167112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com            case DRAW_BITMAP_RECT_TO_RECT: {
1117d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint* paint = this->getPaint(reader);
1118d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkBitmap& bitmap = this->getBitmap(reader);
11197112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com                const SkRect* src = this->getRectPtr(reader);   // may be null
1120ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkRect& dst = reader.skipT<SkRect>();     // required
1121eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                SkCanvas::DrawBitmapRectFlags flags;
112211e055518a0cbe5329232a55fe2cd177e83836d8robertphillips@google.com                flags = (SkCanvas::DrawBitmapRectFlags) reader.readInt();
1123eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                canvas.drawBitmapRectToRect(bitmap, src, dst, paint, flags);
11248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_BITMAP_MATRIX: {
1126d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint* paint = this->getPaint(reader);
1127d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkBitmap& bitmap = this->getBitmap(reader);
1128fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                SkMatrix matrix;
1129fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                this->getMatrix(reader, &matrix);
1130fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                canvas.drawBitmapMatrix(bitmap, matrix, paint);
11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
1132f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com            case DRAW_BITMAP_NINE: {
1133d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint* paint = this->getPaint(reader);
1134d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkBitmap& bitmap = this->getBitmap(reader);
1135ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkIRect& src = reader.skipT<SkIRect>();
1136ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkRect& dst = reader.skipT<SkRect>();
1137a5adf5385dc6958bda4dad47f59c1c45bd98c627reed@google.com                canvas.drawBitmapNine(bitmap, src, dst, paint);
1138f0b5e1190af9807a027c0adba2f1380663c8e910reed@google.com            } break;
11392a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com            case DRAW_CLEAR:
1140ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                canvas.clear(reader.readInt());
11412a98181f048c11f21f52fbd99f803f5fd6118261reed@google.com                break;
1142cb60844b34766aad4151df5e87c144d4a57e9abereed@android.com            case DRAW_DATA: {
1143ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t length = reader.readInt();
1144ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                canvas.drawData(reader.skip(length), length);
1145cb60844b34766aad4151df5e87c144d4a57e9abereed@android.com                // skip handles padding the read out to a multiple of 4
1146cb60844b34766aad4151df5e87c144d4a57e9abereed@android.com            } break;
1147ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org            case DRAW_DRRECT: {
1148d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1149ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org                SkRRect outer, inner;
1150ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org                reader.readRRect(&outer);
1151ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org                reader.readRRect(&inner);
1152ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org                canvas.drawDRRect(outer, inner, paint);
1153ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org            } break;
11540a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com            case BEGIN_COMMENT_GROUP: {
11550a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com                const char* desc = reader.readString();
11560a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com                canvas.beginCommentGroup(desc);
11570a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com            } break;
11580a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com            case COMMENT: {
11590a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com                const char* kywd = reader.readString();
11600a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com                const char* value = reader.readString();
11610a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com                canvas.addComment(kywd, value);
11620a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com            } break;
11630a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com            case END_COMMENT_GROUP: {
11640a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com                canvas.endCommentGroup();
11650a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com            } break;
11664ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com            case DRAW_OVAL: {
1167d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
11684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                canvas.drawOval(reader.skipT<SkRect>(), paint);
11694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com            } break;
11708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_PAINT:
1171d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                canvas.drawPaint(*this->getPaint(reader));
11728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
11738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_PATH: {
1174d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1175ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                canvas.drawPath(getPath(reader), paint);
11768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_PICTURE:
1178d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                canvas.drawPicture(this->getPicture(reader));
11798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
11808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POINTS: {
1181d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1182ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkCanvas::PointMode mode = (SkCanvas::PointMode)reader.readInt();
1183ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t count = reader.readInt();
1184ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkPoint* pts = (const SkPoint*)reader.skip(sizeof(SkPoint) * count);
11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.drawPoints(mode, count, pts, paint);
11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
11878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POS_TEXT: {
1188d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1189ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                getText(reader, &text);
1190ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t points = reader.readInt();
1191ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint));
11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.drawPosText(text.text(), text.length(), pos, paint);
11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
11949efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com            case DRAW_POS_TEXT_TOP_BOTTOM: {
1195d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1196ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                getText(reader, &text);
1197ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t points = reader.readInt();
1198ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint));
1199ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkScalar top = reader.readScalar();
1200ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkScalar bottom = reader.readScalar();
12013b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com                if (!canvas.quickRejectY(top, bottom)) {
12029efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com                    canvas.drawPosText(text.text(), text.length(), pos, paint);
12039efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com                }
12049efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com            } break;
12058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POS_TEXT_H: {
1206d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1207ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                getText(reader, &text);
1208ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t xCount = reader.readInt();
1209ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkScalar constY = reader.readScalar();
1210ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkScalar* xpos = (const SkScalar*)reader.skip(xCount * sizeof(SkScalar));
12118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.drawPosTextH(text.text(), text.length(), xpos, constY,
12128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    paint);
12138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POS_TEXT_H_TOP_BOTTOM: {
1215d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1216ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                getText(reader, &text);
1217ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                size_t xCount = reader.readInt();
1218ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkScalar* xpos = (const SkScalar*)reader.skip((3 + xCount) * sizeof(SkScalar));
12198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                const SkScalar top = *xpos++;
12208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                const SkScalar bottom = *xpos++;
12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                const SkScalar constY = *xpos++;
12223b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com                if (!canvas.quickRejectY(top, bottom)) {
12238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    canvas.drawPosTextH(text.text(), text.length(), xpos,
12248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                        constY, paint);
12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
12268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_RECT: {
1228d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1229ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                canvas.drawRect(reader.skipT<SkRect>(), paint);
12308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com            case DRAW_RRECT: {
1232d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
12334ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com                SkRRect rrect;
12344faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org                reader.readRRect(&rrect);
12354faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org                canvas.drawRRect(rrect, paint);
12364ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com            } break;
12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_SPRITE: {
1238d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint* paint = this->getPaint(reader);
1239d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkBitmap& bitmap = this->getBitmap(reader);
1240ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                int left = reader.readInt();
1241ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                int top = reader.readInt();
124282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com                canvas.drawSprite(bitmap, left, top, paint);
12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_TEXT: {
1245d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1246d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                this->getText(reader, &text);
1247ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar x = reader.readScalar();
1248ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar y = reader.readScalar();
12498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.drawText(text.text(), text.length(), x, y, paint);
12508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_TEXT_TOP_BOTTOM: {
1252d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1253d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                this->getText(reader, &text);
1254ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkScalar* ptr = (const SkScalar*)reader.skip(4 * sizeof(SkScalar));
12558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                // ptr[0] == x
12568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                // ptr[1] == y
12578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                // ptr[2] == top
12588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                // ptr[3] == bottom
12593b3e895df6f8ee0f33010367c215944cd16a8334reed@google.com                if (!canvas.quickRejectY(ptr[2], ptr[3])) {
12608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    canvas.drawText(text.text(), text.length(), ptr[0], ptr[1],
12618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    paint);
12628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
12638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_TEXT_ON_PATH: {
1265d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1266ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                getText(reader, &text);
1267d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPath& path = this->getPath(reader);
1268fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                SkMatrix matrix;
1269fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                this->getMatrix(reader, &matrix);
1270fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                canvas.drawTextOnPath(text.text(), text.length(), path, &matrix, paint);
12718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_VERTICES: {
127385e143c33c214e54187aa28146aa7666961a0d17reed@google.com                SkAutoTUnref<SkXfermode> xfer;
1274d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint& paint = *this->getPaint(reader);
1275ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                DrawVertexFlags flags = (DrawVertexFlags)reader.readInt();
1276ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader.readInt();
1277ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                int vCount = reader.readInt();
1278ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                const SkPoint* verts = (const SkPoint*)reader.skip(
12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    vCount * sizeof(SkPoint));
12808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                const SkPoint* texs = NULL;
12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                const SkColor* colors = NULL;
12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                const uint16_t* indices = NULL;
12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                int iCount = 0;
12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (flags & DRAW_VERTICES_HAS_TEXS) {
1285ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    texs = (const SkPoint*)reader.skip(
12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    vCount * sizeof(SkPoint));
12878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (flags & DRAW_VERTICES_HAS_COLORS) {
1289ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    colors = (const SkColor*)reader.skip(
12908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    vCount * sizeof(SkColor));
12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                if (flags & DRAW_VERTICES_HAS_INDICES) {
1293ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    iCount = reader.readInt();
1294ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                    indices = (const uint16_t*)reader.skip(
12958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                                    iCount * sizeof(uint16_t));
12968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                }
129785e143c33c214e54187aa28146aa7666961a0d17reed@google.com                if (flags & DRAW_VERTICES_HAS_XFER) {
129885e143c33c214e54187aa28146aa7666961a0d17reed@google.com                    int mode = reader.readInt();
129985e143c33c214e54187aa28146aa7666961a0d17reed@google.com                    if (mode < 0 || mode > SkXfermode::kLastMode) {
130085e143c33c214e54187aa28146aa7666961a0d17reed@google.com                        mode = SkXfermode::kModulate_Mode;
130185e143c33c214e54187aa28146aa7666961a0d17reed@google.com                    }
130285e143c33c214e54187aa28146aa7666961a0d17reed@google.com                    xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
130385e143c33c214e54187aa28146aa7666961a0d17reed@google.com                }
130485e143c33c214e54187aa28146aa7666961a0d17reed@google.com                canvas.drawVertices(vmode, vCount, verts, texs, colors, xfer,
13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                                    indices, iCount, paint);
13068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case RESTORE:
13088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.restore();
13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case ROTATE:
1311ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                canvas.rotate(reader.readScalar());
13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SAVE:
13145f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita                // SKPs with version < 29 also store a SaveFlags param.
13155f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita                if (size > 4) {
13165f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita                    SkASSERT(8 == size);
13175f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita                    reader.readInt();
13185f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita                }
13195f6102d07982043542343ff0a6c67b1319ac9fc7Florin Malita                canvas.save();
13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SAVE_LAYER: {
1322d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkRect* boundsPtr = this->getRectPtr(reader);
1323d7e0fbef5d6c7c63b312a5ea1955a9802ad4302fcommit-bot@chromium.org                const SkPaint* paint = this->getPaint(reader);
1324ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader.readInt());
13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SCALE: {
1327ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar sx = reader.readScalar();
1328ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar sy = reader.readScalar();
13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.scale(sx, sy);
13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
1331b4c2819671757044857ec477156699163025a353reed@google.com            case SET_MATRIX: {
1332b4c2819671757044857ec477156699163025a353reed@google.com                SkMatrix matrix;
1333fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                this->getMatrix(reader, &matrix);
1334fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org                matrix.postConcat(initialMatrix);
1335b4c2819671757044857ec477156699163025a353reed@google.com                canvas.setMatrix(matrix);
1336b4c2819671757044857ec477156699163025a353reed@google.com            } break;
13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SKEW: {
1338ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar sx = reader.readScalar();
1339ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar sy = reader.readScalar();
13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.skew(sx, sy);
13418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case TRANSLATE: {
1343ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar dx = reader.readScalar();
1344ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com                SkScalar dy = reader.readScalar();
13458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                canvas.translate(dx, dy);
13468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
13478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            default:
13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkASSERT(0);
13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
13508515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
13513f7137250c8558dedd1f08ed2e5f61d3665c19cbrobertphillips@google.com#ifdef SK_DEVELOPER
13526d9c92b2f6e5be64dd5dd98e44d672877e4c9fbcrobertphillips@google.com        this->postDraw(opIndex);
13536f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com#endif
13546f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com
13558515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com        if (it.isValid()) {
1356a31eacb22e12a4223740e53ff5a11bd08340106ecommit-bot@chromium.org            uint32_t skipTo = it.nextDraw();
13575f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com            if (kDrawComplete == skipTo) {
13581c6307e36fd96894bd11727c995f9cf9991a7be1rileya@google.com                break;
13591c6307e36fd96894bd11727c995f9cf9991a7be1rileya@google.com            }
13605f97114fd28e03e8c4c1c22c924d383b45cdced1robertphillips@google.com            reader.setOffset(skipTo);
13618515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com        }
13628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
136382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1364ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#ifdef SPEW_CLIP_SKIPPING
1365ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    {
1366210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org        size_t size =  skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipRegion.fSize +
1367210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                skipCull.fSize;
1368210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org        SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d cull:%d\n",
13694ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com             size * 100 / reader.offset(), skipRect.fCount, skipRRect.fCount,
1370210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org                 skipPath.fCount, skipRegion.fCount, skipCull.fCount);
1371210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org        SkDebugf("--- Total ops: %d\n", opCount);
1372ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com    }
1373ae814c809e1c4e02a1876c39065775c8c7d00f96reed@android.com#endif
13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//    this->dumpSize();
13758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
13770bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
13780bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#if SK_SUPPORT_GPU
1379db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
138012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                                    int sampleCount) const {
13810bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    // TODO: the heuristic used here needs to be refined
13820bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    static const int kNumPaintWithPathEffectUsesTol = 1;
13830bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    static const int kNumAAConcavePaths = 5;
13840bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
13850bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    SkASSERT(fContentInfo.numAAHairlineConcavePaths() <= fContentInfo.numAAConcavePaths());
13860bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
138712c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    int numNonDashedPathEffects = fContentInfo.numPaintWithPathEffectUses() -
138812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                  fContentInfo.numFastPathDashEffects();
138912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
139012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    bool suitableForDash = (0 == fContentInfo.numPaintWithPathEffectUses()) ||
139112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                           (numNonDashedPathEffects < kNumPaintWithPathEffectUsesTol
139212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                            && 0 == sampleCount);
139312c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
139412c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    bool ret = suitableForDash &&
1395c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein                    (fContentInfo.numAAConcavePaths() - fContentInfo.numAAHairlineConcavePaths())
13960bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips                    < kNumAAConcavePaths;
13970bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    if (!ret && NULL != reason) {
139812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel        if (!suitableForDash) {
139912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel            if (0 != sampleCount) {
140012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                *reason = "Can't use multisample on dash effect.";
140112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel            } else {
140212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                *reason = "Too many non dashed path effects.";
140312c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel            }
1404c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein        } else if ((fContentInfo.numAAConcavePaths() - fContentInfo.numAAHairlineConcavePaths())
140512c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                    >= kNumAAConcavePaths)
14060bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips            *reason = "Too many anti-aliased concave paths.";
14070bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips        else
14080bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips            *reason = "Unknown reason for GPU unsuitability.";
14090bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    }
14100bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    return ret;
14110bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips}
141212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
1413db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
1414db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                                GrPixelConfig config, SkScalar dpi) const {
141512c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
141612c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    if (context != NULL) {
141712c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel        return this->suitableForGpuRasterization(context, reason,
141812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                                 context->getRecommendedSampleCount(config, dpi));
141912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    } else {
142012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel        return this->suitableForGpuRasterization(NULL, reason);
142112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    }
142212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel}
142312c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
14240bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#endif
14258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
14268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG_SIZE
1428db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::size(size_t* sizePtr) {
14298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int objects = bitmaps(sizePtr);
14308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    objects += paints(sizePtr);
14318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    objects += paths(sizePtr);
14328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    objects += pictures(sizePtr);
14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    objects += regions(sizePtr);
1434ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    *sizePtr = fOpData.size();
143582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com    return objects;
14368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1438db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::bitmaps(size_t* size) {
14398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t result = 0;
14408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < fBitmapCount; index++) {
14418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com     //   const SkBitmap& bitmap = fBitmaps[index];
14428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        result += sizeof(SkBitmap); // bitmap->size();
14438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
14448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *size = result;
14458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fBitmapCount;
14468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1448db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::paints(size_t* size) {
14498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t result = 0;
14508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < fPaintCount; index++) {
14518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    //    const SkPaint& paint = fPaints[index];
14528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        result += sizeof(SkPaint); // paint->size();
14538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
14548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *size = result;
14558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fPaintCount;
14568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1458db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::paths(size_t* size) {
14598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t result = 0;
14608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < fPathCount; index++) {
14618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkPath& path = fPaths[index];
14628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        result += path.flatten(NULL);
14638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
14648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *size = result;
14658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return fPathCount;
14668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
14688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG_DUMP
1470db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpBitmap(const SkBitmap& bitmap) const {
14718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char pBuffer[DUMP_BUFFER_SIZE];
14728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* bufferPtr = pBuffer;
14738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "BitmapData bitmap%p = {", &bitmap);
14758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "{kWidth, %d}, ", bitmap.width());
14778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "{kHeight, %d}, ", bitmap.height());
14798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "{kRowBytes, %d}, ", bitmap.rowBytes());
14818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//        start here;
14828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("%s{0}};\n", pBuffer);
14838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
14848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
14858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid dumpMatrix(const SkMatrix& matrix) const {
14868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkMatrix defaultMatrix;
14878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    defaultMatrix.reset();
14888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char pBuffer[DUMP_BUFFER_SIZE];
14898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* bufferPtr = pBuffer;
14908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "MatrixData matrix%p = {", &matrix);
14928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar scaleX = matrix.getScaleX();
14938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (scaleX != defaultMatrix.getScaleX())
14948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kScaleX, %g}, ", SkScalarToFloat(scaleX));
14968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar scaleY = matrix.getScaleY();
14978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (scaleY != defaultMatrix.getScaleY())
14988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
14998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kScaleY, %g}, ", SkScalarToFloat(scaleY));
15008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar skewX = matrix.getSkewX();
15018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (skewX != defaultMatrix.getSkewX())
15028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kSkewX, %g}, ", SkScalarToFloat(skewX));
15048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar skewY = matrix.getSkewY();
15058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (skewY != defaultMatrix.getSkewY())
15068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kSkewY, %g}, ", SkScalarToFloat(skewY));
15088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar translateX = matrix.getTranslateX();
15098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (translateX != defaultMatrix.getTranslateX())
15108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTranslateX, %g}, ", SkScalarToFloat(translateX));
15128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar translateY = matrix.getTranslateY();
15138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (translateY != defaultMatrix.getTranslateY())
15148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTranslateY, %g}, ", SkScalarToFloat(translateY));
15168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar perspX = matrix.getPerspX();
15178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (perspX != defaultMatrix.getPerspX())
15188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15191915fd09f3b60eb907f5ab155e8379b589e2bae1reed@google.com            "{kPerspX, %g}, ", perspX);
15208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar perspY = matrix.getPerspY();
15218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (perspY != defaultMatrix.getPerspY())
15228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15231915fd09f3b60eb907f5ab155e8379b589e2bae1reed@google.com            "{kPerspY, %g}, ", perspY);
15248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("%s{0}};\n", pBuffer);
15258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
15268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
15278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid dumpPaint(const SkPaint& paint) const {
15288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPaint defaultPaint;
15298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char pBuffer[DUMP_BUFFER_SIZE];
15308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* bufferPtr = pBuffer;
15318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "PaintPointers paintPtrs%p = {", &paint);
15338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkTypeface* typeface = paint.getTypeface();
15348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (typeface != defaultPaint.getTypeface())
15358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTypeface, %p}, ", typeface);
15378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkPathEffect* pathEffect = paint.getPathEffect();
15388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (pathEffect != defaultPaint.getPathEffect())
15398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kPathEffect, %p}, ", pathEffect);
15418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkShader* shader = paint.getShader();
15428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (shader != defaultPaint.getShader())
15438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kShader, %p}, ", shader);
15458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkXfermode* xfermode = paint.getXfermode();
15468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (xfermode != defaultPaint.getXfermode())
15478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kXfermode, %p}, ", xfermode);
15498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkMaskFilter* maskFilter = paint.getMaskFilter();
15508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (maskFilter != defaultPaint.getMaskFilter())
15518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kMaskFilter, %p}, ", maskFilter);
15538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkColorFilter* colorFilter = paint.getColorFilter();
15548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (colorFilter != defaultPaint.getColorFilter())
15558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kColorFilter, %p}, ", colorFilter);
15578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkRasterizer* rasterizer = paint.getRasterizer();
15588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (rasterizer != defaultPaint.getRasterizer())
15598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kRasterizer, %p}, ", rasterizer);
15618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkDrawLooper* drawLooper = paint.getLooper();
15628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (drawLooper != defaultPaint.getLooper())
15638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kDrawLooper, %p}, ", drawLooper);
15658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("%s{0}};\n", pBuffer);
15668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr = pBuffer;
15678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "PaintScalars paintScalars%p = {", &paint);
15698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar textSize = paint.getTextSize();
15708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (textSize != defaultPaint.getTextSize())
15718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTextSize, %g}, ", SkScalarToFloat(textSize));
15738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar textScaleX = paint.getTextScaleX();
15748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (textScaleX != defaultPaint.getTextScaleX())
15758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX));
15778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar textSkewX = paint.getTextSkewX();
15788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (textSkewX != defaultPaint.getTextSkewX())
15798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX));
15818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar strokeWidth = paint.getStrokeWidth();
15828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (strokeWidth != defaultPaint.getStrokeWidth())
15838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth));
15858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkScalar strokeMiter = paint.getStrokeMiter();
15868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (strokeMiter != defaultPaint.getStrokeMiter())
15878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter));
15898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("%s{0}};\n", pBuffer);
15908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr = pBuffer;
15918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "PaintInts = paintInts%p = {", &paint);
15938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned color = paint.getColor();
15948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (color != defaultPaint.getColor())
15958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
15968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kColor, 0x%x}, ", color);
15978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    unsigned flags = paint.getFlags();
15988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (flags != defaultPaint.getFlags())
15998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
16008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kFlags, 0x%x}, ", flags);
16018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int align = paint.getTextAlign();
16028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (align != defaultPaint.getTextAlign())
16038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
16048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kAlign, 0x%x}, ", align);
16058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int strokeCap = paint.getStrokeCap();
16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (strokeCap != defaultPaint.getStrokeCap())
16078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
16088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kStrokeCap, 0x%x}, ", strokeCap);
16098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int strokeJoin = paint.getStrokeJoin();
16108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (strokeJoin != defaultPaint.getStrokeJoin())
16118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
16128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kAlign, 0x%x}, ", strokeJoin);
16138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int style = paint.getStyle();
16148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (style != defaultPaint.getStyle())
16158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
16168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kStyle, 0x%x}, ", style);
16178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int textEncoding = paint.getTextEncoding();
16188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (textEncoding != defaultPaint.getTextEncoding())
16198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
16208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "{kTextEncoding, 0x%x}, ", textEncoding);
16218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("%s{0}};\n", pBuffer);
16228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n",
16248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        &paint, &paint, &paint, &paint);
16258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1627db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpPath(const SkPath& path) const {
16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("path dump unimplemented\n");
16298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1631db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpPicture(const SkPicture& picture) const {
16328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("picture dump unimplemented\n");
16338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1635db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpRegion(const SkRegion& region) const {
16368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("region dump unimplemented\n");
16378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1639db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) {
16408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "k%s, ", DrawTypeToString(drawType));
16428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1644db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpInt(char* bufferPtr, char* buffer, char* name) {
16458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "%s:%d, ", name, getInt());
16478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1649db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpRect(char* bufferPtr, char* buffer, char* name) {
16508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkRect* rect = fReader.skipRect();
16518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
165282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft),
16538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalarToFloat(rect.fTop),
16548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom));
16558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1657db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpPoint(char* bufferPtr, char* buffer, char* name) {
16588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint pt;
16598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    getPoint(&pt);
16608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
166182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX),
16628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalarToFloat(pt.fY));
16638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1665db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) {
16668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* bufferPtr = *bufferPtrPtr;
16678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos();
16688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fReadStream.skip(sizeof(SkPoint) * count);
16698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "count:%d {", count);
16718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int index = 0; index < count; index++)
16728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
167382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX),
16748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScalarToFloat(pts[index].fY));
16758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "} ");
16778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *bufferPtrPtr = bufferPtr;
16788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1680db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) {
16818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "%s:%p, ", name, ptr);
16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1685db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpRectPtr(char* bufferPtr, char* buffer, char* name) {
16868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char result;
16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fReadStream.read(&result, sizeof(result));
16888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (result)
16898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return dumpRect(bufferPtr, buffer, name);
16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    else
16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "%s:NULL, ", name);
16938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1695db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsint SkPictureData::dumpScalar(char* bufferPtr, char* buffer, char* name) {
16968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
16978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        "%s:%d, ", name, getScalar());
16988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
16998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1700db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpText(char** bufferPtrPtr, char* buffer) {
17018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* bufferPtr = *bufferPtrPtr;
17028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int length = getInt();
17038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpDrawType(bufferPtr, buffer);
17048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fReadStream.skipToAlign4();
17058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* text = (char*) fReadStream.getAtPos();
17068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fReadStream.skip(length);
17078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpInt(bufferPtr, buffer, "length");
17088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2;
17098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    length >>= 1;
17108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (limit > length)
17118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        limit = length;
17128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (limit > 0) {
17138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *bufferPtr++ = '"';
17148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int index = 0; index < limit; index++) {
17158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            *bufferPtr++ = *(unsigned short*) text;
17168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            text += sizeof(unsigned short);
17178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
17188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        *bufferPtr++ = '"';
17198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
17208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    *bufferPtrPtr = bufferPtr;
17218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
17228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_DRAWTYPE(drawType) \
17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpDrawType(bufferPtr, buffer, drawType)
17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_INT(name) \
17278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpInt(bufferPtr, buffer, #name)
17288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_RECT_PTR(name) \
17308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpRectPtr(bufferPtr, buffer, #name)
17318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_POINT(name) \
17338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpRect(bufferPtr, buffer, #name)
17348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_RECT(name) \
17368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpRect(bufferPtr, buffer, #name)
17378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_POINT_ARRAY(count) \
17398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    dumpPointArray(&bufferPtr, buffer, count)
17408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_PTR(name, ptr) \
17428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr)
17438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_SCALAR(name) \
17458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr += dumpScalar(bufferPtr, buffer, #name)
17468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
17478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define DUMP_TEXT() \
17488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    dumpText(&bufferPtr, buffer)
17498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1750db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dumpStream() {
17518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDebugf("RecordStream stream = {\n");
17528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    DrawType drawType;
17538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    TextContainer text;
17548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fReadStream.rewind();
17558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char buffer[DUMP_BUFFER_SIZE], * bufferPtr;
17568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    while (fReadStream.read(&drawType, sizeof(drawType))) {
17578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bufferPtr = buffer;
17588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        DUMP_DRAWTYPE(drawType);
17598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        switch (drawType) {
17608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CLIP_PATH: {
17618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPath, &getPath());
17628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(SkRegion::Op);
17638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(offsetToRestore);
17648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
17658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CLIP_REGION: {
17668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(SkRegion::Op);
17678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(offsetToRestore);
17688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            } break;
17698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CLIP_RECT: {
17708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_RECT(rect);
17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(SkRegion::Op);
17728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(offsetToRestore);
17738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
17748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case CONCAT:
17758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
17768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_BITMAP: {
17778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
17788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkBitmap, &getBitmap());
17798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(left);
17808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(top);
17818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
17828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_PAINT:
17838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
17848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
17858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_PATH: {
17868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
17878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPath, &getPath());
17888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
17898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_PICTURE: {
17908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPicture, &getPicture());
17918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
17928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POINTS: {
17938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
17948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                (void)getInt(); // PointMode
17958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                size_t count = getInt();
17968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fReadStream.skipToAlign4();
17978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_POINT_ARRAY(count);
17988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
17998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POS_TEXT: {
18008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_TEXT();
18028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                size_t points = getInt();
18038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fReadStream.skipToAlign4();
18048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_POINT_ARRAY(points);
18058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_POS_TEXT_H: {
18078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_TEXT();
18098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                size_t points = getInt();
18108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                fReadStream.skipToAlign4();
18118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(top);
18128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(bottom);
18138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(constY);
18148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_POINT_ARRAY(points);
18158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_RECT: {
18178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_RECT(rect);
18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_SPRITE: {
18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkBitmap, &getBitmap());
18238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(left);
18248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(top);
18258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_TEXT: {
18278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_TEXT();
18298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(x);
18308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(y);
18318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case DRAW_TEXT_ON_PATH: {
18338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_TEXT();
18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPath, &getPath());
18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case RESTORE:
18388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case ROTATE:
18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(rotate);
18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
18428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SAVE:
18438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(SkCanvas::SaveFlags);
18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                break;
18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SAVE_LAYER: {
18468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_RECT_PTR(layer);
18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_PTR(SkPaint, getPaint());
18488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_INT(SkCanvas::SaveFlags);
18498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SCALE: {
18518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(sx);
18528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(sy);
18538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case SKEW: {
18558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(sx);
18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(sy);
18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            case TRANSLATE: {
18598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(dx);
18608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                DUMP_SCALAR(dy);
18618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                } break;
18628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            default:
18638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkASSERT(0);
18648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
18658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("%s\n", buffer);
18668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
18678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
18688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1869db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::dump() const {
18708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char pBuffer[DUMP_BUFFER_SIZE];
18718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    char* bufferPtr = pBuffer;
18728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int index;
18738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fBitmapCount > 0)
18748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("// bitmaps (%d)\n", fBitmapCount);
18758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fBitmapCount; index++) {
18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkBitmap& bitmap = fBitmaps[index];
18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dumpBitmap(bitmap);
18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
18798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fBitmapCount > 0)
188082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
18818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "Bitmaps bitmaps = {");
18828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fBitmapCount; index++)
188382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
18848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "bitmap%p, ", &fBitmaps[index]);
18858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fBitmapCount > 0)
18868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("%s0};\n", pBuffer);
18878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPaintCount > 0)
18908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("// paints (%d)\n", fPaintCount);
18918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fPaintCount; index++) {
18928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkPaint& paint = fPaints[index];
18938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dumpPaint(paint);
18948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
18958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr = pBuffer;
18968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPaintCount > 0)
189782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "Paints paints = {");
18998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fPaintCount; index++)
190082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
19018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "paint%p, ", &fPaints[index]);
19028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPaintCount > 0)
19038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("%s0};\n", pBuffer);
19048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fPathCount; index++) {
19068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkPath& path = fPaths[index];
19078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dumpPath(path);
19088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
19098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr = pBuffer;
19108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPathCount > 0)
191182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
19128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "Paths paths = {");
19138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fPathCount; index++)
191482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
19158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "path%p, ", &fPaths[index]);
19168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPathCount > 0)
19178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("%s0};\n", pBuffer);
19188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fPictureCount; index++) {
19208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dumpPicture(*fPictureRefs[index]);
19218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
19228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bufferPtr = pBuffer;
19238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPictureCount > 0)
192482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
19258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "Pictures pictures = {");
19268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (index = 0; index < fPictureCount; index++)
192782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
19288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            "picture%p, ", fPictureRefs[index]);
19298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPictureCount > 0)
19308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkDebugf("%s0};\n", pBuffer);
19318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1932db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    const_cast<SkPictureData*>(this)->dumpStream();
19338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
19348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
19358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
1936