56#define ASSERT_SINGLE_OWNER SKGPU_ASSERT_SINGLE_OWNER(this->singleOwner())
57#define ASSERT_SINGLE_OWNER_PRIV SKGPU_ASSERT_SINGLE_OWNER(fRecorder->singleOwner())
88 static std::atomic<uint32_t> nextID{1};
91 id = nextID.fetch_add(1, std::memory_order_relaxed);
97 : fSharedContext(
std::move(sharedContext))
98 , fRuntimeEffectDict(
std::make_unique<RuntimeEffectDictionary>())
99 , fRootTaskList(new TaskList)
103 , fAtlasProvider(
std::make_unique<AtlasProvider>(this))
107 fClientImageProvider =
options.fImageProvider;
108 if (!fClientImageProvider) {
112 fResourceProvider = fSharedContext->makeResourceProvider(this->singleOwner(),
115 fUploadBufferManager = std::make_unique<UploadBufferManager>(fResourceProvider.get(),
116 fSharedContext->caps());
117 fDrawBufferManager = std::make_unique<DrawBufferManager>(fResourceProvider.get(),
118 fSharedContext->caps(),
119 fUploadBufferManager.get());
127 for (
int i = 0; i < fFinishedProcs.size(); ++i) {
128 fFinishedProcs[i]->setFailureResult();
131 for (
auto&
device : fTrackedDevices) {
134 device->abandonRecorder();
137#if defined(GRAPHITE_TEST_UTILS)
139 fContext->priv().deregisterRecorder(
this);
144 fStrikeCache->freeAll();
152 this->
priv().flushTrackedDevices();
154 std::unordered_set<sk_sp<TextureProxy>, Recording::ProxyHash> nonVolatileLazyProxies;
155 std::unordered_set<sk_sp<TextureProxy>, Recording::ProxyHash> volatileLazyProxies;
160 if (tex.first->isLazy()) {
161 if (tex.first->isVolatile()) {
162 volatileLazyProxies.insert(tex.first);
164 nonVolatileLazyProxies.insert(tex.first);
170 std::unique_ptr<Recording::LazyProxyData> targetProxyData;
171 if (fTargetProxyData) {
172 targetProxyData = std::move(fTargetProxyData);
173 fTargetProxyDevice.reset();
174 fTargetProxyCanvas.reset();
180 if (fDrawBufferManager->hasMappingFailed() ||
181 fRootTaskList->prepareResources(fResourceProvider.get(),
182 fRuntimeEffectDict.get()) == Task::Status::kFail) {
185 fDrawBufferManager = std::make_unique<DrawBufferManager>(fResourceProvider.get(),
186 fSharedContext->caps(),
187 fUploadBufferManager.get());
188 fTextureDataCache = std::make_unique<TextureDataCache>();
189 fUniformDataCache = std::make_unique<UniformDataCache>();
190 fRootTaskList->reset();
191 fRuntimeEffectDict->reset();
195 std::unique_ptr<Recording> recording(
new Recording(fNextRecordingID++,
197 std::move(nonVolatileLazyProxies),
198 std::move(volatileLazyProxies),
199 std::move(targetProxyData),
200 std::move(fFinishedProcs)));
204 fDrawBufferManager->transferToRecording(recording.get());
205 fUploadBufferManager->transferToRecording(recording.get());
206 recording->priv().addTasks(std::move(*fRootTaskList));
208 SkASSERT(!fRootTaskList->hasTasks());
209 fRuntimeEffectDict->reset();
210 fTextureDataCache = std::make_unique<TextureDataCache>();
211 fUniformDataCache = std::make_unique<UniformDataCache>();
212 if (!this->
priv().caps()->requireOrderedRecordings()) {
213 fAtlasProvider->textAtlasManager()->evictAtlases();
222 if (textureInfo.
mipmapped() == Mipmapped::kYes) {
223 SKGPU_LOG_W(
"Requested a deferred canvas with mipmapping; this is not supported");
227 if (fTargetProxyCanvas) {
229 SKGPU_LOG_W(
"Requested a new deferred canvas before snapping the previous one");
233 fTargetProxyData = std::make_unique<Recording::LazyProxyData>(textureInfo);
237 fTargetProxyData->refLazyProxy(),
242 fTargetProxyCanvas = std::make_unique<SkCanvas>(fTargetProxyDevice);
243 return fTargetProxyCanvas.get();
260 fTrackedDevices.emplace_back(std::move(
device));
263void Recorder::deregisterDevice(
const Device*
device) {
265 for (
int i = 0; i < fTrackedDevices.size(); ++i) {
266 if (fTrackedDevices[i].get() ==
device) {
268 fTrackedDevices[i] =
nullptr;
284 if (!
info.isValid() ||
info.backend() != this->backend()) {
287 return fResourceProvider->createBackendTexture(dimensions,
info);
290#ifdef SK_BUILD_FOR_ANDROID
294 bool isProtectedContent,
296 bool fromAndroidWindow)
const {
298 SKGPU_LOG_W(
"Creating an AHardwareBuffer-backed BackendTexture is only supported with the"
302 return fResourceProvider->createBackendTexture(hardwareBuffer,
316 if (!backendTex.
isValid() || backendTex.
backend() != this->backend()) {
320 if (!srcData || numLevels <= 0) {
325 int numExpectedLevels = 1;
330 if (numLevels != numExpectedLevels) {
336 if (!this->
priv().caps()->areColorTypeAndTextureInfoCompatible(ct, backendTex.
info())) {
347 std::vector<MipLevel> mipLevels;
348 mipLevels.resize(numLevels);
350 for (
int i = 0; i < numLevels; ++i) {
354 mipLevels[i].fPixels = srcData[i].
addr();
355 mipLevels[i].fRowBytes = srcData[i].
rowBytes();
363 colorInfo, colorInfo,
366 std::make_unique<ImageUploadContext>());
368 SKGPU_LOG_E(
"Recorder::updateBackendTexture: Could not create UploadInstance");
376 this->
priv().
add(std::move(uploadTask));
386 if (!backendTex.
isValid() || backendTex.
backend() != this->backend()) {
407 SKGPU_LOG_E(
"Recorder::updateBackendTexture: Could not create UploadInstance");
415 this->
priv().
add(std::move(uploadTask));
426 fResourceProvider->deleteBackendTexture(
texture);
430 if (
info.fFinishedProc) {
433 fFinishedProcs.push_back(std::move(
callback));
448 fAtlasProvider->clearTexturePool();
450 fResourceProvider->freeGpuResources();
456 auto purgeTime = skgpu::StdSteadyClock::now() - msNotUsed;
457 fResourceProvider->purgeResourcesNotUsedSince(purgeTime);
462 return fResourceProvider->getResourceCacheCurrentBudgetedBytes();
467 return fResourceProvider->getResourceCacheLimit();
472 fResourceProvider->dumpMemoryStatistics(traceMemoryDump);
479 fRecorder->fRootTaskList->add(std::move(task));
497 const int startingIndex = fRecorder->fFlushingDevicesIndex;
498 while (fRecorder->fFlushingDevicesIndex < fRecorder->fTrackedDevices.size() - 1) {
501 fRecorder->fFlushingDevicesIndex++;
504 Device*
device = fRecorder->fTrackedDevices[fRecorder->fFlushingDevicesIndex].get();
506 device->flushPendingWorkToRecorder(fRecorder);
515 if (startingIndex < 0) {
519 while (i < fRecorder->fTrackedDevices.size()) {
523 device->abandonRecorder();
525 fRecorder->fTrackedDevices.removeShuffle(i);
532 fRecorder->fFlushingDevicesIndex = -1;
548 return fRecorder->fResourceProvider->getResourceCacheLimit();
551#if defined(GRAPHITE_TEST_UTILS)
552bool RecorderPriv::deviceIsRegistered(
Device*
device)
const {
554 for (
const sk_sp<Device>& currentDevice : fRecorder->fTrackedDevices) {
555 if (
device == currentDevice.get()) {
563void RecorderPriv::setContext(
Context* context) {
564 fRecorder->fContext = context;
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
struct AHardwareBuffer AHardwareBuffer
#define SKGPU_LOG_E(fmt,...)
#define SKGPU_LOG_W(fmt,...)
#define ASSERT_SINGLE_OWNER_PRIV
static SkImage_Base * as_IB(SkImage *image)
sk_sp< T > sk_ref_sp(T *obj)
static constexpr uint32_t SK_InvalidGenID
static int ComputeLevelCount(int baseWidth, int baseHeight)
SkColorType colorType() const
const SkImageInfo & info() const
const void * addr() const
static sk_sp< RefCntedCallback > Make(Callback proc, Context ctx)
const TextureInfo & info() const
BackendApi backend() const
SkISize dimensions() const
sk_sp< SkImage > findOrCreate(Recorder *recorder, const SkImage *image, SkImage::RequiredProperties) override
static sk_sp< DefaultImageProvider > Make()
static sk_sp< Device > Make(Recorder *recorder, sk_sp< TextureProxy >, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
sk_sp< TextureProxy > findOrCreateCachedProxy(Recorder *, const SkBitmap &, Mipmapped)
TokenTracker * tokenTracker()
size_t getResourceCacheLimit() const
static sk_sp< TextureProxy > CreateCachedProxy(Recorder *, const SkBitmap &, Mipmapped=skgpu::Mipmapped::kNo)
ProxyCache * proxyCache()
ResourceProvider * resourceProvider()
void flushTrackedDevices()
SkCanvas * makeDeferredCanvas(const SkImageInfo &, const TextureInfo &)
size_t currentBudgetedBytes() const
BackendApi backend() const
void dumpMemoryStatistics(SkTraceMemoryDump *traceMemoryDump) const
void performDeferredCleanup(std::chrono::milliseconds msNotUsed)
void deleteBackendTexture(const BackendTexture &)
bool updateCompressedBackendTexture(const BackendTexture &, const void *data, size_t dataSize)
size_t maxBudgetedBytes() const
BackendTexture createBackendTexture(SkISize dimensions, const TextureInfo &)
void addFinishInfo(const InsertFinishInfo &)
std::unique_ptr< Recording > snap()
bool updateBackendTexture(const BackendTexture &, const SkPixmap srcData[], int numLevels)
Recorder(const Recorder &)=delete
virtual sk_sp< Texture > createWrappedTexture(const BackendTexture &)=0
std::pair< sk_sp< TextureProxy >, SamplerDesc > SampledTexture
const SampledTexture & texture(int index) const
Mipmapped mipmapped() const
static sk_sp< TextureProxy > Wrap(sk_sp< Texture >)
static UploadInstance MakeCompressed(Recorder *, sk_sp< TextureProxy > targetProxy, const void *data, size_t dataSize)
static UploadInstance Make(Recorder *, sk_sp< TextureProxy > targetProxy, const SkColorInfo &srcColorInfo, const SkColorInfo &dstColorInfo, SkSpan< const MipLevel > levels, const SkIRect &dstRect, std::unique_ptr< ConditionalUploadContext >)
static sk_sp< UploadTask > Make(UploadList *)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlPixelBufferTexturePrivate * priv
#define ASSERT_SINGLE_OWNER
PipelineDataCache< UniformDataBlock > UniformDataCache
static uint32_t next_id()
PipelineDataCache< TextureDataBlock > TextureDataCache
static constexpr SkIRect MakeSize(const SkISize &size)
constexpr int32_t width() const
constexpr int32_t height() const
const SkColorInfo & colorInfo() const
SkISize dimensions() const
#define TRACE_EVENT0(category_group, name)