GrDrawOpAtlas.cpp revision 903da79a19c35723ff198d56923250d5f3fe0f15
15bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt/* 25bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt * Copyright 2015 Google Inc. 35bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt * 45bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt * Use of this source code is governed by a BSD-style license that can be 55bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt * found in the LICENSE file. 65bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt */ 75bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 8903da79a19c35723ff198d56923250d5f3fe0f15Brian Salomon#include "GrDrawOpAtlas.h" 9742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h" 105bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt#include "GrRectanizer.h" 115bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt#include "GrTracing.h" 125bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 135df175ee71164dce97758564f308ab301bfe393ajoshualitt//////////////////////////////////////////////////////////////////////////////// 145bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 155df175ee71164dce97758564f308ab301bfe393ajoshualittGrBatchAtlas::BatchPlot::BatchPlot(int index, uint64_t genID, int offX, int offY, int width, 16c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth int height, GrPixelConfig config) 179afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomon : fLastUpload(GrDrawOpUploadToken::AlreadyFlushedToken()) 189afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomon , fLastUse(GrDrawOpUploadToken::AlreadyFlushedToken()) 195df175ee71164dce97758564f308ab301bfe393ajoshualitt , fIndex(index) 205df175ee71164dce97758564f308ab301bfe393ajoshualitt , fGenID(genID) 215df175ee71164dce97758564f308ab301bfe393ajoshualitt , fID(CreateId(fIndex, fGenID)) 22c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth , fData(nullptr) 235df175ee71164dce97758564f308ab301bfe393ajoshualitt , fWidth(width) 245df175ee71164dce97758564f308ab301bfe393ajoshualitt , fHeight(height) 255df175ee71164dce97758564f308ab301bfe393ajoshualitt , fX(offX) 265df175ee71164dce97758564f308ab301bfe393ajoshualitt , fY(offY) 275df175ee71164dce97758564f308ab301bfe393ajoshualitt , fRects(nullptr) 285df175ee71164dce97758564f308ab301bfe393ajoshualitt , fOffset(SkIPoint16::Make(fX * fWidth, fY * fHeight)) 295df175ee71164dce97758564f308ab301bfe393ajoshualitt , fConfig(config) 305df175ee71164dce97758564f308ab301bfe393ajoshualitt , fBytesPerPixel(GrBytesPerPixel(config)) 315df175ee71164dce97758564f308ab301bfe393ajoshualitt#ifdef SK_DEBUG 325df175ee71164dce97758564f308ab301bfe393ajoshualitt , fDirty(false) 335df175ee71164dce97758564f308ab301bfe393ajoshualitt#endif 345df175ee71164dce97758564f308ab301bfe393ajoshualitt{ 355df175ee71164dce97758564f308ab301bfe393ajoshualitt fDirtyRect.setEmpty(); 365df175ee71164dce97758564f308ab301bfe393ajoshualitt} 375bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 385df175ee71164dce97758564f308ab301bfe393ajoshualittGrBatchAtlas::BatchPlot::~BatchPlot() { 39c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth sk_free(fData); 405df175ee71164dce97758564f308ab301bfe393ajoshualitt delete fRects; 415df175ee71164dce97758564f308ab301bfe393ajoshualitt} 422b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips 435df175ee71164dce97758564f308ab301bfe393ajoshualittbool GrBatchAtlas::BatchPlot::addSubImage(int width, int height, const void* image, 445df175ee71164dce97758564f308ab301bfe393ajoshualitt SkIPoint16* loc) { 455df175ee71164dce97758564f308ab301bfe393ajoshualitt SkASSERT(width <= fWidth && height <= fHeight); 465bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 475df175ee71164dce97758564f308ab301bfe393ajoshualitt if (!fRects) { 485df175ee71164dce97758564f308ab301bfe393ajoshualitt fRects = GrRectanizer::Factory(fWidth, fHeight); 495bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 505bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 515df175ee71164dce97758564f308ab301bfe393ajoshualitt if (!fRects->addRect(width, height, loc)) { 525df175ee71164dce97758564f308ab301bfe393ajoshualitt return false; 53b4c507e03386f2105e33f0c4c09b4a9d0a23196djoshualitt } 545bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 55c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth if (!fData) { 56c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth fData = reinterpret_cast<unsigned char*>(sk_calloc_throw(fBytesPerPixel * fWidth * 57c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth fHeight)); 585df175ee71164dce97758564f308ab301bfe393ajoshualitt } 595df175ee71164dce97758564f308ab301bfe393ajoshualitt size_t rowBytes = width * fBytesPerPixel; 605df175ee71164dce97758564f308ab301bfe393ajoshualitt const unsigned char* imagePtr = (const unsigned char*)image; 615df175ee71164dce97758564f308ab301bfe393ajoshualitt // point ourselves at the right starting spot 62c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth unsigned char* dataPtr = fData; 635df175ee71164dce97758564f308ab301bfe393ajoshualitt dataPtr += fBytesPerPixel * fWidth * loc->fY; 645df175ee71164dce97758564f308ab301bfe393ajoshualitt dataPtr += fBytesPerPixel * loc->fX; 65cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman // copy into the data buffer, swizzling as we go if this is ARGB data 66cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman if (4 == fBytesPerPixel && kSkia8888_GrPixelConfig == kBGRA_8888_GrPixelConfig) { 67cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman for (int i = 0; i < height; ++i) { 68cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman SkOpts::RGBA_to_BGRA(reinterpret_cast<uint32_t*>(dataPtr), imagePtr, width); 69cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman dataPtr += fBytesPerPixel * fWidth; 70cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman imagePtr += rowBytes; 71cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman } 72cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman } else { 73cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman for (int i = 0; i < height; ++i) { 74cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman memcpy(dataPtr, imagePtr, rowBytes); 75cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman dataPtr += fBytesPerPixel * fWidth; 76cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman imagePtr += rowBytes; 77cce3e58f6660a77e1a6f93d8579a279a2450b0daBrian Osman } 785bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 795bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 805df175ee71164dce97758564f308ab301bfe393ajoshualitt fDirtyRect.join(loc->fX, loc->fY, loc->fX + width, loc->fY + height); 815bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 825df175ee71164dce97758564f308ab301bfe393ajoshualitt loc->fX += fOffset.fX; 835df175ee71164dce97758564f308ab301bfe393ajoshualitt loc->fY += fOffset.fY; 845df175ee71164dce97758564f308ab301bfe393ajoshualitt SkDEBUGCODE(fDirty = true;) 855bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 865df175ee71164dce97758564f308ab301bfe393ajoshualitt return true; 875df175ee71164dce97758564f308ab301bfe393ajoshualitt} 885bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 899afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomonvoid GrBatchAtlas::BatchPlot::uploadToTexture(GrDrawOp::WritePixelsFn& writePixels, 905df175ee71164dce97758564f308ab301bfe393ajoshualitt GrTexture* texture) { 915df175ee71164dce97758564f308ab301bfe393ajoshualitt // We should only be issuing uploads if we are in fact dirty 92c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth SkASSERT(fDirty && fData && texture); 935df175ee71164dce97758564f308ab301bfe393ajoshualitt TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "GrBatchPlot::uploadToTexture"); 945df175ee71164dce97758564f308ab301bfe393ajoshualitt size_t rowBytes = fBytesPerPixel * fWidth; 95c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth const unsigned char* dataPtr = fData; 96c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth dataPtr += rowBytes * fDirtyRect.fTop; 97c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth dataPtr += fBytesPerPixel * fDirtyRect.fLeft; 98c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth writePixels(texture, fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop, 99c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth fDirtyRect.width(), fDirtyRect.height(), fConfig, dataPtr, rowBytes); 1005df175ee71164dce97758564f308ab301bfe393ajoshualitt fDirtyRect.setEmpty(); 1015df175ee71164dce97758564f308ab301bfe393ajoshualitt SkDEBUGCODE(fDirty = false;) 1025df175ee71164dce97758564f308ab301bfe393ajoshualitt} 1035bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1045df175ee71164dce97758564f308ab301bfe393ajoshualittvoid GrBatchAtlas::BatchPlot::resetRects() { 1055df175ee71164dce97758564f308ab301bfe393ajoshualitt if (fRects) { 1065df175ee71164dce97758564f308ab301bfe393ajoshualitt fRects->reset(); 1075bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1085bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1095df175ee71164dce97758564f308ab301bfe393ajoshualitt fGenID++; 1105df175ee71164dce97758564f308ab301bfe393ajoshualitt fID = CreateId(fIndex, fGenID); 1112b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips 1125df175ee71164dce97758564f308ab301bfe393ajoshualitt // zero out the plot 113c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth if (fData) { 114c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth sk_bzero(fData, fBytesPerPixel * fWidth * fHeight); 1155bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1165bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1175df175ee71164dce97758564f308ab301bfe393ajoshualitt fDirtyRect.setEmpty(); 1185df175ee71164dce97758564f308ab301bfe393ajoshualitt SkDEBUGCODE(fDirty = false;) 1195df175ee71164dce97758564f308ab301bfe393ajoshualitt} 1205bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1215bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt/////////////////////////////////////////////////////////////////////////////// 1225bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 123594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben WagnerGrBatchAtlas::GrBatchAtlas(sk_sp<GrTexture> texture, int numPlotsX, int numPlotsY) 124594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner : fTexture(std::move(texture)) 1257c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt , fAtlasGeneration(kInvalidAtlasGeneration + 1) { 1262b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips 127594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner fPlotWidth = fTexture->width() / numPlotsX; 128594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner fPlotHeight = fTexture->height() / numPlotsY; 1292b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkASSERT(numPlotsX * numPlotsY <= BulkUseTokenUpdater::kMaxPlots); 130594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner SkASSERT(fPlotWidth * numPlotsX == fTexture->width()); 131594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner SkASSERT(fPlotHeight * numPlotsY == fTexture->height()); 1322b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips 1332b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkDEBUGCODE(fNumPlots = numPlotsX * numPlotsY;) 1345bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1355bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // We currently do not support compressed atlases... 136594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner SkASSERT(!GrPixelConfigIsCompressed(fTexture->desc().fConfig)); 1375bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1385bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // set up allocated plots 139594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner fPlotArray.reset(new sk_sp<BatchPlot>[numPlotsX * numPlotsY]); 1405bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 141594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner sk_sp<BatchPlot>* currPlot = fPlotArray.get(); 1422b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips for (int y = numPlotsY - 1, r = 0; y >= 0; --y, ++r) { 1432b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips for (int x = numPlotsX - 1, c = 0; x >= 0; --x, ++c) { 1442b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips uint32_t index = r * numPlotsX + c; 1456d6b6ad0f30504b6d0540f1f6bc7c072f33e85b2bsalomon currPlot->reset(new BatchPlot(index, 1, x, y, fPlotWidth, fPlotHeight, 146594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner fTexture->desc().fConfig)); 1475bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1485bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // build LRU list 1495bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt fPlotList.addToHead(currPlot->get()); 1505bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt ++currPlot; 1515bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1525bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1535bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt} 1545bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1555bf99f1ca8f30287803b594d06c60a7b6796ad45joshualittvoid GrBatchAtlas::processEviction(AtlasID id) { 1565bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt for (int i = 0; i < fEvictionCallbacks.count(); i++) { 1575bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt (*fEvictionCallbacks[i].fFunc)(id, fEvictionCallbacks[i].fData); 1585bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1595bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt} 1605bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1619afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomoninline void GrBatchAtlas::updatePlot(GrDrawOp::Target* target, AtlasID* id, BatchPlot* plot) { 1625bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt this->makeMRU(plot); 1635bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1645bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // If our most recent upload has already occurred then we have to insert a new 1655bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // upload. Otherwise, we already have a scheduled upload that hasn't yet ocurred. 1665bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // This new update will piggy back on that previously scheduled update. 167342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon if (target->hasDrawBeenFlushed(plot->lastUploadToken())) { 168c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth // With c+14 we could move sk_sp into lamba to only ref once. 169342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon sk_sp<BatchPlot> plotsp(SkRef(plot)); 170594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner GrTexture* texture = fTexture.get(); 1719afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomon GrDrawOpUploadToken lastUploadToken = target->addAsapUpload( 1729afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomon [plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) { 173c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth plotsp->uploadToTexture(writePixels, texture); 174342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon } 175342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon ); 176342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon plot->setLastUploadToken(lastUploadToken); 1775bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1785bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt *id = plot->id(); 1795bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt} 1805bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1819afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomonbool GrBatchAtlas::addToAtlas(AtlasID* id, GrDrawOp::Target* target, 1825bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt int width, int height, const void* image, SkIPoint16* loc) { 1835bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // We should already have a texture, TODO clean this up 1842b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkASSERT(fTexture); 1856d6b6ad0f30504b6d0540f1f6bc7c072f33e85b2bsalomon if (width > fPlotWidth || height > fPlotHeight) { 1866d6b6ad0f30504b6d0540f1f6bc7c072f33e85b2bsalomon return false; 1876d6b6ad0f30504b6d0540f1f6bc7c072f33e85b2bsalomon } 1885bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 1895bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // now look through all allocated plots for one we can share, in Most Recently Refed order 1905bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt GrBatchPlotList::Iter plotIter; 1915bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt plotIter.init(fPlotList, GrBatchPlotList::Iter::kHead_IterStart); 1925bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt BatchPlot* plot; 1935bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt while ((plot = plotIter.get())) { 1942b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkASSERT(GrBytesPerPixel(fTexture->desc().fConfig) == plot->bpp()); 1952b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips if (plot->addSubImage(width, height, image, loc)) { 196342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon this->updatePlot(target, id, plot); 1975bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt return true; 1985bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 1995bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt plotIter.next(); 2005bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 2015bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 2025bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // If the above fails, then see if the least recently refed plot has already been flushed to the 2035bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt // gpu 2042b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips plot = fPlotList.tail(); 2055bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt SkASSERT(plot); 206342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon if (target->hasDrawBeenFlushed(plot->lastUseToken())) { 2075bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt this->processEviction(plot->id()); 2085bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt plot->resetRects(); 2092b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkASSERT(GrBytesPerPixel(fTexture->desc().fConfig) == plot->bpp()); 2102b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, loc); 2115bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt SkASSERT(verify); 212342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon this->updatePlot(target, id, plot); 2137c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt fAtlasGeneration++; 2145bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt return true; 2155bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 2165bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 217342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon // If this plot has been used in a draw that is currently being prepared by a batch, then we 218342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon // have to fail. This gives the batch a chance to enqueue the draw, and call back into this 219342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon // function. When that draw is enqueued, the draw token advances, and the subsequent call will 220342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon // continue past this branch and prepare an inline upload that will occur after the enqueued 221342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon // draw which references the plot's pre-upload content. 222342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon if (plot->lastUseToken() == target->nextDrawToken()) { 2235bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt return false; 2245bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt } 2255bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 2265bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt this->processEviction(plot->id()); 2275bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt fPlotList.remove(plot); 228144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary sk_sp<BatchPlot>& newPlot = fPlotArray[plot->index()]; 2292b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips newPlot.reset(plot->clone()); 2305bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt 2315bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt fPlotList.addToHead(newPlot.get()); 2322b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkASSERT(GrBytesPerPixel(fTexture->desc().fConfig) == newPlot->bpp()); 2332b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, loc); 2345bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt SkASSERT(verify); 2352b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips 2361f0e350af690044b2ba807893ac470800f8914a2robertphillips // Note that this plot will be uploaded inline with the draws whereas the 2371f0e350af690044b2ba807893ac470800f8914a2robertphillips // one it displaced most likely was uploaded asap. 238342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon // With c+14 we could move sk_sp into lamba to only ref once. 239342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon sk_sp<BatchPlot> plotsp(SkRef(newPlot.get())); 240594f9ed9c9cf0fcbbc2fa111b09d376014314315Ben Wagner GrTexture* texture = fTexture.get(); 2419afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomon GrDrawOpUploadToken lastUploadToken = target->addInlineUpload( 2429afd371a8a66f992f98eb2a3fc75ae64bddc730bBrian Salomon [plotsp, texture] (GrDrawOp::WritePixelsFn& writePixels) { 243c3d706f7ce87cdd94158d2266ab2fe2f18f5020ajvanverth plotsp->uploadToTexture(writePixels, texture); 244342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon } 245342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon ); 246342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon newPlot->setLastUploadToken(lastUploadToken); 247342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon 2485bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt *id = newPlot->id(); 2492b0536f37aa8915b6f58dae0b88b18023cb04d17robertphillips 2507c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt fAtlasGeneration++; 2515bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt return true; 2525bf99f1ca8f30287803b594d06c60a7b6796ad45joshualitt} 253