• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/GrFinishCallbacks.h"
9 #include "src/gpu/ganesh/GrGpu.h"
10 
GrFinishCallbacks(GrGpu * gpu)11 GrFinishCallbacks::GrFinishCallbacks(GrGpu* gpu) : fGpu(gpu) {}
12 
~GrFinishCallbacks()13 GrFinishCallbacks::~GrFinishCallbacks() {
14     this->callAll(true);
15 }
16 
add(GrGpuFinishedProc finishedProc,GrGpuFinishedContext finishedContext)17 void GrFinishCallbacks::add(GrGpuFinishedProc finishedProc,
18                             GrGpuFinishedContext finishedContext) {
19     SkASSERT(finishedProc);
20     FinishCallback callback;
21     callback.fCallback = finishedProc;
22     callback.fContext = finishedContext;
23     callback.fFence = fGpu->insertFence();
24     fCallbacks.push_back(callback);
25 }
26 
check()27 void GrFinishCallbacks::check() {
28     // Bail after the first unfinished sync since we expect they signal in the order inserted.
29     while (!fCallbacks.empty() && fGpu->waitFence(fCallbacks.front().fFence)) {
30         // While we are processing a proc we need to make sure to remove it from the callback list
31         // before calling it. This is because the client could trigger a call (e.g. calling
32         // flushAndSubmit(/*sync=*/true)) that has us process the finished callbacks. We also must
33         // process deleting the fence before a client may abandon the context.
34         auto finishCallback = fCallbacks.front();
35         fGpu->deleteFence(finishCallback.fFence);
36         fCallbacks.pop_front();
37         finishCallback.fCallback(finishCallback.fContext);
38     }
39 }
40 
callAll(bool doDelete)41 void GrFinishCallbacks::callAll(bool doDelete) {
42     while (!fCallbacks.empty()) {
43         // While we are processing a proc we need to make sure to remove it from the callback list
44         // before calling it. This is because the client could trigger a call (e.g. calling
45         // flushAndSubmit(/*sync=*/true)) that has us process the finished callbacks. We also must
46         // process deleting the fence before a client may abandon the context.
47         auto finishCallback = fCallbacks.front();
48         if (doDelete) {
49             fGpu->deleteFence(finishCallback.fFence);
50         }
51         fCallbacks.pop_front();
52         finishCallback.fCallback(finishCallback.fContext);
53     }
54 }
55