Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: src/gpu/GrTBaseList.h

Issue 628453002: Create a single command buffer for GrInOrderDrawBuffer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 GrTBaseList_DEFINED
9 #define GrTBaseList_DEFINED
10
11 #include "SkTemplates.h"
12 #include "SkTypes.h"
13
14 template<typename TBase, typename TAlign> class GrTBaseList;
15 template<typename T> class GrTBaseListAllocDesc;
16
17 template <typename TBase, typename TAlign, typename T>
18 void* operator new(size_t, GrTBaseList<TBase, TAlign>&, const GrTBaseListAllocDe sc<T>&);
19
20 /**
21 * List of objects with a common base type and permanent memory addresses.
bsalomon 2014/10/08 19:51:44 This thing seems complicated enough, and isolated
Chris Dalton 2014/10/09 00:06:59 Done.
22 *
23 * This class preallocates its own chunks of memory for storing items in the lis t, so new
24 * objects can be created without excessive calls to malloc().
bsalomon 2014/10/08 19:51:44 Comment about macros to push back? Casual user of
Chris Dalton 2014/10/09 00:06:59 Done.
25 *
26 * @param TBase Common base type of items in the list. If TBase is not a class with a
27 * virtual destructor, the client is responsible for invoking any necessary
28 * destructors.
29 *
30 * For now, any subclass used in the list must have the same star t address
31 * as TBase (or in other words, the types must be convertible via
32 * reinterpret_cast<>). Classes with multiple inheritance (or any subclass
33 * on an obscure compiler) may not be compatible. This is verifie d at
bsalomon 2014/10/08 19:51:45 Can we say "runtime asserted in debug builds" rath
Chris Dalton 2014/10/09 00:06:59 Done.
34 * runtime.
35 *
36 * @param TAlign A type whose size is the desired memory alignment for object a llocations.
37 * This should be the largest known alignment requirement for all objects
38 * that may be stored in the buffer.
39 */
40 template<typename TBase, typename TAlign> class GrTBaseList : SkNoncopyable {
bsalomon 2014/10/08 19:51:44 I'm having trouble coming up with a better name
41 public:
42 class Iter;
43
44 /**
45 * Create a contiguous list
bsalomon 2014/10/08 19:51:44 Can we not say contiguous? That seems like an impl
Chris Dalton 2014/10/09 00:06:59 Oops, I missed that one from before. Done.
46 *
47 * @param initialSizeInBytes The amount of memory reserved by the list init ially, and
48 * and after calls to reset().
49 */
50 GrTBaseList(int initialSizeInBytes)
51 : fHeadBlock(bytes_to_length(initialSizeInBytes)),
52 fTailBlock(&fHeadBlock),
53 fLastItem(NULL) {}
54
55 ~GrTBaseList() { this->reset(); }
56
57 bool empty() { return NULL == fLastItem; }
58
59 TBase& back() {
60 SkASSERT(!this->empty());
61 return *fLastItem;
62 }
63
64 /**
65 * Destruct all items in the list and reset to empty.
66 */
67 void reset();
68
69 private:
70 static int bytes_to_length(int bytes) { return (bytes + sizeof(TAlign) - 1) / sizeof(TAlign); }
71
72 struct ItemHeader {
73 int fTotalLength;
74 };
75 enum { kHeaderLength = (sizeof(ItemHeader) + sizeof(TAlign) - 1) / sizeof(TA lign) };
76
77 template<typename T> void* alloc_back(const GrTBaseListAllocDesc<T>&);
78
79 struct MemBlock {
80 MemBlock(int length) : fLength(length), fBack(0), fBuffer(fLength) {}
81 const int fLength;
82 int fBack;
83 SkAutoTMalloc<TAlign> fBuffer;
84 SkAutoTDelete<MemBlock> fNext;
85 };
86 MemBlock fHeadBlock;
87 MemBlock* fTailBlock;
88
89 TBase* fLastItem;
90
91 template <typename UBase, typename UAlign, typename U>
92 friend void* operator new(size_t, GrTBaseList<UBase, UAlign>&, const GrTBase ListAllocDesc<U>&);
93
94 friend class Iter;
95 };
96
97 /**
98 * Describes a new object allocation for GrTBaseList. Captures type and size.
99 */
100 template<typename T> class GrTBaseListAllocDesc {
101 public:
102 GrTBaseListAllocDesc(int sizeInBytes = sizeof(T)) : fSizeInBytes(sizeInBytes ) {}
103 int sizeInBytes() const { return fSizeInBytes; }
104 private:
105 const int fSizeInBytes;
106 };
107
108 ////////////////////////////////////////////////////////////////////////////////
109
110 template <typename TBase, typename TAlign, typename T>
111 void* operator new(size_t expectedClassSize,
bsalomon 2014/10/08 19:51:44 I think you'll need an operator delete. We don't c
Chris Dalton 2014/10/09 00:06:59 Done.
112 GrTBaseList<TBase, TAlign>& list,
113 const GrTBaseListAllocDesc<T>& desc) {
114 SkASSERT(expectedClassSize == sizeof(T));
115 SkASSERT(desc.sizeInBytes() >= (int)sizeof(T));
116 return list.alloc_back(desc);
117 }
118
119 template<typename TBase, typename TAlign>
120 template<typename T>
121 void* GrTBaseList<TBase, TAlign>::alloc_back(const GrTBaseListAllocDesc<T>& desc ) {
122 SkASSERT(desc.sizeInBytes() >= (int)sizeof(T));
123 const int totalLength = kHeaderLength + bytes_to_length(desc.sizeInBytes());
124
125 if (fTailBlock->fBack + totalLength > fTailBlock->fLength) {
126 SkASSERT(NULL == fTailBlock->fNext.get());
127 MemBlock* next = SkNEW_ARGS(MemBlock, (SkTMax(2 * fTailBlock->fLength, t otalLength)));
128 fTailBlock->fNext.reset(next);
129 fTailBlock = next;
130 }
131
132 ItemHeader* header = reinterpret_cast<ItemHeader*>(&fTailBlock->fBuffer[fTai lBlock->fBack]);
133 TBase* rawPtr = reinterpret_cast<T*>(&fTailBlock->fBuffer[fTailBlock->fBack + kHeaderLength]);
134 fTailBlock->fBack += totalLength;
135
136 header->fTotalLength = totalLength;
137
138 fLastItem = rawPtr;
139
140 // FIXME: We currently require that the base and subclass share the same sta rt address.
141 // This is not required by the C++ spec, and is likely to not be true in the case of
142 // multiple inheritance or a base class that doesn't have virtual methods (w hen the
143 // subclass does). It would be ideal to find a more robust solution that com es at no
144 // extra cost to performance or code generality.
145 SkDEBUGCODE(void* baseAddr = fLastItem;
146 void* subclassAddr = rawPtr);
147 SkASSERT(baseAddr == subclassAddr);
148
149 return rawPtr;
150 }
151
152 template<typename TBase, typename TAlign>
153 class GrTBaseList<TBase, TAlign>::Iter {
154 public:
155 Iter(GrTBaseList& list) : fBlock(&list.fHeadBlock), fPosition(0), fItem(NULL ) {}
156
157 bool next() {
158 if (fPosition >= fBlock->fBack) {
159 SkASSERT(fPosition == fBlock->fBack);
160 if (NULL == fBlock->fNext.get()) {
161 return false;
162 }
163 SkASSERT(0 != fBlock->fNext->fBack);
164 fBlock = fBlock->fNext.get();
165 fPosition = 0;
166 }
167
168 ItemHeader* header = reinterpret_cast<ItemHeader*>(&fBlock->fBuffer[fPos ition]);
169 fItem = reinterpret_cast<TBase*>(&fBlock->fBuffer[fPosition + kHeaderLen gth]);
170 fPosition += header->fTotalLength;
171 return true;
172 }
173
174 TBase* operator->() const {
175 SkASSERT(fItem);
176 return fItem;
177 }
178
179 private:
180 MemBlock* fBlock;
181 int fPosition;
182 TBase* fItem;
183 };
184
185 template<typename TBase, typename TAlign>
186 void GrTBaseList<TBase, TAlign>::reset() {
187 Iter iter(*this);
188 while (iter.next()) {
189 iter->~TBase();
190 }
191 fHeadBlock.fBack = 0;
192 fHeadBlock.fNext.free();
193 fTailBlock = &fHeadBlock;
194 fLastItem = NULL;
195 }
196
197 #define GrNEW_APPEND_TO_TBASELIST(list, type_name, args) \
198 (new (list, GrTBaseListAllocDesc<type_name>()) type_name args)
199
200 #define GrNEW_SIZE_APPEND_TO_TBASELIST(list, size, type_name, args) \
201 (new (list, GrTBaseListAllocDesc<type_name>(size)) type_name args)
202
203 #endif
OLDNEW
« src/gpu/GrInOrderDrawBuffer.cpp ('K') | « src/gpu/GrInOrderDrawBuffer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698