secure AtlasLocator

Add API to atlas locator to manipulate the PlotLocator and rect.
The next step is to store the page index in the rect using the
update methods to maintain the invariants between the PlotLocator
and the rect.

Change-Id: I7e27d20ffce7f08f71fef35d02bbd59eb4235dae
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/313903
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 8197040..b514137 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -24,14 +24,15 @@
 #endif
 
 #ifdef SK_DEBUG
-void GrDrawOpAtlas::AtlasLocator::validate(const GrDrawOpAtlas* drawOpAtlas) const {
+void GrDrawOpAtlas::validate(const AtlasLocator& atlasLocator) const {
     // Verify that the plotIndex stored in the PlotLocator is consistent with the glyph rectangle
-    int numPlotsX = drawOpAtlas->fTextureWidth / drawOpAtlas->fPlotWidth;
-    int numPlotsY = drawOpAtlas->fTextureHeight / drawOpAtlas->fPlotHeight;
+    int numPlotsX = fTextureWidth / fPlotWidth;
+    int numPlotsY = fTextureHeight / fPlotHeight;
 
-    int plotIndex = this->plotIndex();
-    int plotX = fRect.fLeft / drawOpAtlas->fPlotWidth;
-    int plotY = fRect.fTop / drawOpAtlas->fPlotHeight;
+    int plotIndex = atlasLocator.plotIndex();
+    auto rect = atlasLocator.rect();
+    int plotX = rect.fLeft / fPlotWidth;
+    int plotY = rect.fTop / fPlotHeight;
     SkASSERT(plotIndex == (numPlotsY - plotY - 1) * numPlotsX + (numPlotsX - plotX - 1));
 }
 #endif
@@ -123,7 +124,8 @@
     sk_free(fData);
 }
 
-bool GrDrawOpAtlas::Plot::addSubImage(int width, int height, const void* image, GrIRect16* rect) {
+bool GrDrawOpAtlas::Plot::addSubImage(
+        int width, int height, const void* image, AtlasLocator* atlasLocator) {
     SkASSERT(width <= fWidth && height <= fHeight);
 
     SkIPoint16 loc;
@@ -131,18 +133,18 @@
         return false;
     }
 
-    *rect = GrIRect16::MakeXYWH(loc.fX, loc.fY, width, height);
+    GrIRect16 rect = GrIRect16::MakeXYWH(loc.fX, loc.fY, width, height);
 
     if (!fData) {
-        fData = reinterpret_cast<unsigned char*>(sk_calloc_throw(fBytesPerPixel * fWidth *
-                                                                 fHeight));
+        fData = reinterpret_cast<unsigned char*>(
+                sk_calloc_throw(fBytesPerPixel * fWidth * fHeight));
     }
     size_t rowBytes = width * fBytesPerPixel;
     const unsigned char* imagePtr = (const unsigned char*)image;
     // point ourselves at the right starting spot
     unsigned char* dataPtr = fData;
-    dataPtr += fBytesPerPixel * fWidth * rect->fTop;
-    dataPtr += fBytesPerPixel * rect->fLeft;
+    dataPtr += fBytesPerPixel * fWidth * rect.fTop;
+    dataPtr += fBytesPerPixel * rect.fLeft;
     // copy into the data buffer, swizzling as we go if this is ARGB data
     if (4 == fBytesPerPixel && kN32_SkColorType == kBGRA_8888_SkColorType) {
         for (int i = 0; i < height; ++i) {
@@ -158,9 +160,10 @@
         }
     }
 
-    fDirtyRect.join({rect->fLeft, rect->fTop, rect->fRight, rect->fBottom});
+    fDirtyRect.join({rect.fLeft, rect.fTop, rect.fRight, rect.fBottom});
 
-    rect->offset(fOffset.fX, fOffset.fY);
+    rect.offset(fOffset.fX, fOffset.fY);
+    atlasLocator->updateRect(rect);
     SkDEBUGCODE(fDirty = true;)
 
     return true;
@@ -264,8 +267,8 @@
                 });
         plot->setLastUploadToken(lastUploadToken);
     }
-    atlasLocator->fPlotLocator = plot->plotLocator();
-    SkDEBUGCODE(atlasLocator->validate(this);)
+    atlasLocator->updatePlotLocator(plot->plotLocator());
+    SkDEBUGCODE(this->validate(*atlasLocator);)
     return true;
 }
 
@@ -281,7 +284,7 @@
     for (Plot* plot = plotIter.get(); plot; plot = plotIter.next()) {
         SkASSERT(caps.bytesPerPixel(fViews[pageIdx].proxy()->backendFormat()) == plot->bpp());
 
-        if (plot->addSubImage(width, height, image, &atlasLocator->fRect)) {
+        if (plot->addSubImage(width, height, image, atlasLocator)) {
             return this->updatePlot(target, atlasLocator, plot);
         }
     }
@@ -330,8 +333,7 @@
                 this->processEvictionAndResetRects(plot);
                 SkASSERT(caps.bytesPerPixel(fViews[pageIdx].proxy()->backendFormat()) ==
                          plot->bpp());
-                SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image,
-                                                             &atlasLocator->fRect);
+                SkDEBUGCODE(bool verify = )plot->addSubImage(width, height, image, atlasLocator);
                 SkASSERT(verify);
                 if (!this->updatePlot(target, atlasLocator, plot)) {
                     return ErrorCode::kError;
@@ -387,7 +389,7 @@
 
     fPages[pageIdx].fPlotList.addToHead(newPlot.get());
     SkASSERT(caps.bytesPerPixel(fViews[pageIdx].proxy()->backendFormat()) == newPlot->bpp());
-    SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, &atlasLocator->fRect);
+    SkDEBUGCODE(bool verify = )newPlot->addSubImage(width, height, image, atlasLocator);
     SkASSERT(verify);
 
     // Note that this plot will be uploaded inline with the draws whereas the
@@ -404,8 +406,8 @@
             });
     newPlot->setLastUploadToken(lastUploadToken);
 
-    atlasLocator->fPlotLocator = newPlot->plotLocator();
-    SkDEBUGCODE(atlasLocator->validate(this);)
+    atlasLocator->updatePlotLocator(newPlot->plotLocator());
+    SkDEBUGCODE(this->validate(*atlasLocator);)
 
     return ErrorCode::kSucceeded;
 }
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index 9920c5b..3c1c4b1 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -141,11 +141,15 @@
 
         GrIRect16 rect() const { return fRect; }
 
+        void updatePlotLocator(PlotLocator p) {
+            fPlotLocator = p;
+        }
+
+        void updateRect(GrIRect16 rect) {
+            fRect = rect;
+        }
+
     private:
-        friend class GrDrawOpAtlas;
-
-        SkDEBUGCODE(void validate(const GrDrawOpAtlas*) const;)
-
         PlotLocator fPlotLocator{0, 0, 0};
 
         // The inset padded bounds in the atlas.
@@ -393,7 +397,7 @@
         }
         SkDEBUGCODE(size_t bpp() const { return fBytesPerPixel; })
 
-        bool addSubImage(int width, int height, const void* image, GrIRect16* rect);
+        bool addSubImage(int width, int height, const void* image, AtlasLocator* atlasLocator);
 
         /**
          * To manage the lifetime of a plot, we use two tokens. We use the last upload token to
@@ -518,6 +522,8 @@
     uint32_t fMaxPages;
 
     uint32_t fNumActivePages;
+
+    SkDEBUGCODE(void validate(const AtlasLocator& atlasLocator) const;)
 };
 
 // There are three atlases (A8, 565, ARGB) that are kept in relation with one another. In