1 // Copyright 2022 Google LLC.
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
4 #include "include/private/base/SkContainers.h"
5
6 #include "tests/Test.h"
7
8 #include <algorithm>
9 #include <climits>
10 #include <cstddef>
11 #include <cstdint>
12
13 struct SkContainerAllocatorTestingPeer {
RoundUpCapacitySkContainerAllocatorTestingPeer14 static size_t RoundUpCapacity(const SkContainerAllocator& a, int64_t capacity){
15 return a.roundUpCapacity(capacity);
16 }
17
GrowthFactorCapacitySkContainerAllocatorTestingPeer18 static size_t GrowthFactorCapacity(
19 const SkContainerAllocator& a, int capacity, double growthFactor) {
20 return a.growthFactorCapacity(capacity, growthFactor);
21 }
22
23 static constexpr int64_t kCapacityMultiple = SkContainerAllocator::kCapacityMultiple;
24 };
25
max_capacity(size_t sizeOfT)26 static int max_capacity(size_t sizeOfT) {
27 return std::min(SIZE_MAX / sizeOfT, (size_t)INT_MAX);
28 }
29
DEF_TEST(SkContainerAllocatorBasic,reporter)30 DEF_TEST(SkContainerAllocatorBasic, reporter) {
31
32 /* Comment out until a solution can be found.
33 // The following test drive the 32-bit machines out of memory so skip them.
34 if constexpr (SIZE_MAX > UINT_MAX) {
35 {
36 SkContainerAllocator a{1, max_capacity(1)};
37
38 SkSpan<std::byte> span = a.allocate(0, 1.0);
39 REPORTER_ASSERT(reporter, span.empty());
40 sk_free(span.data());
41
42 span = a.allocate(0, 1.5);
43 REPORTER_ASSERT(reporter, span.empty());
44 sk_free(span.data());
45
46 span = a.allocate(max_capacity(1), 1.0);
47 REPORTER_ASSERT(reporter, span.size() >= SkToSizeT(max_capacity(1)));
48 sk_free(span.data());
49 }
50
51 {
52 SkContainerAllocator a{16, max_capacity(16)};
53
54 SkSpan<std::byte> span = a.allocate(0, 1.0);
55 REPORTER_ASSERT(reporter, span.empty());
56 sk_free(span.data());
57
58 span = a.allocate(0, 1.5);
59 REPORTER_ASSERT(reporter, span.empty());
60 sk_free(span.data());
61
62 span = a.allocate(max_capacity(16), 1.0);
63 REPORTER_ASSERT(reporter, span.size() >= SkToSizeT(max_capacity(16)) * 16);
64 sk_free(span.data());
65 }
66 } // end skipped on 32-bit Windows tests.
67 */
68
69 for (int i = 1; i < 33; ++i) {
70 SkContainerAllocator a{(size_t)i, max_capacity(i)};
71 int64_t r = SkContainerAllocatorTestingPeer::RoundUpCapacity(a, 1);
72 REPORTER_ASSERT(reporter, r == SkContainerAllocatorTestingPeer::kCapacityMultiple);
73
74 r = SkContainerAllocatorTestingPeer::RoundUpCapacity(a, INT_MAX);
75 REPORTER_ASSERT(reporter, r == max_capacity(i));
76
77 r = SkContainerAllocatorTestingPeer::RoundUpCapacity(a, max_capacity(i));
78 REPORTER_ASSERT(reporter, r == max_capacity(i));
79 }
80
81 for (int i = 1; i < 33; ++i) {
82 SkContainerAllocator a{(size_t)i, max_capacity(i)};
83 int64_t r = SkContainerAllocatorTestingPeer::GrowthFactorCapacity(a, 1, 1.5);
84 REPORTER_ASSERT(reporter, r == SkContainerAllocatorTestingPeer::kCapacityMultiple);
85
86 r = SkContainerAllocatorTestingPeer::GrowthFactorCapacity(a, INT_MAX, 1.5);
87 REPORTER_ASSERT(reporter, r == max_capacity(i));
88
89 r = SkContainerAllocatorTestingPeer::GrowthFactorCapacity(a, max_capacity(i), 1.5);
90 REPORTER_ASSERT(reporter, r == max_capacity(i));
91 }
92 }
93
94