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
17class GrGpu;
18class GrRectanizer;
19class GrAtlasMgr;
20class 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
32class GrPlot {
33public:
34    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot);
35
36    GrTexture* texture() const { return fTexture; }
37
38    bool addSubImage(int width, int height, const void*, SkIPoint16*);
39
40    GrDrawTarget::DrawToken drawToken() const { return fDrawToken; }
41    void setDrawToken(GrDrawTarget::DrawToken draw) { fDrawToken = draw; }
42
43    void uploadToTexture();
44
45    void resetRects();
46
47private:
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
69typedef SkTInternalLList<GrPlot> GrPlotList;
70
71class GrAtlasMgr {
72public:
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
88    GrTexture* getTexture() const {
89        return fTexture;
90    }
91
92    void uploadPlotsToTexture();
93
94private:
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
111class GrAtlas {
112public:
113    GrAtlas() { }
114    ~GrAtlas() { }
115
116    bool isEmpty() { return 0 == fPlots.count(); }
117
118private:
119    SkTDArray<GrPlot*> fPlots;
120
121    friend class GrAtlasMgr;
122};
123
124#endif
125