content/canvas/compiledtest/TestWebGLElementArrayCache.cpp

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "mozilla/Assertions.h"
michael@0 7
michael@0 8 #include "WebGLElementArrayCache.cpp"
michael@0 9
michael@0 10 #include <cstdlib>
michael@0 11 #include <iostream>
michael@0 12 #include "nscore.h"
michael@0 13 #include "nsTArray.h"
michael@0 14
michael@0 15 using namespace mozilla;
michael@0 16
michael@0 17 int gTestsPassed = 0;
michael@0 18
michael@0 19 void VerifyImplFunction(bool condition, const char* file, int line)
michael@0 20 {
michael@0 21 if (condition) {
michael@0 22 gTestsPassed++;
michael@0 23 } else {
michael@0 24 std::cerr << "Test failed at " << file << ":" << line << std::endl;
michael@0 25 abort();
michael@0 26 }
michael@0 27 }
michael@0 28
michael@0 29 #define VERIFY(condition) \
michael@0 30 VerifyImplFunction((condition), __FILE__, __LINE__)
michael@0 31
michael@0 32 void MakeRandomVector(nsTArray<uint8_t>& a, size_t size) {
michael@0 33 a.SetLength(size);
michael@0 34 // only the most-significant bits of rand() are reasonably random.
michael@0 35 // RAND_MAX can be as low as 0x7fff, and we need 8 bits for the result, so we can only
michael@0 36 // ignore the 7 least significant bits.
michael@0 37 for (size_t i = 0; i < size; i++)
michael@0 38 a[i] = static_cast<uint8_t>((unsigned int)(rand()) >> 7);
michael@0 39 }
michael@0 40
michael@0 41 template<typename T>
michael@0 42 T RandomInteger(T a, T b)
michael@0 43 {
michael@0 44 T result(a + rand() % (b - a + 1));
michael@0 45 return result;
michael@0 46 }
michael@0 47
michael@0 48 template<typename T>
michael@0 49 GLenum GLType()
michael@0 50 {
michael@0 51 switch (sizeof(T))
michael@0 52 {
michael@0 53 case 4: return LOCAL_GL_UNSIGNED_INT;
michael@0 54 case 2: return LOCAL_GL_UNSIGNED_SHORT;
michael@0 55 case 1: return LOCAL_GL_UNSIGNED_BYTE;
michael@0 56 default:
michael@0 57 VERIFY(false);
michael@0 58 return 0;
michael@0 59 }
michael@0 60 }
michael@0 61
michael@0 62 template<typename T>
michael@0 63 void CheckValidateOneType(WebGLElementArrayCache& c, size_t firstByte, size_t countBytes)
michael@0 64 {
michael@0 65 size_t first = firstByte / sizeof(T);
michael@0 66 size_t count = countBytes / sizeof(T);
michael@0 67
michael@0 68 GLenum type = GLType<T>();
michael@0 69
michael@0 70 T max = 0;
michael@0 71 for (size_t i = 0; i < count; i++)
michael@0 72 if (c.Element<T>(first + i) > max)
michael@0 73 max = c.Element<T>(first + i);
michael@0 74
michael@0 75 VERIFY(c.Validate(type, max, first, count));
michael@0 76 VERIFY(c.Validate(type, T(-1), first, count));
michael@0 77 if (T(max + 1)) VERIFY(c.Validate(type, T(max + 1), first, count));
michael@0 78 if (max > 0) {
michael@0 79 VERIFY(!c.Validate(type, max - 1, first, count));
michael@0 80 VERIFY(!c.Validate(type, 0, first, count));
michael@0 81 }
michael@0 82 }
michael@0 83
michael@0 84 void CheckValidate(WebGLElementArrayCache& c, size_t firstByte, size_t countBytes)
michael@0 85 {
michael@0 86 CheckValidateOneType<uint8_t>(c, firstByte, countBytes);
michael@0 87 CheckValidateOneType<uint16_t>(c, firstByte, countBytes);
michael@0 88 CheckValidateOneType<uint32_t>(c, firstByte, countBytes);
michael@0 89 }
michael@0 90
michael@0 91 template<typename T>
michael@0 92 void CheckSanity()
michael@0 93 {
michael@0 94 const size_t numElems = 64; // should be significantly larger than tree leaf size to
michael@0 95 // ensure we exercise some nontrivial tree-walking
michael@0 96 T data[numElems] = {1,0,3,1,2,6,5,4}; // intentionally specify only 8 elements for now
michael@0 97 size_t numBytes = numElems * sizeof(T);
michael@0 98 MOZ_ASSERT(numBytes == sizeof(data));
michael@0 99
michael@0 100 GLenum type = GLType<T>();
michael@0 101
michael@0 102 WebGLElementArrayCache c;
michael@0 103 c.BufferData(data, numBytes);
michael@0 104 VERIFY( c.Validate(type, 6, 0, 8));
michael@0 105 VERIFY(!c.Validate(type, 5, 0, 8));
michael@0 106 VERIFY( c.Validate(type, 3, 0, 3));
michael@0 107 VERIFY(!c.Validate(type, 2, 0, 3));
michael@0 108 VERIFY( c.Validate(type, 6, 2, 4));
michael@0 109 VERIFY(!c.Validate(type, 5, 2, 4));
michael@0 110
michael@0 111 c.BufferSubData(5*sizeof(T), data, sizeof(T));
michael@0 112 VERIFY( c.Validate(type, 5, 0, 8));
michael@0 113 VERIFY(!c.Validate(type, 4, 0, 8));
michael@0 114
michael@0 115 // now test a somewhat larger size to ensure we exceed the size of a tree leaf
michael@0 116 for(size_t i = 0; i < numElems; i++)
michael@0 117 data[i] = numElems - i;
michael@0 118 c.BufferData(data, numBytes);
michael@0 119 VERIFY( c.Validate(type, numElems, 0, numElems));
michael@0 120 VERIFY(!c.Validate(type, numElems - 1, 0, numElems));
michael@0 121
michael@0 122 MOZ_ASSERT(numElems > 10);
michael@0 123 VERIFY( c.Validate(type, numElems - 10, 10, numElems - 10));
michael@0 124 VERIFY(!c.Validate(type, numElems - 11, 10, numElems - 10));
michael@0 125 }
michael@0 126
michael@0 127 template<typename T>
michael@0 128 void CheckUintOverflow()
michael@0 129 {
michael@0 130 // This test is only for integer types smaller than uint32_t
michael@0 131 static_assert(sizeof(T) < sizeof(uint32_t), "This test is only for integer types \
michael@0 132 smaller than uint32_t");
michael@0 133
michael@0 134 const size_t numElems = 64; // should be significantly larger than tree leaf size to
michael@0 135 // ensure we exercise some nontrivial tree-walking
michael@0 136 T data[numElems];
michael@0 137 size_t numBytes = numElems * sizeof(T);
michael@0 138 MOZ_ASSERT(numBytes == sizeof(data));
michael@0 139
michael@0 140 GLenum type = GLType<T>();
michael@0 141
michael@0 142 WebGLElementArrayCache c;
michael@0 143
michael@0 144 for(size_t i = 0; i < numElems; i++)
michael@0 145 data[i] = numElems - i;
michael@0 146 c.BufferData(data, numBytes);
michael@0 147
michael@0 148 // bug 825205
michael@0 149 uint32_t bigValWrappingToZero = uint32_t(T(-1)) + 1;
michael@0 150 VERIFY( c.Validate(type, bigValWrappingToZero, 0, numElems));
michael@0 151 VERIFY( c.Validate(type, bigValWrappingToZero - 1, 0, numElems));
michael@0 152 VERIFY(!c.Validate(type, 0, 0, numElems));
michael@0 153 }
michael@0 154
michael@0 155 int main(int argc, char *argv[])
michael@0 156 {
michael@0 157 srand(0); // do not want a random seed here.
michael@0 158
michael@0 159 CheckSanity<uint8_t>();
michael@0 160 CheckSanity<uint16_t>();
michael@0 161 CheckSanity<uint32_t>();
michael@0 162
michael@0 163 CheckUintOverflow<uint8_t>();
michael@0 164 CheckUintOverflow<uint16_t>();
michael@0 165
michael@0 166 nsTArray<uint8_t> v, vsub;
michael@0 167 WebGLElementArrayCache b;
michael@0 168
michael@0 169 for (int maxBufferSize = 1; maxBufferSize <= 4096; maxBufferSize *= 2) {
michael@0 170 // See bug 800612. We originally had | repeat = min(maxBufferSize, 20) |
michael@0 171 // and a real bug was only caught on Windows and not on Linux due to rand()
michael@0 172 // producing different values. In that case, the minimum value by which to replace
michael@0 173 // this 20 to reproduce the bug on Linux, was 25. Replacing it with 64 should give
michael@0 174 // us some comfort margin.
michael@0 175 int repeat = std::min(maxBufferSize, 64);
michael@0 176 for (int i = 0; i < repeat; i++) {
michael@0 177 size_t size = RandomInteger<size_t>(1, maxBufferSize);
michael@0 178 MakeRandomVector(v, size);
michael@0 179 b.BufferData(v.Elements(), size);
michael@0 180 CheckValidate(b, 0, size);
michael@0 181
michael@0 182 for (int j = 0; j < 16; j++) {
michael@0 183 for (int bufferSubDataCalls = 1; bufferSubDataCalls <= 8; bufferSubDataCalls *= 2) {
michael@0 184 for (int validateCalls = 1; validateCalls <= 8; validateCalls *= 2) {
michael@0 185
michael@0 186 size_t offset = 0, subsize = 0;
michael@0 187
michael@0 188 for (int k = 0; k < bufferSubDataCalls; k++) {
michael@0 189 offset = RandomInteger<size_t>(0, size);
michael@0 190 subsize = RandomInteger<size_t>(0, size - offset);
michael@0 191 MakeRandomVector(vsub, subsize);
michael@0 192 b.BufferSubData(offset, vsub.Elements(), subsize);
michael@0 193 }
michael@0 194
michael@0 195 for (int k = 0; k < validateCalls; k++) {
michael@0 196 offset = RandomInteger<size_t>(0, size);
michael@0 197 subsize = RandomInteger<size_t>(0, size - offset);
michael@0 198 CheckValidate(b, offset, subsize);
michael@0 199 }
michael@0 200 } // validateCalls
michael@0 201 } // bufferSubDataCalls
michael@0 202 } // j
michael@0 203 } // i
michael@0 204 } // maxBufferSize
michael@0 205
michael@0 206 std::cerr << argv[0] << ": all " << gTestsPassed << " tests passed" << std::endl;
michael@0 207 return 0;
michael@0 208 }

mercurial