OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 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 GrWindowRectangles_DEFINED | |
9 #define GrWindowRectangles_DEFINED | |
10 | |
11 #include "GrCaps.h" | |
12 #include <limits> | |
13 | |
14 class GrWindowRectangles { | |
15 public: | |
16 enum class Mode : bool { | |
17 kExclusive, | |
18 kInclusive | |
19 }; | |
20 | |
21 GrWindowRectangles(Mode mode = Mode::kExclusive) : fMode(mode), fCount(0) {} | |
22 GrWindowRectangles(const GrWindowRectangles& that) : fCount(0) { *this = tha t; } | |
23 ~GrWindowRectangles() { SkSafeUnref(this->rec()); } | |
24 | |
25 Mode mode() const { return fMode; } | |
26 uint16_t count() const { return fCount; } | |
27 const SkIRect* data() const; | |
28 | |
29 void reset(Mode mode = Mode::kExclusive); | |
30 GrWindowRectangles& operator=(const GrWindowRectangles&); | |
31 | |
32 void addWindow(const SkIRect& window, const GrCaps& caps) { this->addWindow( caps) = window; } | |
33 SkIRect& addWindow(const GrCaps& caps); | |
csmartdalton
2016/08/16 05:20:17
I'm thinking I'll replace this GrCaps param with j
csmartdalton
2016/08/16 23:38:34
Done. Just used a compile-time constant max as dis
| |
34 | |
35 bool operator!=(const GrWindowRectangles& that) const { return !(*this == th at); } | |
36 bool operator==(const GrWindowRectangles&) const; | |
37 | |
38 private: | |
39 constexpr static int kNumLocalWindows = 1; | |
bsalomon
2016/08/16 19:03:55
What in practice is the limit for the number of wi
csmartdalton
2016/08/16 19:49:45
I believe it's 8 on NVIDIA. GrGLCaps limits us to
| |
40 class Rec; | |
41 | |
42 const Rec* rec() const { return fCount <= kNumLocalWindows ? nullptr : fRec; } | |
43 | |
44 Mode fMode; | |
45 uint8_t fCount; | |
46 union { | |
47 SkIRect fLocalWindows[kNumLocalWindows]; // If fCount <= kNumLocalWind ows. | |
48 Rec* fRec; // If fCount > kNumLocalWindo ws. | |
49 }; | |
50 }; | |
51 | |
52 class GrWindowRectangles::Rec { | |
bsalomon
2016/08/16 19:03:55
Inherit from GrNonAtomicRef?
csmartdalton
2016/08/16 19:49:45
GrWindowRectangles does need to peek at the ref co
csmartdalton
2016/08/16 23:38:34
Done.
| |
53 public: | |
54 static Rec* Create(const SkIRect* windows, int numWindows, const GrCaps& cap s) { | |
55 // "maxWindowRectangles - 1" because sizeof(Rec) already accounts for th e first SkIRect. | |
56 void* p = sk_malloc_throw(sizeof(Rec) + sizeof(SkIRect) * (caps.maxWindo wRectangles() - 1)); | |
57 return new (p) Rec(windows, numWindows, caps.maxWindowRectangles()); | |
58 } | |
59 | |
60 int refCnt() const { return fRefCnt; } | |
61 void ref() const { ++fRefCnt; } | |
62 void unref() const { if (--fRefCnt <= 0) sk_free(const_cast<Rec*>(this)); } | |
63 | |
64 SkDEBUGCODE(int dataLength() const { return fDataLength; }) | |
65 SkIRect* data() { return fData; } | |
66 | |
67 private: | |
68 Rec(const SkIRect* windows, int numWindows, int SkDEBUGCODE(dataLength)) | |
69 : SkDEBUGCODE(fDataLength(dataLength),) fRefCnt(1) { | |
70 SkASSERT(numWindows <= fDataLength); | |
71 memcpy(fData, windows, sizeof(SkIRect) * numWindows); | |
72 } | |
73 | |
74 SkDEBUGCODE(const int fDataLength;) | |
75 mutable int fRefCnt; | |
76 SkIRect fData[1]; | |
77 }; | |
78 | |
79 inline const SkIRect* GrWindowRectangles::data() const { | |
80 return fCount <= kNumLocalWindows ? fLocalWindows : fRec->data(); | |
81 } | |
82 | |
83 inline void GrWindowRectangles::reset(Mode mode) { | |
84 SkSafeUnref(this->rec()); | |
85 fMode = mode; | |
86 fCount = 0; | |
87 } | |
88 | |
89 inline GrWindowRectangles& GrWindowRectangles::operator=(const GrWindowRectangle s& that) { | |
90 SkSafeUnref(this->rec()); | |
91 fMode = that.fMode; | |
92 fCount = that.fCount; | |
93 if (fCount <= kNumLocalWindows) { | |
94 memcpy(fLocalWindows, that.fLocalWindows, fCount * sizeof(SkIRect)); | |
95 } else { | |
96 fRec = SkRef(that.fRec); | |
97 } | |
98 return *this; | |
99 } | |
100 | |
101 inline SkIRect& GrWindowRectangles::addWindow(const GrCaps& caps) { | |
102 SkASSERT(fCount < caps.maxWindowRectangles()); | |
103 if (fCount < kNumLocalWindows) { | |
104 return fLocalWindows[fCount++]; | |
105 } | |
106 if (fCount == kNumLocalWindows) { | |
107 fRec = Rec::Create(fLocalWindows, kNumLocalWindows, caps); | |
108 } else if (fRec->refCnt() > 1) { // Simple copy-on-write. | |
109 fRec->unref(); | |
110 fRec = Rec::Create(fRec->data(), fCount, caps); | |
111 } | |
112 SkASSERT(fRec->dataLength() == caps.maxWindowRectangles()); | |
113 SkASSERT(fRec->dataLength() <= std::numeric_limits<decltype(fCount)>::max()) ; | |
114 return fRec->data()[fCount++]; | |
115 } | |
116 | |
117 inline bool GrWindowRectangles::operator==(const GrWindowRectangles& that) const { | |
118 if (fMode != that.fMode || fCount != that.fCount) { | |
119 return false; | |
120 } | |
121 if (fCount > kNumLocalWindows && fRec == that.fRec) { | |
122 return true; | |
123 } | |
124 return !fCount || !memcmp(this->data(), that.data(), sizeof(SkIRect) * fCoun t); | |
125 } | |
126 | |
127 #endif | |
OLD | NEW |