blob: 27479193aa5102724efd4eace527fc51f0160135 [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//
robertphillips952841b2014-06-30 08:26:50 -070024// Atlased layers get a ref to their atlas GrTexture and 'fRect' contains
25// their absolute location in the backing texture.
skia.committer@gmail.comd9427312014-04-12 03:05:59 +000026//
robertphillips952841b2014-06-30 08:26:50 -070027// Non-atlased layers get a ref to the GrTexture in which they reside. Their
28// 'fRect' will be empty.
29//
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000030// TODO: can we easily reuse the empty space in the non-atlased GrTexture's?
31struct GrCachedLayer {
robertphillips@google.come930a072014-04-03 00:34:27 +000032public:
robertphillips952841b2014-06-30 08:26:50 -070033 GrCachedLayer(uint32_t pictureID, int layerID) {
34 fPictureID = pictureID;
35 fLayerID = layerID;
36 fTexture = NULL;
37 fRect = GrIRect16::MakeEmpty();
38 }
39
robertphillips@google.come930a072014-04-03 00:34:27 +000040 uint32_t pictureID() const { return fPictureID; }
41 int layerID() const { return fLayerID; }
42
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000043 // This call takes over the caller's ref
robertphillips952841b2014-06-30 08:26:50 -070044 void setTexture(GrTexture* texture, const GrIRect16& rect) {
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000045 if (NULL != fTexture) {
46 fTexture->unref();
47 }
48
49 fTexture = texture; // just take over caller's ref
robertphillips952841b2014-06-30 08:26:50 -070050 fRect = rect;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000051 }
robertphillips952841b2014-06-30 08:26:50 -070052 GrTexture* texture() { return fTexture; }
53 const GrIRect16& rect() const { return fRect; }
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000054
robertphillips@google.come930a072014-04-03 00:34:27 +000055private:
56 uint32_t fPictureID;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000057 // 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.comd9427312014-04-12 03:05:59 +000059 int fLayerID;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000060
skia.committer@gmail.comd9427312014-04-12 03:05:59 +000061 // fTexture is a ref on the atlasing texture for atlased layers and a
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000062 // 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
robertphillips952841b2014-06-30 08:26:50 -070066 // For non-atlased layers 'fRect' is empty otherwise it is the bound of
67 // the layer in the atlas.
68 GrIRect16 fRect;
robertphillips@google.come930a072014-04-03 00:34:27 +000069};
70
71// The GrLayerCache caches pre-computed saveLayers for later rendering.
commit-bot@chromium.org365cd312014-04-11 15:53:47 +000072// Non-atlased layers are stored in their own GrTexture while the atlased
73// layers share a single GrTexture.
robertphillips1d86ee82014-06-24 15:08:49 -070074// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888)
robertphillips@google.come930a072014-04-03 00:34:27 +000075// and one GrPlot (for the entire atlas). As such, the GrLayerCache
76// roughly combines the functionality of the GrFontCache and GrTextStrike
77// classes.
78class GrLayerCache {
79public:
robertphillips4ec84da2014-06-24 13:10:43 -070080 GrLayerCache(GrContext*);
robertphillips@google.come930a072014-04-03 00:34:27 +000081 ~GrLayerCache();
82
robertphillips4ec84da2014-06-24 13:10:43 -070083 // As a cache, the GrLayerCache can be ordered to free up all its cached
84 // elements by the GrContext
robertphillips@google.come930a072014-04-03 00:34:27 +000085 void freeAll();
86
robertphillips4ec84da2014-06-24 13:10:43 -070087 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.come930a072014-04-03 00:34:27 +000098
robertphillips952841b2014-06-30 08:26:50 -070099 // Remove all the layers (and unlock any resources) associated with 'picture'
100 void purge(const SkPicture* picture);
101
robertphillips@google.come930a072014-04-03 00:34:27 +0000102private:
robertphillips4ec84da2014-06-24 13:10:43 -0700103 GrContext* fContext; // pointer back to owning context
robertphillips1d86ee82014-06-24 15:08:49 -0700104 SkAutoTDelete<GrAtlas> fAtlas; // TODO: could lazily allocate
105 GrAtlas::ClientPlotUsage fPlotUsage;
robertphillips@google.come930a072014-04-03 00:34:27 +0000106
107 class PictureLayerKey;
commit-bot@chromium.org365cd312014-04-11 15:53:47 +0000108 GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash;
robertphillips@google.come930a072014-04-03 00:34:27 +0000109
robertphillips952841b2014-06-30 08:26:50 -0700110 void initAtlas();
robertphillips4ec84da2014-06-24 13:10:43 -0700111 GrCachedLayer* createLayer(const SkPicture* picture, int layerID);
robertphillips952841b2014-06-30 08:26:50 -0700112
113 // for testing
114 friend class GetNumLayers;
115 int numLayers() const { return fLayerHash.count(); }
robertphillips@google.come930a072014-04-03 00:34:27 +0000116};
117
118#endif