| 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 | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 24 | // Atlased layers get a ref to their atlas GrTexture and 'fRect' contains |
| 25 | // their absolute location in the backing texture. |
| skia.committer@gmail.com | d942731 | 2014-04-12 03:05:59 +0000 | [diff] [blame] | 26 | // |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 27 | // Non-atlased layers get a ref to the GrTexture in which they reside. Their |
| 28 | // 'fRect' will be empty. |
| 29 | // |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 30 | // TODO: can we easily reuse the empty space in the non-atlased GrTexture's? |
| 31 | struct GrCachedLayer { |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 32 | public: |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 33 | GrCachedLayer(uint32_t pictureID, int layerID) { |
| 34 | fPictureID = pictureID; |
| 35 | fLayerID = layerID; |
| 36 | fTexture = NULL; |
| 37 | fRect = GrIRect16::MakeEmpty(); |
| 38 | } |
| 39 | |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 40 | uint32_t pictureID() const { return fPictureID; } |
| 41 | int layerID() const { return fLayerID; } |
| 42 | |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 43 | // This call takes over the caller's ref |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 44 | void setTexture(GrTexture* texture, const GrIRect16& rect) { |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 45 | if (NULL != fTexture) { |
| 46 | fTexture->unref(); |
| 47 | } |
| 48 | |
| 49 | fTexture = texture; // just take over caller's ref |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 50 | fRect = rect; |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 51 | } |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 52 | GrTexture* texture() { return fTexture; } |
| 53 | const GrIRect16& rect() const { return fRect; } |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 54 | |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 55 | private: |
| 56 | uint32_t fPictureID; |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 57 | // fLayerID is only valid when fPicture != kInvalidGenID in which case it |
| 58 | // 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] | 59 | int fLayerID; |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 60 | |
| skia.committer@gmail.com | d942731 | 2014-04-12 03:05:59 +0000 | [diff] [blame] | 61 | // 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] | 62 | // ref on a GrTexture for non-atlased textures. In both cases, if this is |
| 63 | // non-NULL, that means that the texture is locked in the texture cache. |
| 64 | GrTexture* fTexture; |
| 65 | |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 66 | // For non-atlased layers 'fRect' is empty otherwise it is the bound of |
| 67 | // the layer in the atlas. |
| 68 | GrIRect16 fRect; |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 69 | }; |
| 70 | |
| 71 | // The GrLayerCache caches pre-computed saveLayers for later rendering. |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 72 | // Non-atlased layers are stored in their own GrTexture while the atlased |
| 73 | // layers share a single GrTexture. |
| robertphillips | 1d86ee8 | 2014-06-24 15:08:49 -0700 | [diff] [blame] | 74 | // 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] | 75 | // and one GrPlot (for the entire atlas). As such, the GrLayerCache |
| 76 | // roughly combines the functionality of the GrFontCache and GrTextStrike |
| 77 | // classes. |
| 78 | class GrLayerCache { |
| 79 | public: |
| robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 80 | GrLayerCache(GrContext*); |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 81 | ~GrLayerCache(); |
| 82 | |
| robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 83 | // As a cache, the GrLayerCache can be ordered to free up all its cached |
| 84 | // elements by the GrContext |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 85 | void freeAll(); |
| 86 | |
| robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 87 | GrCachedLayer* findLayer(const SkPicture* picture, int layerID); |
| 88 | GrCachedLayer* findLayerOrCreate(const SkPicture* picture, int layerID); |
| 89 | |
| 90 | // Inform the cache that layer's cached image is now required. Return true |
| 91 | // if it was found in the ResourceCache and doesn't need to be regenerated. |
| 92 | // If false is returned the caller should (re)render the layer into the |
| 93 | // newly acquired texture. |
| 94 | bool lock(GrCachedLayer* layer, const GrTextureDesc& desc); |
| 95 | |
| 96 | // Inform the cache that layer's cached image is not currently required |
| 97 | void unlock(GrCachedLayer* layer); |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 98 | |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 99 | // Remove all the layers (and unlock any resources) associated with 'picture' |
| 100 | void purge(const SkPicture* picture); |
| 101 | |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 102 | private: |
| robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 103 | GrContext* fContext; // pointer back to owning context |
| robertphillips | 1d86ee8 | 2014-06-24 15:08:49 -0700 | [diff] [blame] | 104 | SkAutoTDelete<GrAtlas> fAtlas; // TODO: could lazily allocate |
| 105 | GrAtlas::ClientPlotUsage fPlotUsage; |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 106 | |
| 107 | class PictureLayerKey; |
| commit-bot@chromium.org | 365cd31 | 2014-04-11 15:53:47 +0000 | [diff] [blame] | 108 | GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash; |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 109 | |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 110 | void initAtlas(); |
| robertphillips | 4ec84da | 2014-06-24 13:10:43 -0700 | [diff] [blame] | 111 | GrCachedLayer* createLayer(const SkPicture* picture, int layerID); |
| robertphillips | 952841b | 2014-06-30 08:26:50 -0700 | [diff] [blame] | 112 | |
| 113 | // for testing |
| 114 | friend class GetNumLayers; |
| 115 | int numLayers() const { return fLayerHash.count(); } |
| robertphillips@google.com | e930a07 | 2014-04-03 00:34:27 +0000 | [diff] [blame] | 116 | }; |
| 117 | |
| 118 | #endif |