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