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