Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2017 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
Hal Canary | fdcfb8b | 2018-06-13 09:42:32 -0400 | [diff] [blame] | 8 | #include "SkVertices.h" |
Hal Canary | c640d0d | 2018-06-13 09:59:02 -0400 | [diff] [blame] | 9 | |
| 10 | #include "SkAtomics.h" |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 11 | #include "SkData.h" |
| 12 | #include "SkReader32.h" |
Mike Reed | f00faa3 | 2018-01-09 13:30:54 -0500 | [diff] [blame] | 13 | #include "SkSafeMath.h" |
Mike Reed | 165fa63 | 2018-01-23 11:50:25 -0500 | [diff] [blame] | 14 | #include "SkSafeRange.h" |
Hal Canary | c640d0d | 2018-06-13 09:59:02 -0400 | [diff] [blame] | 15 | #include "SkTo.h" |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 16 | #include "SkWriter32.h" |
Mike Klein | 79aea6a | 2018-06-11 10:45:26 -0400 | [diff] [blame] | 17 | #include <new> |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 18 | |
Mike Reed | 9a8065d | 2017-03-14 21:05:17 -0400 | [diff] [blame] | 19 | static int32_t gNextID = 1; |
| 20 | static int32_t next_id() { |
| 21 | int32_t id; |
| 22 | do { |
| 23 | id = sk_atomic_inc(&gNextID); |
| 24 | } while (id == SK_InvalidGenID); |
| 25 | return id; |
| 26 | } |
| 27 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 28 | struct SkVertices::Sizes { |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 29 | Sizes(SkVertices::VertexMode mode, int vertexCount, int indexCount, bool hasTexs, |
| 30 | bool hasColors) { |
Mike Reed | f00faa3 | 2018-01-09 13:30:54 -0500 | [diff] [blame] | 31 | SkSafeMath safe; |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 32 | |
Mike Reed | f00faa3 | 2018-01-09 13:30:54 -0500 | [diff] [blame] | 33 | fVSize = safe.mul(vertexCount, sizeof(SkPoint)); |
| 34 | fTSize = hasTexs ? safe.mul(vertexCount, sizeof(SkPoint)) : 0; |
| 35 | fCSize = hasColors ? safe.mul(vertexCount, sizeof(SkColor)) : 0; |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 36 | |
| 37 | fBuilderTriFanISize = 0; |
Mike Reed | f00faa3 | 2018-01-09 13:30:54 -0500 | [diff] [blame] | 38 | fISize = safe.mul(indexCount, sizeof(uint16_t)); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 39 | if (kTriangleFan_VertexMode == mode) { |
| 40 | int numFanTris = 0; |
| 41 | if (indexCount) { |
| 42 | fBuilderTriFanISize = fISize; |
| 43 | numFanTris = indexCount - 2; |
| 44 | } else { |
| 45 | numFanTris = vertexCount - 2; |
| 46 | // By forcing this to become indexed we are adding a constraint to the maximum |
| 47 | // number of vertices. |
Ben Wagner | dde9b52 | 2018-06-15 16:19:56 -0400 | [diff] [blame^] | 48 | if (vertexCount > (SkTo<int>(UINT16_MAX) + 1)) { |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 49 | sk_bzero(this, sizeof(*this)); |
| 50 | return; |
| 51 | } |
| 52 | } |
| 53 | if (numFanTris <= 0) { |
| 54 | sk_bzero(this, sizeof(*this)); |
| 55 | return; |
| 56 | } |
| 57 | fISize = safe.mul(numFanTris, 3 * sizeof(uint16_t)); |
| 58 | } |
| 59 | |
Mike Reed | f00faa3 | 2018-01-09 13:30:54 -0500 | [diff] [blame] | 60 | fTotal = safe.add(sizeof(SkVertices), |
| 61 | safe.add(fVSize, |
| 62 | safe.add(fTSize, |
| 63 | safe.add(fCSize, |
| 64 | fISize)))); |
| 65 | |
| 66 | if (safe.ok()) { |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 67 | fArrays = fTotal - sizeof(SkVertices); // just the sum of the arrays |
Mike Reed | f00faa3 | 2018-01-09 13:30:54 -0500 | [diff] [blame] | 68 | } else { |
| 69 | sk_bzero(this, sizeof(*this)); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 70 | } |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 71 | } |
| 72 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 73 | bool isValid() const { return fTotal != 0; } |
| 74 | |
| 75 | size_t fTotal; // size of entire SkVertices allocation (obj + arrays) |
| 76 | size_t fArrays; // size of all the arrays (V + T + C + I) |
| 77 | size_t fVSize; |
| 78 | size_t fTSize; |
| 79 | size_t fCSize; |
| 80 | size_t fISize; |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 81 | |
| 82 | // For indexed tri-fans this is the number of amount of space fo indices needed in the builder |
| 83 | // before conversion to indexed triangles (or zero if not indexed or not a triangle fan). |
| 84 | size_t fBuilderTriFanISize; |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 85 | }; |
| 86 | |
Mike Reed | 887cdf1 | 2017-04-03 11:11:09 -0400 | [diff] [blame] | 87 | SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount, |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 88 | uint32_t builderFlags) { |
| 89 | bool hasTexs = SkToBool(builderFlags & SkVertices::kHasTexCoords_BuilderFlag); |
| 90 | bool hasColors = SkToBool(builderFlags & SkVertices::kHasColors_BuilderFlag); |
| 91 | this->init(mode, vertexCount, indexCount, |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 92 | SkVertices::Sizes(mode, vertexCount, indexCount, hasTexs, hasColors)); |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 93 | } |
Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 94 | |
Mike Reed | 887cdf1 | 2017-04-03 11:11:09 -0400 | [diff] [blame] | 95 | SkVertices::Builder::Builder(VertexMode mode, int vertexCount, int indexCount, |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 96 | const SkVertices::Sizes& sizes) { |
| 97 | this->init(mode, vertexCount, indexCount, sizes); |
Mike Reed | 0c492cf | 2017-03-16 16:44:25 +0000 | [diff] [blame] | 98 | } |
| 99 | |
Mike Reed | 887cdf1 | 2017-04-03 11:11:09 -0400 | [diff] [blame] | 100 | void SkVertices::Builder::init(VertexMode mode, int vertexCount, int indexCount, |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 101 | const SkVertices::Sizes& sizes) { |
| 102 | if (!sizes.isValid()) { |
| 103 | return; // fVertices will already be null |
| 104 | } |
| 105 | |
| 106 | void* storage = ::operator new (sizes.fTotal); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 107 | if (sizes.fBuilderTriFanISize) { |
| 108 | fIntermediateFanIndices.reset(new uint8_t[sizes.fBuilderTriFanISize]); |
| 109 | } |
| 110 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 111 | fVertices.reset(new (storage) SkVertices); |
| 112 | |
| 113 | // need to point past the object to store the arrays |
| 114 | char* ptr = (char*)storage + sizeof(SkVertices); |
| 115 | |
| 116 | fVertices->fPositions = (SkPoint*)ptr; ptr += sizes.fVSize; |
| 117 | fVertices->fTexs = sizes.fTSize ? (SkPoint*)ptr : nullptr; ptr += sizes.fTSize; |
| 118 | fVertices->fColors = sizes.fCSize ? (SkColor*)ptr : nullptr; ptr += sizes.fCSize; |
| 119 | fVertices->fIndices = sizes.fISize ? (uint16_t*)ptr : nullptr; |
| 120 | fVertices->fVertexCnt = vertexCount; |
| 121 | fVertices->fIndexCnt = indexCount; |
| 122 | fVertices->fMode = mode; |
| 123 | // We defer assigning fBounds and fUniqueID until detach() is called |
Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | sk_sp<SkVertices> SkVertices::Builder::detach() { |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 127 | if (fVertices) { |
| 128 | fVertices->fBounds.set(fVertices->fPositions, fVertices->fVertexCnt); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 129 | if (fVertices->fMode == kTriangleFan_VertexMode) { |
| 130 | if (fIntermediateFanIndices.get()) { |
| 131 | SkASSERT(fVertices->fIndexCnt); |
| 132 | auto tempIndices = this->indices(); |
| 133 | for (int t = 0; t < fVertices->fIndexCnt - 2; ++t) { |
| 134 | fVertices->fIndices[3 * t + 0] = tempIndices[0]; |
| 135 | fVertices->fIndices[3 * t + 1] = tempIndices[t + 1]; |
| 136 | fVertices->fIndices[3 * t + 2] = tempIndices[t + 2]; |
| 137 | } |
| 138 | fVertices->fIndexCnt = 3 * (fVertices->fIndexCnt - 2); |
| 139 | } else { |
| 140 | SkASSERT(!fVertices->fIndexCnt); |
| 141 | for (int t = 0; t < fVertices->fVertexCnt - 2; ++t) { |
| 142 | fVertices->fIndices[3 * t + 0] = 0; |
| 143 | fVertices->fIndices[3 * t + 1] = SkToU16(t + 1); |
| 144 | fVertices->fIndices[3 * t + 2] = SkToU16(t + 2); |
| 145 | } |
| 146 | fVertices->fIndexCnt = 3 * (fVertices->fVertexCnt - 2); |
| 147 | } |
| 148 | fVertices->fMode = kTriangles_VertexMode; |
| 149 | } |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 150 | fVertices->fUniqueID = next_id(); |
| 151 | return std::move(fVertices); // this will null fVertices after the return |
Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 152 | } |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 153 | return nullptr; |
Mike Reed | 7d9f9e3 | 2017-03-15 18:35:07 +0000 | [diff] [blame] | 154 | } |
| 155 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 156 | int SkVertices::Builder::vertexCount() const { |
| 157 | return fVertices ? fVertices->vertexCount() : 0; |
| 158 | } |
| 159 | |
| 160 | int SkVertices::Builder::indexCount() const { |
| 161 | return fVertices ? fVertices->indexCount() : 0; |
| 162 | } |
| 163 | |
| 164 | SkPoint* SkVertices::Builder::positions() { |
| 165 | return fVertices ? const_cast<SkPoint*>(fVertices->positions()) : nullptr; |
| 166 | } |
| 167 | |
| 168 | SkPoint* SkVertices::Builder::texCoords() { |
| 169 | return fVertices ? const_cast<SkPoint*>(fVertices->texCoords()) : nullptr; |
| 170 | } |
| 171 | |
| 172 | SkColor* SkVertices::Builder::colors() { |
| 173 | return fVertices ? const_cast<SkColor*>(fVertices->colors()) : nullptr; |
| 174 | } |
| 175 | |
| 176 | uint16_t* SkVertices::Builder::indices() { |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 177 | if (!fVertices) { |
| 178 | return nullptr; |
| 179 | } |
| 180 | if (fIntermediateFanIndices) { |
| 181 | return reinterpret_cast<uint16_t*>(fIntermediateFanIndices.get()); |
| 182 | } |
| 183 | return const_cast<uint16_t*>(fVertices->indices()); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
| 187 | |
Mike Reed | 887cdf1 | 2017-04-03 11:11:09 -0400 | [diff] [blame] | 188 | sk_sp<SkVertices> SkVertices::MakeCopy(VertexMode mode, int vertexCount, |
Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 189 | const SkPoint pos[], const SkPoint texs[], |
| 190 | const SkColor colors[], int indexCount, |
| 191 | const uint16_t indices[]) { |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 192 | Sizes sizes(mode, vertexCount, indexCount, texs != nullptr, colors != nullptr); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 193 | if (!sizes.isValid()) { |
Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 194 | return nullptr; |
| 195 | } |
| 196 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 197 | Builder builder(mode, vertexCount, indexCount, sizes); |
| 198 | SkASSERT(builder.isValid()); |
| 199 | |
| 200 | sk_careful_memcpy(builder.positions(), pos, sizes.fVSize); |
| 201 | sk_careful_memcpy(builder.texCoords(), texs, sizes.fTSize); |
| 202 | sk_careful_memcpy(builder.colors(), colors, sizes.fCSize); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 203 | size_t isize = (mode == kTriangleFan_VertexMode) ? sizes.fBuilderTriFanISize : sizes.fISize; |
| 204 | sk_careful_memcpy(builder.indices(), indices, isize); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 205 | |
Mike Reed | 97eb4fe | 2017-03-14 12:04:16 -0400 | [diff] [blame] | 206 | return builder.detach(); |
| 207 | } |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 208 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 209 | size_t SkVertices::approximateSize() const { |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 210 | Sizes sizes(fMode, fVertexCnt, fIndexCnt, this->hasTexCoords(), this->hasColors()); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 211 | SkASSERT(sizes.isValid()); |
| 212 | return sizeof(SkVertices) + sizes.fArrays; |
| 213 | } |
| 214 | |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 215 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
| 216 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 217 | // storage = packed | vertex_count | index_count | pos[] | texs[] | colors[] | indices[] |
| 218 | // = header + arrays |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 219 | |
| 220 | #define kMode_Mask 0x0FF |
| 221 | #define kHasTexs_Mask 0x100 |
| 222 | #define kHasColors_Mask 0x200 |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 223 | #define kHeaderSize (3 * sizeof(uint32_t)) |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 224 | |
| 225 | sk_sp<SkData> SkVertices::encode() const { |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 226 | // packed has room for addtional flags in the future (e.g. versioning) |
| 227 | uint32_t packed = static_cast<uint32_t>(fMode); |
| 228 | SkASSERT((packed & ~kMode_Mask) == 0); // our mode fits in the mask bits |
| 229 | if (this->hasTexCoords()) { |
| 230 | packed |= kHasTexs_Mask; |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 231 | } |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 232 | if (this->hasColors()) { |
| 233 | packed |= kHasColors_Mask; |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 234 | } |
| 235 | |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 236 | Sizes sizes(fMode, fVertexCnt, fIndexCnt, this->hasTexCoords(), this->hasColors()); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 237 | SkASSERT(sizes.isValid()); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 238 | SkASSERT(!sizes.fBuilderTriFanISize); |
Mike Reed | 6ff6af9 | 2017-04-05 17:05:16 -0400 | [diff] [blame] | 239 | // need to force alignment to 4 for SkWriter32 -- will pad w/ 0s as needed |
| 240 | const size_t size = SkAlign4(kHeaderSize + sizes.fArrays); |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 241 | |
| 242 | sk_sp<SkData> data = SkData::MakeUninitialized(size); |
| 243 | SkWriter32 writer(data->writable_data(), data->size()); |
| 244 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 245 | writer.write32(packed); |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 246 | writer.write32(fVertexCnt); |
| 247 | writer.write32(fIndexCnt); |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 248 | writer.write(fPositions, sizes.fVSize); |
| 249 | writer.write(fTexs, sizes.fTSize); |
| 250 | writer.write(fColors, sizes.fCSize); |
Mike Reed | 6ff6af9 | 2017-04-05 17:05:16 -0400 | [diff] [blame] | 251 | // if index-count is odd, we won't be 4-bytes aligned, so we call the pad version |
| 252 | writer.writePad(fIndices, sizes.fISize); |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 253 | |
| 254 | return data; |
| 255 | } |
| 256 | |
| 257 | sk_sp<SkVertices> SkVertices::Decode(const void* data, size_t length) { |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 258 | if (length < kHeaderSize) { |
| 259 | return nullptr; |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 260 | } |
| 261 | |
| 262 | SkReader32 reader(data, length); |
Mike Reed | 165fa63 | 2018-01-23 11:50:25 -0500 | [diff] [blame] | 263 | SkSafeRange safe; |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 264 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 265 | const uint32_t packed = reader.readInt(); |
Mike Reed | d2bc620 | 2018-02-01 10:48:59 -0500 | [diff] [blame] | 266 | const int vertexCount = safe.checkGE(reader.readInt(), 0); |
| 267 | const int indexCount = safe.checkGE(reader.readInt(), 0); |
Mike Reed | 165fa63 | 2018-01-23 11:50:25 -0500 | [diff] [blame] | 268 | const VertexMode mode = safe.checkLE<VertexMode>(packed & kMode_Mask, |
| 269 | SkVertices::kLast_VertexMode); |
Mike Reed | d2bc620 | 2018-02-01 10:48:59 -0500 | [diff] [blame] | 270 | if (!safe) { |
| 271 | return nullptr; |
| 272 | } |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 273 | const bool hasTexs = SkToBool(packed & kHasTexs_Mask); |
| 274 | const bool hasColors = SkToBool(packed & kHasColors_Mask); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 275 | Sizes sizes(mode, vertexCount, indexCount, hasTexs, hasColors); |
Mike Reed | d2bc620 | 2018-02-01 10:48:59 -0500 | [diff] [blame] | 276 | if (!sizes.isValid()) { |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 277 | return nullptr; |
| 278 | } |
Mike Reed | 6ff6af9 | 2017-04-05 17:05:16 -0400 | [diff] [blame] | 279 | // logically we can be only 2-byte aligned, but our buffer is always 4-byte aligned |
| 280 | if (SkAlign4(kHeaderSize + sizes.fArrays) != length) { |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 281 | return nullptr; |
| 282 | } |
| 283 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 284 | Builder builder(mode, vertexCount, indexCount, sizes); |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 285 | |
Mike Reed | aa9e332 | 2017-03-16 14:38:48 -0400 | [diff] [blame] | 286 | reader.read(builder.positions(), sizes.fVSize); |
| 287 | reader.read(builder.texCoords(), sizes.fTSize); |
| 288 | reader.read(builder.colors(), sizes.fCSize); |
Brian Salomon | cccafe8 | 2018-04-28 16:13:08 -0400 | [diff] [blame] | 289 | size_t isize = (mode == kTriangleFan_VertexMode) ? sizes.fBuilderTriFanISize : sizes.fISize; |
| 290 | reader.read(builder.indices(), isize); |
Mike Reed | d2bc620 | 2018-02-01 10:48:59 -0500 | [diff] [blame] | 291 | if (indexCount > 0) { |
| 292 | // validate that the indicies are in range |
| 293 | SkASSERT(indexCount == builder.indexCount()); |
| 294 | const uint16_t* indices = builder.indices(); |
| 295 | for (int i = 0; i < indexCount; ++i) { |
| 296 | if (indices[i] >= (unsigned)vertexCount) { |
| 297 | return nullptr; |
| 298 | } |
| 299 | } |
| 300 | } |
Mike Reed | bdce9c2 | 2017-03-14 14:10:54 -0400 | [diff] [blame] | 301 | return builder.detach(); |
| 302 | } |
Yong-Hwan Baek | 701a3ca | 2018-04-20 21:44:43 +0900 | [diff] [blame] | 303 | |
| 304 | void SkVertices::operator delete(void* p) |
| 305 | { |
| 306 | ::operator delete(p); |
| 307 | } |