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
|
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrStencilBuffer_DEFINED
#define GrStencilBuffer_DEFINED
#include "GrClipData.h"
#include "GrResource.h"
class GrRenderTarget;
class GrResourceEntry;
class GrStencilBuffer : public GrResource {
public:
virtual ~GrStencilBuffer() {
// currently each rt that has attached this sb keeps a ref
// TODO: allow SB to be purged and detach itself from rts
GrAssert(0 == fRTAttachmentCnt);
}
int width() const { return fWidth; }
int height() const { return fHeight; }
int bits() const { return fBits; }
int numSamples() const { return fSampleCnt; }
// called to note the last clip drawn to this buffer.
void setLastClip(const GrClipData& clipData, int width, int height) {
// the clip stack needs to be copied separately (and deeply) since
// it could change beneath the stencil buffer
fLastClipStack = *clipData.fClipStack;
fLastClipData.fClipStack = &fLastClipStack;
fLastClipData.fOrigin = clipData.fOrigin;
fLastClipWidth = width;
fLastClipHeight = height;
GrAssert(width <= fWidth);
GrAssert(height <= fHeight);
}
// called to determine if we have to render the clip into SB.
bool mustRenderClip(const GrClipData& clipData, int width, int height) const {
// The clip is in device space. That is it doesn't scale to fit a
// smaller RT. It is just truncated on the right / bottom edges.
// Note that this assumes that the viewport origin never moves within
// the stencil buffer. This is valid today.
return width > fLastClipWidth ||
height > fLastClipHeight ||
clipData != fLastClipData;
}
const GrClipData& getLastClip() const {
return fLastClipData;
}
// places the sb in the cache and locks it. Caller transfers
// a ref to the the cache which will unref when purged.
void transferToCacheAndLock();
void wasAttachedToRenderTarget(const GrRenderTarget* rt) {
++fRTAttachmentCnt;
}
void wasDetachedFromRenderTarget(const GrRenderTarget* rt);
protected:
GrStencilBuffer(GrGpu* gpu, int width, int height, int bits, int sampleCnt)
: GrResource(gpu)
, fWidth(width)
, fHeight(height)
, fBits(bits)
, fSampleCnt(sampleCnt)
, fLastClipStack()
, fLastClipData()
, fLastClipWidth(-1)
, fLastClipHeight(-1)
, fCacheEntry(NULL)
, fRTAttachmentCnt(0) {
}
// GrResource overrides
// subclass override must call INHERITED::onRelease
virtual void onRelease();
// subclass override must call INHERITED::onAbandon
virtual void onAbandon();
private:
void unlockInCache();
int fWidth;
int fHeight;
int fBits;
int fSampleCnt;
SkClipStack fLastClipStack;
GrClipData fLastClipData;
int fLastClipWidth;
int fLastClipHeight;
GrResourceEntry* fCacheEntry;
int fRTAttachmentCnt;
typedef GrResource INHERITED;
};
#endif
|