const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern, int patternSize, int reps, int vertCount, const GrUniqueKey& key) { size_t bufferSize = patternSize * reps * sizeof(uint16_t); GrIndexBuffer* buffer = this->getIndexBuffer(bufferSize, /* dynamic = */ false, true); if (!buffer) { return NULL; } uint16_t* data = (uint16_t*) buffer->map(); bool useTempData = (NULL == data); if (useTempData) { data = SkNEW_ARRAY(uint16_t, reps * patternSize); } for (int i = 0; i < reps; ++i) { int baseIdx = i * patternSize; uint16_t baseVert = (uint16_t)(i * vertCount); for (int j = 0; j < patternSize; ++j) { data[baseIdx+j] = baseVert + pattern[j]; } } if (useTempData) { if (!buffer->updateData(data, bufferSize)) { buffer->unref(); return NULL; } SkDELETE_ARRAY(data); } else { buffer->unmap(); } this->assignUniqueKeyToResource(key, buffer); return buffer; }
const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern, int patternSize, int reps, int vertCount, const GrUniqueKey& key) { size_t bufferSize = patternSize * reps * sizeof(uint16_t); // This is typically used in GrBatchs, so we assume kNoPendingIO. GrIndexBuffer* buffer = this->createIndexBuffer(bufferSize, kStatic_BufferUsage, kNoPendingIO_Flag); if (!buffer) { return nullptr; } uint16_t* data = (uint16_t*) buffer->map(); bool useTempData = (nullptr == data); if (useTempData) { data = new uint16_t[reps * patternSize]; } for (int i = 0; i < reps; ++i) { int baseIdx = i * patternSize; uint16_t baseVert = (uint16_t)(i * vertCount); for (int j = 0; j < patternSize; ++j) { data[baseIdx+j] = baseVert + pattern[j]; } } if (useTempData) { if (!buffer->updateData(data, bufferSize)) { buffer->unref(); return nullptr; } delete[] data; } else { buffer->unmap(); } this->assignUniqueKeyToResource(key, buffer); return buffer; }