1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "src/gpu/vk/GrVkMemoryReclaimer.h" 17 18#include "include/core/SkLog.h" 19 20#define VK_CALL(GPU, X) GR_VK_CALL((GPU)->vkInterface(), X) 21 22SkExecutor& GrVkMemoryReclaimer::getThreadPool() 23{ 24 static std::unique_ptr<SkExecutor> executor = ({ 25 auto executor = SkExecutor::MakeFIFOThreadPool(1, false); 26 executor->add([]() { 27 int err = pthread_setname_np(pthread_self(), "async-reclaimer"); 28 if (err) { 29 SK_LOGE("GrVkMemoryReclaimer::GetThreadPool pthread_setname_np, error = %d", err); 30 } 31 }); 32 std::move(executor); 33 }); 34 return *executor; 35} 36 37bool GrVkMemoryReclaimer::addMemoryToWaitQueue(const GrVkGpu* gpu, const GrVkAlloc& alloc, const VkBuffer& buffer) 38{ 39 if (!fEnabled) { 40 return false; 41 } 42 fWaitQueues.emplace_back(WaitQueueItem{.fGpu = gpu, .fAlloc = alloc, .fType = ItemType::BUFFER, .fBuffer = buffer}); 43 if (fWaitQueues.size() > fMemoryCountThreshold) { 44 invokeParallelReclaiming(); 45 } 46 return true; 47} 48 49bool GrVkMemoryReclaimer::addMemoryToWaitQueue(const GrVkGpu* gpu, const GrVkAlloc& alloc, const VkImage& image) 50{ 51 if (!fEnabled) { 52 return false; 53 } 54 fWaitQueues.emplace_back(WaitQueueItem{.fGpu = gpu, .fAlloc = alloc, .fType = ItemType::IMAGE, .fImage = image}); 55 if (fWaitQueues.size() > fMemoryCountThreshold) { 56 invokeParallelReclaiming(); 57 } 58 return true; 59} 60 61void GrVkMemoryReclaimer::flushGpuMemoryInWaitQueue() 62{ 63 if (!fEnabled) { 64 return; 65 } 66 if (!fWaitQueues.size()) { 67 return; 68 } 69 invokeParallelReclaiming(); 70} 71 72void GrVkMemoryReclaimer::invokeParallelReclaiming() 73{ 74 getThreadPool().add([freeQueues {std::move(fWaitQueues)}] { 75 for (auto& item : freeQueues) { 76 if (item.fType == ItemType::BUFFER) { 77 GrVkBuffer::DestroyAndFreeBufferMemory(item.fGpu, item.fAlloc, item.fBuffer); 78 } else { 79 GrVkImage::DestroyAndFreeImageMemory(item.fGpu, item.fAlloc, item.fImage); 80 } 81 } 82 }); 83} 84 85void GrVkMemoryReclaimer::setGpuMemoryAsyncReclaimerSwitch(bool enabled) 86{ 87 fEnabled = enabled; 88} 89