xref: /aosp_15_r20/frameworks/base/libs/hwui/canvas/OpBuffer.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #pragma once
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <algorithm>
20*d57664e9SAndroid Build Coastguard Worker #include <array>
21*d57664e9SAndroid Build Coastguard Worker #include <cinttypes>
22*d57664e9SAndroid Build Coastguard Worker #include <cstddef>
23*d57664e9SAndroid Build Coastguard Worker #include <cstdlib>
24*d57664e9SAndroid Build Coastguard Worker #include <type_traits>
25*d57664e9SAndroid Build Coastguard Worker #include <utility>
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker namespace android::uirenderer {
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker template <typename T>
30*d57664e9SAndroid Build Coastguard Worker struct OpBufferItemHeader {
31*d57664e9SAndroid Build Coastguard Worker     T type : 8;
32*d57664e9SAndroid Build Coastguard Worker     uint32_t size : 24;
33*d57664e9SAndroid Build Coastguard Worker };
34*d57664e9SAndroid Build Coastguard Worker 
35*d57664e9SAndroid Build Coastguard Worker struct OpBufferAllocationHeader {
36*d57664e9SAndroid Build Coastguard Worker     // Used size, including header size
37*d57664e9SAndroid Build Coastguard Worker     size_t used = 0;
38*d57664e9SAndroid Build Coastguard Worker     // Capacity, including header size
39*d57664e9SAndroid Build Coastguard Worker     size_t capacity = 0;
40*d57664e9SAndroid Build Coastguard Worker     // Offset relative to `this` at which the first item is
41*d57664e9SAndroid Build Coastguard Worker     size_t startOffset = 0;
42*d57664e9SAndroid Build Coastguard Worker     // Offset relative to `this` at which the last item is
43*d57664e9SAndroid Build Coastguard Worker     size_t endOffset = 0;
44*d57664e9SAndroid Build Coastguard Worker };
45*d57664e9SAndroid Build Coastguard Worker 
46*d57664e9SAndroid Build Coastguard Worker #define BE_OPBUFFERS_FRIEND()                                      \
47*d57664e9SAndroid Build Coastguard Worker     template <typename ItemTypes, template <ItemTypes> typename, typename, typename> \
48*d57664e9SAndroid Build Coastguard Worker     friend class OpBuffer
49*d57664e9SAndroid Build Coastguard Worker 
50*d57664e9SAndroid Build Coastguard Worker template <typename ItemTypes, template <ItemTypes> typename ItemContainer,
51*d57664e9SAndroid Build Coastguard Worker           typename BufferHeader = OpBufferAllocationHeader,
52*d57664e9SAndroid Build Coastguard Worker           typename ItemTypesSequence = std::make_index_sequence<static_cast<int>(ItemTypes::COUNT)>>
53*d57664e9SAndroid Build Coastguard Worker class OpBuffer {
54*d57664e9SAndroid Build Coastguard Worker     // Instead of re-aligning individual inserts, just pad the size of everything
55*d57664e9SAndroid Build Coastguard Worker     // to a multiple of pointer alignment. This assumes we never work with doubles.
56*d57664e9SAndroid Build Coastguard Worker     // Which we don't.
57*d57664e9SAndroid Build Coastguard Worker     static constexpr size_t Alignment = alignof(void*);
58*d57664e9SAndroid Build Coastguard Worker 
PadAlign(size_t size)59*d57664e9SAndroid Build Coastguard Worker     static constexpr size_t PadAlign(size_t size) {
60*d57664e9SAndroid Build Coastguard Worker         return (size + (Alignment - 1)) & -Alignment;
61*d57664e9SAndroid Build Coastguard Worker     }
62*d57664e9SAndroid Build Coastguard Worker 
63*d57664e9SAndroid Build Coastguard Worker public:
64*d57664e9SAndroid Build Coastguard Worker     static constexpr auto STARTING_SIZE = PadAlign(sizeof(BufferHeader));
65*d57664e9SAndroid Build Coastguard Worker     using ItemHeader = OpBufferItemHeader<ItemTypes>;
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker     explicit OpBuffer() = default;
68*d57664e9SAndroid Build Coastguard Worker 
69*d57664e9SAndroid Build Coastguard Worker     // Prevent copying by default
70*d57664e9SAndroid Build Coastguard Worker     OpBuffer(const OpBuffer&) = delete;
71*d57664e9SAndroid Build Coastguard Worker     void operator=(const OpBuffer&) = delete;
72*d57664e9SAndroid Build Coastguard Worker 
OpBuffer(OpBuffer && other)73*d57664e9SAndroid Build Coastguard Worker     OpBuffer(OpBuffer&& other) {
74*d57664e9SAndroid Build Coastguard Worker         mBuffer = other.mBuffer;
75*d57664e9SAndroid Build Coastguard Worker         other.mBuffer = nullptr;
76*d57664e9SAndroid Build Coastguard Worker     }
77*d57664e9SAndroid Build Coastguard Worker 
78*d57664e9SAndroid Build Coastguard Worker     void operator=(OpBuffer&& other) {
79*d57664e9SAndroid Build Coastguard Worker         destroy();
80*d57664e9SAndroid Build Coastguard Worker         mBuffer = other.mBuffer;
81*d57664e9SAndroid Build Coastguard Worker         other.mBuffer = nullptr;
82*d57664e9SAndroid Build Coastguard Worker     }
83*d57664e9SAndroid Build Coastguard Worker 
~OpBuffer()84*d57664e9SAndroid Build Coastguard Worker     ~OpBuffer() {
85*d57664e9SAndroid Build Coastguard Worker         destroy();
86*d57664e9SAndroid Build Coastguard Worker     }
87*d57664e9SAndroid Build Coastguard Worker 
capacity()88*d57664e9SAndroid Build Coastguard Worker     constexpr size_t capacity() const { return mBuffer ? mBuffer->capacity : 0; }
89*d57664e9SAndroid Build Coastguard Worker 
size()90*d57664e9SAndroid Build Coastguard Worker     constexpr size_t size() const { return mBuffer ? mBuffer->used : 0; }
91*d57664e9SAndroid Build Coastguard Worker 
remaining()92*d57664e9SAndroid Build Coastguard Worker     constexpr size_t remaining() const { return capacity() - size(); }
93*d57664e9SAndroid Build Coastguard Worker 
94*d57664e9SAndroid Build Coastguard Worker     // TODO: Add less-copy'ing variants of this. emplace_back? deferred initialization?
95*d57664e9SAndroid Build Coastguard Worker     template <ItemTypes T>
push_container(ItemContainer<T> && op)96*d57664e9SAndroid Build Coastguard Worker     void push_container(ItemContainer<T>&& op) {
97*d57664e9SAndroid Build Coastguard Worker         static_assert(alignof(ItemContainer<T>) <= Alignment);
98*d57664e9SAndroid Build Coastguard Worker         static_assert(offsetof(ItemContainer<T>, header) == 0);
99*d57664e9SAndroid Build Coastguard Worker 
100*d57664e9SAndroid Build Coastguard Worker         constexpr auto padded_size = PadAlign(sizeof(ItemContainer<T>));
101*d57664e9SAndroid Build Coastguard Worker         if (remaining() < padded_size) {
102*d57664e9SAndroid Build Coastguard Worker             resize(std::max(padded_size, capacity()) * 2);
103*d57664e9SAndroid Build Coastguard Worker         }
104*d57664e9SAndroid Build Coastguard Worker         mBuffer->endOffset = mBuffer->used;
105*d57664e9SAndroid Build Coastguard Worker         mBuffer->used += padded_size;
106*d57664e9SAndroid Build Coastguard Worker 
107*d57664e9SAndroid Build Coastguard Worker         void* allocateAt = reinterpret_cast<uint8_t*>(mBuffer) + mBuffer->endOffset;
108*d57664e9SAndroid Build Coastguard Worker         auto temp = new (allocateAt) ItemContainer<T>{std::move(op)};
109*d57664e9SAndroid Build Coastguard Worker         temp->header = {.type = T, .size = padded_size};
110*d57664e9SAndroid Build Coastguard Worker     }
111*d57664e9SAndroid Build Coastguard Worker 
resize(size_t newsize)112*d57664e9SAndroid Build Coastguard Worker     void resize(size_t newsize) {
113*d57664e9SAndroid Build Coastguard Worker         // Add the header size to newsize
114*d57664e9SAndroid Build Coastguard Worker         const size_t adjustedSize = newsize + STARTING_SIZE;
115*d57664e9SAndroid Build Coastguard Worker 
116*d57664e9SAndroid Build Coastguard Worker         if (adjustedSize < size()) {
117*d57664e9SAndroid Build Coastguard Worker             // todo: throw?
118*d57664e9SAndroid Build Coastguard Worker             return;
119*d57664e9SAndroid Build Coastguard Worker         }
120*d57664e9SAndroid Build Coastguard Worker         if (newsize == 0) {
121*d57664e9SAndroid Build Coastguard Worker             free(mBuffer);
122*d57664e9SAndroid Build Coastguard Worker             mBuffer = nullptr;
123*d57664e9SAndroid Build Coastguard Worker         } else {
124*d57664e9SAndroid Build Coastguard Worker             if (mBuffer) {
125*d57664e9SAndroid Build Coastguard Worker                 mBuffer = reinterpret_cast<BufferHeader*>(realloc(mBuffer, adjustedSize));
126*d57664e9SAndroid Build Coastguard Worker                 mBuffer->capacity = adjustedSize;
127*d57664e9SAndroid Build Coastguard Worker             } else {
128*d57664e9SAndroid Build Coastguard Worker                 mBuffer = new (malloc(adjustedSize)) BufferHeader();
129*d57664e9SAndroid Build Coastguard Worker                 mBuffer->capacity = adjustedSize;
130*d57664e9SAndroid Build Coastguard Worker                 mBuffer->used = STARTING_SIZE;
131*d57664e9SAndroid Build Coastguard Worker                 mBuffer->startOffset = STARTING_SIZE;
132*d57664e9SAndroid Build Coastguard Worker             }
133*d57664e9SAndroid Build Coastguard Worker         }
134*d57664e9SAndroid Build Coastguard Worker     }
135*d57664e9SAndroid Build Coastguard Worker 
136*d57664e9SAndroid Build Coastguard Worker     template <typename F>
for_each(F && f)137*d57664e9SAndroid Build Coastguard Worker     void for_each(F&& f) const {
138*d57664e9SAndroid Build Coastguard Worker         do_for_each(std::forward<F>(f), ItemTypesSequence{});
139*d57664e9SAndroid Build Coastguard Worker     }
140*d57664e9SAndroid Build Coastguard Worker 
141*d57664e9SAndroid Build Coastguard Worker     void clear();
142*d57664e9SAndroid Build Coastguard Worker 
first()143*d57664e9SAndroid Build Coastguard Worker     ItemHeader* first() const { return isEmpty() ? nullptr : itemAt(mBuffer->startOffset); }
144*d57664e9SAndroid Build Coastguard Worker 
last()145*d57664e9SAndroid Build Coastguard Worker     ItemHeader* last() const { return isEmpty() ? nullptr : itemAt(mBuffer->endOffset); }
146*d57664e9SAndroid Build Coastguard Worker 
147*d57664e9SAndroid Build Coastguard Worker     class sentinal {
148*d57664e9SAndroid Build Coastguard Worker     public:
sentinal(const uint8_t * end)149*d57664e9SAndroid Build Coastguard Worker         explicit sentinal(const uint8_t* end) : end(end) {}
150*d57664e9SAndroid Build Coastguard Worker     private:
151*d57664e9SAndroid Build Coastguard Worker         const uint8_t* const end;
152*d57664e9SAndroid Build Coastguard Worker     };
153*d57664e9SAndroid Build Coastguard Worker 
end()154*d57664e9SAndroid Build Coastguard Worker     sentinal end() const {
155*d57664e9SAndroid Build Coastguard Worker         return sentinal{end_ptr()};
156*d57664e9SAndroid Build Coastguard Worker     }
157*d57664e9SAndroid Build Coastguard Worker 
158*d57664e9SAndroid Build Coastguard Worker     template <ItemTypes T>
159*d57664e9SAndroid Build Coastguard Worker     class filtered_iterator {
160*d57664e9SAndroid Build Coastguard Worker     public:
filtered_iterator(uint8_t * start,const uint8_t * end)161*d57664e9SAndroid Build Coastguard Worker         explicit filtered_iterator(uint8_t* start, const uint8_t* end)
162*d57664e9SAndroid Build Coastguard Worker                 : mCurrent(start), mEnd(end) {
163*d57664e9SAndroid Build Coastguard Worker             ItemHeader* header = reinterpret_cast<ItemHeader*>(mCurrent);
164*d57664e9SAndroid Build Coastguard Worker             if (header->type != T) {
165*d57664e9SAndroid Build Coastguard Worker                 advance();
166*d57664e9SAndroid Build Coastguard Worker             }
167*d57664e9SAndroid Build Coastguard Worker         }
168*d57664e9SAndroid Build Coastguard Worker 
169*d57664e9SAndroid Build Coastguard Worker         filtered_iterator& operator++() {
170*d57664e9SAndroid Build Coastguard Worker             advance();
171*d57664e9SAndroid Build Coastguard Worker             return *this;
172*d57664e9SAndroid Build Coastguard Worker         }
173*d57664e9SAndroid Build Coastguard Worker 
174*d57664e9SAndroid Build Coastguard Worker         // Although this iterator self-terminates, we need a placeholder to compare against
175*d57664e9SAndroid Build Coastguard Worker         // to make for-each loops happy
176*d57664e9SAndroid Build Coastguard Worker         bool operator!=(const sentinal& other) const {
177*d57664e9SAndroid Build Coastguard Worker             return mCurrent != mEnd;
178*d57664e9SAndroid Build Coastguard Worker         }
179*d57664e9SAndroid Build Coastguard Worker 
180*d57664e9SAndroid Build Coastguard Worker         ItemContainer<T>& operator*() {
181*d57664e9SAndroid Build Coastguard Worker             return *reinterpret_cast<ItemContainer<T>*>(mCurrent);
182*d57664e9SAndroid Build Coastguard Worker         }
183*d57664e9SAndroid Build Coastguard Worker     private:
advance()184*d57664e9SAndroid Build Coastguard Worker         void advance() {
185*d57664e9SAndroid Build Coastguard Worker             ItemHeader* header = reinterpret_cast<ItemHeader*>(mCurrent);
186*d57664e9SAndroid Build Coastguard Worker             do {
187*d57664e9SAndroid Build Coastguard Worker                 mCurrent += header->size;
188*d57664e9SAndroid Build Coastguard Worker                 header = reinterpret_cast<ItemHeader*>(mCurrent);
189*d57664e9SAndroid Build Coastguard Worker             } while (mCurrent != mEnd && header->type != T);
190*d57664e9SAndroid Build Coastguard Worker         }
191*d57664e9SAndroid Build Coastguard Worker         uint8_t* mCurrent;
192*d57664e9SAndroid Build Coastguard Worker         const uint8_t* const mEnd;
193*d57664e9SAndroid Build Coastguard Worker     };
194*d57664e9SAndroid Build Coastguard Worker 
195*d57664e9SAndroid Build Coastguard Worker     template <ItemTypes T>
196*d57664e9SAndroid Build Coastguard Worker     class filtered_view {
197*d57664e9SAndroid Build Coastguard Worker     public:
filtered_view(uint8_t * start,const uint8_t * end)198*d57664e9SAndroid Build Coastguard Worker         explicit filtered_view(uint8_t* start, const uint8_t* end) : mStart(start), mEnd(end) {}
199*d57664e9SAndroid Build Coastguard Worker 
begin()200*d57664e9SAndroid Build Coastguard Worker         filtered_iterator<T> begin() const {
201*d57664e9SAndroid Build Coastguard Worker             return filtered_iterator<T>{mStart, mEnd};
202*d57664e9SAndroid Build Coastguard Worker         }
203*d57664e9SAndroid Build Coastguard Worker 
end()204*d57664e9SAndroid Build Coastguard Worker         sentinal end() const {
205*d57664e9SAndroid Build Coastguard Worker             return sentinal{mEnd};
206*d57664e9SAndroid Build Coastguard Worker         }
207*d57664e9SAndroid Build Coastguard Worker     private:
208*d57664e9SAndroid Build Coastguard Worker         uint8_t* mStart;
209*d57664e9SAndroid Build Coastguard Worker         const uint8_t* const mEnd;
210*d57664e9SAndroid Build Coastguard Worker     };
211*d57664e9SAndroid Build Coastguard Worker 
212*d57664e9SAndroid Build Coastguard Worker     template <ItemTypes T>
filter()213*d57664e9SAndroid Build Coastguard Worker     filtered_view<T> filter() const {
214*d57664e9SAndroid Build Coastguard Worker         return filtered_view<T>{start_ptr(), end_ptr()};
215*d57664e9SAndroid Build Coastguard Worker     }
216*d57664e9SAndroid Build Coastguard Worker 
217*d57664e9SAndroid Build Coastguard Worker private:
218*d57664e9SAndroid Build Coastguard Worker 
start_ptr()219*d57664e9SAndroid Build Coastguard Worker     uint8_t* start_ptr() const {
220*d57664e9SAndroid Build Coastguard Worker         return reinterpret_cast<uint8_t*>(mBuffer) + mBuffer->startOffset;
221*d57664e9SAndroid Build Coastguard Worker     }
222*d57664e9SAndroid Build Coastguard Worker 
end_ptr()223*d57664e9SAndroid Build Coastguard Worker     const uint8_t* end_ptr() const {
224*d57664e9SAndroid Build Coastguard Worker         return reinterpret_cast<uint8_t*>(mBuffer) + mBuffer->used;
225*d57664e9SAndroid Build Coastguard Worker     }
226*d57664e9SAndroid Build Coastguard Worker 
227*d57664e9SAndroid Build Coastguard Worker     template <typename F, std::size_t... I>
do_for_each(F && f,std::index_sequence<I...>)228*d57664e9SAndroid Build Coastguard Worker     void do_for_each(F&& f, std::index_sequence<I...>) const {
229*d57664e9SAndroid Build Coastguard Worker         // Validate we're not empty
230*d57664e9SAndroid Build Coastguard Worker         if (isEmpty()) return;
231*d57664e9SAndroid Build Coastguard Worker 
232*d57664e9SAndroid Build Coastguard Worker         // Setup the jump table, mapping from each type to a springboard that invokes the template
233*d57664e9SAndroid Build Coastguard Worker         // function with the appropriate concrete type
234*d57664e9SAndroid Build Coastguard Worker         using F_PTR = decltype(&f);
235*d57664e9SAndroid Build Coastguard Worker         using THUNK = void (*)(F_PTR, void*);
236*d57664e9SAndroid Build Coastguard Worker         static constexpr auto jump = std::array<THUNK, sizeof...(I)>{[](F_PTR fp, void* t) {
237*d57664e9SAndroid Build Coastguard Worker             (*fp)(reinterpret_cast<const ItemContainer<static_cast<ItemTypes>(I)>*>(t));
238*d57664e9SAndroid Build Coastguard Worker         }...};
239*d57664e9SAndroid Build Coastguard Worker 
240*d57664e9SAndroid Build Coastguard Worker         // Do the actual iteration of each item
241*d57664e9SAndroid Build Coastguard Worker         uint8_t* current = start_ptr();
242*d57664e9SAndroid Build Coastguard Worker         const uint8_t* end = end_ptr();
243*d57664e9SAndroid Build Coastguard Worker         while (current != end) {
244*d57664e9SAndroid Build Coastguard Worker             auto header = reinterpret_cast<ItemHeader*>(current);
245*d57664e9SAndroid Build Coastguard Worker             // `f` could be a destructor, so ensure all accesses to the OP happen prior to invoking
246*d57664e9SAndroid Build Coastguard Worker             // `f`
247*d57664e9SAndroid Build Coastguard Worker             auto it = (void*)current;
248*d57664e9SAndroid Build Coastguard Worker             current += header->size;
249*d57664e9SAndroid Build Coastguard Worker             jump[static_cast<int>(header->type)](&f, it);
250*d57664e9SAndroid Build Coastguard Worker         }
251*d57664e9SAndroid Build Coastguard Worker     }
252*d57664e9SAndroid Build Coastguard Worker 
destroy()253*d57664e9SAndroid Build Coastguard Worker     void destroy() {
254*d57664e9SAndroid Build Coastguard Worker         clear();
255*d57664e9SAndroid Build Coastguard Worker         resize(0);
256*d57664e9SAndroid Build Coastguard Worker     }
257*d57664e9SAndroid Build Coastguard Worker 
offsetIsValid(size_t offset)258*d57664e9SAndroid Build Coastguard Worker     bool offsetIsValid(size_t offset) const {
259*d57664e9SAndroid Build Coastguard Worker         return offset >= mBuffer->startOffset && offset < mBuffer->used;
260*d57664e9SAndroid Build Coastguard Worker     }
261*d57664e9SAndroid Build Coastguard Worker 
itemAt(size_t offset)262*d57664e9SAndroid Build Coastguard Worker     ItemHeader* itemAt(size_t offset) const {
263*d57664e9SAndroid Build Coastguard Worker         if (!offsetIsValid(offset)) return nullptr;
264*d57664e9SAndroid Build Coastguard Worker         return reinterpret_cast<ItemHeader*>(reinterpret_cast<uint8_t*>(mBuffer) + offset);
265*d57664e9SAndroid Build Coastguard Worker     }
266*d57664e9SAndroid Build Coastguard Worker 
isEmpty()267*d57664e9SAndroid Build Coastguard Worker     bool isEmpty() const { return mBuffer == nullptr || mBuffer->used == STARTING_SIZE; }
268*d57664e9SAndroid Build Coastguard Worker 
269*d57664e9SAndroid Build Coastguard Worker     BufferHeader* mBuffer = nullptr;
270*d57664e9SAndroid Build Coastguard Worker };
271*d57664e9SAndroid Build Coastguard Worker 
272*d57664e9SAndroid Build Coastguard Worker template <typename ItemTypes, template <ItemTypes> typename ItemContainer, typename BufferHeader,
273*d57664e9SAndroid Build Coastguard Worker         typename ItemTypeSequence>
clear()274*d57664e9SAndroid Build Coastguard Worker void OpBuffer<ItemTypes, ItemContainer, BufferHeader, ItemTypeSequence>::clear() {
275*d57664e9SAndroid Build Coastguard Worker 
276*d57664e9SAndroid Build Coastguard Worker     // Don't need to do anything if we don't have a buffer
277*d57664e9SAndroid Build Coastguard Worker     if (!mBuffer) return;
278*d57664e9SAndroid Build Coastguard Worker 
279*d57664e9SAndroid Build Coastguard Worker     for_each([](auto op) {
280*d57664e9SAndroid Build Coastguard Worker         using T = std::remove_reference_t<decltype(*op)>;
281*d57664e9SAndroid Build Coastguard Worker         op->~T();
282*d57664e9SAndroid Build Coastguard Worker     });
283*d57664e9SAndroid Build Coastguard Worker     mBuffer->used = STARTING_SIZE;
284*d57664e9SAndroid Build Coastguard Worker     mBuffer->startOffset = STARTING_SIZE;
285*d57664e9SAndroid Build Coastguard Worker     mBuffer->endOffset = 0;
286*d57664e9SAndroid Build Coastguard Worker }
287*d57664e9SAndroid Build Coastguard Worker 
288*d57664e9SAndroid Build Coastguard Worker }  // namespace android::uirenderer