blob: f2420aca9ef74a1895da75f9ed4147609f565a6e [file] [log] [blame]
/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/gpu/graphite/Recording.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/RecordingPriv.h"
#include "src/gpu/graphite/Resource.h"
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/TaskGraph.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureProxy.h"
#include <unordered_set>
namespace skgpu::graphite {
Recording::Recording(std::unique_ptr<TaskGraph> graph,
std::unordered_set<sk_sp<TextureProxy>, ProxyHash>&& nonVolatileLazyProxies,
std::unordered_set<sk_sp<TextureProxy>, ProxyHash>&& volatileLazyProxies,
std::unique_ptr<LazyProxyData> targetProxyData)
: fGraph(std::move(graph))
, fNonVolatileLazyProxies(std::move(nonVolatileLazyProxies))
, fVolatileLazyProxies(std::move(volatileLazyProxies))
, fTargetProxyData(std::move(targetProxyData)) {}
Recording::~Recording() {}
#if GRAPHITE_TEST_UTILS
bool Recording::isTargetProxyInstantiated() const {
return fTargetProxyData->lazyProxy()->isInstantiated();
}
#endif
////////////////////////////////////////////////////////////////////////////////
bool RecordingPriv::hasNonVolatileLazyProxies() const {
return !fRecording->fNonVolatileLazyProxies.empty();
}
bool RecordingPriv::instantiateNonVolatileLazyProxies(ResourceProvider* resourceProvider) {
SkASSERT(this->hasNonVolatileLazyProxies());
for (auto proxy : fRecording->fNonVolatileLazyProxies) {
if (!proxy->lazyInstantiate(resourceProvider)) {
return false;
}
}
// Note: once all the lazy proxies have been instantiated, that's it - there are no more
// chances to instantiate.
fRecording->fNonVolatileLazyProxies.clear();
return true;
}
bool RecordingPriv::hasVolatileLazyProxies() const {
return !fRecording->fVolatileLazyProxies.empty();
}
bool RecordingPriv::instantiateVolatileLazyProxies(ResourceProvider* resourceProvider) {
SkASSERT(this->hasVolatileLazyProxies());
for (auto proxy : fRecording->fVolatileLazyProxies) {
if (!proxy->lazyInstantiate(resourceProvider)) {
return false;
}
}
return true;
}
void RecordingPriv::deinstantiateVolatileLazyProxies() {
if (!this->hasVolatileLazyProxies()) {
return;
}
for (auto proxy : fRecording->fVolatileLazyProxies) {
SkASSERT(proxy->isVolatile());
proxy->deinstantiate();
}
}
#if GRAPHITE_TEST_UTILS
int RecordingPriv::numVolatilePromiseImages() const {
return fRecording->fVolatileLazyProxies.size();
}
int RecordingPriv::numNonVolatilePromiseImages() const {
return fRecording->fNonVolatileLazyProxies.size();
}
bool RecordingPriv::hasTasks() const { return fRecording->fGraph->hasTasks(); }
#endif
bool RecordingPriv::addCommands(Context* context,
CommandBuffer* commandBuffer,
Surface* replaySurface,
SkIVector replayTranslation) {
AutoDeinstantiateTextureProxy autoDeinstantiateTargetProxy(
fRecording->fTargetProxyData ? fRecording->fTargetProxyData->lazyProxy() : nullptr);
const Texture* replayTarget = nullptr;
SkASSERT(SkToBool(fRecording->fTargetProxyData) == SkToBool(replaySurface));
ResourceProvider* resourceProvider = context->priv().resourceProvider();
if (fRecording->fTargetProxyData) {
if (!replaySurface) {
SKGPU_LOG_E("No surface provided to instantiate target texture proxy.");
return false;
}
TextureProxy* surfaceTexture = replaySurface->backingTextureProxy();
if (!surfaceTexture->instantiate(resourceProvider)) {
SKGPU_LOG_E("Could not instantiate target texture proxy.");
return false;
}
if (!fRecording->fTargetProxyData->lazyInstantiate(resourceProvider,
surfaceTexture->refTexture())) {
SKGPU_LOG_E("Could not instantiate deferred texture proxy.");
return false;
}
replayTarget = surfaceTexture->texture();
}
if (!fRecording->fGraph->addCommands(
context, commandBuffer, {replayTarget, replayTranslation})) {
return false;
}
for (size_t i = 0; i < fRecording->fExtraResourceRefs.size(); ++i) {
commandBuffer->trackResource(fRecording->fExtraResourceRefs[i]);
}
return true;
}
void RecordingPriv::addResourceRef(sk_sp<Resource> resource) {
fRecording->fExtraResourceRefs.push_back(std::move(resource));
}
void RecordingPriv::addTask(sk_sp<Task> task) {
fRecording->fGraph->prepend(std::move(task));
}
Recording::LazyProxyData::LazyProxyData(const TextureInfo& textureInfo) {
fTargetProxy = TextureProxy::MakeFullyLazy(
textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, [this](ResourceProvider*) {
SkASSERT(SkToBool(fTarget));
return std::move(fTarget);
});
}
TextureProxy* Recording::LazyProxyData::lazyProxy() { return fTargetProxy.get(); }
sk_sp<TextureProxy> Recording::LazyProxyData::refLazyProxy() { return fTargetProxy; }
bool Recording::LazyProxyData::lazyInstantiate(ResourceProvider* resourceProvider,
sk_sp<Texture> texture) {
fTarget = std::move(texture);
return fTargetProxy->lazyInstantiate(resourceProvider);
}
} // namespace skgpu::graphite