• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 "experimental/graphite/src/Gpu.h"
9 
10 #include "experimental/graphite/include/BackendTexture.h"
11 #include "experimental/graphite/include/TextureInfo.h"
12 #include "experimental/graphite/src/Caps.h"
13 #include "experimental/graphite/src/CommandBuffer.h"
14 #include "experimental/graphite/src/GpuWorkSubmission.h"
15 #include "experimental/graphite/src/Log.h"
16 #include "experimental/graphite/src/ResourceProvider.h"
17 #include "src/sksl/SkSLCompiler.h"
18 
19 namespace skgpu {
20 
21 // This constant determines how many OutstandingSubmissions are allocated together as a block in
22 // the deque. As such it needs to balance allocating too much memory vs. incurring
23 // allocation/deallocation thrashing. It should roughly correspond to the max number of outstanding
24 // submissions we expect to see.
25 static constexpr int kDefaultOutstandingAllocCnt = 8;
26 
Gpu(sk_sp<const Caps> caps)27 Gpu::Gpu(sk_sp<const Caps> caps)
28     : fOutstandingSubmissions(sizeof(OutstandingSubmission), kDefaultOutstandingAllocCnt)
29     , fCaps(std::move(caps)) {
30     // subclasses create their own subclassed resource provider
31 }
32 
~Gpu()33 Gpu::~Gpu() {
34     // TODO: add disconnect?
35 
36 
37     // TODO: destroyResources instead?
38     // TODO: how do we handle command buffers that haven't been submitted yet?
39     this->checkForFinishedWork(SyncToCpu::kYes);
40 }
41 
initCompiler()42 void Gpu::initCompiler() {
43     fCompiler = std::make_unique<SkSL::Compiler>(fCaps->shaderCaps());
44 }
45 
refCaps() const46 sk_sp<const Caps> Gpu::refCaps() const {
47     return fCaps;
48 }
49 
submit(sk_sp<CommandBuffer> commandBuffer)50 bool Gpu::submit(sk_sp<CommandBuffer> commandBuffer) {
51     if (!commandBuffer) {
52         return false;
53     }
54 
55 #ifdef SK_DEBUG
56     if (!commandBuffer->hasWork()) {
57         SKGPU_LOG_W("Submitting empty command buffer!");
58     }
59 #endif
60 
61     return this->onSubmit(std::move(commandBuffer));
62 }
63 
checkForFinishedWork(SyncToCpu sync)64 void Gpu::checkForFinishedWork(SyncToCpu sync) {
65     if (sync == SyncToCpu::kYes) {
66         // wait for the last submission to finish
67         OutstandingSubmission* back = (OutstandingSubmission*)fOutstandingSubmissions.back();
68         if (back) {
69             (*back)->waitUntilFinished(this);
70         }
71     }
72 
73     // Iterate over all the outstanding submissions to see if any have finished. The work
74     // submissions are in order from oldest to newest, so we start at the front to check if they
75     // have finished. If so we pop it off and move onto the next.
76     // Repeat till we find a submission that has not finished yet (and all others afterwards are
77     // also guaranteed to not have finished).
78     OutstandingSubmission* front = (OutstandingSubmission*)fOutstandingSubmissions.front();
79     while (front && (*front)->isFinished()) {
80         // Make sure we remove before deleting as deletion might try to kick off another submit
81         // (though hopefully *not* in Graphite).
82         fOutstandingSubmissions.pop_front();
83         // Since we used placement new we are responsible for calling the destructor manually.
84         front->~OutstandingSubmission();
85         front = (OutstandingSubmission*)fOutstandingSubmissions.front();
86     }
87     SkASSERT(sync == SyncToCpu::kNo || fOutstandingSubmissions.empty());
88 }
89 
createBackendTexture(SkISize dimensions,const TextureInfo & info)90 BackendTexture Gpu::createBackendTexture(SkISize dimensions, const TextureInfo& info) {
91     if (dimensions.isEmpty() || dimensions.width()  > this->caps()->maxTextureSize() ||
92                                 dimensions.height() > this->caps()->maxTextureSize()) {
93         return {};
94     }
95 
96     return this->onCreateBackendTexture(dimensions, info);
97 }
98 
deleteBackendTexture(BackendTexture & texture)99 void Gpu::deleteBackendTexture(BackendTexture& texture) {
100     this->onDeleteBackendTexture(texture);
101     // Invalidate the texture;
102     texture = BackendTexture();
103 }
104 
105 
106 } // namespace skgpu
107