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 */
795e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <new>
995e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary
1095e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h"
11c3470340b6658dea7baa3ac90d3b716c0afd7051fmalita#include "SkImageGenerator.h"
12db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#include "SkPictureData.h"
138016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkPictureRecord.h"
148016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkReadBuffer.h"
15b7425173f96e93b090787e2386ba5f022b6c2869fmalita#include "SkTextBlob.h"
168016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkTypeface.h"
178016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkWriteBuffer.h"
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#if SK_SUPPORT_GPU
2012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#include "GrContext.h"
2112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#endif
2212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
23f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.comtemplate <typename T> int SafeCount(const T* obj) {
24f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    return obj ? obj->count() : 0;
25f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com}
26f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com
27db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictInfo& info)
28e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(info) {
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->init();
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
32db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::initForPlayback() const {
33e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    // ensure that the paths bounds are pre-computed
34703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    for (int i = 0; i < fPaths.count(); i++) {
35703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein        fPaths[i].updateBoundsCache();
36e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    }
37e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips}
38e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips
39db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictureRecord& record,
404d9ff62fa21326003cf5394cd1d16f4b4633102amtklein                             const SkPictInfo& info)
41e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(info) {
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4370512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    this->init();
440bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
454d9ff62fa21326003cf5394cd1d16f4b4633102amtklein    fOpData = record.opData();
4682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
470bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    fContentInfo.set(record.fContentInfo);
488515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
49703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    fPaints  = record.fPaints;
50c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein
51c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein    fPaths.reset(record.fPaths.count());
52c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein    record.fPaths.foreach([this](const SkPath& path, int n) {
53c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein        // These indices are logically 1-based, but we need to serialize them
54c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein        // 0-based to keep the deserializing SkPictureData::getPath() working.
55c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein        fPaths[n-1] = path;
56c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein    });
57c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
58e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    this->initForPlayback();
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
609b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPictureCount = pictures.count();
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPictureCount > 0) {
63385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        fPictureRefs = new const SkPicture* [fPictureCount];
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = 0; i < fPictureCount; i++) {
656de27127c4d50ef90b5435aefaeef47fa84b819drobertphillips            fPictureRefs[i] = pictures[i];
666de27127c4d50ef90b5435aefaeef47fa84b819drobertphillips            fPictureRefs[i]->ref();
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
69b7425173f96e93b090787e2386ba5f022b6c2869fmalita
7095416f477d2ca264f2fb065455e95778a2289a1dmsarett    const SkTDArray<SkDrawable* >& drawables = record.getDrawableRefs();
7195416f477d2ca264f2fb065455e95778a2289a1dmsarett    fDrawableCount = drawables.count();
7295416f477d2ca264f2fb065455e95778a2289a1dmsarett    if (fDrawableCount > 0) {
7395416f477d2ca264f2fb065455e95778a2289a1dmsarett        fDrawableRefs = new SkDrawable* [fDrawableCount];
7495416f477d2ca264f2fb065455e95778a2289a1dmsarett        for (int i = 0; i < fDrawableCount; i++) {
7595416f477d2ca264f2fb065455e95778a2289a1dmsarett            fDrawableRefs[i] = drawables[i];
7695416f477d2ca264f2fb065455e95778a2289a1dmsarett            fDrawableRefs[i]->ref();
7795416f477d2ca264f2fb065455e95778a2289a1dmsarett        }
7895416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
7995416f477d2ca264f2fb065455e95778a2289a1dmsarett
80b7425173f96e93b090787e2386ba5f022b6c2869fmalita    // templatize to consolidate with similar picture logic?
81b7425173f96e93b090787e2386ba5f022b6c2869fmalita    const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs();
82b7425173f96e93b090787e2386ba5f022b6c2869fmalita    fTextBlobCount = blobs.count();
83b7425173f96e93b090787e2386ba5f022b6c2869fmalita    if (fTextBlobCount > 0) {
84385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        fTextBlobRefs = new const SkTextBlob* [fTextBlobCount];
85b7425173f96e93b090787e2386ba5f022b6c2869fmalita        for (int i = 0; i < fTextBlobCount; ++i) {
86b7425173f96e93b090787e2386ba5f022b6c2869fmalita            fTextBlobRefs[i] = SkRef(blobs[i]);
87b7425173f96e93b090787e2386ba5f022b6c2869fmalita        }
88b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
890c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
9014583e11fd622c686993b741499060a6f3527055Mike Reed    const SkTDArray<const SkVertices*>& verts = record.getVerticesRefs();
9114583e11fd622c686993b741499060a6f3527055Mike Reed    fVerticesCount = verts.count();
9214583e11fd622c686993b741499060a6f3527055Mike Reed    if (fVerticesCount > 0) {
9314583e11fd622c686993b741499060a6f3527055Mike Reed        fVerticesRefs = new const SkVertices* [fVerticesCount];
9414583e11fd622c686993b741499060a6f3527055Mike Reed        for (int i = 0; i < fVerticesCount; ++i) {
9514583e11fd622c686993b741499060a6f3527055Mike Reed            fVerticesRefs[i] = SkRef(verts[i]);
9614583e11fd622c686993b741499060a6f3527055Mike Reed        }
9714583e11fd622c686993b741499060a6f3527055Mike Reed    }
9814583e11fd622c686993b741499060a6f3527055Mike Reed
99871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    const SkTDArray<const SkImage*>& imgs = record.getImageRefs();
100871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    fImageCount = imgs.count();
101871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (fImageCount > 0) {
102385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        fImageRefs = new const SkImage* [fImageCount];
103871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        for (int i = 0; i < fImageCount; ++i) {
104871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            fImageRefs[i] = SkRef(imgs[i]);
105871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
106871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
109db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::init() {
11096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fPictureRefs = nullptr;
111f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    fPictureCount = 0;
11295416f477d2ca264f2fb065455e95778a2289a1dmsarett    fDrawableRefs = nullptr;
11395416f477d2ca264f2fb065455e95778a2289a1dmsarett    fDrawableCount = 0;
11496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fTextBlobRefs = nullptr;
115b7425173f96e93b090787e2386ba5f022b6c2869fmalita    fTextBlobCount = 0;
11614583e11fd622c686993b741499060a6f3527055Mike Reed    fVerticesRefs = nullptr;
11714583e11fd622c686993b741499060a6f3527055Mike Reed    fVerticesCount = 0;
11896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fImageRefs = nullptr;
119871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    fImageCount = 0;
12096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fFactoryPlayback = nullptr;
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
123db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::~SkPictureData() {
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < fPictureCount; i++) {
1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPictureRefs[i]->unref();
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
127385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete[] fPictureRefs;
12882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
12995416f477d2ca264f2fb065455e95778a2289a1dmsarett    for (int i = 0; i < fDrawableCount; i++) {
13095416f477d2ca264f2fb065455e95778a2289a1dmsarett        fDrawableRefs[i]->unref();
13195416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
13295416f477d2ca264f2fb065455e95778a2289a1dmsarett    if (fDrawableCount > 0) {
13395416f477d2ca264f2fb065455e95778a2289a1dmsarett        SkASSERT(fDrawableRefs);
13495416f477d2ca264f2fb065455e95778a2289a1dmsarett        delete[] fDrawableRefs;
13595416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
13695416f477d2ca264f2fb065455e95778a2289a1dmsarett
137b7425173f96e93b090787e2386ba5f022b6c2869fmalita    for (int i = 0; i < fTextBlobCount; i++) {
138b7425173f96e93b090787e2386ba5f022b6c2869fmalita        fTextBlobRefs[i]->unref();
139b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
140385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete[] fTextBlobRefs;
1410c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
14214583e11fd622c686993b741499060a6f3527055Mike Reed    for (int i = 0; i < fVerticesCount; i++) {
14314583e11fd622c686993b741499060a6f3527055Mike Reed        fVerticesRefs[i]->unref();
14414583e11fd622c686993b741499060a6f3527055Mike Reed    }
14514583e11fd622c686993b741499060a6f3527055Mike Reed    delete[] fVerticesRefs;
14614583e11fd622c686993b741499060a6f3527055Mike Reed
147871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    for (int i = 0; i < fImageCount; i++) {
148871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        fImageRefs[i]->unref();
149871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
150385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete[] fImageRefs;
1510c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
152385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete fFactoryPlayback;
1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
155db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::containsBitmaps() const {
156a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    if (fBitmapImageCount > 0 || fImageCount > 0) {
157381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        return true;
158381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    }
159381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    for (int i = 0; i < fPictureCount; ++i) {
160381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        if (fPictureRefs[i]->willPlayBackBitmaps()) {
161381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com            return true;
162381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        }
163381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    }
164381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    return false;
165381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com}
166381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com
1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
172dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.orgstatic size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
173dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    size_t size = 4;  // for 'count'
174dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
175dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    for (int i = 0; i < count; i++) {
176dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        const char* name = SkFlattenable::FactoryToName(array[i]);
17796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == name || 0 == *name) {
178dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += SkWStream::SizeOfPackedUInt(0);
179dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        } else {
180dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size_t len = strlen(name);
181dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += SkWStream::SizeOfPackedUInt(len);
182dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += len;
183dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        }
184dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    }
185dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
186dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    return size;
187dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org}
18882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1896142609b22814283210f79d698182b651a93136crobertphillipsstatic void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
1906142609b22814283210f79d698182b651a93136crobertphillips    buffer.writeUInt(tag);
1916142609b22814283210f79d698182b651a93136crobertphillips    buffer.writeUInt(SkToU32(size));
1926142609b22814283210f79d698182b651a93136crobertphillips}
1936142609b22814283210f79d698182b651a93136crobertphillips
1946142609b22814283210f79d698182b651a93136crobertphillipsstatic void write_tag_size(SkWStream* stream, uint32_t tag, size_t size) {
1956142609b22814283210f79d698182b651a93136crobertphillips    stream->write32(tag);
1966142609b22814283210f79d698182b651a93136crobertphillips    stream->write32(SkToU32(size));
1976142609b22814283210f79d698182b651a93136crobertphillips}
1986142609b22814283210f79d698182b651a93136crobertphillips
199db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
200dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    int count = rec.count();
20182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
204e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    rec.copyToArray(array);
20582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
206dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    size_t size = compute_chunk_size(array, count);
207dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
208dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    // TODO: write_tag_size should really take a size_t
2096142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
21006e975252112eb5ca62ebacd484118a640c19168commit-bot@chromium.org    SkDEBUGCODE(size_t start = stream->bytesWritten());
211dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    stream->write32(count);
212dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const char* name = SkFlattenable::FactoryToName(array[i]);
21596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == name || 0 == *name) {
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->writePackedUInt(0);
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
2182cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org            size_t len = strlen(name);
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->writePackedUInt(len);
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->write(name, len);
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
223dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
22406e975252112eb5ca62ebacd484118a640c19168commit-bot@chromium.org    SkASSERT(size == (stream->bytesWritten() - start));
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
227db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count = rec.count();
22982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2306142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count);
23182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkTypeface*> storage(count);
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkTypeface** array = (SkTypeface**)storage.get();
234e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    rec.copyToArray((SkRefCnt**)array);
23582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        array[i]->serialize(stream);
2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
241db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
242f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    int i, n;
24382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
244703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    if ((n = fPaints.count()) > 0) {
2456142609b22814283210f79d698182b651a93136crobertphillips        write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
246f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com        for (i = 0; i < n; i++) {
247703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein            buffer.writePaint(fPaints[i]);
2486756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        }
2496756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    }
250a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
251703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    if ((n = fPaths.count()) > 0) {
2526142609b22814283210f79d698182b651a93136crobertphillips        write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
25371a236370792416b367a7d2d6b8e471b06b331cdmtklein        buffer.writeInt(n);
25471a236370792416b367a7d2d6b8e471b06b331cdmtklein        for (int i = 0; i < n; i++) {
255703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein            buffer.writePath(fPaths[i]);
25671a236370792416b367a7d2d6b8e471b06b331cdmtklein        }
257e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    }
258b7425173f96e93b090787e2386ba5f022b6c2869fmalita
259b7425173f96e93b090787e2386ba5f022b6c2869fmalita    if (fTextBlobCount > 0) {
260b7425173f96e93b090787e2386ba5f022b6c2869fmalita        write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount);
261b7425173f96e93b090787e2386ba5f022b6c2869fmalita        for (i = 0; i  < fTextBlobCount; ++i) {
262b7425173f96e93b090787e2386ba5f022b6c2869fmalita            fTextBlobRefs[i]->flatten(buffer);
263b7425173f96e93b090787e2386ba5f022b6c2869fmalita        }
264b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
2650c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
26614583e11fd622c686993b741499060a6f3527055Mike Reed    if (fVerticesCount > 0) {
26714583e11fd622c686993b741499060a6f3527055Mike Reed        write_tag_size(buffer, SK_PICT_VERTICES_BUFFER_TAG, fVerticesCount);
26814583e11fd622c686993b741499060a6f3527055Mike Reed        for (i = 0; i  < fVerticesCount; ++i) {
26914583e11fd622c686993b741499060a6f3527055Mike Reed            buffer.writeDataAsByteArray(fVerticesRefs[i]->encode().get());
27014583e11fd622c686993b741499060a6f3527055Mike Reed        }
27114583e11fd622c686993b741499060a6f3527055Mike Reed    }
27214583e11fd622c686993b741499060a6f3527055Mike Reed
273871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (fImageCount > 0) {
274871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount);
275871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        for (i = 0; i  < fImageCount; ++i) {
276871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            buffer.writeImage(fImageRefs[i]);
277871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
278871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
2796756209ee0a0103d395ac908edbdcf5268b920dareed@google.com}
2806756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
281db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::serialize(SkWStream* stream,
2820c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                              SkPixelSerializer* pixelSerializer,
2830c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                              SkRefCntSet* topLevelTypeFaceSet) const {
2840c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // This can happen at pretty much any time, so might as well do it first.
2856142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
286ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    stream->write(fOpData->bytes(), fOpData->size());
28782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2880c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We serialize all typefaces into the typeface section of the top-level picture.
2890c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    SkRefCntSet localTypefaceSet;
2900c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    SkRefCntSet* typefaceSet = topLevelTypeFaceSet ? topLevelTypeFaceSet : &localTypefaceSet;
2910c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
2920c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We delay serializing the bulk of our data until after we've serialized
2930c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // factories and typefaces by first serializing to an in-memory write buffer.
2940c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    SkFactorySet factSet;  // buffer refs factSet, so factSet must come first.
295fad98562d8f9db63839a8d902a301b174320f27fbrianosman    SkBinaryWriteBuffer buffer(SkBinaryWriteBuffer::kCrossProcess_Flag);
2960c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.setFactoryRecorder(&factSet);
2976bd5284415bd983b0628c4941dff5def40018f5abungeman    buffer.setPixelSerializer(sk_ref_sp(pixelSerializer));
2980c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.setTypefaceRecorder(typefaceSet);
2990c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    this->flattenToBuffer(buffer);
3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3010c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // Dummy serialize our sub-pictures for the side effect of filling
3020c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // typefaceSet with typefaces from sub-pictures.
3030c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    struct DevNull: public SkWStream {
3040c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        DevNull() : fBytesWritten(0) {}
3050c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        size_t fBytesWritten;
3060c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        bool write(const void*, size_t size) override { fBytesWritten += size; return true; }
3070c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        size_t bytesWritten() const override { return fBytesWritten; }
3080c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    } devnull;
3090c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    for (int i = 0; i < fPictureCount; i++) {
3100c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        fPictureRefs[i]->serialize(&devnull, pixelSerializer, typefaceSet);
3110c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    }
31234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
3130c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We need to write factories before we write the buffer.
3140c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We need to write typefaces before we write the buffer or any sub-picture.
3150c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    WriteFactories(stream, factSet);
3160c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    if (typefaceSet == &localTypefaceSet) {
3170c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        WriteTypefaces(stream, *typefaceSet);
3180c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    }
31982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
3200c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // Write the buffer.
3210c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
3220c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.writeToStream(stream);
3236756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
3240c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // Write sub-pictures by calling serialize again.
3250c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    if (fPictureCount > 0) {
3260c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
3270c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        for (int i = 0; i < fPictureCount; i++) {
3280c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            fPictureRefs[i]->serialize(stream, pixelSerializer, typefaceSet);
3290c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        }
3306756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    }
331ed38495c7cf5bdeb2843b6f1f090579fbefe497dreed@google.com
3326f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    stream->write32(SK_PICT_EOF_TAG);
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
335db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::flatten(SkWriteBuffer& buffer) const {
3366142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size());
3375e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    buffer.writeByteArray(fOpData->bytes(), fOpData->size());
3385e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
3395e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    if (fPictureCount > 0) {
3406142609b22814283210f79d698182b651a93136crobertphillips        write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
3415e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        for (int i = 0; i < fPictureCount; i++) {
3425e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            fPictureRefs[i]->flatten(buffer);
3435e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
3445e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
3455e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
34695416f477d2ca264f2fb065455e95778a2289a1dmsarett    if (fDrawableCount > 0) {
34795416f477d2ca264f2fb065455e95778a2289a1dmsarett        write_tag_size(buffer, SK_PICT_DRAWABLE_TAG, fDrawableCount);
34895416f477d2ca264f2fb065455e95778a2289a1dmsarett        for (int i = 0; i < fDrawableCount; i++) {
34995416f477d2ca264f2fb065455e95778a2289a1dmsarett            buffer.writeFlattenable(fDrawableRefs[i]);
35095416f477d2ca264f2fb065455e95778a2289a1dmsarett        }
35195416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
35295416f477d2ca264f2fb065455e95778a2289a1dmsarett
3535e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    // Write this picture playback's data into a writebuffer
3545e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    this->flattenToBuffer(buffer);
3556f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    buffer.write32(SK_PICT_EOF_TAG);
3565e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
3575e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
36034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com/**
3618b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *  Return the corresponding SkReadBuffer flags, given a set of
36234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com *  SkPictInfo flags.
36334342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com */
36434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.comstatic uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
36534342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    static const struct {
36634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        uint32_t    fSrc;
36734342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        uint32_t    fDst;
36834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    } gSD[] = {
3698b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kCrossProcess_Flag,   SkReadBuffer::kCrossProcess_Flag },
3708b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kScalarIsFloat_Flag,  SkReadBuffer::kScalarIsFloat_Flag },
3718b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kPtrIs64Bit_Flag,     SkReadBuffer::kPtrIs64Bit_Flag },
37234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    };
373fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
37434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    uint32_t rbMask = 0;
37534342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
37634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        if (pictInfoFlags & gSD[i].fSrc) {
37734342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com            rbMask |= gSD[i].fDst;
37834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        }
37934342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    }
38034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    return rbMask;
38134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com}
38234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
383db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseStreamTag(SkStream* stream,
384ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips                                   uint32_t tag,
385ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips                                   uint32_t size,
386a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                   SkImageDeserializer* factory,
3870c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                                   SkTypefacePlayback* topLevelTFPlayback) {
3886756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    /*
3896756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
3906756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
3916756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  but if they are present, they need to have been seen before the buffer.
3926756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *
3936756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  We assert that if/when we see either of these, that we have not yet seen
3946756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  the buffer tag, because if we have, then its too-late to deal with the
3956756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  factories or typefaces.
3966756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     */
397c4dc831f7be430dc8a7d68fd9eb84bfda8a1c519scroggo@google.com    SkDEBUGCODE(bool haveBuffer = false;)
3986756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
3996756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    switch (tag) {
4009594da111dc1c36c1912eb61207aaa54c17ea550reed        case SK_PICT_READER_TAG:
40196fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkASSERT(nullptr == fOpData);
402fde05114e6c4107b36e1aa571c64d31def40f613reed            fOpData = SkData::MakeFromStream(stream, size);
4039594da111dc1c36c1912eb61207aaa54c17ea550reed            if (!fOpData) {
40412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
40512705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
4069594da111dc1c36c1912eb61207aaa54c17ea550reed            break;
4076f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_FACTORY_TAG: {
4086756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkASSERT(!haveBuffer);
40988fd0fbcccea615f2d2cd61a121ac9e3185adfe4mtklein            size = stream->readU32();
410385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary            fFactoryPlayback = new SkFactoryPlayback(size);
4116756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            for (size_t i = 0; i < size; i++) {
4126756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                SkString str;
41312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                const size_t len = stream->readPackedUInt();
4146756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                str.resize(len);
41512705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                if (stream->read(str.writable_str(), len) != len) {
41612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    return false;
41712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
4186756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
4196756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
4206756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4216f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_TYPEFACE_TAG: {
4226756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkASSERT(!haveBuffer);
423dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
424dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            fTFPlayback.setCount(count);
425dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; i++) {
42613b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                sk_sp<SkTypeface> tf(SkTypeface::MakeDeserialize(stream));
42773c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                if (!tf.get()) {    // failed to deserialize
42873c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    // fTFPlayback asserts it never has a null, so we plop in
42973c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    // the default here.
43013b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                    tf = SkTypeface::MakeDefault();
43173c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                }
43213b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                fTFPlayback.set(i, tf.get());
4336756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
4346756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4356f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PICTURE_TAG: {
4365479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita            fPictureCount = 0;
437385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary            fPictureRefs = new const SkPicture* [size];
4385479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita            for (uint32_t i = 0; i < size; i++) {
439a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                fPictureRefs[i] = SkPicture::MakeFromStream(stream, factory, topLevelTFPlayback).release();
4405479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita                if (!fPictureRefs[i]) {
4415479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita                    return false;
44212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
4435479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita                fPictureCount++;
4446756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
4456756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4466f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_BUFFER_SIZE_TAG: {
4476756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkAutoMalloc storage(size);
44812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            if (stream->read(storage.get(), size) != size) {
44912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
45012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
451fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
452ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            /* Should we use SkValidatingReadBuffer instead? */
4538b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org            SkReadBuffer buffer(storage.get(), size);
4540943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org            buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
455b3f543d955637c6e10d7109554b5a46c6e25291aMike Reed            buffer.setVersion(fInfo.getVersion());
45634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
45746895be9189f9d43f10fe5d57be6ca1eb1a795d2caryclark            if (!fFactoryPlayback) {
45846895be9189f9d43f10fe5d57be6ca1eb1a795d2caryclark                return false;
45946895be9189f9d43f10fe5d57be6ca1eb1a795d2caryclark            }
4606756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            fFactoryPlayback->setupBuffer(buffer);
461a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed            buffer.setImageDeserializer(factory);
462fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4630c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            if (fTFPlayback.count() > 0) {
4640c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                // .skp files <= v43 have typefaces serialized with each sub picture.
4650c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                fTFPlayback.setupBuffer(buffer);
4660c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            } else {
4670c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                // Newer .skp files serialize all typefaces with the top picture.
4680c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                topLevelTFPlayback->setupBuffer(buffer);
4690c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            }
4700c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
471ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            while (!buffer.eof() && buffer.isValid()) {
472c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                tag = buffer.readUInt();
473c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                size = buffer.readUInt();
474e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips                if (!this->parseBufferTag(buffer, tag, size)) {
47512705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    return false;
47612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
4776756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
478ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            if (!buffer.isValid()) {
479ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed                return false;
480ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            }
481c4dc831f7be430dc8a7d68fd9eb84bfda8a1c519scroggo@google.com            SkDEBUGCODE(haveBuffer = true;)
4826756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
48412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;    // success
4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
487871872f3f247f6b699617f6d9ef50ef5da6fbe74reedstatic const SkImage* create_image_from_buffer(SkReadBuffer& buffer) {
488a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    return buffer.readImage().release();
489a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed}
49014583e11fd622c686993b741499060a6f3527055Mike Reedstatic const SkVertices* create_vertices_from_buffer(SkReadBuffer& buffer) {
49114583e11fd622c686993b741499060a6f3527055Mike Reed    auto data = buffer.readByteArrayAsData();
49214583e11fd622c686993b741499060a6f3527055Mike Reed    return data ? SkVertices::Decode(data->data(), data->size()).release() : nullptr;
49314583e11fd622c686993b741499060a6f3527055Mike Reed}
494a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed
495a9ca05ca5e604b9ee18e9cce19b059085ca0e22creedstatic const SkImage* create_bitmap_image_from_buffer(SkReadBuffer& buffer) {
496a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    return buffer.readBitmapAsImage().release();
497871872f3f247f6b699617f6d9ef50ef5da6fbe74reed}
498871872f3f247f6b699617f6d9ef50ef5da6fbe74reed
499871872f3f247f6b699617f6d9ef50ef5da6fbe74reed// Need a shallow wrapper to return const SkPicture* to match the other factories,
500871872f3f247f6b699617f6d9ef50ef5da6fbe74reed// as SkPicture::CreateFromBuffer() returns SkPicture*
501871872f3f247f6b699617f6d9ef50ef5da6fbe74reedstatic const SkPicture* create_picture_from_buffer(SkReadBuffer& buffer) {
502ca2622ba051829fed5f30facd74c5b41cd4b931creed    return SkPicture::MakeFromBuffer(buffer).release();
503871872f3f247f6b699617f6d9ef50ef5da6fbe74reed}
504871872f3f247f6b699617f6d9ef50ef5da6fbe74reed
50595416f477d2ca264f2fb065455e95778a2289a1dmsarettstatic const SkDrawable* create_drawable_from_buffer(SkReadBuffer& buffer) {
50695416f477d2ca264f2fb065455e95778a2289a1dmsarett    return (SkDrawable*) buffer.readFlattenable(SkFlattenable::kSkDrawable_Type);
50795416f477d2ca264f2fb065455e95778a2289a1dmsarett}
50895416f477d2ca264f2fb065455e95778a2289a1dmsarett
509871872f3f247f6b699617f6d9ef50ef5da6fbe74reedtemplate <typename T>
510871872f3f247f6b699617f6d9ef50ef5da6fbe74reedbool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount,
511871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                           const T*** array, int* outCount, const T* (*factory)(SkReadBuffer&)) {
51296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (!buffer.validate((0 == *outCount) && (nullptr == *array))) {
513871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        return false;
514871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
515871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (0 == inCount) {
516871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        return true;
517871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
51820dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips    if (!buffer.validate(SkTFitsIn<int>(inCount))) {
51920dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips        return false;
52020dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips    }
52120dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips
522871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    *outCount = inCount;
523385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    *array = new const T* [*outCount];
524871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    bool success = true;
525871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    int i = 0;
526871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    for (; i < *outCount; i++) {
527871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        (*array)[i] = factory(buffer);
52896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == (*array)[i]) {
529871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            success = false;
530871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            break;
531871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
532871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
533871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (!success) {
534871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        // Delete all of the blobs that were already created (up to but excluding i):
535871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        for (int j = 0; j < i; j++) {
536871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            (*array)[j]->unref();
537871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
538871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        // Delete the array
539385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        delete[] * array;
54096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        *array = nullptr;
541871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        *outCount = 0;
542871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        return false;
543871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
544871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    return true;
545871872f3f247f6b699617f6d9ef50ef5da6fbe74reed}
546871872f3f247f6b699617f6d9ef50ef5da6fbe74reed
547871872f3f247f6b699617f6d9ef50ef5da6fbe74reedbool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) {
5486756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    switch (tag) {
549a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed        case SK_PICT_BITMAP_BUFFER_TAG:
550a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed            if (!new_array_from_buffer(buffer, size, &fBitmapImageRefs, &fBitmapImageCount,
551a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                       create_bitmap_image_from_buffer)) {
552a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                return false;
5536756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
554a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed            break;
5556f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PAINT_BUFFER_TAG: {
55620dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips            if (!buffer.validate(SkTFitsIn<int>(size))) {
55720dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips                return false;
55820dd31fed5f63d7d97719ce7f53755fa94086cfdRobert Phillips            }
559dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
560703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein            fPaints.reset(count);
561dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; ++i) {
562703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein                buffer.readPaint(&fPaints[i]);
5636756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
5646756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5656f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PATH_BUFFER_TAG:
566e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips            if (size > 0) {
56771a236370792416b367a7d2d6b8e471b06b331cdmtklein                const int count = buffer.readInt();
568703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein                fPaths.reset(count);
56971a236370792416b367a7d2d6b8e471b06b331cdmtklein                for (int i = 0; i < count; i++) {
570703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein                    buffer.readPath(&fPaths[i]);
57171a236370792416b367a7d2d6b8e471b06b331cdmtklein                }
57271a236370792416b367a7d2d6b8e471b06b331cdmtklein            } break;
573871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        case SK_PICT_TEXTBLOB_BUFFER_TAG:
574871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            if (!new_array_from_buffer(buffer, size, &fTextBlobRefs, &fTextBlobCount,
575871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                                       SkTextBlob::CreateFromBuffer)) {
576b7425173f96e93b090787e2386ba5f022b6c2869fmalita                return false;
577b7425173f96e93b090787e2386ba5f022b6c2869fmalita            }
578871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            break;
57914583e11fd622c686993b741499060a6f3527055Mike Reed        case SK_PICT_VERTICES_BUFFER_TAG:
58014583e11fd622c686993b741499060a6f3527055Mike Reed            if (!new_array_from_buffer(buffer, size, &fVerticesRefs, &fVerticesCount,
58114583e11fd622c686993b741499060a6f3527055Mike Reed                                       create_vertices_from_buffer)) {
58214583e11fd622c686993b741499060a6f3527055Mike Reed                return false;
58314583e11fd622c686993b741499060a6f3527055Mike Reed            }
58414583e11fd622c686993b741499060a6f3527055Mike Reed            break;
585871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        case SK_PICT_IMAGE_BUFFER_TAG:
586871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            if (!new_array_from_buffer(buffer, size, &fImageRefs, &fImageCount,
587871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                                       create_image_from_buffer)) {
588b7425173f96e93b090787e2386ba5f022b6c2869fmalita                return false;
589b7425173f96e93b090787e2386ba5f022b6c2869fmalita            }
590871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            break;
5919e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        case SK_PICT_READER_TAG: {
592fde05114e6c4107b36e1aa571c64d31def40f613reed            auto data(SkData::MakeUninitialized(size));
5939594da111dc1c36c1912eb61207aaa54c17ea550reed            if (!buffer.readByteArray(data->writable_data(), size) ||
59496fcdcc219d2a0d3579719b84b28bede76efba64halcanary                !buffer.validate(nullptr == fOpData)) {
5959e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
5969e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
59796fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkASSERT(nullptr == fOpData);
598fde05114e6c4107b36e1aa571c64d31def40f613reed            fOpData = std::move(data);
5999e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        } break;
600871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        case SK_PICT_PICTURE_TAG:
601871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            if (!new_array_from_buffer(buffer, size, &fPictureRefs, &fPictureCount,
602871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                                       create_picture_from_buffer)) {
6039e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
60495416f477d2ca264f2fb065455e95778a2289a1dmsarett            }
60595416f477d2ca264f2fb065455e95778a2289a1dmsarett            break;
60695416f477d2ca264f2fb065455e95778a2289a1dmsarett        case SK_PICT_DRAWABLE_TAG:
60795416f477d2ca264f2fb065455e95778a2289a1dmsarett            if (!new_array_from_buffer(buffer, size, (const SkDrawable***)&fDrawableRefs,
60895416f477d2ca264f2fb065455e95778a2289a1dmsarett                                       &fDrawableCount, create_drawable_from_buffer)) {
60995416f477d2ca264f2fb065455e95778a2289a1dmsarett                return false;
6109e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
611c21003507110363e43c672313d041cf37c83fad7reed            break;
61212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        default:
61312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            // The tag was invalid.
61412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            return false;
6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
61612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;    // success
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
619db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
620db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               const SkPictInfo& info,
621a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                               SkImageDeserializer* factory,
6220c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                                               SkTypefacePlayback* topLevelTFPlayback) {
623145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<SkPictureData> data(new SkPictureData(info));
6240c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    if (!topLevelTFPlayback) {
6250c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        topLevelTFPlayback = &data->fTFPlayback;
6260c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    }
62712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com
628a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    if (!data->parseStream(stream, factory, topLevelTFPlayback)) {
62996fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
63012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    }
63118300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein    return data.release();
63212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com}
6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
634db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer,
635db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               const SkPictInfo& info) {
636145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<SkPictureData> data(new SkPictureData(info));
637b3f543d955637c6e10d7109554b5a46c6e25291aMike Reed    buffer.setVersion(info.getVersion());
6385e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
639db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    if (!data->parseBuffer(buffer)) {
64096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
6415e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
64218300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein    return data.release();
6435e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
6445e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
645db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseStream(SkStream* stream,
646a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                SkImageDeserializer* factory,
6470c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                                SkTypefacePlayback* topLevelTFPlayback) {
6486756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    for (;;) {
6496756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        uint32_t tag = stream->readU32();
6506f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
6516756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            break;
652ed38495c7cf5bdeb2843b6f1f090579fbefe497dreed@google.com        }
6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6546756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        uint32_t size = stream->readU32();
655a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed        if (!this->parseStreamTag(stream, tag, size, factory, topLevelTFPlayback)) {
65612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            return false; // we're invalid
65712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        }
6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
65912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;
6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
662db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseBuffer(SkReadBuffer& buffer) {
6635e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    for (;;) {
6645e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        uint32_t tag = buffer.readUInt();
6656f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
6665e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            break;
6675e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
6685e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
6695e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        uint32_t size = buffer.readUInt();
670e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        if (!this->parseBufferTag(buffer, tag, size)) {
6715e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            return false; // we're invalid
6725e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
6735e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
6745e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    return true;
6755e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
6765e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6800bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#if SK_SUPPORT_GPU
681db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
682afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw                                                int sampleCount) const {
683afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw    return fContentInfo.suitableForGpuRasterization(context, reason, sampleCount);
6840bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips}
68512c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
686db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
687db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                                GrPixelConfig config, SkScalar dpi) const {
68812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
68996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (context != nullptr) {
69012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel        return this->suitableForGpuRasterization(context, reason,
69112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                                 context->getRecommendedSampleCount(config, dpi));
69212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    } else {
69396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return this->suitableForGpuRasterization(nullptr, reason);
69412c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    }
69512c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel}
69612c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
697c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillipsbool SkPictureData::suitableForLayerOptimization() const {
698c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips    return fContentInfo.numLayers() > 0;
699c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips}
7000bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#endif
7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
702