michael@0: michael@0: /* michael@0: * Copyright 2010 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef GrAtlas_DEFINED michael@0: #define GrAtlas_DEFINED michael@0: michael@0: michael@0: #include "GrPoint.h" michael@0: #include "GrTexture.h" michael@0: #include "GrDrawTarget.h" michael@0: michael@0: class GrGpu; michael@0: class GrRectanizer; michael@0: class GrAtlasMgr; michael@0: class GrAtlas; michael@0: michael@0: // The backing GrTexture for a set of GrAtlases is broken into a spatial grid of GrPlots. When michael@0: // a GrAtlas needs space on the texture, it requests a GrPlot. Each GrAtlas can claim one michael@0: // or more GrPlots. The GrPlots keep track of subimage placement via their GrRectanizer. Once a michael@0: // GrPlot is "full" (i.e. there is no room for the new subimage according to the GrRectanizer), the michael@0: // GrAtlas can request a new GrPlot via GrAtlasMgr::addToAtlas(). michael@0: // michael@0: // If all GrPlots are allocated, the replacement strategy is up to the client. The drawToken is michael@0: // available to ensure that all draw calls are finished for that particular GrPlot. michael@0: // GrAtlasMgr::removeUnusedPlots() will free up any finished plots for a given GrAtlas. michael@0: michael@0: class GrPlot { michael@0: public: michael@0: SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot); michael@0: michael@0: int getOffsetX() const { return fOffset.fX; } michael@0: int getOffsetY() const { return fOffset.fY; } michael@0: michael@0: GrTexture* texture() const { return fTexture; } michael@0: michael@0: bool addSubImage(int width, int height, const void*, GrIPoint16*); michael@0: michael@0: GrDrawTarget::DrawToken drawToken() const { return fDrawToken; } michael@0: void setDrawToken(GrDrawTarget::DrawToken draw) { fDrawToken = draw; } michael@0: michael@0: void resetRects(); michael@0: michael@0: private: michael@0: GrPlot(); michael@0: ~GrPlot(); // does not try to delete the fNext field michael@0: michael@0: // for recycling michael@0: GrDrawTarget::DrawToken fDrawToken; michael@0: michael@0: GrTexture* fTexture; michael@0: GrRectanizer* fRects; michael@0: GrAtlasMgr* fAtlasMgr; michael@0: GrIPoint16 fOffset; michael@0: size_t fBytesPerPixel; michael@0: michael@0: friend class GrAtlasMgr; michael@0: }; michael@0: michael@0: typedef SkTInternalLList GrPlotList; michael@0: michael@0: class GrAtlasMgr { michael@0: public: michael@0: GrAtlasMgr(GrGpu*, GrPixelConfig); michael@0: ~GrAtlasMgr(); michael@0: michael@0: // add subimage of width, height dimensions to atlas michael@0: // returns the containing GrPlot and location relative to the backing texture michael@0: GrPlot* addToAtlas(GrAtlas*, int width, int height, const void*, GrIPoint16*); michael@0: michael@0: // remove reference to this plot michael@0: bool removePlot(GrAtlas* atlas, const GrPlot* plot); michael@0: michael@0: // get a plot that's not being used by the current draw michael@0: // this allows us to overwrite this plot without flushing michael@0: GrPlot* getUnusedPlot(); michael@0: michael@0: GrTexture* getTexture() const { michael@0: return fTexture; michael@0: } michael@0: michael@0: private: michael@0: void moveToHead(GrPlot* plot); michael@0: michael@0: GrGpu* fGpu; michael@0: GrPixelConfig fPixelConfig; michael@0: GrTexture* fTexture; michael@0: michael@0: // allocated array of GrPlots michael@0: GrPlot* fPlotArray; michael@0: // LRU list of GrPlots michael@0: GrPlotList fPlotList; michael@0: }; michael@0: michael@0: class GrAtlas { michael@0: public: michael@0: GrAtlas() { } michael@0: ~GrAtlas() { } michael@0: michael@0: bool isEmpty() { return 0 == fPlots.count(); } michael@0: michael@0: SkISize getSize() const; michael@0: michael@0: private: michael@0: SkTDArray fPlots; michael@0: michael@0: friend class GrAtlasMgr; michael@0: }; michael@0: michael@0: #endif