blob: 566a738279bc5f4d6e52cb6c9e270d01a16f8038 [file] [log] [blame]
robertphillips@google.come930a072014-04-03 00:34:27 +00001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrLayerCache_DEFINED
9#define GrLayerCache_DEFINED
10
robertphillips952841b2014-06-30 08:26:50 -070011#define USE_ATLAS 0
12
robertphillips@google.come930a072014-04-03 00:34:27 +000013#include "GrAllocPool.h"
robertphillips4ec84da2014-06-24 13:10:43 -070014#include "GrAtlas.h"
robertphillips@google.come930a072014-04-03 00:34:27 +000015#include "GrTHashTable.h"
16#include "GrPictureUtils.h"
17#include "GrRect.h"
18
robertphillips@google.come930a072014-04-03 00:34:27 +000019class GrGpu;
robertphillips@google.come930a072014-04-03 00:34:27 +000020class SkPicture;
21
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000022// GrCachedLayer encapsulates the caching information for a single saveLayer.
23//
robertphillips21048b52014-07-15 19:46:35 -070024// Atlased layers get a ref to the backing GrTexture while non-atlased layers
25// get a ref to the GrTexture in which they reside. In both cases 'fRect'
26// contains the layer's extent in its texture.
robertphillips952841b2014-06-30 08:26:50 -070027//
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000028// TODO: can we easily reuse the empty space in the non-atlased GrTexture's?
29struct GrCachedLayer {
robertphillips@google.come930a072014-04-03 00:34:27 +000030public:
robertphillips21048b52014-07-15 19:46:35 -070031 GrCachedLayer(uint32_t pictureID, int layerID)
32 : fAtlased(false) {
robertphillips952841b2014-06-30 08:26:50 -070033 fPictureID = pictureID;
34 fLayerID = layerID;
35 fTexture = NULL;
36 fRect = GrIRect16::MakeEmpty();
37 }
38
robertphillips@google.come930a072014-04-03 00:34:27 +000039 uint32_t pictureID() const { return fPictureID; }
40 int layerID() const { return fLayerID; }
41
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000042 // This call takes over the caller's ref
robertphillips952841b2014-06-30 08:26:50 -070043 void setTexture(GrTexture* texture, const GrIRect16& rect) {
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000044 if (NULL != fTexture) {
45 fTexture->unref();
46 }
47
48 fTexture = texture; // just take over caller's ref
robertphillips952841b2014-06-30 08:26:50 -070049 fRect = rect;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000050 }
robertphillips952841b2014-06-30 08:26:50 -070051 GrTexture* texture() { return fTexture; }
52 const GrIRect16& rect() const { return fRect; }
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000053
robertphillips21048b52014-07-15 19:46:35 -070054 void setAtlased(bool atlased) { fAtlased = atlased; }
55 bool isAtlased() const { return fAtlased; }
56
57 SkDEBUGCODE(void validate(GrTexture* backingTexture) const;)
58
robertphillips@google.come930a072014-04-03 00:34:27 +000059private:
robertphillips21048b52014-07-15 19:46:35 -070060 // ID of the picture of which this layer is a part
robertphillips@google.come930a072014-04-03 00:34:27 +000061 uint32_t fPictureID;
robertphillips21048b52014-07-15 19:46:35 -070062
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000063 // fLayerID is only valid when fPicture != kInvalidGenID in which case it
64 // is the index of this layer in the picture (one of 0 .. #layers).
skia.committer@gmail.comd9427312014-04-12 03:05:59 +000065 int fLayerID;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000066
skia.committer@gmail.comd9427312014-04-12 03:05:59 +000067 // fTexture is a ref on the atlasing texture for atlased layers and a
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000068 // ref on a GrTexture for non-atlased textures. In both cases, if this is
69 // non-NULL, that means that the texture is locked in the texture cache.
70 GrTexture* fTexture;
71
robertphillips21048b52014-07-15 19:46:35 -070072 // True if this layer is in an atlas; false otherwise.
73 bool fAtlased;
74
75 // For both atlased and non-atlased layers 'fRect' contains the bound of
76 // the layer in whichever texture it resides. It is empty when 'fTexture'
77 // is NULL.
robertphillips952841b2014-06-30 08:26:50 -070078 GrIRect16 fRect;
robertphillips@google.come930a072014-04-03 00:34:27 +000079};
80
81// The GrLayerCache caches pre-computed saveLayers for later rendering.
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000082// Non-atlased layers are stored in their own GrTexture while the atlased
83// layers share a single GrTexture.
robertphillips1d86ee82014-06-24 15:08:49 -070084// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888)
robertphillips@google.come930a072014-04-03 00:34:27 +000085// and one GrPlot (for the entire atlas). As such, the GrLayerCache
86// roughly combines the functionality of the GrFontCache and GrTextStrike
87// classes.
88class GrLayerCache {
89public:
robertphillips4ec84da2014-06-24 13:10:43 -070090 GrLayerCache(GrContext*);
robertphillips@google.come930a072014-04-03 00:34:27 +000091 ~GrLayerCache();
92
robertphillips4ec84da2014-06-24 13:10:43 -070093 // As a cache, the GrLayerCache can be ordered to free up all its cached
94 // elements by the GrContext
robertphillips@google.come930a072014-04-03 00:34:27 +000095 void freeAll();
96
robertphillips4ec84da2014-06-24 13:10:43 -070097 GrCachedLayer* findLayer(const SkPicture* picture, int layerID);
98 GrCachedLayer* findLayerOrCreate(const SkPicture* picture, int layerID);
99
100 // Inform the cache that layer's cached image is now required. Return true
101 // if it was found in the ResourceCache and doesn't need to be regenerated.
102 // If false is returned the caller should (re)render the layer into the
103 // newly acquired texture.
104 bool lock(GrCachedLayer* layer, const GrTextureDesc& desc);
105
106 // Inform the cache that layer's cached image is not currently required
107 void unlock(GrCachedLayer* layer);
robertphillips@google.come930a072014-04-03 00:34:27 +0000108
robertphillips952841b2014-06-30 08:26:50 -0700109 // Remove all the layers (and unlock any resources) associated with 'picture'
110 void purge(const SkPicture* picture);
111
robertphillips21048b52014-07-15 19:46:35 -0700112 SkDEBUGCODE(void validate() const;)
113
robertphillips@google.come930a072014-04-03 00:34:27 +0000114private:
robertphillips4ec84da2014-06-24 13:10:43 -0700115 GrContext* fContext; // pointer back to owning context
robertphillips1d86ee82014-06-24 15:08:49 -0700116 SkAutoTDelete<GrAtlas> fAtlas; // TODO: could lazily allocate
117 GrAtlas::ClientPlotUsage fPlotUsage;
robertphillips@google.come930a072014-04-03 00:34:27 +0000118
119 class PictureLayerKey;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +0000120 GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash;
robertphillips@google.come930a072014-04-03 00:34:27 +0000121
robertphillips952841b2014-06-30 08:26:50 -0700122 void initAtlas();
robertphillips4ec84da2014-06-24 13:10:43 -0700123 GrCachedLayer* createLayer(const SkPicture* picture, int layerID);
robertphillips952841b2014-06-30 08:26:50 -0700124
125 // for testing
126 friend class GetNumLayers;
127 int numLayers() const { return fLayerHash.count(); }
robertphillips@google.come930a072014-04-03 00:34:27 +0000128};
129
130#endif