1 /* 2 * Copyright 2020 Google LLC 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 8 #include "src/gpu/ganesh/GrStagingBufferManager.h" 9 10 #include "include/gpu/GrDirectContext.h" 11 #include "src/gpu/ganesh/GrDirectContextPriv.h" 12 #include "src/gpu/ganesh/GrGpu.h" 13 #include "src/gpu/ganesh/GrResourceProvider.h" 14 allocateStagingBufferSlice(size_t size,size_t requiredAlignment)15GrStagingBufferManager::Slice GrStagingBufferManager::allocateStagingBufferSlice( 16 size_t size, size_t requiredAlignment) { 17 StagingBuffer* buffer = nullptr; 18 size_t offset = 0; 19 for (size_t i = 0; i < fBuffers.size(); ++i) { 20 size_t totalBufferSize = fBuffers[i].fBuffer->size(); 21 size_t currentOffset = fBuffers[i].fOffset; 22 offset = ((currentOffset + requiredAlignment - 1)/requiredAlignment)*requiredAlignment; 23 if (totalBufferSize - offset >= size) { 24 buffer = &fBuffers[i]; 25 break; 26 } 27 } 28 29 if (!buffer) { 30 GrResourceProvider* resourceProvider = fGpu->getContext()->priv().resourceProvider(); 31 size_t bufferSize = std::max(size, kMinStagingBufferSize); 32 sk_sp<GrGpuBuffer> newBuffer = resourceProvider->createBuffer( 33 bufferSize, 34 GrGpuBufferType::kXferCpuToGpu, 35 kDynamic_GrAccessPattern, 36 GrResourceProvider::ZeroInit::kNo); 37 if (!newBuffer) { 38 return {}; // invalid slice 39 } 40 void* mapPtr = newBuffer->map(); 41 if (!mapPtr) { 42 return {}; // invalid slice 43 } 44 fBuffers.emplace_back(std::move(newBuffer), mapPtr); 45 buffer = &fBuffers.back(); 46 offset = 0; 47 } 48 49 SkASSERT(buffer); 50 SkASSERT(buffer->remaining() >= size); 51 52 buffer->fOffset = offset + size; 53 char* offsetMapPtr = static_cast<char*>(buffer->fMapPtr) + offset; 54 return {buffer->fBuffer.get(), offset, offsetMapPtr}; 55 } 56 detachBuffers()57void GrStagingBufferManager::detachBuffers() { 58 for (size_t i = 0; i < fBuffers.size(); ++i) { 59 fBuffers[i].fBuffer->unmap(); 60 fGpu->takeOwnershipOfBuffer(std::move(fBuffers[i].fBuffer)); 61 } 62 fBuffers.clear(); 63 } 64