blob: 5ef2dab82bc5e23f5f8534c28274e694df7afeab [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
reed@google.comac10a2d2010-12-22 21:39:39 +00009#ifndef GrAtlas_DEFINED
10#define GrAtlas_DEFINED
11
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +000012
robertphillipsea461502015-05-26 11:38:03 -070013#include "SkTDArray.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000014#include "GrTexture.h"
bsalomonc44be0e2014-07-25 07:32:33 -070015#include "SkPoint.h"
16#include "SkTInternalLList.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017
18class GrGpu;
19class GrRectanizer;
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +000020class GrAtlas;
reed@google.comac10a2d2010-12-22 21:39:39 +000021
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +000022// 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
robertphillips1d86ee82014-06-24 15:08:49 -070026// GrAtlas can request a new GrPlot via GrAtlas::addToAtlas().
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +000027//
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.
robertphillips1d86ee82014-06-24 15:08:49 -070030// GrAtlas::removeUnusedPlots() will free up any finished plots for a given GrAtlas.
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +000031
32class GrPlot {
reed@google.comac10a2d2010-12-22 21:39:39 +000033public:
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +000034 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot);
skia.committer@gmail.comade9a342014-03-04 03:02:32 +000035
robertphillips17dabfc2014-07-16 13:26:24 -070036 // This returns a plot ID unique to each plot in a given GrAtlas. They are
37 // consecutive and start at 0.
38 int id() const { return fID; }
39
reed@google.comac10a2d2010-12-22 21:39:39 +000040 GrTexture* texture() const { return fTexture; }
41
robertphillipsd5373412014-06-02 10:20:14 -070042 bool addSubImage(int width, int height, const void*, SkIPoint16*);
reed@google.comac10a2d2010-12-22 21:39:39 +000043
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +000044 void resetRects();
45
reed@google.comac10a2d2010-12-22 21:39:39 +000046private:
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +000047 GrPlot();
48 ~GrPlot(); // does not try to delete the fNext field
robertphillips17dabfc2014-07-16 13:26:24 -070049 void init(GrAtlas* atlas, int id, int offX, int offY, int width, int height, size_t bpp,
commit-bot@chromium.org7801faa2014-05-14 15:14:51 +000050 bool batchUploads);
reed@google.comac10a2d2010-12-22 21:39:39 +000051
robertphillips17dabfc2014-07-16 13:26:24 -070052 int fID;
commit-bot@chromium.org7801faa2014-05-14 15:14:51 +000053 unsigned char* fPlotData;
commit-bot@chromium.orga8916ff2013-08-16 15:53:46 +000054 GrTexture* fTexture;
55 GrRectanizer* fRects;
robertphillips1d86ee82014-06-24 15:08:49 -070056 GrAtlas* fAtlas;
robertphillipsd5373412014-06-02 10:20:14 -070057 SkIPoint16 fOffset; // the offset of the plot in the backing texture
robertphillips@google.com8b169312013-10-15 17:47:36 +000058 size_t fBytesPerPixel;
commit-bot@chromium.org7801faa2014-05-14 15:14:51 +000059 SkIRect fDirtyRect;
60 bool fDirty;
61 bool fBatchUploads;
reed@google.comac10a2d2010-12-22 21:39:39 +000062
robertphillips1d86ee82014-06-24 15:08:49 -070063 friend class GrAtlas;
reed@google.comac10a2d2010-12-22 21:39:39 +000064};
65
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +000066typedef SkTInternalLList<GrPlot> GrPlotList;
67
robertphillips1d86ee82014-06-24 15:08:49 -070068class GrAtlas {
reed@google.comac10a2d2010-12-22 21:39:39 +000069public:
robertphillips1d86ee82014-06-24 15:08:49 -070070 // This class allows each client to independently track the GrPlots in
71 // which its data is stored.
72 class ClientPlotUsage {
73 public:
74 bool isEmpty() const { return 0 == fPlots.count(); }
75
robertphillips320c9232014-07-29 06:07:19 -070076#ifdef SK_DEBUG
77 bool contains(const GrPlot* plot) const {
78 return fPlots.contains(const_cast<GrPlot*>(plot));
79 }
80#endif
81
robertphillips1d86ee82014-06-24 15:08:49 -070082 private:
83 SkTDArray<GrPlot*> fPlots;
84
85 friend class GrAtlas;
86 };
87
bsalomonf2703d82014-10-28 14:33:06 -070088 GrAtlas(GrGpu*, GrPixelConfig, GrSurfaceFlags flags,
robertphillips952841b2014-06-30 08:26:50 -070089 const SkISize& backingTextureSize,
robertphillips1d86ee82014-06-24 15:08:49 -070090 int numPlotsX, int numPlotsY, bool batchUploads);
91 ~GrAtlas();
reed@google.comac10a2d2010-12-22 21:39:39 +000092
robertphillips952841b2014-06-30 08:26:50 -070093 // Adds a width x height subimage to the atlas. Upon success it returns
94 // the containing GrPlot and absolute location in the backing texture.
95 // NULL is returned if the subimage cannot fit in the atlas.
96 // If provided, the image data will either be immediately uploaded or
97 // written to the CPU-side backing bitmap.
98 GrPlot* addToAtlas(ClientPlotUsage*, int width, int height, const void* image, SkIPoint16* loc);
skia.committer@gmail.com50df4d02013-09-28 07:01:33 +000099
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +0000100 // remove reference to this plot
robertphillipsc4f30b12014-07-13 10:09:42 -0700101 static void RemovePlot(ClientPlotUsage* usage, const GrPlot* plot);
skia.committer@gmail.com50df4d02013-09-28 07:01:33 +0000102
commit-bot@chromium.org3fddf0e2013-09-26 12:57:19 +0000103 GrTexture* getTexture() const {
104 return fTexture;
reed@google.com759c16e2011-03-15 19:15:15 +0000105 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000106
robertphillips320c9232014-07-29 06:07:19 -0700107 enum IterOrder {
108 kLRUFirst_IterOrder,
109 kMRUFirst_IterOrder
110 };
111
112 typedef GrPlotList::Iter PlotIter;
113 GrPlot* iterInit(PlotIter* iter, IterOrder order) {
joshualitt8debd892015-05-19 15:05:24 -0700114 return iter->init(fPlotList, kLRUFirst_IterOrder == order
robertphillips320c9232014-07-29 06:07:19 -0700115 ? GrPlotList::Iter::kTail_IterStart
116 : GrPlotList::Iter::kHead_IterStart);
117 }
118
reed@google.comac10a2d2010-12-22 21:39:39 +0000119private:
robertphillips1d86ee82014-06-24 15:08:49 -0700120 void makeMRU(GrPlot* plot);
skia.committer@gmail.com50df4d02013-09-28 07:01:33 +0000121
robertphillips952841b2014-06-30 08:26:50 -0700122 GrGpu* fGpu;
123 GrPixelConfig fPixelConfig;
bsalomonf2703d82014-10-28 14:33:06 -0700124 GrSurfaceFlags fFlags;
robertphillips952841b2014-06-30 08:26:50 -0700125 GrTexture* fTexture;
126 SkISize fBackingTextureSize;
127 int fNumPlotsX;
128 int fNumPlotsY;
129 bool fBatchUploads;
skia.committer@gmail.com50df4d02013-09-28 07:01:33 +0000130
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +0000131 // allocated array of GrPlots
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +0000132 GrPlot* fPlotArray;
robertphillips1d86ee82014-06-24 15:08:49 -0700133 // LRU list of GrPlots (MRU at head - LRU at tail)
commit-bot@chromium.orgc9b2c882014-03-03 14:30:25 +0000134 GrPlotList fPlotList;
commit-bot@chromium.org7d330eb2013-09-27 19:39:38 +0000135};
136
reed@google.comac10a2d2010-12-22 21:39:39 +0000137#endif