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)11GrFinishCallbacks::GrFinishCallbacks(GrGpu* gpu) : fGpu(gpu) {} 12 ~GrFinishCallbacks()13GrFinishCallbacks::~GrFinishCallbacks() { 14 this->callAll(true); 15 } 16 add(GrGpuFinishedProc finishedProc,GrGpuFinishedContext finishedContext)17void 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()27void 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)41void 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