35#if defined(DUMP_ATLAS_DATA)
42void GrDrawOpAtlas::validate(
const AtlasLocator& atlasLocator)
const {
44 int numPlotsX = fTextureWidth / fPlotWidth;
45 int numPlotsY = fTextureHeight / fPlotHeight;
48 auto topLeft = atlasLocator.
topLeft();
49 int plotX = topLeft.
x() / fPlotWidth;
50 int plotY = topLeft.y() / fPlotHeight;
51 SkASSERT(plotIndex == (numPlotsY - plotY - 1) * numPlotsX + (numPlotsX - plotX - 1));
64 for (uint32_t
i = 0;
i < fNumActivePages; ++
i) {
66 SkASSERT(fViews[
i].proxy() && fViews[
i].proxy()->isInstantiated());
73 int height,
int plotWidth,
int plotHeight,
77 std::string_view label) {
85 allowMultitexturing, label));
86 if (!
atlas->createPages(proxyProvider, generationCounter) || !
atlas->getViews()[0].proxy()) {
90 if (evictor !=
nullptr) {
91 atlas->fEvictionCallbacks.emplace_back(evictor);
101 AllowMultitexturing allowMultitexturing, std::string_view label)
104 , fBytesPerPixel(bpp)
105 , fTextureWidth(
width)
107 , fPlotWidth(plotWidth)
108 , fPlotHeight(plotHeight)
110 , fGenerationCounter(generationCounter)
111 , fAtlasGeneration(fGenerationCounter->
next())
113 , fFlushesSinceLastUse(0)
114 , fMaxPages(AllowMultitexturing::
kYes == allowMultitexturing ?
116 , fNumActivePages(0) {
117 int numPlotsX =
width/plotWidth;
118 int numPlotsY =
height/plotHeight;
120 SkASSERT(fPlotWidth * numPlotsX == fTextureWidth);
121 SkASSERT(fPlotHeight * numPlotsY == fTextureHeight);
123 fNumPlots = numPlotsX * numPlotsY;
126inline void GrDrawOpAtlas::processEviction(
PlotLocator plotLocator) {
128 evictor->evict(plotLocator);
131 fAtlasGeneration = fGenerationCounter->
next();
142 std::tie(dataPtr,
rect) =
plot->prepareForUpload();
148 fBytesPerPixel*fPlotWidth);
153 uint32_t pageIdx =
plot->pageIndex();
154 if (pageIdx >= fNumActivePages) {
157 this->makeMRU(
plot, pageIdx);
162 if (
plot->lastUploadToken() <
target->tokenTracker()->nextFlushToken()) {
171 this->uploadPlotToTexture(writePixels, proxy, plotsp.get());
173 plot->setLastUploadToken(lastUploadToken);
182 SkASSERT(fViews[pageIdx].proxy() && fViews[pageIdx].proxy()->isInstantiated());
185 PlotList::Iter plotIter;
186 plotIter.init(fPages[pageIdx].fPlotList, PlotList::Iter::kHead_IterStart);
193 return this->updatePlot(
target, atlasLocator,
plot);
220 for (
unsigned int pageIdx = 0; pageIdx < fNumActivePages; ++pageIdx) {
231 if (fNumActivePages == this->
maxPages()) {
232 for (
unsigned int pageIdx = 0; pageIdx < fNumActivePages; ++pageIdx) {
233 Plot*
plot = fPages[pageIdx].fPlotList.tail();
235 if (
plot->lastUseToken() <
target->tokenTracker()->nextFlushToken()) {
236 this->processEvictionAndResetRects(
plot);
241 if (!this->updatePlot(
target, atlasLocator,
plot)) {
249 if (!this->activateNewPage(resourceProvider)) {
262 if (!fNumActivePages) {
269 for (
int pageIdx = ((
int)fNumActivePages)-1; pageIdx >= 0; --pageIdx) {
270 Plot* currentPlot = fPages[pageIdx].fPlotList.tail();
286 this->processEviction(
plot->plotLocator());
287 int pageIdx =
plot->pageIndex();
288 fPages[pageIdx].fPlotList.remove(
plot);
290 newPlot =
plot->clone();
292 fPages[pageIdx].fPlotList.addToHead(newPlot.
get());
308 this->uploadPlotToTexture(writePixels, proxy, plotsp.
get());
310 newPlot->setLastUploadToken(lastUploadToken);
319 if (fNumActivePages < 1) {
320 fPrevFlushToken = startTokenForNextFlush;
325 PlotList::Iter plotIter;
326 bool atlasUsedThisFlush =
false;
327 for (uint32_t pageIndex = 0; pageIndex < fNumActivePages; ++pageIndex) {
328 plotIter.init(fPages[pageIndex].fPlotList, PlotList::Iter::kHead_IterStart);
329 while (
Plot*
plot = plotIter.get()) {
331 if (
plot->lastUseToken().inInterval(fPrevFlushToken, startTokenForNextFlush)) {
332 plot->resetFlushesSinceLastUsed();
333 atlasUsedThisFlush =
true;
340 if (atlasUsedThisFlush) {
341 fFlushesSinceLastUse = 0;
343 ++fFlushesSinceLastUse;
352 uint32_t lastPageIndex = fNumActivePages - 1;
356 for (uint32_t pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex) {
361 plotIter.init(fPages[pageIndex].fPlotList, PlotList::Iter::kHead_IterStart);
362 while (
Plot*
plot = plotIter.get()) {
367 if (!
plot->lastUseToken().inInterval(fPrevFlushToken, startTokenForNextFlush)) {
368 plot->incFlushesSinceLastUsed();
392 plotIter.init(fPages[lastPageIndex].fPlotList, PlotList::Iter::kHead_IterStart);
393 unsigned int usedPlots = 0;
395 SkDebugf(
"page %u: ", lastPageIndex);
398 while (
Plot*
plot = plotIter.get()) {
400 if (!
plot->lastUseToken().inInterval(fPrevFlushToken, startTokenForNextFlush)) {
401 plot->incFlushesSinceLastUsed();
413 this->processEvictionAndResetRects(
plot);
426 if (!availablePlots.
empty() && usedPlots && usedPlots <= fNumPlots / 4) {
427 plotIter.init(fPages[lastPageIndex].fPlotList, PlotList::Iter::kHead_IterStart);
428 while (
Plot*
plot = plotIter.get()) {
434 if (!availablePlots.
empty()) {
435 this->processEvictionAndResetRects(
plot);
436 this->processEvictionAndResetRects(availablePlots.
back());
440 if (!usedPlots || availablePlots.
empty()) {
451 SkDebugf(
"delete %u\n", fNumActivePages - 1);
454 this->deactivateLastPage();
455 fFlushesSinceLastUse = 0;
459 fPrevFlushToken = startTokenForNextFlush;
462bool GrDrawOpAtlas::createPages(
466 SkISize dims = {fTextureWidth, fTextureHeight};
468 int numPlotsX = fTextureWidth/fPlotWidth;
469 int numPlotsY = fTextureHeight/fPlotHeight;
495 fPages[
i].fPlotArray = std::make_unique<sk_sp<Plot>[]>(numPlotsX * numPlotsY);
498 for (
int y = numPlotsY - 1, r = 0;
y >= 0; --
y, ++r) {
499 for (
int x = numPlotsX - 1, c = 0;
x >= 0; --
x, ++c) {
500 uint32_t plotIndex = r * numPlotsX + c;
501 currPlot->reset(
new Plot(
502 i, plotIndex, generationCounter,
x,
y, fPlotWidth, fPlotHeight, fColorType,
506 fPages[
i].fPlotList.addToHead(currPlot->get());
519 if (!fViews[fNumActivePages].proxy()->
instantiate(resourceProvider)) {
524 SkDebugf(
"activated page#: %u\n", fNumActivePages);
531inline void GrDrawOpAtlas::deactivateLastPage() {
534 uint32_t lastPageIndex = fNumActivePages - 1;
536 int numPlotsX = fTextureWidth/fPlotWidth;
537 int numPlotsY = fTextureHeight/fPlotHeight;
539 fPages[lastPageIndex].fPlotList.reset();
540 for (
int r = 0; r < numPlotsY; ++r) {
541 for (
int c = 0; c < numPlotsX; ++c) {
542 uint32_t plotIndex = r * numPlotsX + c;
544 Plot* currPlot = fPages[lastPageIndex].fPlotArray[plotIndex].get();
550 fPages[lastPageIndex].fPlotList.addToHead(currPlot);
560 static const SkISize kARGBDimensions[] = {
572 int index = maxBytes > 0
578 fARGBDimensions.
set(std::min<int>(kARGBDimensions[index].
width(), maxTextureSize),
579 std::min<int>(kARGBDimensions[index].
height(), maxTextureSize));
580 fMaxTextureSize = std::min<int>(maxTextureSize, kMaxAtlasDim);
584 if (MaskFormat::kA8 ==
type) {
586 return { std::min<int>(2 * fARGBDimensions.
width(), fMaxTextureSize),
587 std::min<int>(2 * fARGBDimensions.
height(), fMaxTextureSize) };
589 return fARGBDimensions;
594 if (MaskFormat::kA8 ==
type) {
605 return { plotWidth, plotHeight };
size_t GrBackendFormatBytesPerPixel(const GrBackendFormat &format)
std::function< bool(GrTextureProxy *, SkIRect, GrColorType srcColorType, const void *, size_t rowBytes)> GrDeferredTextureUploadWritePixelsFn
skgpu::AtlasLocator AtlasLocator
static constexpr auto kPlotRecentlyUsedCount
static constexpr auto kAtlasRecentlyUsedCount
skgpu::PlotLocator PlotLocator
skgpu::AtlasToken AtlasToken
static const constexpr bool kDumpAtlasData
static constexpr bool GrColorTypeIsAlphaOnly(GrColorType ct)
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
@ kTopLeft_GrSurfaceOrigin
static float next(float f)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static int SkPrevLog2(uint32_t value)
constexpr bool SkIsPow2(T value)
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
skgpu::Swizzle getReadSwizzle(const GrBackendFormat &format, GrColorType colorType) const
SkISize atlasDimensions(skgpu::MaskFormat type) const
SkISize plotDimensions(skgpu::MaskFormat type) const
void compact(skgpu::AtlasToken startTokenForNextFlush)
static std::unique_ptr< GrDrawOpAtlas > Make(GrProxyProvider *proxyProvider, const GrBackendFormat &format, SkColorType ct, size_t bpp, int width, int height, int plotWidth, int plotHeight, skgpu::AtlasGenerationCounter *generationCounter, AllowMultitexturing allowMultitexturing, skgpu::PlotEvictionCallback *evictor, std::string_view label)
ErrorCode addToAtlas(GrResourceProvider *, GrDeferredUploadTarget *, int width, int height, const void *image, skgpu::AtlasLocator *)
void instantiate(GrOnFlushResourceProvider *)
uint32_t maxPages() const
sk_sp< GrTextureProxy > createProxy(const GrBackendFormat &, SkISize dimensions, GrRenderable, int renderTargetSampleCnt, skgpu::Mipmapped, SkBackingFit, skgpu::Budgeted, GrProtected, std::string_view label, GrInternalSurfaceFlags=GrInternalSurfaceFlags::kNone, UseAllocator useAllocator=UseAllocator::kYes)
const GrCaps * caps() const
GrTextureProxy * asTextureProxy() const
GrSurfaceProxy * proxy() const
GrTexture * peekTexture() const
bool isInstantiated() const
uint32_t plotIndex() const
void updatePlotLocator(PlotLocator p)
static AtlasToken InvalidToken()
static constexpr int kMaxPlots
skgpu::AtlasToken lastUseToken() const
void resetFlushesSinceLastUsed()
static constexpr Swizzle Concat(const Swizzle &a, const Swizzle &b)
uint32_t uint32_t * format
sk_sp< const SkImage > atlas
sk_sp< const SkImage > image
sk_sp< SkBlender > blender SkRect rect
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SkTInternalLList< Plot > PlotList
static void plot(SkCanvas *canvas, const char *fn, float xMin, float xMax, float yMin, float yMax, const char *label=nullptr, bool requireES3=false)
constexpr int32_t x() const
constexpr int32_t width() const
void set(int32_t w, int32_t h)
constexpr int32_t height() const
#define TRACE_EVENT0(category_group, name)