1 /* 2 Copyright 2010 Google Inc. 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 18 #include "GrDrawTarget.h" 19 #include "GrTDArray.h" 20 #include "GrTBSearch.h" 21 #include "GrMatrix.h" 22 #include "GrRedBlackTree.h" 23 #include "GrPath.h" 24 #include "GrBinHashKey.h" 25 26 static void dump(const GrTDArray<int>& array) { 27 #if 0 28 for (int i = 0; i < array.count(); i++) { 29 printf(" %d", array[i]); 30 } 31 printf("\n"); 32 #endif 33 } 34 35 static void test_tdarray() { 36 GrTDArray<int> array; 37 38 *array.append() = 0; dump(array); 39 *array.append() = 2; dump(array); 40 *array.append() = 4; dump(array); 41 *array.append() = 6; dump(array); 42 GrAssert(array.count() == 4); 43 44 *array.insert(0) = -1; dump(array); 45 *array.insert(2) = 1; dump(array); 46 *array.insert(4) = 3; dump(array); 47 *array.insert(7) = 7; dump(array); 48 GrAssert(array.count() == 8); 49 array.remove(3); dump(array); 50 array.remove(0); dump(array); 51 array.removeShuffle(4); dump(array); 52 array.removeShuffle(1); dump(array); 53 GrAssert(array.count() == 4); 54 } 55 56 static bool LT(const int& elem, int value) { 57 return elem < value; 58 } 59 static bool EQ(const int& elem, int value) { 60 return elem == value; 61 } 62 63 static void test_bsearch() { 64 const int array[] = { 65 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99 66 }; 67 68 for (size_t n = 0; n < GR_ARRAY_COUNT(array); n++) { 69 for (size_t i = 0; i < n; i++) { 70 int index = GrTBSearch<int, int>(array, n, array[i]); 71 GrAssert(index == (int) i); 72 index = GrTBSearch<int, int>(array, n, -array[i]); 73 GrAssert(index < 0); 74 } 75 } 76 } 77 78 // bogus empty class for GrBinHashKey 79 class BogusEntry {}; 80 81 static void test_binHashKey() 82 { 83 const char* testStringA = "abcdABCD"; 84 const char* testStringB = "abcdBBCD"; 85 enum { 86 kDataLenUsedForKey = 8 87 }; 88 89 typedef GrBinHashKey<BogusEntry, kDataLenUsedForKey> KeyType; 90 91 KeyType keyA; 92 int passCnt = 0; 93 while (keyA.doPass()) { 94 ++passCnt; 95 keyA.keyData(reinterpret_cast<const uint32_t*>(testStringA), kDataLenUsedForKey); 96 } 97 GrAssert(passCnt == 1); //We expect the static allocation to suffice 98 GrBinHashKey<BogusEntry, kDataLenUsedForKey-1> keyBust; 99 passCnt = 0; 100 while (keyBust.doPass()) { 101 ++passCnt; 102 // Exceed static storage by 1 103 keyBust.keyData(reinterpret_cast<const uint32_t*>(testStringA), kDataLenUsedForKey); 104 } 105 GrAssert(passCnt == 2); //We expect dynamic allocation to be necessary 106 GrAssert(keyA.getHash() == keyBust.getHash()); 107 108 // Test that adding keyData in chunks gives 109 // the same hash as with one chunk 110 KeyType keyA2; 111 while (keyA2.doPass()) { 112 keyA2.keyData(reinterpret_cast<const uint32_t*>(testStringA), 4); 113 keyA2.keyData(&reinterpret_cast<const uint32_t*>(testStringA)[4], kDataLenUsedForKey-4); 114 } 115 GrAssert(keyA.getHash() == keyA2.getHash()); 116 117 KeyType keyB; 118 while (keyB.doPass()){ 119 keyB.keyData(reinterpret_cast<const uint32_t*>(testStringB), kDataLenUsedForKey); 120 } 121 GrAssert(keyA.compare(keyB) < 0); 122 GrAssert(keyA.compare(keyA2) == 0); 123 124 //Test ownership tranfer and copying 125 keyB.copyAndTakeOwnership(keyA); 126 GrAssert(keyA.fIsValid == false); 127 GrAssert(keyB.fIsValid); 128 GrAssert(keyB.getHash() == keyA2.getHash()); 129 GrAssert(keyB.compare(keyA2) == 0); 130 keyA.deepCopyFrom(keyB); 131 GrAssert(keyA.fIsValid); 132 GrAssert(keyB.fIsValid); 133 GrAssert(keyA.getHash() == keyA2.getHash()); 134 GrAssert(keyA.compare(keyA2) == 0); 135 136 //Test ownership tranfer and copying with key on heap 137 GrBinHashKey<BogusEntry, kDataLenUsedForKey-1> keyBust2; 138 keyBust2.deepCopyFrom(keyBust); 139 GrAssert(keyBust.fIsValid); 140 GrAssert(keyBust2.fIsValid); 141 GrAssert(keyBust.getHash() == keyBust2.getHash()); 142 GrAssert(keyBust.compare(keyBust2) == 0); 143 GrBinHashKey<BogusEntry, kDataLenUsedForKey-1> keyBust3; 144 keyBust3.deepCopyFrom(keyBust); 145 GrAssert(keyBust.fIsValid == false); 146 GrAssert(keyBust3.fIsValid); 147 GrAssert(keyBust3.getHash() == keyBust2.getHash()); 148 GrAssert(keyBust3.compare(keyBust2) == 0); 149 } 150 151 static void test_convex() { 152 #if 0 153 GrPath testPath; 154 GrPath::Iter testIter; 155 156 GrPath pt; 157 pt.moveTo(0, 0); 158 pt.close(); 159 160 testIter.reset(pt); 161 testPath.resetFromIter(&testIter); 162 GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); 163 164 GrPath line; 165 line.moveTo(GrIntToScalar(12), GrIntToScalar(20)); 166 line.lineTo(GrIntToScalar(-12), GrIntToScalar(-20)); 167 line.close(); 168 169 testIter.reset(line); 170 testPath.resetFromIter(&testIter); 171 GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); 172 173 GrPath triLeft; 174 triLeft.moveTo(0, 0); 175 triLeft.lineTo(1, 0); 176 triLeft.lineTo(1, 1); 177 triLeft.close(); 178 179 testIter.reset(triLeft); 180 testPath.resetFromIter(&testIter); 181 GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); 182 183 GrPath triRight; 184 triRight.moveTo(0, 0); 185 triRight.lineTo(-1, 0); 186 triRight.lineTo(1, 1); 187 triRight.close(); 188 189 testIter.reset(triRight); 190 testPath.resetFromIter(&testIter); 191 GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); 192 193 GrPath square; 194 square.moveTo(0, 0); 195 square.lineTo(1, 0); 196 square.lineTo(1, 1); 197 square.lineTo(0, 1); 198 square.close(); 199 200 testIter.reset(square); 201 testPath.resetFromIter(&testIter); 202 GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); 203 204 GrPath redundantSquare; 205 square.moveTo(0, 0); 206 square.lineTo(0, 0); 207 square.lineTo(0, 0); 208 square.lineTo(1, 0); 209 square.lineTo(1, 0); 210 square.lineTo(1, 0); 211 square.lineTo(1, 1); 212 square.lineTo(1, 1); 213 square.lineTo(1, 1); 214 square.lineTo(0, 1); 215 square.lineTo(0, 1); 216 square.lineTo(0, 1); 217 square.close(); 218 219 testIter.reset(redundantSquare); 220 testPath.resetFromIter(&testIter); 221 GrAssert(kConvex_ConvexHint == testPath.getConvexHint()); 222 223 GrPath bowTie; 224 bowTie.moveTo(0, 0); 225 bowTie.lineTo(0, 0); 226 bowTie.lineTo(0, 0); 227 bowTie.lineTo(1, 1); 228 bowTie.lineTo(1, 1); 229 bowTie.lineTo(1, 1); 230 bowTie.lineTo(1, 0); 231 bowTie.lineTo(1, 0); 232 bowTie.lineTo(1, 0); 233 bowTie.lineTo(0, 1); 234 bowTie.lineTo(0, 1); 235 bowTie.lineTo(0, 1); 236 bowTie.close(); 237 238 testIter.reset(bowTie); 239 testPath.resetFromIter(&testIter); 240 GrAssert(kConcave_ConvexHint == testPath.getConvexHint()); 241 242 GrPath spiral; 243 spiral.moveTo(0, 0); 244 spiral.lineTo(1, 0); 245 spiral.lineTo(1, 1); 246 spiral.lineTo(0, 1); 247 spiral.lineTo(0,.5); 248 spiral.lineTo(.5,.5); 249 spiral.lineTo(.5,.75); 250 spiral.close(); 251 252 testIter.reset(spiral); 253 testPath.resetFromIter(&testIter); 254 GrAssert(kConcave_ConvexHint == testPath.getConvexHint()); 255 256 GrPath dent; 257 dent.moveTo(0, 0); 258 dent.lineTo(1, 1); 259 dent.lineTo(0, 1); 260 dent.lineTo(-.5,2); 261 dent.lineTo(-2, 1); 262 dent.close(); 263 264 testIter.reset(dent); 265 testPath.resetFromIter(&testIter); 266 GrAssert(kConcave_ConvexHint == testPath.getConvexHint()); 267 #endif 268 } 269 270 void gr_run_unittests() { 271 test_tdarray(); 272 test_bsearch(); 273 test_binHashKey(); 274 test_convex(); 275 GrRedBlackTree<int>::UnitTest(); 276 GrDrawTarget::VertexLayoutUnitTest(); 277 } 278