blob: fb5a337738802bba6cccac70b07aedafb8db0d77 [file] [log] [blame]
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +00001/*
2 * Copyright 2011 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 */
reed@google.comebd24962012-05-17 14:28:11 +00007
reed@google.comebd24962012-05-17 14:28:11 +00008#include "SkChunkAlloc.h"
milko.leporis401e77c2016-06-05 13:14:21 -07009#include "SkRandom.h"
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +000010#include "SkUtils.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000011#include "Test.h"
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +000012
robertphillipsa9061de2015-02-27 08:31:57 -080013static void check_alloc(skiatest::Reporter* reporter, const SkChunkAlloc& alloc,
14 size_t capacity, size_t used, int numBlocks) {
15 REPORTER_ASSERT(reporter, alloc.totalCapacity() >= capacity);
16 REPORTER_ASSERT(reporter, alloc.totalUsed() == used);
17 SkDEBUGCODE(REPORTER_ASSERT(reporter, alloc.blockCount() == numBlocks);)
18}
rmistry@google.comd6176b02012-08-23 18:14:13 +000019
robertphillipsa9061de2015-02-27 08:31:57 -080020static void* simple_alloc(skiatest::Reporter* reporter, SkChunkAlloc* alloc, size_t size) {
21 void* ptr = alloc->allocThrow(size);
22 check_alloc(reporter, *alloc, size, size, 1);
23 REPORTER_ASSERT(reporter, alloc->contains(ptr));
24 return ptr;
25}
halcanary9d524f22016-03-29 09:03:52 -070026
milko.leporis401e77c2016-06-05 13:14:21 -070027static void check_alloc_alignment(skiatest::Reporter* reporter,
28 SkChunkAlloc* alloc, size_t size) {
29 const size_t kAlignment = 8;
30 void* ptr = alloc->allocThrow(size);
31 REPORTER_ASSERT(reporter, ptr != nullptr);
32 REPORTER_ASSERT(reporter, (size_t)ptr % kAlignment == 0);
33}
34
robertphillipsa9061de2015-02-27 08:31:57 -080035static void test_chunkalloc(skiatest::Reporter* reporter) {
36 static const size_t kMin = 1024;
37 SkChunkAlloc alloc(kMin);
38
39 //------------------------------------------------------------------------
40 // check empty
41 check_alloc(reporter, alloc, 0, 0, 0);
halcanary96fcdcc2015-08-27 07:41:13 -070042 REPORTER_ASSERT(reporter, !alloc.contains(nullptr));
reed@google.comebd24962012-05-17 14:28:11 +000043 REPORTER_ASSERT(reporter, !alloc.contains(reporter));
44
robertphillipsa9061de2015-02-27 08:31:57 -080045 // reset on empty allocator
reed@google.comebd24962012-05-17 14:28:11 +000046 alloc.reset();
robertphillipsa9061de2015-02-27 08:31:57 -080047 check_alloc(reporter, alloc, 0, 0, 0);
reed@google.comebd24962012-05-17 14:28:11 +000048
robertphillipsa9061de2015-02-27 08:31:57 -080049 // rewind on empty allocator
50 alloc.rewind();
51 check_alloc(reporter, alloc, 0, 0, 0);
52
53 //------------------------------------------------------------------------
54 // test reset when something is allocated
55 size_t size = kMin >> 1;
56 void* ptr = simple_alloc(reporter, &alloc, size);
57
58 alloc.reset();
59 check_alloc(reporter, alloc, 0, 0, 0);
60 REPORTER_ASSERT(reporter, !alloc.contains(ptr));
61
62 //------------------------------------------------------------------------
63 // test rewind when something is allocated
64 ptr = simple_alloc(reporter, &alloc, size);
65
66 alloc.rewind();
67 check_alloc(reporter, alloc, size, 0, 1);
68 REPORTER_ASSERT(reporter, !alloc.contains(ptr));
69
70 // use the available block
71 ptr = simple_alloc(reporter, &alloc, size);
72 alloc.reset();
73
74 //------------------------------------------------------------------------
75 // test out allocating a second block
76 ptr = simple_alloc(reporter, &alloc, size);
77
78 ptr = alloc.allocThrow(kMin);
79 check_alloc(reporter, alloc, 2*kMin, size+kMin, 2);
reed@google.comebd24962012-05-17 14:28:11 +000080 REPORTER_ASSERT(reporter, alloc.contains(ptr));
rmistry@google.comd6176b02012-08-23 18:14:13 +000081
robertphillipsa9061de2015-02-27 08:31:57 -080082 //------------------------------------------------------------------------
83 // test out unalloc
84 size_t freed = alloc.unalloc(ptr);
85 REPORTER_ASSERT(reporter, freed == kMin);
86 check_alloc(reporter, alloc, 2*kMin, size, 2);
reed@google.comebd24962012-05-17 14:28:11 +000087 REPORTER_ASSERT(reporter, !alloc.contains(ptr));
milko.leporis401e77c2016-06-05 13:14:21 -070088
89 //------------------------------------------------------------------------
90 // test the alignment
91 alloc.reset();
92 SkRandom rand;
93 for (int i = 0; i < 1000; i++) {
94 check_alloc_alignment(reporter, &alloc, rand.nextU16());
95 }
reed@google.comebd24962012-05-17 14:28:11 +000096}
97
98///////////////////////////////////////////////////////////////////////////////
99
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000100static void set_zero(void* dst, size_t bytes) {
101 char* ptr = (char*)dst;
102 for (size_t i = 0; i < bytes; ++i) {
103 ptr[i] = 0;
104 }
105}
106
107#define MAX_ALIGNMENT 64
108#define MAX_COUNT ((MAX_ALIGNMENT) * 32)
109#define PAD 32
110#define TOTAL (PAD + MAX_ALIGNMENT + MAX_COUNT + PAD)
111
112#define VALUE16 0x1234
113#define VALUE32 0x12345678
114
halcanary7d571242016-02-24 17:59:16 -0800115static void compare16(skiatest::Reporter* r, const uint16_t base[],
116 uint16_t value, int count) {
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000117 for (int i = 0; i < count; ++i) {
118 if (base[i] != value) {
halcanary7d571242016-02-24 17:59:16 -0800119 ERRORF(r, "[%d] expected %x found %x\n", i, value, base[i]);
120 return;
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000121 }
122 }
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000123}
124
halcanary7d571242016-02-24 17:59:16 -0800125static void compare32(skiatest::Reporter* r, const uint32_t base[],
126 uint32_t value, int count) {
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000127 for (int i = 0; i < count; ++i) {
128 if (base[i] != value) {
halcanary7d571242016-02-24 17:59:16 -0800129 ERRORF(r, "[%d] expected %x found %x\n", i, value, base[i]);
130 return;
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000131 }
132 }
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000133}
134
135static void test_16(skiatest::Reporter* reporter) {
136 uint16_t buffer[TOTAL];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000137
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000138 for (int count = 0; count < MAX_COUNT; ++count) {
139 for (int alignment = 0; alignment < MAX_ALIGNMENT; ++alignment) {
140 set_zero(buffer, sizeof(buffer));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000141
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000142 uint16_t* base = &buffer[PAD + alignment];
143 sk_memset16(base, VALUE16, count);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000144
halcanary7d571242016-02-24 17:59:16 -0800145 compare16(reporter, buffer, 0, PAD + alignment);
146 compare16(reporter, base, VALUE16, count);
147 compare16(reporter, base + count, 0, TOTAL - count - PAD - alignment);
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000148 }
149 }
150}
151
152static void test_32(skiatest::Reporter* reporter) {
153 uint32_t buffer[TOTAL];
rmistry@google.comd6176b02012-08-23 18:14:13 +0000154
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000155 for (int count = 0; count < MAX_COUNT; ++count) {
156 for (int alignment = 0; alignment < MAX_ALIGNMENT; ++alignment) {
157 set_zero(buffer, sizeof(buffer));
rmistry@google.comd6176b02012-08-23 18:14:13 +0000158
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000159 uint32_t* base = &buffer[PAD + alignment];
160 sk_memset32(base, VALUE32, count);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000161
halcanary7d571242016-02-24 17:59:16 -0800162 compare32(reporter, buffer, 0, PAD + alignment);
163 compare32(reporter, base, VALUE32, count);
164 compare32(reporter, base + count, 0, TOTAL - count - PAD - alignment);
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000165 }
166 }
167}
168
169/**
170 * Test sk_memset16 and sk_memset32.
171 * For performance considerations, implementations may take different paths
172 * depending on the alignment of the dst, and/or the size of the count.
173 */
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000174DEF_TEST(Memset, reporter) {
mike@reedtribe.orgc52b1922012-01-07 03:49:13 +0000175 test_16(reporter);
176 test_32(reporter);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000177
reed@google.comebd24962012-05-17 14:28:11 +0000178 test_chunkalloc(reporter);
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000179}