aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrLayerCache.h
blob: a7ba2afb30f2a63969b5234d17b881a65b115189 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrLayerCache_DEFINED
#define GrLayerCache_DEFINED

#include "GrAllocPool.h"
#include "GrAtlas.h"
#include "GrTHashTable.h"
#include "GrPictureUtils.h"
#include "GrRect.h"

class GrGpu;
class SkPicture;

// GrAtlasLocation captures an atlased item's position in the atlas. This
// means the plot in which it resides and its bounds inside the plot.
// TODO: Make GrGlyph use one of these?
class GrAtlasLocation {
public:
    GrAtlasLocation() : fPlot(NULL) {}

    void set(GrPlot* plot, const GrIRect16& bounds) {
        fPlot = plot;
        fBounds = bounds;
    }

    const GrPlot* plot() const {
        return fPlot;
    }

    const GrIRect16& bounds() const {
        return fBounds;
    }

private:
    GrPlot*   fPlot;
    GrIRect16 fBounds;  // only valid is fPlot != NULL
};

// GrCachedLayer encapsulates the caching information for a single saveLayer.
//
// Atlased layers get a ref to their atlas GrTexture and their GrAtlasLocation
// is filled in.
// In this case GrCachedLayer is roughly equivalent to a GrGlyph in the font
// caching system.
//
// Non-atlased layers get a ref to the GrTexture in which they reside.
// TODO: can we easily reuse the empty space in the non-atlased GrTexture's?
struct GrCachedLayer {
public:
    uint32_t pictureID() const { return fPictureID; }
    int layerID() const { return fLayerID; }

    void init(uint32_t pictureID, int layerID) {
        fPictureID = pictureID;
        fLayerID   = layerID;
        fTexture   = NULL;
        fLocation.set(NULL, GrIRect16::MakeEmpty());
    }

    // This call takes over the caller's ref
    void setTexture(GrTexture* texture) {
        if (NULL != fTexture) {
            fTexture->unref();
        }

        fTexture = texture; // just take over caller's ref
    }
    GrTexture* getTexture() { return fTexture; }

private:
    uint32_t        fPictureID;
    // fLayerID is only valid when fPicture != kInvalidGenID in which case it
    // is the index of this layer in the picture (one of 0 .. #layers).
    int             fLayerID;

    // fTexture is a ref on the atlasing texture for atlased layers and a
    // ref on a GrTexture for non-atlased textures. In both cases, if this is
    // non-NULL, that means that the texture is locked in the texture cache.
    GrTexture*      fTexture;

    GrAtlasLocation fLocation;       // only valid if the layer is atlased
};

// The GrLayerCache caches pre-computed saveLayers for later rendering.
// Non-atlased layers are stored in their own GrTexture while the atlased
// layers share a single GrTexture.
// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888)
// and one GrPlot (for the entire atlas). As such, the GrLayerCache
// roughly combines the functionality of the GrFontCache and GrTextStrike
// classes.
class GrLayerCache {
public:
    GrLayerCache(GrContext*);
    ~GrLayerCache();

    // As a cache, the GrLayerCache can be ordered to free up all its cached
    // elements by the GrContext
    void freeAll();

    GrCachedLayer* findLayer(const SkPicture* picture, int layerID);
    GrCachedLayer* findLayerOrCreate(const SkPicture* picture, int layerID);
    
    // Inform the cache that layer's cached image is now required. Return true
    // if it was found in the ResourceCache and doesn't need to be regenerated.
    // If false is returned the caller should (re)render the layer into the
    // newly acquired texture.
    bool lock(GrCachedLayer* layer, const GrTextureDesc& desc);

    // Inform the cache that layer's cached image is not currently required
    void unlock(GrCachedLayer* layer);

private:
    GrContext*                fContext;  // pointer back to owning context
    SkAutoTDelete<GrAtlas>    fAtlas;    // TODO: could lazily allocate
    GrAtlas::ClientPlotUsage  fPlotUsage;

    class PictureLayerKey;
    GrTHashTable<GrCachedLayer, PictureLayerKey, 7> fLayerHash;
    GrTAllocPool<GrCachedLayer> fLayerPool;

    void init();
    GrCachedLayer* createLayer(const SkPicture* picture, int layerID);
};

#endif