1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "experimental/graphite/src/Gpu.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "experimental/graphite/src/Caps.h" 11cb93a386Sopenharmony_ci#include "experimental/graphite/src/CommandBuffer.h" 12cb93a386Sopenharmony_ci#include "experimental/graphite/src/GpuWorkSubmission.h" 13cb93a386Sopenharmony_ci#include "experimental/graphite/src/ResourceProvider.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cinamespace skgpu { 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci// This constant determines how many OutstandingSubmissions are allocated together as a block in 18cb93a386Sopenharmony_ci// the deque. As such it needs to balance allocating too much memory vs. incurring 19cb93a386Sopenharmony_ci// allocation/deallocation thrashing. It should roughly correspond to the max number of outstanding 20cb93a386Sopenharmony_ci// submissions we expect to see. 21cb93a386Sopenharmony_cistatic constexpr int kDefaultOutstandingAllocCnt = 8; 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciGpu::Gpu(sk_sp<const Caps> caps) 24cb93a386Sopenharmony_ci : fOutstandingSubmissions(sizeof(OutstandingSubmission), kDefaultOutstandingAllocCnt) 25cb93a386Sopenharmony_ci , fCaps(std::move(caps)) { 26cb93a386Sopenharmony_ci // subclasses create their own subclassed resource provider 27cb93a386Sopenharmony_ci} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ciGpu::~Gpu() { 30cb93a386Sopenharmony_ci // TODO: add disconnect? 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci // TODO: destroyResources instead? 34cb93a386Sopenharmony_ci // TODO: how do we handle command buffers that haven't been submitted yet? 35cb93a386Sopenharmony_ci this->checkForFinishedWork(SyncToCpu::kYes); 36cb93a386Sopenharmony_ci fResourceProvider.reset(); 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_cisk_sp<const Caps> Gpu::refCaps() const { 40cb93a386Sopenharmony_ci return fCaps; 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_cibool Gpu::submit(sk_sp<CommandBuffer> commandBuffer) { 44cb93a386Sopenharmony_ci if (!commandBuffer) { 45cb93a386Sopenharmony_ci return false; 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci if (!commandBuffer->hasWork()) { 49cb93a386Sopenharmony_ci return true; 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci return this->onSubmit(std::move(commandBuffer)); 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_civoid Gpu::checkForFinishedWork(SyncToCpu sync) { 56cb93a386Sopenharmony_ci if (sync == SyncToCpu::kYes) { 57cb93a386Sopenharmony_ci // wait for the last submission to finish 58cb93a386Sopenharmony_ci OutstandingSubmission* back = (OutstandingSubmission*)fOutstandingSubmissions.back(); 59cb93a386Sopenharmony_ci if (back) { 60cb93a386Sopenharmony_ci (*back)->waitUntilFinished(this); 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci // Iterate over all the outstanding submissions to see if any have finished. The work 65cb93a386Sopenharmony_ci // submissions are in order from oldest to newest, so we start at the front to check if they 66cb93a386Sopenharmony_ci // have finished. If so we pop it off and move onto the next. 67cb93a386Sopenharmony_ci // Repeat till we find a submission that has not finished yet (and all others afterwards are 68cb93a386Sopenharmony_ci // also guaranteed to not have finished). 69cb93a386Sopenharmony_ci OutstandingSubmission* front = (OutstandingSubmission*)fOutstandingSubmissions.front(); 70cb93a386Sopenharmony_ci while (front && (*front)->isFinished()) { 71cb93a386Sopenharmony_ci // Make sure we remove before deleting as deletion might try to kick off another submit 72cb93a386Sopenharmony_ci // (though hopefully *not* in Graphite). 73cb93a386Sopenharmony_ci fOutstandingSubmissions.pop_front(); 74cb93a386Sopenharmony_ci // Since we used placement new we are responsible for calling the destructor manually. 75cb93a386Sopenharmony_ci front->~OutstandingSubmission(); 76cb93a386Sopenharmony_ci front = (OutstandingSubmission*)fOutstandingSubmissions.front(); 77cb93a386Sopenharmony_ci } 78cb93a386Sopenharmony_ci SkASSERT(sync == SyncToCpu::kNo || fOutstandingSubmissions.empty()); 79cb93a386Sopenharmony_ci} 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci} // namespace skgpu 82