SkPictureData.cpp revision b3f543d955637c6e10d7109554b5a46c6e25291a
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>
8c3470340b6658dea7baa3ac90d3b716c0afd7051fmalita#include "SkImageGenerator.h"
9db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#include "SkPictureData.h"
108016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkPictureRecord.h"
118016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkReadBuffer.h"
12b7425173f96e93b090787e2386ba5f022b6c2869fmalita#include "SkTextBlob.h"
138016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkTypeface.h"
148016f79cfc6b4e9b34049ecbccdb65ee222d537acommit-bot@chromium.org#include "SkWriteBuffer.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1612c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#if SK_SUPPORT_GPU
1712c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#include "GrContext.h"
1812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel#endif
1912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
20f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.comtemplate <typename T> int SafeCount(const T* obj) {
21f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    return obj ? obj->count() : 0;
22f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com}
23f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com
24db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictInfo& info)
25e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(info) {
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    this->init();
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
29db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::initForPlayback() const {
30e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    // ensure that the paths bounds are pre-computed
31703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    for (int i = 0; i < fPaths.count(); i++) {
32703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein        fPaths[i].updateBoundsCache();
33e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    }
34e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips}
35e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips
36db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::SkPictureData(const SkPictureRecord& record,
374d9ff62fa21326003cf5394cd1d16f4b4633102amtklein                             const SkPictInfo& info)
38e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    : fInfo(info) {
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4070512af9dd7a6b2c0a3f5971fd6e103dc577a400commit-bot@chromium.org    this->init();
410bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
424d9ff62fa21326003cf5394cd1d16f4b4633102amtklein    fOpData = record.opData();
4382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
440bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    fContentInfo.set(record.fContentInfo);
458515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
46703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    fPaints  = record.fPaints;
47c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein
48c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein    fPaths.reset(record.fPaths.count());
49c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein    record.fPaths.foreach([this](const SkPath& path, int n) {
50c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein        // These indices are logically 1-based, but we need to serialize them
51c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein        // 0-based to keep the deserializing SkPictureData::getPath() working.
52c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein        fPaths[n-1] = path;
53c2e2977014c4581aed5da435fc2b7eba38e777b6mtklein    });
54c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
55e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    this->initForPlayback();
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
579b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    const SkTDArray<const SkPicture* >& pictures = record.getPictureRefs();
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fPictureCount = pictures.count();
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (fPictureCount > 0) {
60385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        fPictureRefs = new const SkPicture* [fPictureCount];
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        for (int i = 0; i < fPictureCount; i++) {
626de27127c4d50ef90b5435aefaeef47fa84b819drobertphillips            fPictureRefs[i] = pictures[i];
636de27127c4d50ef90b5435aefaeef47fa84b819drobertphillips            fPictureRefs[i]->ref();
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
66b7425173f96e93b090787e2386ba5f022b6c2869fmalita
6795416f477d2ca264f2fb065455e95778a2289a1dmsarett    const SkTDArray<SkDrawable* >& drawables = record.getDrawableRefs();
6895416f477d2ca264f2fb065455e95778a2289a1dmsarett    fDrawableCount = drawables.count();
6995416f477d2ca264f2fb065455e95778a2289a1dmsarett    if (fDrawableCount > 0) {
7095416f477d2ca264f2fb065455e95778a2289a1dmsarett        fDrawableRefs = new SkDrawable* [fDrawableCount];
7195416f477d2ca264f2fb065455e95778a2289a1dmsarett        for (int i = 0; i < fDrawableCount; i++) {
7295416f477d2ca264f2fb065455e95778a2289a1dmsarett            fDrawableRefs[i] = drawables[i];
7395416f477d2ca264f2fb065455e95778a2289a1dmsarett            fDrawableRefs[i]->ref();
7495416f477d2ca264f2fb065455e95778a2289a1dmsarett        }
7595416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
7695416f477d2ca264f2fb065455e95778a2289a1dmsarett
77b7425173f96e93b090787e2386ba5f022b6c2869fmalita    // templatize to consolidate with similar picture logic?
78b7425173f96e93b090787e2386ba5f022b6c2869fmalita    const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs();
79b7425173f96e93b090787e2386ba5f022b6c2869fmalita    fTextBlobCount = blobs.count();
80b7425173f96e93b090787e2386ba5f022b6c2869fmalita    if (fTextBlobCount > 0) {
81385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        fTextBlobRefs = new const SkTextBlob* [fTextBlobCount];
82b7425173f96e93b090787e2386ba5f022b6c2869fmalita        for (int i = 0; i < fTextBlobCount; ++i) {
83b7425173f96e93b090787e2386ba5f022b6c2869fmalita            fTextBlobRefs[i] = SkRef(blobs[i]);
84b7425173f96e93b090787e2386ba5f022b6c2869fmalita        }
85b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
860c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
87871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    const SkTDArray<const SkImage*>& imgs = record.getImageRefs();
88871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    fImageCount = imgs.count();
89871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (fImageCount > 0) {
90385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        fImageRefs = new const SkImage* [fImageCount];
91871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        for (int i = 0; i < fImageCount; ++i) {
92871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            fImageRefs[i] = SkRef(imgs[i]);
93871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
94871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
97db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::init() {
9896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fPictureRefs = nullptr;
99f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    fPictureCount = 0;
10095416f477d2ca264f2fb065455e95778a2289a1dmsarett    fDrawableRefs = nullptr;
10195416f477d2ca264f2fb065455e95778a2289a1dmsarett    fDrawableCount = 0;
10296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fTextBlobRefs = nullptr;
103b7425173f96e93b090787e2386ba5f022b6c2869fmalita    fTextBlobCount = 0;
10496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fImageRefs = nullptr;
105871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    fImageCount = 0;
10696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fFactoryPlayback = nullptr;
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
109db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData::~SkPictureData() {
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < fPictureCount; i++) {
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPictureRefs[i]->unref();
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
113385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete[] fPictureRefs;
11482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
11595416f477d2ca264f2fb065455e95778a2289a1dmsarett    for (int i = 0; i < fDrawableCount; i++) {
11695416f477d2ca264f2fb065455e95778a2289a1dmsarett        fDrawableRefs[i]->unref();
11795416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
11895416f477d2ca264f2fb065455e95778a2289a1dmsarett    if (fDrawableCount > 0) {
11995416f477d2ca264f2fb065455e95778a2289a1dmsarett        SkASSERT(fDrawableRefs);
12095416f477d2ca264f2fb065455e95778a2289a1dmsarett        delete[] fDrawableRefs;
12195416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
12295416f477d2ca264f2fb065455e95778a2289a1dmsarett
123b7425173f96e93b090787e2386ba5f022b6c2869fmalita    for (int i = 0; i < fTextBlobCount; i++) {
124b7425173f96e93b090787e2386ba5f022b6c2869fmalita        fTextBlobRefs[i]->unref();
125b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
126385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete[] fTextBlobRefs;
1270c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
128871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    for (int i = 0; i < fImageCount; i++) {
129871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        fImageRefs[i]->unref();
130871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
131385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete[] fImageRefs;
1320c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
133385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete fFactoryPlayback;
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
136db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::containsBitmaps() const {
137a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    if (fBitmapImageCount > 0 || fImageCount > 0) {
138381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        return true;
139381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    }
140381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    for (int i = 0; i < fPictureCount; ++i) {
141381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        if (fPictureRefs[i]->willPlayBackBitmaps()) {
142381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com            return true;
143381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com        }
144381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    }
145381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    return false;
146381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com}
147381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h"
1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
153dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.orgstatic size_t compute_chunk_size(SkFlattenable::Factory* array, int count) {
154dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    size_t size = 4;  // for 'count'
155dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
156dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    for (int i = 0; i < count; i++) {
157dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        const char* name = SkFlattenable::FactoryToName(array[i]);
15896fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == name || 0 == *name) {
159dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += SkWStream::SizeOfPackedUInt(0);
160dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        } else {
161dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size_t len = strlen(name);
162dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += SkWStream::SizeOfPackedUInt(len);
163dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org            size += len;
164dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org        }
165dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    }
166dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
167dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    return size;
168dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org}
16982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1706142609b22814283210f79d698182b651a93136crobertphillipsstatic void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, size_t size) {
1716142609b22814283210f79d698182b651a93136crobertphillips    buffer.writeUInt(tag);
1726142609b22814283210f79d698182b651a93136crobertphillips    buffer.writeUInt(SkToU32(size));
1736142609b22814283210f79d698182b651a93136crobertphillips}
1746142609b22814283210f79d698182b651a93136crobertphillips
1756142609b22814283210f79d698182b651a93136crobertphillipsstatic void write_tag_size(SkWStream* stream, uint32_t tag, size_t size) {
1766142609b22814283210f79d698182b651a93136crobertphillips    stream->write32(tag);
1776142609b22814283210f79d698182b651a93136crobertphillips    stream->write32(SkToU32(size));
1786142609b22814283210f79d698182b651a93136crobertphillips}
1796142609b22814283210f79d698182b651a93136crobertphillips
180db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) {
181dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    int count = rec.count();
18282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
185e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    rec.copyToArray(array);
18682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
187dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    size_t size = compute_chunk_size(array, count);
188dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
189dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    // TODO: write_tag_size should really take a size_t
1906142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size);
19106e975252112eb5ca62ebacd484118a640c19168commit-bot@chromium.org    SkDEBUGCODE(size_t start = stream->bytesWritten());
192dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org    stream->write32(count);
193dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const char* name = SkFlattenable::FactoryToName(array[i]);
19696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == name || 0 == *name) {
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->writePackedUInt(0);
1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        } else {
1992cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org            size_t len = strlen(name);
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->writePackedUInt(len);
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            stream->write(name, len);
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
204dcb8e54ffdc9194744c0ec839969102bd0f582c6commit-bot@chromium.org
20506e975252112eb5ca62ebacd484118a640c19168commit-bot@chromium.org    SkASSERT(size == (stream->bytesWritten() - start));
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
208db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) {
2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int count = rec.count();
21082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2116142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count);
21282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkAutoSTMalloc<16, SkTypeface*> storage(count);
2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkTypeface** array = (SkTypeface**)storage.get();
215e9e08cc7b29f97ee9e823e68c3daf0f55c84b21amike@reedtribe.org    rec.copyToArray((SkRefCnt**)array);
21682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    for (int i = 0; i < count; i++) {
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        array[i]->serialize(stream);
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
222db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
223f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    int i, n;
22482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
225703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    if ((n = fPaints.count()) > 0) {
2266142609b22814283210f79d698182b651a93136crobertphillips        write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n);
227f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com        for (i = 0; i < n; i++) {
228703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein            buffer.writePaint(fPaints[i]);
2296756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        }
2306756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    }
231a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com
232703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein    if ((n = fPaths.count()) > 0) {
2336142609b22814283210f79d698182b651a93136crobertphillips        write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
23471a236370792416b367a7d2d6b8e471b06b331cdmtklein        buffer.writeInt(n);
23571a236370792416b367a7d2d6b8e471b06b331cdmtklein        for (int i = 0; i < n; i++) {
236703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein            buffer.writePath(fPaths[i]);
23771a236370792416b367a7d2d6b8e471b06b331cdmtklein        }
238e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    }
239b7425173f96e93b090787e2386ba5f022b6c2869fmalita
240b7425173f96e93b090787e2386ba5f022b6c2869fmalita    if (fTextBlobCount > 0) {
241b7425173f96e93b090787e2386ba5f022b6c2869fmalita        write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount);
242b7425173f96e93b090787e2386ba5f022b6c2869fmalita        for (i = 0; i  < fTextBlobCount; ++i) {
243b7425173f96e93b090787e2386ba5f022b6c2869fmalita            fTextBlobRefs[i]->flatten(buffer);
244b7425173f96e93b090787e2386ba5f022b6c2869fmalita        }
245b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
2460c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
247871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (fImageCount > 0) {
248871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount);
249871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        for (i = 0; i  < fImageCount; ++i) {
250871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            buffer.writeImage(fImageRefs[i]);
251871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
252871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
2536756209ee0a0103d395ac908edbdcf5268b920dareed@google.com}
2546756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
255db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::serialize(SkWStream* stream,
2560c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                              SkPixelSerializer* pixelSerializer,
2570c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                              SkRefCntSet* topLevelTypeFaceSet) const {
2580c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // This can happen at pretty much any time, so might as well do it first.
2596142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
260ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    stream->write(fOpData->bytes(), fOpData->size());
26182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2620c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We serialize all typefaces into the typeface section of the top-level picture.
2630c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    SkRefCntSet localTypefaceSet;
2640c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    SkRefCntSet* typefaceSet = topLevelTypeFaceSet ? topLevelTypeFaceSet : &localTypefaceSet;
2650c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
2660c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We delay serializing the bulk of our data until after we've serialized
2670c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // factories and typefaces by first serializing to an in-memory write buffer.
2680c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    SkFactorySet factSet;  // buffer refs factSet, so factSet must come first.
269fad98562d8f9db63839a8d902a301b174320f27fbrianosman    SkBinaryWriteBuffer buffer(SkBinaryWriteBuffer::kCrossProcess_Flag);
2700c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.setFactoryRecorder(&factSet);
2710c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.setPixelSerializer(pixelSerializer);
2720c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.setTypefaceRecorder(typefaceSet);
2730c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    this->flattenToBuffer(buffer);
2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2750c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // Dummy serialize our sub-pictures for the side effect of filling
2760c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // typefaceSet with typefaces from sub-pictures.
2770c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    struct DevNull: public SkWStream {
2780c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        DevNull() : fBytesWritten(0) {}
2790c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        size_t fBytesWritten;
2800c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        bool write(const void*, size_t size) override { fBytesWritten += size; return true; }
2810c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        size_t bytesWritten() const override { return fBytesWritten; }
2820c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    } devnull;
2830c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    for (int i = 0; i < fPictureCount; i++) {
2840c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        fPictureRefs[i]->serialize(&devnull, pixelSerializer, typefaceSet);
2850c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    }
28634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
2870c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We need to write factories before we write the buffer.
2880c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // We need to write typefaces before we write the buffer or any sub-picture.
2890c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    WriteFactories(stream, factSet);
2900c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    if (typefaceSet == &localTypefaceSet) {
2910c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        WriteTypefaces(stream, *typefaceSet);
2920c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    }
29382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com
2940c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // Write the buffer.
2950c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten());
2960c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    buffer.writeToStream(stream);
2976756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
2980c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    // Write sub-pictures by calling serialize again.
2990c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    if (fPictureCount > 0) {
3000c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
3010c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        for (int i = 0; i < fPictureCount; i++) {
3020c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            fPictureRefs[i]->serialize(stream, pixelSerializer, typefaceSet);
3030c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        }
3046756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    }
305ed38495c7cf5bdeb2843b6f1f090579fbefe497dreed@google.com
3066f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    stream->write32(SK_PICT_EOF_TAG);
3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
309db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsvoid SkPictureData::flatten(SkWriteBuffer& buffer) const {
3106142609b22814283210f79d698182b651a93136crobertphillips    write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size());
3115e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    buffer.writeByteArray(fOpData->bytes(), fOpData->size());
3125e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
3135e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    if (fPictureCount > 0) {
3146142609b22814283210f79d698182b651a93136crobertphillips        write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount);
3155e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        for (int i = 0; i < fPictureCount; i++) {
3165e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            fPictureRefs[i]->flatten(buffer);
3175e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
3185e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
3195e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
32095416f477d2ca264f2fb065455e95778a2289a1dmsarett    if (fDrawableCount > 0) {
32195416f477d2ca264f2fb065455e95778a2289a1dmsarett        write_tag_size(buffer, SK_PICT_DRAWABLE_TAG, fDrawableCount);
32295416f477d2ca264f2fb065455e95778a2289a1dmsarett        for (int i = 0; i < fDrawableCount; i++) {
32395416f477d2ca264f2fb065455e95778a2289a1dmsarett            buffer.writeFlattenable(fDrawableRefs[i]);
32495416f477d2ca264f2fb065455e95778a2289a1dmsarett        }
32595416f477d2ca264f2fb065455e95778a2289a1dmsarett    }
32695416f477d2ca264f2fb065455e95778a2289a1dmsarett
3275e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    // Write this picture playback's data into a writebuffer
3285e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    this->flattenToBuffer(buffer);
3296f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org    buffer.write32(SK_PICT_EOF_TAG);
3305e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
3315e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
33434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com/**
3358b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *  Return the corresponding SkReadBuffer flags, given a set of
33634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com *  SkPictInfo flags.
33734342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com */
33834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.comstatic uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
33934342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    static const struct {
34034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        uint32_t    fSrc;
34134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        uint32_t    fDst;
34234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    } gSD[] = {
3438b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kCrossProcess_Flag,   SkReadBuffer::kCrossProcess_Flag },
3448b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kScalarIsFloat_Flag,  SkReadBuffer::kScalarIsFloat_Flag },
3458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org        { SkPictInfo::kPtrIs64Bit_Flag,     SkReadBuffer::kPtrIs64Bit_Flag },
34634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    };
347fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
34834342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    uint32_t rbMask = 0;
34934342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
35034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        if (pictInfoFlags & gSD[i].fSrc) {
35134342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com            rbMask |= gSD[i].fDst;
35234342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com        }
35334342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    }
35434342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com    return rbMask;
35534342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com}
35634342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
357db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseStreamTag(SkStream* stream,
358ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips                                   uint32_t tag,
359ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips                                   uint32_t size,
360a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                   SkImageDeserializer* factory,
3610c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                                   SkTypefacePlayback* topLevelTFPlayback) {
3626756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    /*
3636756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
3646756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
3656756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  but if they are present, they need to have been seen before the buffer.
3666756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *
3676756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  We assert that if/when we see either of these, that we have not yet seen
3686756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  the buffer tag, because if we have, then its too-late to deal with the
3696756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     *  factories or typefaces.
3706756209ee0a0103d395ac908edbdcf5268b920dareed@google.com     */
371c4dc831f7be430dc8a7d68fd9eb84bfda8a1c519scroggo@google.com    SkDEBUGCODE(bool haveBuffer = false;)
3726756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
3736756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    switch (tag) {
3749594da111dc1c36c1912eb61207aaa54c17ea550reed        case SK_PICT_READER_TAG:
37596fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkASSERT(nullptr == fOpData);
376fde05114e6c4107b36e1aa571c64d31def40f613reed            fOpData = SkData::MakeFromStream(stream, size);
3779594da111dc1c36c1912eb61207aaa54c17ea550reed            if (!fOpData) {
37812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
37912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
3809594da111dc1c36c1912eb61207aaa54c17ea550reed            break;
3816f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_FACTORY_TAG: {
3826756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkASSERT(!haveBuffer);
38388fd0fbcccea615f2d2cd61a121ac9e3185adfe4mtklein            size = stream->readU32();
384385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary            fFactoryPlayback = new SkFactoryPlayback(size);
3856756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            for (size_t i = 0; i < size; i++) {
3866756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                SkString str;
38712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                const size_t len = stream->readPackedUInt();
3886756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                str.resize(len);
38912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                if (stream->read(str.writable_str(), len) != len) {
39012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    return false;
39112705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
3926756209ee0a0103d395ac908edbdcf5268b920dareed@google.com                fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
3936756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
3946756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
3956f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_TYPEFACE_TAG: {
3966756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkASSERT(!haveBuffer);
397dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
398dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            fTFPlayback.setCount(count);
399dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; i++) {
40013b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                sk_sp<SkTypeface> tf(SkTypeface::MakeDeserialize(stream));
40173c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                if (!tf.get()) {    // failed to deserialize
40273c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    // fTFPlayback asserts it never has a null, so we plop in
40373c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                    // the default here.
40413b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                    tf = SkTypeface::MakeDefault();
40573c0abc2affdd5703f66c777e1cb3199179f3a09reed@google.com                }
40613b9c95295f4c5732e34574789e721a6bc08f7b4bungeman                fTFPlayback.set(i, tf.get());
4076756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
4086756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4096f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PICTURE_TAG: {
4105479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita            fPictureCount = 0;
411385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary            fPictureRefs = new const SkPicture* [size];
4125479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita            for (uint32_t i = 0; i < size; i++) {
413a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                fPictureRefs[i] = SkPicture::MakeFromStream(stream, factory, topLevelTFPlayback).release();
4145479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita                if (!fPictureRefs[i]) {
4155479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita                    return false;
41612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
4175479d3b5690c274bb53c78333c7c4d41cd5f9137fmalita                fPictureCount++;
4186756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
4196756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4206f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_BUFFER_SIZE_TAG: {
4216756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            SkAutoMalloc storage(size);
42212705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            if (stream->read(storage.get(), size) != size) {
42312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                return false;
42412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            }
425fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
426ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            /* Should we use SkValidatingReadBuffer instead? */
4278b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org            SkReadBuffer buffer(storage.get(), size);
4280943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org            buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags));
429b3f543d955637c6e10d7109554b5a46c6e25291aMike Reed            buffer.setVersion(fInfo.getVersion());
43034342f6f5127122ecc32166dcffa7f3d2a45c387reed@google.com
43146895be9189f9d43f10fe5d57be6ca1eb1a795d2caryclark            if (!fFactoryPlayback) {
43246895be9189f9d43f10fe5d57be6ca1eb1a795d2caryclark                return false;
43346895be9189f9d43f10fe5d57be6ca1eb1a795d2caryclark            }
4346756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            fFactoryPlayback->setupBuffer(buffer);
435a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed            buffer.setImageDeserializer(factory);
436fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4370c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            if (fTFPlayback.count() > 0) {
4380c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                // .skp files <= v43 have typefaces serialized with each sub picture.
4390c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                fTFPlayback.setupBuffer(buffer);
4400c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            } else {
4410c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                // Newer .skp files serialize all typefaces with the top picture.
4420c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                topLevelTFPlayback->setupBuffer(buffer);
4430c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein            }
4440c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein
445ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            while (!buffer.eof() && buffer.isValid()) {
446c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                tag = buffer.readUInt();
447c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com                size = buffer.readUInt();
448e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips                if (!this->parseBufferTag(buffer, tag, size)) {
44912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                    return false;
45012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com                }
4516756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
452ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            if (!buffer.isValid()) {
453ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed                return false;
454ac6a2f964ee9821df6a4a8f3c46796322a4c37b8reed            }
455c4dc831f7be430dc8a7d68fd9eb84bfda8a1c519scroggo@google.com            SkDEBUGCODE(haveBuffer = true;)
4566756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
45812705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;    // success
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
461871872f3f247f6b699617f6d9ef50ef5da6fbe74reedstatic const SkImage* create_image_from_buffer(SkReadBuffer& buffer) {
462a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    return buffer.readImage().release();
463a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed}
464a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed
465a9ca05ca5e604b9ee18e9cce19b059085ca0e22creedstatic const SkImage* create_bitmap_image_from_buffer(SkReadBuffer& buffer) {
466a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    return buffer.readBitmapAsImage().release();
467871872f3f247f6b699617f6d9ef50ef5da6fbe74reed}
468871872f3f247f6b699617f6d9ef50ef5da6fbe74reed
469871872f3f247f6b699617f6d9ef50ef5da6fbe74reed// Need a shallow wrapper to return const SkPicture* to match the other factories,
470871872f3f247f6b699617f6d9ef50ef5da6fbe74reed// as SkPicture::CreateFromBuffer() returns SkPicture*
471871872f3f247f6b699617f6d9ef50ef5da6fbe74reedstatic const SkPicture* create_picture_from_buffer(SkReadBuffer& buffer) {
472ca2622ba051829fed5f30facd74c5b41cd4b931creed    return SkPicture::MakeFromBuffer(buffer).release();
473871872f3f247f6b699617f6d9ef50ef5da6fbe74reed}
474871872f3f247f6b699617f6d9ef50ef5da6fbe74reed
47595416f477d2ca264f2fb065455e95778a2289a1dmsarettstatic const SkDrawable* create_drawable_from_buffer(SkReadBuffer& buffer) {
47695416f477d2ca264f2fb065455e95778a2289a1dmsarett    return (SkDrawable*) buffer.readFlattenable(SkFlattenable::kSkDrawable_Type);
47795416f477d2ca264f2fb065455e95778a2289a1dmsarett}
47895416f477d2ca264f2fb065455e95778a2289a1dmsarett
479871872f3f247f6b699617f6d9ef50ef5da6fbe74reedtemplate <typename T>
480871872f3f247f6b699617f6d9ef50ef5da6fbe74reedbool new_array_from_buffer(SkReadBuffer& buffer, uint32_t inCount,
481871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                           const T*** array, int* outCount, const T* (*factory)(SkReadBuffer&)) {
48296fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (!buffer.validate((0 == *outCount) && (nullptr == *array))) {
483871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        return false;
484871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
485871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (0 == inCount) {
486871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        return true;
487871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
488871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    *outCount = inCount;
489385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    *array = new const T* [*outCount];
490871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    bool success = true;
491871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    int i = 0;
492871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    for (; i < *outCount; i++) {
493871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        (*array)[i] = factory(buffer);
49496fcdcc219d2a0d3579719b84b28bede76efba64halcanary        if (nullptr == (*array)[i]) {
495871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            success = false;
496871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            break;
497871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
498871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
499871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    if (!success) {
500871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        // Delete all of the blobs that were already created (up to but excluding i):
501871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        for (int j = 0; j < i; j++) {
502871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            (*array)[j]->unref();
503871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        }
504871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        // Delete the array
505385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        delete[] * array;
50696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        *array = nullptr;
507871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        *outCount = 0;
508871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        return false;
509871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    }
510871872f3f247f6b699617f6d9ef50ef5da6fbe74reed    return true;
511871872f3f247f6b699617f6d9ef50ef5da6fbe74reed}
512871872f3f247f6b699617f6d9ef50ef5da6fbe74reed
513871872f3f247f6b699617f6d9ef50ef5da6fbe74reedbool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t size) {
5146756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    switch (tag) {
515a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed        case SK_PICT_BITMAP_BUFFER_TAG:
516a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed            if (!new_array_from_buffer(buffer, size, &fBitmapImageRefs, &fBitmapImageCount,
517a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                       create_bitmap_image_from_buffer)) {
518a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                return false;
5196756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
520a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed            break;
5216f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PAINT_BUFFER_TAG: {
522dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            const int count = SkToInt(size);
523703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein            fPaints.reset(count);
524dcecb168968ca136c7fb9e8b444bec56f19af70ccommit-bot@chromium.org            for (int i = 0; i < count; ++i) {
525703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein                buffer.readPaint(&fPaints[i]);
5266756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            }
5276756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        } break;
5286f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        case SK_PICT_PATH_BUFFER_TAG:
529e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips            if (size > 0) {
53071a236370792416b367a7d2d6b8e471b06b331cdmtklein                const int count = buffer.readInt();
531703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein                fPaths.reset(count);
53271a236370792416b367a7d2d6b8e471b06b331cdmtklein                for (int i = 0; i < count; i++) {
533703d3c7093f1fb8a40a46d465d9dd5ae60a456d5mtklein                    buffer.readPath(&fPaths[i]);
53471a236370792416b367a7d2d6b8e471b06b331cdmtklein                }
53571a236370792416b367a7d2d6b8e471b06b331cdmtklein            } break;
536871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        case SK_PICT_TEXTBLOB_BUFFER_TAG:
537871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            if (!new_array_from_buffer(buffer, size, &fTextBlobRefs, &fTextBlobCount,
538871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                                       SkTextBlob::CreateFromBuffer)) {
539b7425173f96e93b090787e2386ba5f022b6c2869fmalita                return false;
540b7425173f96e93b090787e2386ba5f022b6c2869fmalita            }
541871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            break;
542871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        case SK_PICT_IMAGE_BUFFER_TAG:
543871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            if (!new_array_from_buffer(buffer, size, &fImageRefs, &fImageCount,
544871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                                       create_image_from_buffer)) {
545b7425173f96e93b090787e2386ba5f022b6c2869fmalita                return false;
546b7425173f96e93b090787e2386ba5f022b6c2869fmalita            }
547871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            break;
5489e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        case SK_PICT_READER_TAG: {
549fde05114e6c4107b36e1aa571c64d31def40f613reed            auto data(SkData::MakeUninitialized(size));
5509594da111dc1c36c1912eb61207aaa54c17ea550reed            if (!buffer.readByteArray(data->writable_data(), size) ||
55196fcdcc219d2a0d3579719b84b28bede76efba64halcanary                !buffer.validate(nullptr == fOpData)) {
5529e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
5539e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
55496fcdcc219d2a0d3579719b84b28bede76efba64halcanary            SkASSERT(nullptr == fOpData);
555fde05114e6c4107b36e1aa571c64d31def40f613reed            fOpData = std::move(data);
5569e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org        } break;
557871872f3f247f6b699617f6d9ef50ef5da6fbe74reed        case SK_PICT_PICTURE_TAG:
558871872f3f247f6b699617f6d9ef50ef5da6fbe74reed            if (!new_array_from_buffer(buffer, size, &fPictureRefs, &fPictureCount,
559871872f3f247f6b699617f6d9ef50ef5da6fbe74reed                                       create_picture_from_buffer)) {
5609e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org                return false;
56195416f477d2ca264f2fb065455e95778a2289a1dmsarett            }
56295416f477d2ca264f2fb065455e95778a2289a1dmsarett            break;
56395416f477d2ca264f2fb065455e95778a2289a1dmsarett        case SK_PICT_DRAWABLE_TAG:
56495416f477d2ca264f2fb065455e95778a2289a1dmsarett            if (!new_array_from_buffer(buffer, size, (const SkDrawable***)&fDrawableRefs,
56595416f477d2ca264f2fb065455e95778a2289a1dmsarett                                       &fDrawableCount, create_drawable_from_buffer)) {
56695416f477d2ca264f2fb065455e95778a2289a1dmsarett                return false;
5679e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org            }
568c21003507110363e43c672313d041cf37c83fad7reed            break;
56912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        default:
57012705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            // The tag was invalid.
57112705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            return false;
5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
57312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;    // success
5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
576db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
577db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               const SkPictInfo& info,
578a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                               SkImageDeserializer* factory,
5790c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                                               SkTypefacePlayback* topLevelTFPlayback) {
580385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    SkAutoTDelete<SkPictureData> data(new SkPictureData(info));
5810c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    if (!topLevelTFPlayback) {
5820c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein        topLevelTFPlayback = &data->fTFPlayback;
5830c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein    }
58412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com
585a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed    if (!data->parseStream(stream, factory, topLevelTFPlayback)) {
58696fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
58712705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    }
58818300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein    return data.release();
58912705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com}
5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
591db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsSkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer,
592db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                               const SkPictInfo& info) {
593385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    SkAutoTDelete<SkPictureData> data(new SkPictureData(info));
594b3f543d955637c6e10d7109554b5a46c6e25291aMike Reed    buffer.setVersion(info.getVersion());
5955e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
596db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    if (!data->parseBuffer(buffer)) {
59796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
5985e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
59918300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein    return data.release();
6005e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
6015e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
602db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseStream(SkStream* stream,
603a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed                                SkImageDeserializer* factory,
6040c263fa9f80b9a20b6f6161a2e9a263c2c586a9bmtklein                                SkTypefacePlayback* topLevelTFPlayback) {
6056756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    for (;;) {
6066756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        uint32_t tag = stream->readU32();
6076f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
6086756209ee0a0103d395ac908edbdcf5268b920dareed@google.com            break;
609ed38495c7cf5bdeb2843b6f1f090579fbefe497dreed@google.com        }
6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6116756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        uint32_t size = stream->readU32();
612a9ca05ca5e604b9ee18e9cce19b059085ca0e22creed        if (!this->parseStreamTag(stream, tag, size, factory, topLevelTFPlayback)) {
61312705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com            return false; // we're invalid
61412705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com        }
6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
61612705329d0807863d4d80cac0f02e543c26f24a1scroggo@google.com    return true;
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
619db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::parseBuffer(SkReadBuffer& buffer) {
6205e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    for (;;) {
6215e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        uint32_t tag = buffer.readUInt();
6226f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org        if (SK_PICT_EOF_TAG == tag) {
6235e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            break;
6245e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
6255e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
6265e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        uint32_t size = buffer.readUInt();
627e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        if (!this->parseBufferTag(buffer, tag, size)) {
6285e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org            return false; // we're invalid
6295e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org        }
6305e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    }
6315e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    return true;
6325e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org}
6335e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org
6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6370bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#if SK_SUPPORT_GPU
638db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
639afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw                                                int sampleCount) const {
640afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw    return fContentInfo.suitableForGpuRasterization(context, reason, sampleCount);
6410bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips}
64212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
643db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsbool SkPictureData::suitableForGpuRasterization(GrContext* context, const char **reason,
644db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips                                                GrPixelConfig config, SkScalar dpi) const {
64512c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
64696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (context != nullptr) {
64712c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel        return this->suitableForGpuRasterization(context, reason,
64812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                                 context->getRecommendedSampleCount(config, dpi));
64912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    } else {
65096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return this->suitableForGpuRasterization(nullptr, reason);
65112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    }
65212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel}
65312c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
654c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillipsbool SkPictureData::suitableForLayerOptimization() const {
655c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips    return fContentInfo.numLayers() > 0;
656c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips}
6570bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#endif
6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////
659