1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2020 Google LLC. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLFinishCallbacks.h" 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h" 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 15*c8dee2aaSAndroid Build Coastguard Worker GrGLFinishCallbacks(GrGLGpu * gpu)16*c8dee2aaSAndroid Build Coastguard WorkerGrGLFinishCallbacks::GrGLFinishCallbacks(GrGLGpu* gpu) : fGpu(gpu) {} 17*c8dee2aaSAndroid Build Coastguard Worker ~GrGLFinishCallbacks()18*c8dee2aaSAndroid Build Coastguard WorkerGrGLFinishCallbacks::~GrGLFinishCallbacks() { 19*c8dee2aaSAndroid Build Coastguard Worker this->callAll(true); 20*c8dee2aaSAndroid Build Coastguard Worker } 21*c8dee2aaSAndroid Build Coastguard Worker add(skgpu::AutoCallback callback,GrGLint timerQuery)22*c8dee2aaSAndroid Build Coastguard Workervoid GrGLFinishCallbacks::add(skgpu::AutoCallback callback, GrGLint timerQuery) { 23*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(callback); 24*c8dee2aaSAndroid Build Coastguard Worker FinishCallback finishCallback; 25*c8dee2aaSAndroid Build Coastguard Worker finishCallback.fCallback = std::move(callback); 26*c8dee2aaSAndroid Build Coastguard Worker finishCallback.fSync = fGpu->insertSync(); 27*c8dee2aaSAndroid Build Coastguard Worker finishCallback.fTimerQuery = timerQuery; 28*c8dee2aaSAndroid Build Coastguard Worker fCallbacks.push_back(std::move(finishCallback)); 29*c8dee2aaSAndroid Build Coastguard Worker } 30*c8dee2aaSAndroid Build Coastguard Worker check()31*c8dee2aaSAndroid Build Coastguard Workervoid GrGLFinishCallbacks::check() { 32*c8dee2aaSAndroid Build Coastguard Worker // Bail after the first unfinished sync since we expect they signal in the order inserted. 33*c8dee2aaSAndroid Build Coastguard Worker while (!fCallbacks.empty() && fGpu->testSync(fCallbacks.front().fSync)) { 34*c8dee2aaSAndroid Build Coastguard Worker // While we are processing a proc we need to make sure to remove it from the callback list 35*c8dee2aaSAndroid Build Coastguard Worker // before calling it. This is because the client could trigger a call (e.g. calling 36*c8dee2aaSAndroid Build Coastguard Worker // flushAndSubmit(/*sync=*/true)) that has us process the finished callbacks. We also must 37*c8dee2aaSAndroid Build Coastguard Worker // process deleting the sync before a client may abandon the context. 38*c8dee2aaSAndroid Build Coastguard Worker auto& finishCallback = fCallbacks.front(); 39*c8dee2aaSAndroid Build Coastguard Worker if (finishCallback.fSync) { 40*c8dee2aaSAndroid Build Coastguard Worker fGpu->deleteSync(finishCallback.fSync); 41*c8dee2aaSAndroid Build Coastguard Worker } 42*c8dee2aaSAndroid Build Coastguard Worker skgpu::GpuStats stats; 43*c8dee2aaSAndroid Build Coastguard Worker if (auto timerQuery = finishCallback.fTimerQuery) { 44*c8dee2aaSAndroid Build Coastguard Worker stats.elapsedTime = fGpu->getTimerQueryResult(timerQuery); 45*c8dee2aaSAndroid Build Coastguard Worker if (finishCallback.fCallback.receivesGpuStats()) { 46*c8dee2aaSAndroid Build Coastguard Worker finishCallback.fCallback.setStats(stats); 47*c8dee2aaSAndroid Build Coastguard Worker } 48*c8dee2aaSAndroid Build Coastguard Worker } 49*c8dee2aaSAndroid Build Coastguard Worker fCallbacks.pop_front(); 50*c8dee2aaSAndroid Build Coastguard Worker } 51*c8dee2aaSAndroid Build Coastguard Worker } 52*c8dee2aaSAndroid Build Coastguard Worker callAll(bool doDelete)53*c8dee2aaSAndroid Build Coastguard Workervoid GrGLFinishCallbacks::callAll(bool doDelete) { 54*c8dee2aaSAndroid Build Coastguard Worker while (!fCallbacks.empty()) { 55*c8dee2aaSAndroid Build Coastguard Worker // While we are processing a proc we need to make sure to remove it from the callback list 56*c8dee2aaSAndroid Build Coastguard Worker // before calling it. This is because the client could trigger a call (e.g. calling 57*c8dee2aaSAndroid Build Coastguard Worker // flushAndSubmit(/*sync=*/true)) that has us process the finished callbacks. We also must 58*c8dee2aaSAndroid Build Coastguard Worker // process deleting the sync before a client may abandon the context. 59*c8dee2aaSAndroid Build Coastguard Worker auto& finishCallback = fCallbacks.front(); 60*c8dee2aaSAndroid Build Coastguard Worker skgpu::GpuStats stats; 61*c8dee2aaSAndroid Build Coastguard Worker if (doDelete && finishCallback.fSync) { 62*c8dee2aaSAndroid Build Coastguard Worker fGpu->deleteSync(finishCallback.fSync); 63*c8dee2aaSAndroid Build Coastguard Worker if (finishCallback.fTimerQuery) { 64*c8dee2aaSAndroid Build Coastguard Worker stats.elapsedTime = fGpu->getTimerQueryResult(finishCallback.fTimerQuery); 65*c8dee2aaSAndroid Build Coastguard Worker if (finishCallback.fCallback.receivesGpuStats()) { 66*c8dee2aaSAndroid Build Coastguard Worker finishCallback.fCallback.setStats(stats); 67*c8dee2aaSAndroid Build Coastguard Worker } 68*c8dee2aaSAndroid Build Coastguard Worker } 69*c8dee2aaSAndroid Build Coastguard Worker } 70*c8dee2aaSAndroid Build Coastguard Worker fCallbacks.pop_front(); 71*c8dee2aaSAndroid Build Coastguard Worker } 72*c8dee2aaSAndroid Build Coastguard Worker } 73