robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 1 | /* |
| 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 | |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 11 | #define USE_ATLAS 0 |
| 12 | |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 13 | #include "GrAllocPool.h" |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 14 | #include "GrAtlas.h" |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 15 | #include "GrTHashTable.h" |
| 16 | #include "GrPictureUtils.h" |
| 17 | #include "GrRect.h" |
| 18 | |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 19 | class GrGpu; |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 20 | class SkPicture; |
| 21 | |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 22 | // GrCachedLayer encapsulates the caching information for a single saveLayer. |
| 23 | // |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 24 | // 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. |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 27 | // |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 28 | // TODO: can we easily reuse the empty space in the non-atlased GrTexture's? |
| 29 | struct GrCachedLayer { |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 30 | public: |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 31 | GrCachedLayer(uint32_t pictureID, int layerID) |
| 32 | : fAtlased(false) { |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 33 | fPictureID = pictureID; |
| 34 | fLayerID = layerID; |
| 35 | fTexture = NULL; |
| 36 | fRect = GrIRect16::MakeEmpty(); |
| 37 | } |
| 38 | |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 39 | uint32_t pictureID() const { return fPictureID; } |
| 40 | int layerID() const { return fLayerID; } |
| 41 | |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 42 | // This call takes over the caller's ref |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 43 | void setTexture(GrTexture* texture, const GrIRect16& rect) { |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 44 | if (NULL != fTexture) { |
| 45 | fTexture->unref(); |
| 46 | } |
| 47 | |
| 48 | fTexture = texture; // just take over caller's ref |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 49 | fRect = rect; |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 50 | } |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 51 | GrTexture* texture() { return fTexture; } |
| 52 | const GrIRect16& rect() const { return fRect; } |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 53 | |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 54 | void setAtlased(bool atlased) { fAtlased = atlased; } |
| 55 | bool isAtlased() const { return fAtlased; } |
| 56 | |
| 57 | SkDEBUGCODE(void validate(GrTexture* backingTexture) const;) |
| 58 | |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 59 | private: |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 60 | // ID of the picture of which this layer is a part |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 61 | uint32_t fPictureID; |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 62 | |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 63 | // 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.com | d942731 | 2014-04-12 03:05:59 +0000 | [diff] [blame] | 65 | int fLayerID; |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 66 | |
skia.committer@gmail.com | d942731 | 2014-04-12 03:05:59 +0000 | [diff] [blame] | 67 | // fTexture is a ref on the atlasing texture for atlased layers and a |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 68 | // 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 | |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 72 | // 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. |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 78 | GrIRect16 fRect; |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 79 | }; |
| 80 | |
| 81 | // The GrLayerCache caches pre-computed saveLayers for later rendering. |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 82 | // Non-atlased layers are stored in their own GrTexture while the atlased |
| 83 | // layers share a single GrTexture. |
robertphillips | 1d86ee8 | 2014-06-24 15:08:49 -0700 | [diff] [blame] | 84 | // Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888) |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 85 | // and one GrPlot (for the entire atlas). As such, the GrLayerCache |
| 86 | // roughly combines the functionality of the GrFontCache and GrTextStrike |
| 87 | // classes. |
| 88 | class GrLayerCache { |
| 89 | public: |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 90 | GrLayerCache(GrContext*); |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 91 | ~GrLayerCache(); |
| 92 | |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 93 | // As a cache, the GrLayerCache can be ordered to free up all its cached |
| 94 | // elements by the GrContext |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 95 | void freeAll(); |
| 96 | |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 97 | 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.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 108 | |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 109 | // Remove all the layers (and unlock any resources) associated with 'picture' |
| 110 | void purge(const SkPicture* picture); |
| 111 | |
robertphillips | 21048b5 | 2014-07-15 19:46:35 -0700 | [diff] [blame] | 112 | SkDEBUGCODE(void validate() const;) |
| 113 | |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 114 | private: |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 115 | GrContext* fContext; // pointer back to owning context |
robertphillips | 1d86ee8 | 2014-06-24 15:08:49 -0700 | [diff] [blame] | 116 | SkAutoTDelete<GrAtlas> fAtlas; // TODO: could lazily allocate |
| 117 | GrAtlas::ClientPlotUsage fPlotUsage; |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 118 | |
| 119 | class PictureLayerKey; |
commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 120 | GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash; |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 121 | |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 122 | void initAtlas(); |
robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 123 | GrCachedLayer* createLayer(const SkPicture* picture, int layerID); |
robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 124 | |
| 125 | // for testing |
| 126 | friend class GetNumLayers; |
| 127 | int numLayers() const { return fLayerHash.count(); } |
robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 128 | }; |
| 129 | |
| 130 | #endif |