xref: /aosp_15_r20/external/angle/src/common/MemoryBuffer.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "common/MemoryBuffer.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
10*8975f5c5SAndroid Build Coastguard Worker #include <cstdlib>
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker namespace angle
15*8975f5c5SAndroid Build Coastguard Worker {
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker // MemoryBuffer implementation.
~MemoryBuffer()18*8975f5c5SAndroid Build Coastguard Worker MemoryBuffer::~MemoryBuffer()
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker     clear();
21*8975f5c5SAndroid Build Coastguard Worker }
22*8975f5c5SAndroid Build Coastguard Worker 
resize(size_t size)23*8975f5c5SAndroid Build Coastguard Worker bool MemoryBuffer::resize(size_t size)
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker     if (size == 0)
26*8975f5c5SAndroid Build Coastguard Worker     {
27*8975f5c5SAndroid Build Coastguard Worker         if (mData)
28*8975f5c5SAndroid Build Coastguard Worker         {
29*8975f5c5SAndroid Build Coastguard Worker             free(mData);
30*8975f5c5SAndroid Build Coastguard Worker             mData     = nullptr;
31*8975f5c5SAndroid Build Coastguard Worker             mCapacity = 0;
32*8975f5c5SAndroid Build Coastguard Worker         }
33*8975f5c5SAndroid Build Coastguard Worker         mSize = 0;
34*8975f5c5SAndroid Build Coastguard Worker         return true;
35*8975f5c5SAndroid Build Coastguard Worker     }
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker     if (size == mCapacity)
38*8975f5c5SAndroid Build Coastguard Worker     {
39*8975f5c5SAndroid Build Coastguard Worker         mSize = size;
40*8975f5c5SAndroid Build Coastguard Worker         return true;
41*8975f5c5SAndroid Build Coastguard Worker     }
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker     // Only reallocate if the size has changed.
44*8975f5c5SAndroid Build Coastguard Worker     uint8_t *newMemory = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * size));
45*8975f5c5SAndroid Build Coastguard Worker     if (newMemory == nullptr)
46*8975f5c5SAndroid Build Coastguard Worker     {
47*8975f5c5SAndroid Build Coastguard Worker         return false;
48*8975f5c5SAndroid Build Coastguard Worker     }
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker     if (mData)
51*8975f5c5SAndroid Build Coastguard Worker     {
52*8975f5c5SAndroid Build Coastguard Worker         // Copy the intersection of the old data and the new data
53*8975f5c5SAndroid Build Coastguard Worker         std::copy(mData, mData + std::min(mSize, size), newMemory);
54*8975f5c5SAndroid Build Coastguard Worker         free(mData);
55*8975f5c5SAndroid Build Coastguard Worker     }
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker     mData     = newMemory;
58*8975f5c5SAndroid Build Coastguard Worker     mCapacity = size;
59*8975f5c5SAndroid Build Coastguard Worker     mSize     = size;
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker     return true;
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker 
fill(uint8_t datum)64*8975f5c5SAndroid Build Coastguard Worker void MemoryBuffer::fill(uint8_t datum)
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker     if (!empty())
67*8975f5c5SAndroid Build Coastguard Worker     {
68*8975f5c5SAndroid Build Coastguard Worker         std::fill(mData, mData + mSize, datum);
69*8975f5c5SAndroid Build Coastguard Worker     }
70*8975f5c5SAndroid Build Coastguard Worker }
71*8975f5c5SAndroid Build Coastguard Worker 
MemoryBuffer(MemoryBuffer && other)72*8975f5c5SAndroid Build Coastguard Worker MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) : MemoryBuffer()
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker     *this = std::move(other);
75*8975f5c5SAndroid Build Coastguard Worker }
76*8975f5c5SAndroid Build Coastguard Worker 
operator =(MemoryBuffer && other)77*8975f5c5SAndroid Build Coastguard Worker MemoryBuffer &MemoryBuffer::operator=(MemoryBuffer &&other)
78*8975f5c5SAndroid Build Coastguard Worker {
79*8975f5c5SAndroid Build Coastguard Worker     std::swap(mSize, other.mSize);
80*8975f5c5SAndroid Build Coastguard Worker     std::swap(mCapacity, other.mCapacity);
81*8975f5c5SAndroid Build Coastguard Worker     std::swap(mData, other.mData);
82*8975f5c5SAndroid Build Coastguard Worker     return *this;
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker namespace
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker static constexpr uint32_t kDefaultScratchBufferLifetime = 1000u;
88*8975f5c5SAndroid Build Coastguard Worker 
89*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker // ScratchBuffer implementation.
ScratchBuffer()92*8975f5c5SAndroid Build Coastguard Worker ScratchBuffer::ScratchBuffer() : ScratchBuffer(kDefaultScratchBufferLifetime) {}
93*8975f5c5SAndroid Build Coastguard Worker 
ScratchBuffer(uint32_t lifetime)94*8975f5c5SAndroid Build Coastguard Worker ScratchBuffer::ScratchBuffer(uint32_t lifetime) : mLifetime(lifetime), mResetCounter(lifetime) {}
95*8975f5c5SAndroid Build Coastguard Worker 
~ScratchBuffer()96*8975f5c5SAndroid Build Coastguard Worker ScratchBuffer::~ScratchBuffer() {}
97*8975f5c5SAndroid Build Coastguard Worker 
ScratchBuffer(ScratchBuffer && other)98*8975f5c5SAndroid Build Coastguard Worker ScratchBuffer::ScratchBuffer(ScratchBuffer &&other)
99*8975f5c5SAndroid Build Coastguard Worker {
100*8975f5c5SAndroid Build Coastguard Worker     *this = std::move(other);
101*8975f5c5SAndroid Build Coastguard Worker }
102*8975f5c5SAndroid Build Coastguard Worker 
operator =(ScratchBuffer && other)103*8975f5c5SAndroid Build Coastguard Worker ScratchBuffer &ScratchBuffer::operator=(ScratchBuffer &&other)
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker     std::swap(mLifetime, other.mLifetime);
106*8975f5c5SAndroid Build Coastguard Worker     std::swap(mResetCounter, other.mResetCounter);
107*8975f5c5SAndroid Build Coastguard Worker     std::swap(mScratchMemory, other.mScratchMemory);
108*8975f5c5SAndroid Build Coastguard Worker     return *this;
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker 
get(size_t requestedSize,MemoryBuffer ** memoryBufferOut)111*8975f5c5SAndroid Build Coastguard Worker bool ScratchBuffer::get(size_t requestedSize, MemoryBuffer **memoryBufferOut)
112*8975f5c5SAndroid Build Coastguard Worker {
113*8975f5c5SAndroid Build Coastguard Worker     return getImpl(requestedSize, memoryBufferOut, Optional<uint8_t>::Invalid());
114*8975f5c5SAndroid Build Coastguard Worker }
115*8975f5c5SAndroid Build Coastguard Worker 
getInitialized(size_t requestedSize,MemoryBuffer ** memoryBufferOut,uint8_t initValue)116*8975f5c5SAndroid Build Coastguard Worker bool ScratchBuffer::getInitialized(size_t requestedSize,
117*8975f5c5SAndroid Build Coastguard Worker                                    MemoryBuffer **memoryBufferOut,
118*8975f5c5SAndroid Build Coastguard Worker                                    uint8_t initValue)
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker     return getImpl(requestedSize, memoryBufferOut, Optional<uint8_t>(initValue));
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker 
getImpl(size_t requestedSize,MemoryBuffer ** memoryBufferOut,Optional<uint8_t> initValue)123*8975f5c5SAndroid Build Coastguard Worker bool ScratchBuffer::getImpl(size_t requestedSize,
124*8975f5c5SAndroid Build Coastguard Worker                             MemoryBuffer **memoryBufferOut,
125*8975f5c5SAndroid Build Coastguard Worker                             Optional<uint8_t> initValue)
126*8975f5c5SAndroid Build Coastguard Worker {
127*8975f5c5SAndroid Build Coastguard Worker     mScratchMemory.setSizeToCapacity();
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     if (mScratchMemory.size() == requestedSize)
130*8975f5c5SAndroid Build Coastguard Worker     {
131*8975f5c5SAndroid Build Coastguard Worker         mResetCounter    = mLifetime;
132*8975f5c5SAndroid Build Coastguard Worker         *memoryBufferOut = &mScratchMemory;
133*8975f5c5SAndroid Build Coastguard Worker         return true;
134*8975f5c5SAndroid Build Coastguard Worker     }
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker     if (mScratchMemory.size() > requestedSize)
137*8975f5c5SAndroid Build Coastguard Worker     {
138*8975f5c5SAndroid Build Coastguard Worker         tick();
139*8975f5c5SAndroid Build Coastguard Worker     }
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker     if (mScratchMemory.size() < requestedSize)
142*8975f5c5SAndroid Build Coastguard Worker     {
143*8975f5c5SAndroid Build Coastguard Worker         if (!mScratchMemory.resize(requestedSize))
144*8975f5c5SAndroid Build Coastguard Worker         {
145*8975f5c5SAndroid Build Coastguard Worker             return false;
146*8975f5c5SAndroid Build Coastguard Worker         }
147*8975f5c5SAndroid Build Coastguard Worker         mResetCounter = mLifetime;
148*8975f5c5SAndroid Build Coastguard Worker         if (initValue.valid())
149*8975f5c5SAndroid Build Coastguard Worker         {
150*8975f5c5SAndroid Build Coastguard Worker             mScratchMemory.fill(initValue.value());
151*8975f5c5SAndroid Build Coastguard Worker         }
152*8975f5c5SAndroid Build Coastguard Worker     }
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mScratchMemory.size() >= requestedSize);
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     *memoryBufferOut = &mScratchMemory;
157*8975f5c5SAndroid Build Coastguard Worker     return true;
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker 
tick()160*8975f5c5SAndroid Build Coastguard Worker void ScratchBuffer::tick()
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker     if (mResetCounter > 0)
163*8975f5c5SAndroid Build Coastguard Worker     {
164*8975f5c5SAndroid Build Coastguard Worker         --mResetCounter;
165*8975f5c5SAndroid Build Coastguard Worker         if (mResetCounter == 0)
166*8975f5c5SAndroid Build Coastguard Worker         {
167*8975f5c5SAndroid Build Coastguard Worker             clear();
168*8975f5c5SAndroid Build Coastguard Worker         }
169*8975f5c5SAndroid Build Coastguard Worker     }
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker 
clear()172*8975f5c5SAndroid Build Coastguard Worker void ScratchBuffer::clear()
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker     mResetCounter = mLifetime;
175*8975f5c5SAndroid Build Coastguard Worker     if (mScratchMemory.size() > 0)
176*8975f5c5SAndroid Build Coastguard Worker     {
177*8975f5c5SAndroid Build Coastguard Worker         mScratchMemory.clear();
178*8975f5c5SAndroid Build Coastguard Worker     }
179*8975f5c5SAndroid Build Coastguard Worker }
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
182