| /* | |
| * Copyright 2025 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "tests/Test.h" | |
| #if defined(SK_GRAPHITE) | |
| #include "include/gpu/graphite/Context.h" | |
| #include "include/gpu/graphite/PrecompileContext.h" | |
| #include "include/gpu/graphite/precompile/PaintOptions.h" | |
| #include "include/gpu/graphite/precompile/Precompile.h" | |
| #include "src/gpu/graphite/ContextPriv.h" | |
| #include "src/gpu/graphite/PrecompileContextPriv.h" | |
| namespace { | |
| // The cache behavior shouldn't change based on the backend so just pick one for testing | |
| bool is_dawn_metal_context_type(skgpu::ContextType type) { | |
| return type == skgpu::ContextType::kDawn_Metal; | |
| } | |
| } // anonymous namespace | |
| DEF_GRAPHITE_TEST_FOR_CONTEXTS(PrecompileStatsTest, is_dawn_metal_context_type, | |
| reporter, context, /* testContext */, CtsEnforcement::kNever) { | |
| using namespace skgpu::graphite; | |
| std::unique_ptr<PrecompileContext> precompileContext = context->makePrecompileContext(); | |
| GlobalCache* cache = precompileContext->priv().globalCache(); | |
| const RenderPassProperties kBGRA_1_D { DepthStencilFlags::kDepth, | |
| kBGRA_8888_SkColorType, | |
| /* fDstCS= */ nullptr, | |
| /* fRequiresMSAA= */ false }; | |
| PaintOptions paintOptions; | |
| paintOptions.setBlendModes(SKSPAN_INIT_ONE( SkBlendMode::kSrcOver )); | |
| // Epoch 1 ------------------------------------------------------------------------------------- | |
| REPORTER_ASSERT(reporter, cache->getEpoch() == 1); | |
| Precompile(precompileContext.get(), | |
| paintOptions, | |
| DrawTypeFlags::kBitmapText_Mask, | |
| { &kBGRA_1_D, 1 }); | |
| // We need to explicitly wait for the precompilation to finish here | |
| context->priv().sharedContext()->pipelineManager()->wait_TestOnly(); | |
| GlobalCache::PipelineStats stats = cache->getStats(); | |
| uint16_t saved = stats.fPipelineUsesInEpoch; | |
| REPORTER_ASSERT(reporter, stats.fPipelineUsesInEpoch > 0); // we should see some uses | |
| precompileContext->reportPipelineStats(PrecompileContext::StatOptions::kPipelineCache); | |
| stats = cache->getStats(); | |
| REPORTER_ASSERT(reporter, stats.fPipelineUsesInEpoch == 0); // stats should've been reset | |
| // Epoch 2 ------------------------------------------------------------------------------------- | |
| REPORTER_ASSERT(reporter, cache->getEpoch() == 2); | |
| Precompile(precompileContext.get(), | |
| paintOptions, | |
| DrawTypeFlags::kBitmapText_Mask, | |
| { &kBGRA_1_D, 1 }); | |
| // We need to explicitly wait for the precompilation to finish here | |
| context->priv().sharedContext()->pipelineManager()->wait_TestOnly(); | |
| stats = cache->getStats(); | |
| // It's a new epoch so the cache lookups count as new uses | |
| REPORTER_ASSERT(reporter, stats.fPipelineUsesInEpoch == saved); | |
| Precompile(precompileContext.get(), | |
| paintOptions, | |
| DrawTypeFlags::kBitmapText_Mask, | |
| { &kBGRA_1_D, 1 }); | |
| // We need to explicitly wait for the precompilation to finish here | |
| context->priv().sharedContext()->pipelineManager()->wait_TestOnly(); | |
| stats = cache->getStats(); | |
| // The epoch hasn't changed so the additional uses don't contribute | |
| REPORTER_ASSERT(reporter, stats.fPipelineUsesInEpoch == saved); | |
| // Test epoch overflow - back to Epoch 1 ------------------------------------------------------- | |
| cache->forceNextEpochOverflow(); | |
| precompileContext->reportPipelineStats(PrecompileContext::StatOptions::kPipelineCache); | |
| stats = cache->getStats(); | |
| REPORTER_ASSERT(reporter, stats.fPipelineUsesInEpoch == 0); // stats should've been reset | |
| REPORTER_ASSERT(reporter, cache->getEpoch() == 1); | |
| Precompile(precompileContext.get(), | |
| paintOptions, | |
| DrawTypeFlags::kBitmapText_Mask, | |
| { &kBGRA_1_D, 1 }); | |
| // We need to explicitly wait for the precompilation to finish here | |
| context->priv().sharedContext()->pipelineManager()->wait_TestOnly(); | |
| stats = cache->getStats(); | |
| // Usage counting should still work across epoch reset | |
| REPORTER_ASSERT(reporter, stats.fPipelineUsesInEpoch == saved); | |
| } | |
| #endif // SK_GRAPHITE |