• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include <C2AllocatorIon.h>
20 #include <C2AllocatorGralloc.h>
21 #include <C2Buffer.h>
22 #include <C2BufferPriv.h>
23 #include <C2ParamDef.h>
24 
25 #include <system/graphics.h>
26 
27 namespace android {
28 
29 class C2BufferUtilsTest : public ::testing::Test {
StaticSegmentTest()30     static void StaticSegmentTest() {
31         // constructor
32         static_assert(C2Segment(123u, 456u).offset == 123, "");
33         static_assert(C2Segment(123u, 456u).size == 456, "");
34 
35         // empty
36         static_assert(!C2Segment(123u, 456u).isEmpty(), "");
37         static_assert(C2Segment(123u, 0u).isEmpty(), "");
38 
39         // valid
40         static_assert(C2Segment(123u, 456u).isValid(), "");
41         static_assert(C2Segment(123u, ~123u).isValid(), "");
42         static_assert(!C2Segment(123u, 1 + ~123u).isValid(), "");
43 
44         // bool()
45         static_assert(C2Segment(123u, 456u), "");
46         static_assert((bool)C2Segment(123u, ~123u), "");
47         static_assert(!bool(C2Segment(123u, 1 + ~123u)), "");
48         static_assert(!bool(C2Segment(123u, 0)), "");
49 
50         // !
51         static_assert(!!C2Segment(123u, 456u), "");
52         static_assert(!!C2Segment(123u, ~123u), "");
53         static_assert(!C2Segment(123u, 1 + ~123u), "");
54         static_assert(!C2Segment(123u, 0), "");
55 
56         // contains
57         static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, 0)), "");
58         static_assert(!C2Segment(123u, 1 + ~123u).contains(C2Segment(123u, 0)), "");
59         static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, ~123u)), "");
60         static_assert(!C2Segment(123u, ~123u).contains(C2Segment(123u, 1 + ~123u)), "");
61         static_assert(!C2Segment(123u, 1 + ~123u).contains(C2Segment(123u, 1 + ~123u)), "");
62         static_assert(!C2Segment(123u, ~123u).contains(C2Segment(122u, 2u)), "");
63         static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, 2u)), "");
64         static_assert(C2Segment(123u, 3u).contains(C2Segment(124u, 2u)), "");
65         static_assert(!C2Segment(123u, 3u).contains(C2Segment(125u, 2u)), "");
66 
67         // ==
68         static_assert(C2Segment(123u, 456u) == C2Segment(123u, 456u), "");
69         static_assert(!(C2Segment(123u, 456u) == C2Segment(123u, 457u)), "");
70         static_assert(!(C2Segment(123u, 456u) == C2Segment(123u, 455u)), "");
71         static_assert(!(C2Segment(123u, 456u) == C2Segment(122u, 456u)), "");
72         static_assert(!(C2Segment(123u, 456u) == C2Segment(124u, 456u)), "");
73         static_assert(!(C2Segment(123u, 0u) == C2Segment(124u, 0u)), "");
74         static_assert(C2Segment(123u, 0u) == C2Segment(123u, 0u), "");
75         static_assert(C2Segment(123u, 1 + ~123u) == C2Segment(124u, 1 + ~124u), "");
76 
77         // !=
78         static_assert(!(C2Segment(123u, 456u) != C2Segment(123u, 456u)), "");
79         static_assert(C2Segment(123u, 456u) != C2Segment(123u, 457u), "");
80         static_assert(C2Segment(123u, 456u) != C2Segment(123u, 455u), "");
81         static_assert(C2Segment(123u, 456u) != C2Segment(122u, 456u), "");
82         static_assert(C2Segment(123u, 456u) != C2Segment(124u, 456u), "");
83         static_assert(C2Segment(123u, 0u) != C2Segment(124u, 0u), "");
84         static_assert(!(C2Segment(123u, 0u) != C2Segment(123u, 0u)), "");
85         static_assert(!(C2Segment(123u, 1 + ~123u) != C2Segment(124u, 1 + ~124u)), "");
86 
87         // <=
88         static_assert(C2Segment(123u, 456u) <= C2Segment(123u, 456u), "");
89         static_assert(C2Segment(123u, 456u) <= C2Segment(123u, 457u), "");
90         static_assert(C2Segment(123u, 456u) <= C2Segment(122u, 457u), "");
91         static_assert(!(C2Segment(123u, 457u) <= C2Segment(123u, 456u)), "");
92         static_assert(!(C2Segment(122u, 457u) <= C2Segment(123u, 456u)), "");
93         static_assert(!(C2Segment(123u, 457u) <= C2Segment(124u, 457u)), "");
94         static_assert(!(C2Segment(122u, 457u) <= C2Segment(123u, 457u)), "");
95         static_assert(!(C2Segment(122u, 0u) <= C2Segment(123u, 0u)), "");
96         static_assert(C2Segment(123u, 0u) <= C2Segment(122u, 1u), "");
97         static_assert(C2Segment(122u, 0u) <= C2Segment(122u, 1u), "");
98         static_assert(!(C2Segment(122u, ~122u) <= C2Segment(122u, 1 + ~122u)), "");
99         static_assert(!(C2Segment(122u, 1 + ~122u) <= C2Segment(122u, ~122u)), "");
100         static_assert(!(C2Segment(122u, 1 + ~122u) <= C2Segment(122u, 1 + ~122u)), "");
101 
102         // <
103         static_assert(!(C2Segment(123u, 456u) < C2Segment(123u, 456u)), "");
104         static_assert(C2Segment(123u, 456u) < C2Segment(123u, 457u), "");
105         static_assert(C2Segment(123u, 456u) < C2Segment(122u, 457u), "");
106         static_assert(!(C2Segment(123u, 457u) < C2Segment(123u, 456u)), "");
107         static_assert(!(C2Segment(122u, 457u) < C2Segment(123u, 456u)), "");
108         static_assert(!(C2Segment(123u, 457u) < C2Segment(124u, 457u)), "");
109         static_assert(!(C2Segment(122u, 457u) < C2Segment(123u, 457u)), "");
110         static_assert(!(C2Segment(122u, 0u) < C2Segment(123u, 0u)), "");
111         static_assert(C2Segment(123u, 0u) < C2Segment(122u, 1u), "");
112         static_assert(C2Segment(122u, 0u) < C2Segment(122u, 1u), "");
113         static_assert(!(C2Segment(122u, ~122u) < C2Segment(122u, 1 + ~122u)), "");
114         static_assert(!(C2Segment(122u, 1 + ~122u) < C2Segment(122u, ~122u)), "");
115         static_assert(!(C2Segment(122u, 1 + ~122u) < C2Segment(122u, 1 + ~122u)), "");
116 
117         // <=
118         static_assert(C2Segment(123u, 456u) >= C2Segment(123u, 456u), "");
119         static_assert(C2Segment(123u, 457u) >= C2Segment(123u, 456u), "");
120         static_assert(C2Segment(122u, 457u) >= C2Segment(123u, 456u), "");
121         static_assert(!(C2Segment(123u, 456u) >= C2Segment(123u, 457u)), "");
122         static_assert(!(C2Segment(123u, 456u) >= C2Segment(122u, 457u)), "");
123         static_assert(!(C2Segment(124u, 457u) >= C2Segment(123u, 457u)), "");
124         static_assert(!(C2Segment(123u, 457u) >= C2Segment(122u, 457u)), "");
125         static_assert(!(C2Segment(123u, 0u) >= C2Segment(122u, 0u)), "");
126         static_assert(C2Segment(122u, 1u) >= C2Segment(123u, 0u), "");
127         static_assert(C2Segment(122u, 1u) >= C2Segment(122u, 0u), "");
128         static_assert(!(C2Segment(122u, 1 + ~122u) >= C2Segment(122u, ~122u)), "");
129         static_assert(!(C2Segment(122u, ~122u) >= C2Segment(122u, 1 + ~122u)), "");
130         static_assert(!(C2Segment(122u, 1 + ~122u) >= C2Segment(122u, 1 + ~122u)), "");
131 
132         // <
133         static_assert(!(C2Segment(123u, 456u) > C2Segment(123u, 456u)), "");
134         static_assert(C2Segment(123u, 457u) > C2Segment(123u, 456u), "");
135         static_assert(C2Segment(122u, 457u) > C2Segment(123u, 456u), "");
136         static_assert(!(C2Segment(123u, 456u) > C2Segment(123u, 457u)), "");
137         static_assert(!(C2Segment(123u, 456u) > C2Segment(122u, 457u)), "");
138         static_assert(!(C2Segment(124u, 457u) > C2Segment(123u, 457u)), "");
139         static_assert(!(C2Segment(123u, 457u) > C2Segment(122u, 457u)), "");
140         static_assert(!(C2Segment(123u, 0u) > C2Segment(122u, 0u)), "");
141         static_assert(C2Segment(122u, 1u) > C2Segment(123u, 0u), "");
142         static_assert(C2Segment(122u, 1u) > C2Segment(122u, 0u), "");
143         static_assert(!(C2Segment(122u, 1 + ~122u) > C2Segment(122u, ~122u)), "");
144         static_assert(!(C2Segment(122u, ~122u) > C2Segment(122u, 1 + ~122u)), "");
145         static_assert(!(C2Segment(122u, 1 + ~122u) > C2Segment(122u, 1 + ~122u)), "");
146 
147         // end
148         static_assert(C2Segment(123u, 456u).end() == 579u, "");
149         static_assert(C2Segment(123u, 0u).end() == 123u, "");
150         static_assert(C2Segment(123u, ~123u).end() == 0xffffffffu, "");
151         static_assert(C2Segment(123u, 1 + ~123u).end() == 0u, "");
152 
153         // intersect
154         static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 456u)) == C2Segment(123u, 456u), "");
155         static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 460u)) == C2Segment(123u, 456u), "");
156         static_assert(C2Segment(123u, 456u).intersect(C2Segment(124u, 460u)) == C2Segment(124u, 455u), "");
157         static_assert(C2Segment(123u, 456u).intersect(C2Segment(579u, 460u)) == C2Segment(579u, 0u), "");
158         static_assert(C2Segment(123u, 456u).intersect(C2Segment(589u, 460u)) == C2Segment(589u, ~9u /* -10 */), "");
159         static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 455u)) == C2Segment(123u, 455u), "");
160         static_assert(C2Segment(123u, 456u).intersect(C2Segment(122u, 456u)) == C2Segment(123u, 455u), "");
161         static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 123u)) == C2Segment(123u, 0u), "");
162         static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 0u)) == C2Segment(123u, ~122u /* -123 */), "");
163 
164         // normalize (change invalid segments to empty segments)
165         static_assert(C2Segment(123u, 456u).normalize() == C2Segment(123u, 456u), "");
166         static_assert(C2Segment(123u, ~123u).normalize() == C2Segment(123u, ~123u), "");
167         static_assert(C2Segment(123u, 1 + ~123u).normalize() == C2Segment(123u, 0u), "");
168 
169         // note: normalize cannot be used to make this work
170         static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, ~150u)).normalize() == C2Segment(150u, 429u), "");
171         static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u)).normalize() != C2Segment(150u, 429u), "");
172         static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u)).normalize() == C2Segment(150u, 0u), "");
173 
174         // saturate (change invalid segments to full segments up to max)
175         static_assert(C2Segment(123u, 456u).saturate() == C2Segment(123u, 456u), "");
176         static_assert(C2Segment(123u, ~123u).saturate() == C2Segment(123u, ~123u), "");
177         static_assert(C2Segment(123u, 1 + ~123u).saturate() == C2Segment(123u, ~123u), "");
178 
179         // note: saturate can be used to make this work but only partially
180         static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u).saturate()).normalize() == C2Segment(150u, 429u), "");
181         static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 100u).saturate()).normalize() == C2Segment(123u, 0u), "");
182         static_assert(C2Segment(123u, 456u).intersect(C2Segment(1000u, 100u).saturate()).normalize() != C2Segment(579u, 0u), "");
183         static_assert(C2Segment(123u, 456u).intersect(C2Segment(1000u, 100u).saturate()).normalize() == C2Segment(1000u, 0u), "");
184 
185     }
186 
StaticLinearRangeAndCapacityTest()187     static void StaticLinearRangeAndCapacityTest() {
188         class TestCapacity : public _C2LinearCapacityAspect {
189             using _C2LinearCapacityAspect::_C2LinearCapacityAspect;
190             friend class C2BufferUtilsTest;
191         };
192 
193         class TestRange : public _C2LinearRangeAspect {
194             using _C2LinearRangeAspect::_C2LinearRangeAspect;
195             friend class C2BufferUtilsTest;
196         };
197 
198         // _C2LinearCapacityAspect
199         static_assert(TestCapacity(0u).capacity() == 0u, "");
200         constexpr TestCapacity cap(123u);
201         static_assert(TestCapacity(&cap).capacity() == 123u, "");
202         static_assert(TestCapacity(nullptr).capacity() == 0u, "");
203 
204         // _C2LinearCapacityRange
205         static_assert(TestRange(&cap).capacity() == 123u, "");
206         static_assert(TestRange(&cap).offset() == 0u, "");
207         static_assert(TestRange(&cap).size() == 123u, "");
208         static_assert(TestRange(&cap).endOffset() == 123u, "");
209 
210         constexpr TestRange range(&cap, 50u, 100u);
211 
212         static_assert(range.capacity() == 123u, "");
213         static_assert(range.offset() == 50u, "");
214         static_assert(range.size() == 73u, "");
215         static_assert(range.endOffset() == 123u, "");
216 
217         static_assert(TestRange(&cap, 20u, 30u).capacity() == 123u, "");
218         static_assert(TestRange(&cap, 20u, 30u).offset() == 20u, "");
219         static_assert(TestRange(&cap, 20u, 30u).size() == 30u, "");
220         static_assert(TestRange(&cap, 20u, 30u).endOffset() == 50u, "");
221 
222         static_assert(TestRange(&cap, 200u, 30u).capacity() == 123u, "");
223         static_assert(TestRange(&cap, 200u, 30u).offset() == 123u, "");
224         static_assert(TestRange(&cap, 200u, 30u).size() == 0u, "");
225         static_assert(TestRange(&cap, 200u, 30u).endOffset() == 123u, "");
226 
227     }
228 
229 };
230 
231 
232 class C2BufferTest : public ::testing::Test {
233 public:
C2BufferTest()234     C2BufferTest()
235         : mBlockPoolId(C2BlockPool::PLATFORM_START),
236           mLinearAllocator(std::make_shared<C2AllocatorIon>('i')),
237           mSize(0u),
238           mAddr(nullptr),
239           mGraphicAllocator(std::make_shared<C2AllocatorGralloc>('g')) {
240     }
241 
242     ~C2BufferTest() = default;
243 
allocateLinear(size_t capacity)244     void allocateLinear(size_t capacity) {
245         c2_status_t err = mLinearAllocator->newLinearAllocation(
246                 capacity,
247                 { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
248                 &mLinearAllocation);
249         if (err != C2_OK) {
250             mLinearAllocation.reset();
251             FAIL() << "C2Allocator::newLinearAllocation() failed: " << err;
252         }
253     }
254 
mapLinear(size_t offset,size_t size,uint8_t ** addr)255     void mapLinear(size_t offset, size_t size, uint8_t **addr) {
256         ASSERT_TRUE(mLinearAllocation);
257         c2_status_t err = mLinearAllocation->map(
258                 offset,
259                 size,
260                 { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
261                 // TODO: fence
262                 nullptr,
263                 &mAddr);
264         if (err != C2_OK) {
265             mAddr = nullptr;
266             FAIL() << "C2LinearAllocation::map() failed: " << err;
267         }
268         ASSERT_NE(nullptr, mAddr);
269         mSize = size;
270         *addr = (uint8_t *)mAddr;
271     }
272 
unmapLinear()273     void unmapLinear() {
274         ASSERT_TRUE(mLinearAllocation);
275         ASSERT_NE(nullptr, mAddr);
276         ASSERT_NE(0u, mSize);
277 
278         // TODO: fence
279         ASSERT_EQ(C2_OK, mLinearAllocation->unmap(mAddr, mSize, nullptr));
280         mSize = 0u;
281         mAddr = nullptr;
282     }
283 
makeLinearBlockPool()284     std::shared_ptr<C2BlockPool> makeLinearBlockPool() {
285         return std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
286     }
287 
allocateGraphic(uint32_t width,uint32_t height)288     void allocateGraphic(uint32_t width, uint32_t height) {
289         c2_status_t err = mGraphicAllocator->newGraphicAllocation(
290                 width,
291                 height,
292                 HAL_PIXEL_FORMAT_YCBCR_420_888,
293                 { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
294                 &mGraphicAllocation);
295         if (err != C2_OK) {
296             mGraphicAllocation.reset();
297             FAIL() << "C2Allocator::newGraphicAllocation() failed: " << err;
298         }
299     }
300 
mapGraphic(C2Rect rect,C2PlanarLayout * layout,uint8_t ** addr)301     void mapGraphic(C2Rect rect, C2PlanarLayout *layout, uint8_t **addr) {
302         ASSERT_TRUE(mGraphicAllocation);
303         c2_status_t err = mGraphicAllocation->map(
304                 rect,
305                 { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
306                 // TODO: fence
307                 nullptr,
308                 layout,
309                 addr);
310         if (err != C2_OK) {
311             addr[C2PlanarLayout::PLANE_Y] = nullptr;
312             addr[C2PlanarLayout::PLANE_U] = nullptr;
313             addr[C2PlanarLayout::PLANE_V] = nullptr;
314             FAIL() << "C2GraphicAllocation::map() failed: " << err;
315         }
316         mMappedRect = rect;
317         memcpy(mAddrGraphic, addr, sizeof(uint8_t*) * C2PlanarLayout::MAX_NUM_PLANES);
318     }
319 
unmapGraphic()320     void unmapGraphic() {
321         ASSERT_TRUE(mGraphicAllocation);
322 
323         // TODO: fence
324         ASSERT_EQ(C2_OK, mGraphicAllocation->unmap(mAddrGraphic, mMappedRect, nullptr));
325     }
326 
makeGraphicBlockPool()327     std::shared_ptr<C2BlockPool> makeGraphicBlockPool() {
328         return std::make_shared<C2BasicGraphicBlockPool>(mGraphicAllocator);
329     }
330 
331 private:
332     C2BlockPool::local_id_t mBlockPoolId;
333     std::shared_ptr<C2Allocator> mLinearAllocator;
334     std::shared_ptr<C2LinearAllocation> mLinearAllocation;
335     size_t mSize;
336     void *mAddr;
337     C2Rect mMappedRect;
338     uint8_t* mAddrGraphic[C2PlanarLayout::MAX_NUM_PLANES];
339 
340     std::shared_ptr<C2Allocator> mGraphicAllocator;
341     std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
342 };
343 
TEST_F(C2BufferTest,LinearAllocationTest)344 TEST_F(C2BufferTest, LinearAllocationTest) {
345     constexpr size_t kCapacity = 1024u * 1024u;
346 
347     allocateLinear(kCapacity);
348 
349     uint8_t *addr = nullptr;
350     mapLinear(0u, kCapacity, &addr);
351     ASSERT_NE(nullptr, addr);
352 
353     for (size_t i = 0; i < kCapacity; ++i) {
354         addr[i] = i % 100u;
355     }
356 
357     unmapLinear();
358     addr = nullptr;
359 
360     mapLinear(kCapacity / 3, kCapacity / 3, &addr);
361     ASSERT_NE(nullptr, addr);
362     for (size_t i = 0; i < kCapacity / 3; ++i) {
363         ASSERT_EQ((i + kCapacity / 3) % 100, addr[i]) << " at i = " << i;
364     }
365 }
366 
TEST_F(C2BufferTest,BlockPoolTest)367 TEST_F(C2BufferTest, BlockPoolTest) {
368     constexpr size_t kCapacity = 1024u * 1024u;
369 
370     std::shared_ptr<C2BlockPool> blockPool(makeLinearBlockPool());
371 
372     std::shared_ptr<C2LinearBlock> block;
373     ASSERT_EQ(C2_OK, blockPool->fetchLinearBlock(
374             kCapacity,
375             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
376             &block));
377     ASSERT_TRUE(block);
378 
379     C2Acquirable<C2WriteView> writeViewHolder = block->map();
380     C2WriteView writeView = writeViewHolder.get();
381     ASSERT_EQ(C2_OK, writeView.error());
382     ASSERT_EQ(kCapacity, writeView.capacity());
383     ASSERT_EQ(0u, writeView.offset());
384     ASSERT_EQ(kCapacity, writeView.size());
385 
386     uint8_t *data = writeView.data();
387     ASSERT_NE(nullptr, data);
388     for (size_t i = 0; i < writeView.size(); ++i) {
389         data[i] = i % 100u;
390     }
391 
392     writeView.setOffset(kCapacity / 3);
393     data = writeView.data();
394     ASSERT_NE(nullptr, data);
395     for (size_t i = 0; i < writeView.size(); ++i) {
396         ASSERT_EQ((i + kCapacity / 3) % 100u, data[i]) << " at i = " << i
397             << "; data = " << static_cast<void *>(data);
398     }
399 
400     C2Fence fence;
401     C2ConstLinearBlock constBlock = block->share(
402             kCapacity / 3, kCapacity / 3, fence);
403 
404     C2Acquirable<C2ReadView> readViewHolder = constBlock.map();
405     C2ReadView readView = readViewHolder.get();
406     ASSERT_EQ(C2_OK, readView.error());
407     ASSERT_EQ(kCapacity / 3, readView.capacity());
408 
409     // TODO: fence
410     const uint8_t *constData = readView.data();
411     ASSERT_NE(nullptr, constData);
412     for (size_t i = 0; i < readView.capacity(); ++i) {
413         ASSERT_EQ((i + kCapacity / 3) % 100u, constData[i]) << " at i = " << i
414                 << "; data = " << static_cast<void *>(data)
415                 << "; constData = " << static_cast<const void *>(constData);
416     }
417 
418     readView = readView.subView(333u, 100u);
419     ASSERT_EQ(C2_OK, readView.error());
420     ASSERT_EQ(100u, readView.capacity());
421 
422     constData = readView.data();
423     ASSERT_NE(nullptr, constData);
424     for (size_t i = 0; i < readView.capacity(); ++i) {
425         ASSERT_EQ((i + 333u + kCapacity / 3) % 100u, constData[i]) << " at i = " << i;
426     }
427 }
428 
fillPlane(const C2Rect rect,const C2PlaneInfo info,uint8_t * addr,uint8_t value)429 void fillPlane(const C2Rect rect, const C2PlaneInfo info, uint8_t *addr, uint8_t value) {
430     for (uint32_t row = 0; row < rect.height / info.rowSampling; ++row) {
431         int32_t rowOffset = (row + rect.top / info.rowSampling) * info.rowInc;
432         for (uint32_t col = 0; col < rect.width / info.colSampling; ++col) {
433             int32_t colOffset = (col + rect.left / info.colSampling) * info.colInc;
434             addr[rowOffset + colOffset] = value;
435         }
436     }
437 }
438 
verifyPlane(const C2Rect rect,const C2PlaneInfo info,const uint8_t * addr,uint8_t value)439 bool verifyPlane(const C2Rect rect, const C2PlaneInfo info, const uint8_t *addr, uint8_t value) {
440     for (uint32_t row = 0; row < rect.height / info.rowSampling; ++row) {
441         int32_t rowOffset = (row + rect.top / info.rowSampling) * info.rowInc;
442         for (uint32_t col = 0; col < rect.width / info.colSampling; ++col) {
443             int32_t colOffset = (col + rect.left / info.colSampling) * info.colInc;
444             if (addr[rowOffset + colOffset] != value) {
445                 return false;
446             }
447         }
448     }
449     return true;
450 }
451 
TEST_F(C2BufferTest,GraphicAllocationTest)452 TEST_F(C2BufferTest, GraphicAllocationTest) {
453     constexpr uint32_t kWidth = 320;
454     constexpr uint32_t kHeight = 240;
455 
456     allocateGraphic(kWidth, kHeight);
457 
458     uint8_t *addr[C2PlanarLayout::MAX_NUM_PLANES];
459     C2Rect rect(kWidth, kHeight);
460     C2PlanarLayout layout;
461     mapGraphic(rect, &layout, addr);
462     ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_Y]);
463     ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_U]);
464     ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_V]);
465 
466     uint8_t *y = addr[C2PlanarLayout::PLANE_Y];
467     C2PlaneInfo yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
468     uint8_t *u = addr[C2PlanarLayout::PLANE_U];
469     C2PlaneInfo uInfo = layout.planes[C2PlanarLayout::PLANE_U];
470     uint8_t *v = addr[C2PlanarLayout::PLANE_V];
471     C2PlaneInfo vInfo = layout.planes[C2PlanarLayout::PLANE_V];
472 
473     fillPlane(rect, yInfo, y, 0);
474     fillPlane(rect, uInfo, u, 0);
475     fillPlane(rect, vInfo, v, 0);
476     fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, y, 0x12);
477     fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, u, 0x34);
478     fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, v, 0x56);
479 
480     unmapGraphic();
481 
482     mapGraphic(rect, &layout, addr);
483     ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_Y]);
484     ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_U]);
485     ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_V]);
486 
487     y = addr[C2PlanarLayout::PLANE_Y];
488     yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
489     u = addr[C2PlanarLayout::PLANE_U];
490     uInfo = layout.planes[C2PlanarLayout::PLANE_U];
491     v = addr[C2PlanarLayout::PLANE_V];
492     vInfo = layout.planes[C2PlanarLayout::PLANE_V];
493 
494     ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, y, 0x12));
495     ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, u, 0x34));
496     ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, v, 0x56));
497     ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, yInfo, y, 0));
498     ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, uInfo, u, 0));
499     ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, vInfo, v, 0));
500     ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, yInfo, y, 0));
501     ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, uInfo, u, 0));
502     ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, vInfo, v, 0));
503 }
504 
TEST_F(C2BufferTest,GraphicBlockPoolTest)505 TEST_F(C2BufferTest, GraphicBlockPoolTest) {
506     constexpr uint32_t kWidth = 320;
507     constexpr uint32_t kHeight = 240;
508 
509     std::shared_ptr<C2BlockPool> blockPool(makeGraphicBlockPool());
510 
511     std::shared_ptr<C2GraphicBlock> block;
512     ASSERT_EQ(C2_OK, blockPool->fetchGraphicBlock(
513             kWidth,
514             kHeight,
515             HAL_PIXEL_FORMAT_YCBCR_420_888,
516             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
517             &block));
518     ASSERT_TRUE(block);
519 
520     C2Acquirable<C2GraphicView> graphicViewHolder = block->map();
521     C2GraphicView graphicView = graphicViewHolder.get();
522     ASSERT_EQ(C2_OK, graphicView.error());
523     ASSERT_EQ(kWidth, graphicView.width());
524     ASSERT_EQ(kHeight, graphicView.height());
525 
526     uint8_t *const *data = graphicView.data();
527     C2PlanarLayout layout = graphicView.layout();
528     ASSERT_NE(nullptr, data);
529 
530     uint8_t *y = data[C2PlanarLayout::PLANE_Y];
531     C2PlaneInfo yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
532     uint8_t *u = data[C2PlanarLayout::PLANE_U];
533     C2PlaneInfo uInfo = layout.planes[C2PlanarLayout::PLANE_U];
534     uint8_t *v = data[C2PlanarLayout::PLANE_V];
535     C2PlaneInfo vInfo = layout.planes[C2PlanarLayout::PLANE_V];
536 
537     fillPlane({ kWidth, kHeight }, yInfo, y, 0);
538     fillPlane({ kWidth, kHeight }, uInfo, u, 0);
539     fillPlane({ kWidth, kHeight }, vInfo, v, 0);
540     fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, y, 0x12);
541     fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, u, 0x34);
542     fillPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, v, 0x56);
543 
544     C2Fence fence;
545     C2ConstGraphicBlock constBlock = block->share(C2Rect(kWidth, kHeight), fence);
546     block.reset();
547 
548     C2Acquirable<const C2GraphicView> constViewHolder = constBlock.map();
549     const C2GraphicView constGraphicView = constViewHolder.get();
550     ASSERT_EQ(C2_OK, constGraphicView.error());
551     ASSERT_EQ(kWidth, constGraphicView.width());
552     ASSERT_EQ(kHeight, constGraphicView.height());
553 
554     const uint8_t *const *constData = constGraphicView.data();
555     layout = graphicView.layout();
556     ASSERT_NE(nullptr, constData);
557 
558     const uint8_t *cy = constData[C2PlanarLayout::PLANE_Y];
559     yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
560     const uint8_t *cu = constData[C2PlanarLayout::PLANE_U];
561     uInfo = layout.planes[C2PlanarLayout::PLANE_U];
562     const uint8_t *cv = constData[C2PlanarLayout::PLANE_V];
563     vInfo = layout.planes[C2PlanarLayout::PLANE_V];
564 
565     ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), yInfo, cy, 0x12));
566     ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), uInfo, cu, 0x34));
567     ASSERT_TRUE(verifyPlane(C2Rect(kWidth / 2, kHeight / 2).at(kWidth / 4, kHeight / 4), vInfo, cv, 0x56));
568     ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, yInfo, cy, 0));
569     ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, uInfo, cu, 0));
570     ASSERT_TRUE(verifyPlane({ kWidth, kHeight / 4 }, vInfo, cv, 0));
571     ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, yInfo, cy, 0));
572     ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, uInfo, cu, 0));
573     ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight }, vInfo, cv, 0));
574 }
575 
576 class BufferData : public C2BufferData {
577 public:
BufferData(const std::vector<C2ConstLinearBlock> & blocks)578     explicit BufferData(const std::vector<C2ConstLinearBlock> &blocks) : C2BufferData(blocks) {}
BufferData(const std::vector<C2ConstGraphicBlock> & blocks)579     explicit BufferData(const std::vector<C2ConstGraphicBlock> &blocks) : C2BufferData(blocks) {}
580 };
581 
582 class Buffer : public C2Buffer {
583 public:
Buffer(const std::vector<C2ConstLinearBlock> & blocks)584     explicit Buffer(const std::vector<C2ConstLinearBlock> &blocks) : C2Buffer(blocks) {}
Buffer(const std::vector<C2ConstGraphicBlock> & blocks)585     explicit Buffer(const std::vector<C2ConstGraphicBlock> &blocks) : C2Buffer(blocks) {}
586 };
587 
TEST_F(C2BufferTest,BufferDataTest)588 TEST_F(C2BufferTest, BufferDataTest) {
589     std::shared_ptr<C2BlockPool> linearBlockPool(makeLinearBlockPool());
590     std::shared_ptr<C2BlockPool> graphicBlockPool(makeGraphicBlockPool());
591 
592     constexpr uint32_t kWidth1 = 320;
593     constexpr uint32_t kHeight1 = 240;
594     constexpr C2Rect kCrop1(kWidth1, kHeight1);
595     constexpr uint32_t kWidth2 = 176;
596     constexpr uint32_t kHeight2 = 144;
597     constexpr C2Rect kCrop2(kWidth2, kHeight2);
598     constexpr size_t kCapacity1 = 1024u;
599     constexpr size_t kCapacity2 = 2048u;
600 
601     std::shared_ptr<C2LinearBlock> linearBlock1;
602     std::shared_ptr<C2LinearBlock> linearBlock2;
603     ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
604             kCapacity1,
605             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
606             &linearBlock1));
607     ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
608             kCapacity2,
609             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
610             &linearBlock2));
611     std::shared_ptr<C2GraphicBlock> graphicBlock1;
612     std::shared_ptr<C2GraphicBlock> graphicBlock2;
613     ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
614             kWidth1,
615             kHeight1,
616             HAL_PIXEL_FORMAT_YCBCR_420_888,
617             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
618             &graphicBlock1));
619     ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
620             kWidth2,
621             kHeight2,
622             HAL_PIXEL_FORMAT_YCBCR_420_888,
623             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
624             &graphicBlock2));
625 
626     std::shared_ptr<C2BufferData> data(new BufferData({ linearBlock1->share(0, kCapacity1, C2Fence()) }));
627     EXPECT_EQ(C2BufferData::LINEAR, data->type());
628     ASSERT_EQ(1u, data->linearBlocks().size());
629     EXPECT_EQ(linearBlock1->handle(), data->linearBlocks().front().handle());
630     EXPECT_TRUE(data->graphicBlocks().empty());
631 
632     data.reset(new BufferData({
633         linearBlock1->share(0, kCapacity1, C2Fence()),
634         linearBlock2->share(0, kCapacity2, C2Fence()),
635     }));
636     EXPECT_EQ(C2BufferData::LINEAR_CHUNKS, data->type());
637     ASSERT_EQ(2u, data->linearBlocks().size());
638     EXPECT_EQ(linearBlock1->handle(), data->linearBlocks().front().handle());
639     EXPECT_EQ(linearBlock2->handle(), data->linearBlocks().back().handle());
640     EXPECT_TRUE(data->graphicBlocks().empty());
641 
642     data.reset(new BufferData({ graphicBlock1->share(kCrop1, C2Fence()) }));
643     EXPECT_EQ(C2BufferData::GRAPHIC, data->type());
644     ASSERT_EQ(1u, data->graphicBlocks().size());
645     EXPECT_EQ(graphicBlock1->handle(), data->graphicBlocks().front().handle());
646     EXPECT_TRUE(data->linearBlocks().empty());
647 
648     data.reset(new BufferData({
649         graphicBlock1->share(kCrop1, C2Fence()),
650         graphicBlock2->share(kCrop2, C2Fence()),
651     }));
652     EXPECT_EQ(C2BufferData::GRAPHIC_CHUNKS, data->type());
653     ASSERT_EQ(2u, data->graphicBlocks().size());
654     EXPECT_EQ(graphicBlock1->handle(), data->graphicBlocks().front().handle());
655     EXPECT_EQ(graphicBlock2->handle(), data->graphicBlocks().back().handle());
656     EXPECT_TRUE(data->linearBlocks().empty());
657 }
658 
DestroyCallback(const C2Buffer *,void * arg)659 void DestroyCallback(const C2Buffer * /* buf */, void *arg) {
660     std::function<void(void)> *cb = (std::function<void(void)> *)arg;
661     (*cb)();
662 }
663 
664 enum : uint32_t {
665     kParamIndexNumber1,
666     kParamIndexNumber2,
667 };
668 
669 typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber1> C2Number1Info;
670 typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber2> C2Number2Info;
671 
TEST_F(C2BufferTest,BufferTest)672 TEST_F(C2BufferTest, BufferTest) {
673     std::shared_ptr<C2BlockPool> alloc(makeLinearBlockPool());
674     constexpr size_t kCapacity = 1024u;
675     std::shared_ptr<C2LinearBlock> block;
676 
677     ASSERT_EQ(C2_OK, alloc->fetchLinearBlock(
678             kCapacity,
679             { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
680             &block));
681 
682     std::atomic_bool destroyed(false);
683     std::function<void(void)> arg = [&destroyed](){ destroyed = true; };
684 
685     std::shared_ptr<C2Buffer> buffer(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
686     ASSERT_EQ(C2_OK, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
687     EXPECT_FALSE(destroyed);
688     ASSERT_EQ(C2_DUPLICATE, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
689     buffer.reset();
690     EXPECT_TRUE(destroyed);
691 
692     buffer.reset(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
693     destroyed = false;
694     ASSERT_EQ(C2_OK, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
695     EXPECT_FALSE(destroyed);
696     ASSERT_EQ(C2_NOT_FOUND, buffer->unregisterOnDestroyNotify(&DestroyCallback, nullptr));
697     ASSERT_EQ(C2_OK, buffer->unregisterOnDestroyNotify(&DestroyCallback, &arg));
698     EXPECT_FALSE(destroyed);
699     ASSERT_EQ(C2_NOT_FOUND, buffer->unregisterOnDestroyNotify(&DestroyCallback, &arg));
700     buffer.reset();
701     EXPECT_FALSE(destroyed);
702 
703     std::shared_ptr<C2Info> info1(new C2Number1Info(1));
704     std::shared_ptr<C2Info> info2(new C2Number2Info(2));
705     buffer.reset(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
706     EXPECT_TRUE(buffer->info().empty());
707     EXPECT_FALSE(buffer->hasInfo(info1->type()));
708     EXPECT_FALSE(buffer->hasInfo(info2->type()));
709 
710     ASSERT_EQ(C2_OK, buffer->setInfo(info1));
711     EXPECT_EQ(1u, buffer->info().size());
712     EXPECT_EQ(*info1, *buffer->info().front());
713     EXPECT_TRUE(buffer->hasInfo(info1->type()));
714     EXPECT_FALSE(buffer->hasInfo(info2->type()));
715 
716     ASSERT_EQ(C2_OK, buffer->setInfo(info2));
717     EXPECT_EQ(2u, buffer->info().size());
718     EXPECT_TRUE(buffer->hasInfo(info1->type()));
719     EXPECT_TRUE(buffer->hasInfo(info2->type()));
720 
721     std::shared_ptr<C2Info> removed = buffer->removeInfo(info1->type());
722     ASSERT_TRUE(removed);
723     EXPECT_EQ(*removed, *info1);
724     EXPECT_EQ(1u, buffer->info().size());
725     EXPECT_EQ(*info2, *buffer->info().front());
726     EXPECT_FALSE(buffer->hasInfo(info1->type()));
727     EXPECT_TRUE(buffer->hasInfo(info2->type()));
728 
729     removed = buffer->removeInfo(info1->type());
730     ASSERT_FALSE(removed);
731     EXPECT_EQ(1u, buffer->info().size());
732     EXPECT_FALSE(buffer->hasInfo(info1->type()));
733     EXPECT_TRUE(buffer->hasInfo(info2->type()));
734 
735     std::shared_ptr<C2Info> info3(new C2Number2Info(3));
736     ASSERT_EQ(C2_OK, buffer->setInfo(info3));
737     EXPECT_EQ(1u, buffer->info().size());
738     EXPECT_FALSE(buffer->hasInfo(info1->type()));
739     EXPECT_TRUE(buffer->hasInfo(info2->type()));
740 
741     removed = buffer->removeInfo(info2->type());
742     ASSERT_TRUE(removed);
743     EXPECT_EQ(*info3, *removed);
744     EXPECT_TRUE(buffer->info().empty());
745     EXPECT_FALSE(buffer->hasInfo(info1->type()));
746     EXPECT_FALSE(buffer->hasInfo(info2->type()));
747 }
748 
TEST_F(C2BufferTest,MultipleLinearMapTest)749 TEST_F(C2BufferTest, MultipleLinearMapTest) {
750     std::shared_ptr<C2BlockPool> pool(makeLinearBlockPool());
751     constexpr size_t kCapacity = 524288u;
752     for (int i = 0; i < 100; ++i) {
753         std::vector<C2WriteView> wViews;
754         std::vector<C2ReadView> rViews;
755         for (int j = 0; j < 16; ++j) {
756             std::shared_ptr<C2LinearBlock> block;
757             ASSERT_EQ(C2_OK, pool->fetchLinearBlock(
758                     kCapacity,
759                     { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
760                     &block));
761             wViews.push_back(block->map().get());
762             C2ConstLinearBlock cBlock = block->share(0, kCapacity / 2, C2Fence());
763             rViews.push_back(cBlock.map().get());
764         }
765     }
766 }
767 
768 } // namespace android
769