SkWriter32.h revision adacc7067ad617cdc7bbef39192ca80f4b4d27f9
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2008 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkWriter32_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkWriter32_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypes.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h" 1694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com#include "SkPath.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPoint.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRect.h" 194ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com#include "SkRRect.h" 202b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkMatrix.h" 212b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com#include "SkRegion.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkStream; 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWStream; 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkWriter32 : SkNoncopyable { 275595af1b2ebe6590e98641464d43d22281a7f295reed@google.com struct BlockHeader; 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 29e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com /** 30e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com * The caller can specify an initial block of storage, which the caller manages. 31e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com * SkWriter32 will not attempt to free this in its destructor. It is up to the 32e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com * implementation to decide if, and how much, of the storage to utilize, and it 33e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com * is possible that it may be ignored entirely. 34e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com */ 35e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com SkWriter32(size_t minSize, void* initialStorage, size_t storageSize); 36e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com 37e1bc274295ec57cb3d3f01aaa8abff3b49c76c73vandebo@chromium.org SkWriter32(size_t minSize) 38f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org : fHead(NULL) 39f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org , fTail(NULL) 40f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org , fMinSize(minSize) 41f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org , fSize(0) 42f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org , fWrittenBeforeLastBlock(0) 43f6100c8b1aba89027cf74da8a324a744fd1d53famike@reedtribe.org {} 44e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkWriter32(); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 471cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com // return the current offset (will always be a multiple of 4) 48adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com size_t bytesWritten() const { return fSize; } 49ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org // DEPRECATED: use bytesWritten instead TODO(mtklein): clean up 50adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com size_t size() const { return this->bytesWritten(); } 511cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com 52ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org // Returns true if we've written only into the storage passed into constructor or reset. 53ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org // (You may be able to use this to avoid a call to flatten.) 54ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org bool wroteOnlyToStorage() const { 55ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org return fHead == &fExternalBlock && this->bytesWritten() <= fExternalBlock.fSizeOfBlock; 56ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org } 57ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org 58ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org void reset(); 59ff36a1d07f23f2b7feddaba110d448073a96f83ccommit-bot@chromium.org void reset(void* storage, size_t size); 60b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com 615595af1b2ebe6590e98641464d43d22281a7f295reed@google.com // size MUST be multiple of 4 625595af1b2ebe6590e98641464d43d22281a7f295reed@google.com uint32_t* reserve(size_t size) { 635595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(SkAlign4(size) == size); 64b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com 655595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* block = fTail; 665595af1b2ebe6590e98641464d43d22281a7f295reed@google.com if (NULL == block || block->available() < size) { 675595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block = this->doReserve(size); 685595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 695595af1b2ebe6590e98641464d43d22281a7f295reed@google.com fSize += size; 705595af1b2ebe6590e98641464d43d22281a7f295reed@google.com return block->alloc(size); 715595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 72a27096b4740775ae141fd0abaf456d706065c5eeskia.committer@gmail.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool writeBool(bool value) { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->writeInt(value); 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return value; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 77fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeInt(int32_t value) { 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(int32_t*)this->reserve(sizeof(value)) = value; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void write8(int32_t value) { 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF; 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 85fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void write16(int32_t value) { 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF; 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 89fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void write32(int32_t value) { 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(int32_t*)this->reserve(sizeof(value)) = value; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 93fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com void writePtr(void* ptr) { 9551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com // Since we "know" that we're always 4-byte aligned, we can tell the 9651c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com // compiler that here, by assigning to an int32 ptr. 9751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com int32_t* addr = (int32_t*)this->reserve(sizeof(void*)); 9851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com if (4 == sizeof(void*)) { 9951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com *(void**)addr = ptr; 10051c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com } else { 10151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com memcpy(addr, &ptr, sizeof(void*)); 10251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com } 10351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com } 10451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeScalar(SkScalar value) { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(SkScalar*)this->reserve(sizeof(value)) = value; 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 108fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writePoint(const SkPoint& pt) { 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(SkPoint*)this->reserve(sizeof(pt)) = pt; 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 112fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeRect(const SkRect& rect) { 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *(SkRect*)this->reserve(sizeof(rect)) = rect; 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 116306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 1175587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com void writeIRect(const SkIRect& rect) { 1185587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com *(SkIRect*)this->reserve(sizeof(rect)) = rect; 1195587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com } 1205587ac09beec4c056332504f3fa85990520b43fddjsollen@google.com 1214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com void writeRRect(const SkRRect& rrect) { 1224ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com rrect.writeToMemory(this->reserve(SkRRect::kSizeInMemory)); 1234ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 124306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 12594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com void writePath(const SkPath& path) { 12694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com size_t size = path.writeToMemory(NULL); 12794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com SkASSERT(SkAlign4(size) == size); 12894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com path.writeToMemory(this->reserve(size)); 12994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com } 13094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com 1312b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com void writeMatrix(const SkMatrix& matrix) { 13294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com size_t size = matrix.writeToMemory(NULL); 1332b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com SkASSERT(SkAlign4(size) == size); 13494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com matrix.writeToMemory(this->reserve(size)); 1352b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com } 136fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1372b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com void writeRegion(const SkRegion& rgn) { 13894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com size_t size = rgn.writeToMemory(NULL); 1392b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com SkASSERT(SkAlign4(size) == size); 14094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com rgn.writeToMemory(this->reserve(size)); 1412b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com } 1422b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // write count bytes (must be a multiple of 4) 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writeMul4(const void* values, size_t size) { 1455b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com this->write(values, size); 1465b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com } 1475b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com 1485b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com /** 1495b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com * Write size bytes from values. size must be a multiple of 4, though 1505b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com * values need not be 4-byte aligned. 1515b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com */ 1525b3d5349bedf37ec6fcf03bac04cf33129fc176areed@google.com void write(const void* values, size_t size) { 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkAlign4(size) == size); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we could query how much is avail in the current block, we might 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // copy that much, and then alloc the rest. That would reduce the waste 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // in the current block 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(this->reserve(size), values, size); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 159fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1605a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com /** 1615a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com * Reserve size bytes. Does not need to be 4 byte aligned. The remaining space (if any) will be 1625a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com * filled in with zeroes. 1635a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com */ 1645a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com uint32_t* reservePad(size_t size); 1655a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com 1665a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com /** 1675a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com * Write size bytes from src, and pad to 4 byte alignment with zeroes. 1685a7c6be72b940dde8ff6ad2485a09aecd56a2660scroggo@google.com */ 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void writePad(const void* src, size_t size); 170dde0956375e87027df2fdd80d430dd819c217aacreed@google.com 171dde0956375e87027df2fdd80d430dd819c217aacreed@google.com /** 172dde0956375e87027df2fdd80d430dd819c217aacreed@google.com * Writes a string to the writer, which can be retrieved with 173dde0956375e87027df2fdd80d430dd819c217aacreed@google.com * SkReader32::readString(). 174dde0956375e87027df2fdd80d430dd819c217aacreed@google.com * The length can be specified, or if -1 is passed, it will be computed by 1750038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com * calling strlen(). The length must be < max size_t. 1760038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com * 1770038c12f337b7037ef698e2723099c7e3b19c4camtklein@google.com * If you write NULL, it will be read as "". 178dde0956375e87027df2fdd80d430dd819c217aacreed@google.com */ 179dde0956375e87027df2fdd80d430dd819c217aacreed@google.com void writeString(const char* str, size_t len = (size_t)-1); 180dde0956375e87027df2fdd80d430dd819c217aacreed@google.com 181dde0956375e87027df2fdd80d430dd819c217aacreed@google.com /** 182dde0956375e87027df2fdd80d430dd819c217aacreed@google.com * Computes the size (aligned to multiple of 4) need to write the string 183dde0956375e87027df2fdd80d430dd819c217aacreed@google.com * in a call to writeString(). If the length is not specified, it will be 184dde0956375e87027df2fdd80d430dd819c217aacreed@google.com * computed by calling strlen(). 185dde0956375e87027df2fdd80d430dd819c217aacreed@google.com */ 186dde0956375e87027df2fdd80d430dd819c217aacreed@google.com static size_t WriteStringSize(const char* str, size_t len = (size_t)-1); 187dde0956375e87027df2fdd80d430dd819c217aacreed@google.com 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return the address of the 4byte int at the specified offset (which must 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // be a multiple of 4. This does not allocate any new space, so the returned 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // address is only valid for 1 int. 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t* peek32(size_t offset); 192fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1931cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com /** 1941cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com * Move the cursor back to offset bytes from the beginning. 1951cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com * This has the same restrictions as peek32: offset must be <= size() and 1961cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com * offset must be a multiple of 4. 1971cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com */ 1981cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com void rewindToOffset(size_t offset); 1991cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // copy into a single buffer (allocated by caller). Must be at least size() 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void flatten(void* dst) const; 202fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // read from the stream, and write up to length bytes. Return the actual 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // number of bytes written. 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t readFromStream(SkStream*, size_t length); 206fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool writeToStream(SkWStream*); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2105595af1b2ebe6590e98641464d43d22281a7f295reed@google.com struct Block { 2115595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* fNext; 2125595af1b2ebe6590e98641464d43d22281a7f295reed@google.com char* fBasePtr; 2135595af1b2ebe6590e98641464d43d22281a7f295reed@google.com size_t fSizeOfBlock; // total space allocated (after this) 2145595af1b2ebe6590e98641464d43d22281a7f295reed@google.com size_t fAllocatedSoFar; // space used so far 2155595af1b2ebe6590e98641464d43d22281a7f295reed@google.com 2165595af1b2ebe6590e98641464d43d22281a7f295reed@google.com size_t available() const { return fSizeOfBlock - fAllocatedSoFar; } 2175595af1b2ebe6590e98641464d43d22281a7f295reed@google.com char* base() { return fBasePtr; } 2185595af1b2ebe6590e98641464d43d22281a7f295reed@google.com const char* base() const { return fBasePtr; } 2195595af1b2ebe6590e98641464d43d22281a7f295reed@google.com 2205595af1b2ebe6590e98641464d43d22281a7f295reed@google.com uint32_t* alloc(size_t size) { 2215595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(SkAlign4(size) == size); 2225595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(this->available() >= size); 2235595af1b2ebe6590e98641464d43d22281a7f295reed@google.com void* ptr = this->base() + fAllocatedSoFar; 2245595af1b2ebe6590e98641464d43d22281a7f295reed@google.com fAllocatedSoFar += size; 2255595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(fAllocatedSoFar <= fSizeOfBlock); 2265595af1b2ebe6590e98641464d43d22281a7f295reed@google.com return (uint32_t*)ptr; 2275595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 228acd471f47ccfb97cf2f2f00dc01cd1fd45bc1ef2reed@google.com 2295595af1b2ebe6590e98641464d43d22281a7f295reed@google.com uint32_t* peek32(size_t offset) { 2305595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(offset <= fAllocatedSoFar + 4); 2315595af1b2ebe6590e98641464d43d22281a7f295reed@google.com void* ptr = this->base() + offset; 2325595af1b2ebe6590e98641464d43d22281a7f295reed@google.com return (uint32_t*)ptr; 2335595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 234b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com 2355595af1b2ebe6590e98641464d43d22281a7f295reed@google.com void rewind() { 2365595af1b2ebe6590e98641464d43d22281a7f295reed@google.com fNext = NULL; 2375595af1b2ebe6590e98641464d43d22281a7f295reed@google.com fAllocatedSoFar = 0; 2385595af1b2ebe6590e98641464d43d22281a7f295reed@google.com // keep fSizeOfBlock as is 2395595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 240b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com 2415595af1b2ebe6590e98641464d43d22281a7f295reed@google.com static Block* Create(size_t size) { 2425595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(SkIsAlign4(size)); 2435595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* block = (Block*)sk_malloc_throw(sizeof(Block) + size); 2445595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fNext = NULL; 2455595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fBasePtr = (char*)(block + 1); 2465595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fSizeOfBlock = size; 2475595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fAllocatedSoFar = 0; 2485595af1b2ebe6590e98641464d43d22281a7f295reed@google.com return block; 2495595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 250e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com 2515595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* initFromStorage(void* storage, size_t size) { 2525595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(SkIsAlign4((intptr_t)storage)); 2535595af1b2ebe6590e98641464d43d22281a7f295reed@google.com SkASSERT(SkIsAlign4(size)); 2545595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* block = this; 2555595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fNext = NULL; 2565595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fBasePtr = (char*)storage; 2575595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fSizeOfBlock = size; 2585595af1b2ebe6590e98641464d43d22281a7f295reed@google.com block->fAllocatedSoFar = 0; 2595595af1b2ebe6590e98641464d43d22281a7f295reed@google.com return block; 2605595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 2615595af1b2ebe6590e98641464d43d22281a7f295reed@google.com }; 2625595af1b2ebe6590e98641464d43d22281a7f295reed@google.com 2635595af1b2ebe6590e98641464d43d22281a7f295reed@google.com enum { 2645595af1b2ebe6590e98641464d43d22281a7f295reed@google.com MIN_BLOCKSIZE = sizeof(SkWriter32::Block) + sizeof(intptr_t) 2655595af1b2ebe6590e98641464d43d22281a7f295reed@google.com }; 266b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com 2675595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block fExternalBlock; 2685595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* fHead; 2695595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* fTail; 2705595af1b2ebe6590e98641464d43d22281a7f295reed@google.com size_t fMinSize; 271adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com size_t fSize; 272f56225c848cb0cd0fde4cb37558174ae096b93d1reed@google.com // sum of bytes written in all blocks *before* fTail 273adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.com size_t fWrittenBeforeLastBlock; 274f56225c848cb0cd0fde4cb37558174ae096b93d1reed@google.com 2755595af1b2ebe6590e98641464d43d22281a7f295reed@google.com bool isHeadExternallyAllocated() const { 2765595af1b2ebe6590e98641464d43d22281a7f295reed@google.com return fHead == &fExternalBlock; 2775595af1b2ebe6590e98641464d43d22281a7f295reed@google.com } 278e49aca968ca27d90ca919a972a86839ecaf1224areed@google.com 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Block* newBlock(size_t bytes); 280b89a03c890668f98d9f8b269b6ad00824409435bskia.committer@gmail.com 2815595af1b2ebe6590e98641464d43d22281a7f295reed@google.com // only call from reserve() 2825595af1b2ebe6590e98641464d43d22281a7f295reed@google.com Block* doReserve(size_t bytes); 2831cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com 2841cf58d03a87e1ff17cd47e9de3da4c678456618dreed@google.com SkDEBUGCODE(void validate() const;) 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com/** 28851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com * Helper class to allocated SIZE bytes as part of the writer, and to provide 28951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com * that storage to the constructor as its initial storage buffer. 29051c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com * 29151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com * This wrapper ensures proper alignment rules are met for the storage. 29251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com */ 29351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comtemplate <size_t SIZE> class SkSWriter32 : public SkWriter32 { 29451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.compublic: 29551c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com SkSWriter32(size_t minSize) : SkWriter32(minSize, fData.fStorage, SIZE) {} 296fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 29751c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.comprivate: 29851c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com union { 29951c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com void* fPtrAlignment; 30051c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com double fDoubleAlignment; 30151c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com char fStorage[SIZE]; 30251c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com } fData; 30351c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com}; 30451c62a6cfadc302bb65bb5a98e358c93223dc73freed@google.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 306