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 */
7beb1af2f34b5c538fc08d849b132355160b4c93frobertphillips@google.com
8db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#ifndef SkPictureData_DEFINED
9db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips#define SkPictureData_DEFINED
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmap.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathHeap.h"
13e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips#include "SkPicture.h"
14afdada2eabdef47a59e08c884b2beb1af3f31aa5hendrikw#include "SkPictureContentInfo.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPictureFlat.h"
166142609b22814283210f79d698182b651a93136crobertphillips#include "SkPictureStateTree.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
18e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillipsclass SkData;
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPictureRecord;
20e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillipsclass SkReader32;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkStream;
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWStream;
238515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.comclass SkBBoxHierarchy;
24e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillipsclass SkMatrix;
25e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillipsclass SkPaint;
26e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillipsclass SkPath;
278515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.comclass SkPictureStateTree;
28e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillipsclass SkReadBuffer;
29b7425173f96e93b090787e2386ba5f022b6c2869fmalitaclass SkTextBlob;
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
316756209ee0a0103d395ac908edbdcf5268b920dareed@google.comstruct SkPictInfo {
326756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    enum Flags {
336756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        kCrossProcess_Flag      = 1 << 0,
346756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        kScalarIsFloat_Flag     = 1 << 1,
356756209ee0a0103d395ac908edbdcf5268b920dareed@google.com        kPtrIs64Bit_Flag        = 1 << 2,
366756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    };
37fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
389e5f85e89d03a850d435fc951e74e9861a0c1bddcommit-bot@chromium.org    char        fMagic[8];
396756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    uint32_t    fVersion;
40a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkRect      fCullRect;
416756209ee0a0103d395ac908edbdcf5268b920dareed@google.com    uint32_t    fFlags;
426756209ee0a0103d395ac908edbdcf5268b920dareed@google.com};
436756209ee0a0103d395ac908edbdcf5268b920dareed@google.com
446f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
456f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
466f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
476f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
486f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
496f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// This tag specifies the size of the ReadBuffer, needed for the following tags
506f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
516f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// these are all inside the ARRAYS tag
52b7425173f96e93b090787e2386ba5f022b6c2869fmalita#define SK_PICT_BITMAP_BUFFER_TAG   SkSetFourByteTag('b', 't', 'm', 'p')
53b7425173f96e93b090787e2386ba5f022b6c2869fmalita#define SK_PICT_PAINT_BUFFER_TAG    SkSetFourByteTag('p', 'n', 't', ' ')
54b7425173f96e93b090787e2386ba5f022b6c2869fmalita#define SK_PICT_PATH_BUFFER_TAG     SkSetFourByteTag('p', 't', 'h', ' ')
55b7425173f96e93b090787e2386ba5f022b6c2869fmalita#define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
566f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
576f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org// Always write this guy last (with no length field afterwards)
586f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org#define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
596f4fb0f1296422a44d5d0dac155d82595dc5ebeccommit-bot@chromium.org
60d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
61c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com/**
62c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com * Container for data that is needed to deep copy a SkPicture. The container
63c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com * enables the data to be generated once and reused for subsequent copies.
64c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com */
65c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.comstruct SkPictCopyInfo {
66cfaeec446d06058cacef068b09f58ae2c78338faRobert Phillips    SkPictCopyInfo() : controller(1024) {}
67c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
68c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    SkChunkFlatController controller;
69c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    SkTDArray<SkFlatData*> paintData;
70c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com};
71d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#endif
72c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
73db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillipsclass SkPictureData {
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
75d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
76ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips    SkPictureData(const SkPictureData& src, SkPictCopyInfo* deepCopyInfo = NULL);
77d3e474e20c6f0f24ddb6b2643e92975d60190daamtklein#endif
78db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    SkPictureData(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps);
79db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    static SkPictureData* CreateFromStream(SkStream*,
80ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips                                           const SkPictInfo&,
81ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips                                           SkPicture::InstallPixelRefProc);
82ce4dd3de38cd7c29bf5b9d8a8efb55c08ec9be47robertphillips    static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
84db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    virtual ~SkPictureData();
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
86533eb782edaa0b6fece6166d3001edf72ec39f11mtklein    const SkPicture::OperationList* getActiveOps(const SkRect& queryRect) const;
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8832ef131f5279da0850f865dece4935aeddddb40ascroggo@google.com    void serialize(SkWStream*, SkPicture::EncodeBitmap) const;
895e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org    void flatten(SkWriteBuffer&) const;
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
91381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com    bool containsBitmaps() const;
92381010e5501a8d681f8f059486da74f4924f81e5tomhudson@google.com
93750ae26745d261183001a78d24251f6392e96b27ajuma    bool hasText() const { return fContentInfo.hasText(); }
94750ae26745d261183001a78d24251f6392e96b27ajuma
955a246bb48708cfdbf5b63f8df7e2b09b3704cae4mtklein    int opCount() const { return fContentInfo.numOperations(); }
965a246bb48708cfdbf5b63f8df7e2b09b3704cae4mtklein
971ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips    const SkData* opData() const { return fOpData; }
981ad00e4b245d464c16ba78bdaa377281f29972cdrobertphillips
996f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.comprotected:
100db539905bb3af7bd05839a7d2558e97d5cb51ca2robertphillips    explicit SkPictureData(const SkPictInfo& info);
1010943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org
102e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
103e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    bool parseBuffer(SkReadBuffer& buffer);
1046f6dfb4e8c0e71ff75c63b27c1a3ca71d1e36bbbrobertphillips@google.com
1056142609b22814283210f79d698182b651a93136crobertphillipspublic:
1063afef1f75f710b8f183113cdc5188416f7d01f28robertphillips    const SkBitmap& getBitmap(SkReader32* reader) const {
1073afef1f75f710b8f183113cdc5188416f7d01f28robertphillips        const int index = reader->readInt();
1084b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com        if (SkBitmapHeap::INVALID_SLOT == index) {
109826b41525b5d4e67c7777b41da1435f921a47cdescroggo@google.com#ifdef SK_DEBUG
1104b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com            SkDebugf("An invalid bitmap was recorded!\n");
111826b41525b5d4e67c7777b41da1435f921a47cdescroggo@google.com#endif
1124b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com            return fBadBitmap;
1134b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com        }
11421830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com        return (*fBitmaps)[index];
1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1173afef1f75f710b8f183113cdc5188416f7d01f28robertphillips    const SkPath& getPath(SkReader32* reader) const {
1183afef1f75f710b8f183113cdc5188416f7d01f28robertphillips        int index = reader->readInt() - 1;
119e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips        return (*fPathHeap.get())[index];
1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1223afef1f75f710b8f183113cdc5188416f7d01f28robertphillips    const SkPicture* getPicture(SkReader32* reader) const {
1233afef1f75f710b8f183113cdc5188416f7d01f28robertphillips        int index = reader->readInt();
1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkASSERT(index > 0 && index <= fPictureCount);
1259b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips        return fPictureRefs[index - 1];
1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
12774b461961607fa57a150a9282c410ef0cab38764vandebo@chromium.org
1283afef1f75f710b8f183113cdc5188416f7d01f28robertphillips    const SkPaint* getPaint(SkReader32* reader) const {
1293afef1f75f710b8f183113cdc5188416f7d01f28robertphillips        int index = reader->readInt();
1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        if (index == 0) {
1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            return NULL;
1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        }
133f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com        return &(*fPaints)[index - 1];
1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
136b7425173f96e93b090787e2386ba5f022b6c2869fmalita    const SkTextBlob* getTextBlob(SkReader32* reader) const {
137b7425173f96e93b090787e2386ba5f022b6c2869fmalita        int index = reader->readInt();
138b7425173f96e93b090787e2386ba5f022b6c2869fmalita        SkASSERT(index > 0 && index <= fTextBlobCount);
139b7425173f96e93b090787e2386ba5f022b6c2869fmalita        return fTextBlobRefs[index - 1];
140b7425173f96e93b090787e2386ba5f022b6c2869fmalita    }
141b7425173f96e93b090787e2386ba5f022b6c2869fmalita
1425a246bb48708cfdbf5b63f8df7e2b09b3704cae4mtklein    void initIterator(SkPictureStateTree::Iterator* iter,
1436142609b22814283210f79d698182b651a93136crobertphillips                      const SkTDArray<void*>& draws,
1446142609b22814283210f79d698182b651a93136crobertphillips                      SkCanvas* canvas) const {
14549f085dddff10473b6ebf832a974288300224e60bsalomon        if (fStateTree) {
1466142609b22814283210f79d698182b651a93136crobertphillips            fStateTree->initIterator(iter, draws, canvas);
1476142609b22814283210f79d698182b651a93136crobertphillips        }
1486142609b22814283210f79d698182b651a93136crobertphillips    }
1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1500bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#if SK_SUPPORT_GPU
15112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    /**
15212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel     * sampleCount is the number of samples-per-pixel or zero if non-MSAA.
15312c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel     * It is defaulted to be zero.
15412c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel     */
15512c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    bool suitableForGpuRasterization(GrContext* context, const char **reason,
15612c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                     int sampleCount = 0) const;
15712c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel
15812c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    /**
15912c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel     * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount
16012c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel     * and then calls the above version of suitableForGpuRasterization
16112c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel     */
16212c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel    bool suitableForGpuRasterization(GrContext* context, const char **reason,
16312c2198535759ee9aae91ec385e8e31e5dbc12d7egdaniel                                     GrPixelConfig config, SkScalar dpi) const;
164c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips
165c019ec412ba2704bc6e2cdfd321ea06787ba415drobertphillips    bool suitableForLayerOptimization() const;
1660bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips#endif
1670bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
1686142609b22814283210f79d698182b651a93136crobertphillipsprivate:
169e50737332d67ca7c88ee304e48ee21fa3e3f84b1robertphillips    friend class SkPicture; // needed in SkPicture::clone (rm when it is removed)
170e50737332d67ca7c88ee304e48ee21fa3e3f84b1robertphillips
1716142609b22814283210f79d698182b651a93136crobertphillips    void init();
1726142609b22814283210f79d698182b651a93136crobertphillips
1736142609b22814283210f79d698182b651a93136crobertphillips    // these help us with reading/writing
174e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc);
175e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
1768b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org    void flattenToBuffer(SkWriteBuffer&) const;
177fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1784b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com    // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
1794b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com    // bitmap allows playback to draw nothing and move on.
1804b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com    SkBitmap fBadBitmap;
1814b90b1122c93e6600ea352f4ccf1dfc54c8bb146scroggo@google.com
182c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com    SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
183c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com
184f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    SkTRefArray<SkBitmap>* fBitmaps;
185f4cc18726b52a76ba18c07a6490851c4a5e38835reed@google.com    SkTRefArray<SkPaint>* fPaints;
186fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
187ddf98a88340a7e453eef4e3c236c82a5766a5f01reed@google.com    SkData* fOpData;    // opcodes and parameters
1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
189e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    SkAutoTUnref<const SkPathHeap> fPathHeap;  // reference counted
190e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips
1919b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    const SkPicture** fPictureRefs;
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int fPictureCount;
193b7425173f96e93b090787e2386ba5f022b6c2869fmalita    const SkTextBlob** fTextBlobRefs;
194b7425173f96e93b090787e2386ba5f022b6c2869fmalita    int fTextBlobCount;
19509b84a00f79979142fbcfd691ccaeb5e5600922dreed@android.com
1968515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkBBoxHierarchy* fBoundingHierarchy;
1978515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com    SkPictureStateTree* fStateTree;
1988515e79a7699922e0f95f93e8cc11d4c88657c58rileya@google.com
1990bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips    SkPictureContentInfo fContentInfo;
2000bdbea75ff1a6f3c313c18cab0139728967cb93erobertphillips
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkTypefacePlayback fTFPlayback;
20221830d90096d2dccc4168d99a427e78035ce942adjsollen@google.com    SkFactoryPlayback* fFactoryPlayback;
20375cf29be4d3bcda4ce4118facec574242d4cc106commit-bot@chromium.org
2040943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org    const SkPictInfo fInfo;
2050943f5f58abcff15c7583faafe44549b9a44f47acommit-bot@chromium.org
2068f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
2078f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org    static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec);
2088f831f262f5e57665587cb3033860eea39fe1621commit-bot@chromium.org
209e26e65e8f831f7a5626c92d11bbb8c2cec1f70derobertphillips    void initForPlayback() const;
2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
213