1 2 /* 3 * Copyright 2010 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #ifndef GrAtlas_DEFINED 10 #define GrAtlas_DEFINED 11 12 13 #include "SkPoint.h" 14 #include "GrTexture.h" 15 #include "GrDrawTarget.h" 16 17 class GrGpu; 18 class GrRectanizer; 19 class GrAtlasMgr; 20 class GrAtlas; 21 22 // The backing GrTexture for a set of GrAtlases is broken into a spatial grid of GrPlots. When 23 // a GrAtlas needs space on the texture, it requests a GrPlot. Each GrAtlas can claim one 24 // or more GrPlots. The GrPlots keep track of subimage placement via their GrRectanizer. Once a 25 // GrPlot is "full" (i.e. there is no room for the new subimage according to the GrRectanizer), the 26 // GrAtlas can request a new GrPlot via GrAtlasMgr::addToAtlas(). 27 // 28 // If all GrPlots are allocated, the replacement strategy is up to the client. The drawToken is 29 // available to ensure that all draw calls are finished for that particular GrPlot. 30 // GrAtlasMgr::removeUnusedPlots() will free up any finished plots for a given GrAtlas. 31 32 class GrPlot { 33 public: 34 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot); 35 texture()36 GrTexture* texture() const { return fTexture; } 37 38 bool addSubImage(int width, int height, const void*, SkIPoint16*); 39 drawToken()40 GrDrawTarget::DrawToken drawToken() const { return fDrawToken; } setDrawToken(GrDrawTarget::DrawToken draw)41 void setDrawToken(GrDrawTarget::DrawToken draw) { fDrawToken = draw; } 42 43 void uploadToTexture(); 44 45 void resetRects(); 46 47 private: 48 GrPlot(); 49 ~GrPlot(); // does not try to delete the fNext field 50 void init(GrAtlasMgr* mgr, int offX, int offY, int width, int height, size_t bpp, 51 bool batchUploads); 52 53 // for recycling 54 GrDrawTarget::DrawToken fDrawToken; 55 56 unsigned char* fPlotData; 57 GrTexture* fTexture; 58 GrRectanizer* fRects; 59 GrAtlasMgr* fAtlasMgr; 60 SkIPoint16 fOffset; // the offset of the plot in the backing texture 61 size_t fBytesPerPixel; 62 SkIRect fDirtyRect; 63 bool fDirty; 64 bool fBatchUploads; 65 66 friend class GrAtlasMgr; 67 }; 68 69 typedef SkTInternalLList<GrPlot> GrPlotList; 70 71 class GrAtlasMgr { 72 public: 73 GrAtlasMgr(GrGpu*, GrPixelConfig, const SkISize& backingTextureSize, 74 int numPlotsX, int numPlotsY, bool batchUploads); 75 ~GrAtlasMgr(); 76 77 // add subimage of width, height dimensions to atlas 78 // returns the containing GrPlot and location relative to the backing texture 79 GrPlot* addToAtlas(GrAtlas*, int width, int height, const void*, SkIPoint16*); 80 81 // remove reference to this plot 82 bool removePlot(GrAtlas* atlas, const GrPlot* plot); 83 84 // get a plot that's not being used by the current draw 85 // this allows us to overwrite this plot without flushing 86 GrPlot* getUnusedPlot(); 87 getTexture()88 GrTexture* getTexture() const { 89 return fTexture; 90 } 91 92 void uploadPlotsToTexture(); 93 94 private: 95 void moveToHead(GrPlot* plot); 96 97 GrGpu* fGpu; 98 GrPixelConfig fPixelConfig; 99 GrTexture* fTexture; 100 SkISize fBackingTextureSize; 101 int fNumPlotsX; 102 int fNumPlotsY; 103 bool fBatchUploads; 104 105 // allocated array of GrPlots 106 GrPlot* fPlotArray; 107 // LRU list of GrPlots 108 GrPlotList fPlotList; 109 }; 110 111 class GrAtlas { 112 public: GrAtlas()113 GrAtlas() { } ~GrAtlas()114 ~GrAtlas() { } 115 isEmpty()116 bool isEmpty() { return 0 == fPlots.count(); } 117 118 private: 119 SkTDArray<GrPlot*> fPlots; 120 121 friend class GrAtlasMgr; 122 }; 123 124 #endif 125