1 /* 2 * Copyright 2019 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 */ 7 8 #include "Test.h" 9 10 #include "GrQuad.h" 11 12 #define ASSERT(cond) REPORTER_ASSERT(r, cond) 13 #define ASSERTF(cond, ...) REPORTER_ASSERT(r, cond, __VA_ARGS__) 14 #define TEST(name) DEF_TEST(GrQuadList##name, r) 15 16 struct TestData { 17 int fItem1; 18 float fItem2; 19 }; 20 21 // Simple factories to make placeholder quads used in the tests. The 2D quads 22 // will have the kRect quad type. 23 static GrQuad make_2d_quad() { 24 return GrQuad(SkRect::MakeLTRB(1.f, 2.f, 3.f, 4.f)); 25 } 26 static bool is_2d_quad(const GrPerspQuad& quad) { 27 return quad.x(0) == 1.f && quad.x(1) == 1.f && quad.x(2) == 3.f && quad.x(3) == 3.f && 28 quad.y(0) == 2.f && quad.y(1) == 4.f && quad.y(2) == 2.f && quad.y(3) == 4.f && 29 quad.w(0) == 1.f && quad.w(1) == 1.f && quad.w(2) == 1.f && quad.w(3) == 1.f; 30 } 31 32 static GrPerspQuad make_2d_persp_quad() { 33 return GrPerspQuad(SkRect::MakeLTRB(5.f, 6.f, 7.f, 8.f), SkMatrix::I()); 34 } 35 static bool is_2d_persp_quad(const GrPerspQuad& quad) { 36 return quad.x(0) == 5.f && quad.x(1) == 5.f && quad.x(2) == 7.f && quad.x(3) == 7.f && 37 quad.y(0) == 6.f && quad.y(1) == 8.f && quad.y(2) == 6.f && quad.y(3) == 8.f && 38 quad.w(0) == 1.f && quad.w(1) == 1.f && quad.w(2) == 1.f && quad.w(3) == 1.f; 39 } 40 41 static GrPerspQuad make_3d_persp_quad() { 42 // This perspective matrix leaves x and y unmodified, and sets w to the persp2 value 43 SkMatrix p = SkMatrix::I(); 44 p[SkMatrix::kMPersp2] = 13.f; 45 SkASSERT(p.hasPerspective()); // Sanity check 46 return GrPerspQuad(SkRect::MakeLTRB(9.f, 10.f, 11.f, 12.f), p); 47 } 48 static bool is_3d_persp_quad(const GrPerspQuad& quad) { 49 return quad.x(0) == 9.f && quad.x(1) == 9.f && quad.x(2) == 11.f && quad.x(3) == 11.f && 50 quad.y(0) == 10.f && quad.y(1) == 12.f && quad.y(2) == 10.f && quad.y(3) == 12.f && 51 quad.w(0) == 13.f && quad.w(1) == 13.f && quad.w(2) == 13.f && quad.w(3) == 13.f; 52 } 53 54 TEST(Add2D) { 55 GrQuadList list2D; 56 // Add a plain quad, a 2D persp quad, and then a 3D persp quad, then read back and make sure 57 // the coordinates make sense (including that the type was lifted to perspective). 58 list2D.push_back(make_2d_quad(), GrQuadType::kRect); 59 list2D.push_back(make_2d_persp_quad(), GrQuadType::kRect); 60 61 // Check 2D state of the list 62 ASSERTF(list2D.count() == 2, "Unexpected count: %d", list2D.count()); 63 ASSERTF(list2D.quadType() == GrQuadType::kRect, "Unexpected quad type: %d", 64 (uint32_t) list2D.quadType()); 65 ASSERTF(is_2d_quad(list2D[0]), "Incorrect quad at i=0"); 66 ASSERTF(is_2d_persp_quad(list2D[1]), "Incorrect quad at i=1"); 67 68 // Force the 2D quads to be updated to store ws by adding a perspective quad 69 list2D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective); 70 ASSERTF(list2D.quadType() == GrQuadType::kPerspective, 71 "Expected 2D list to be upgraded to perspective"); 72 73 // Re-check full state of list after type upgrade 74 ASSERTF(list2D.count() == 3, "Unexpected count: %d", list2D.count()); 75 ASSERTF(is_2d_quad(list2D[0]), "Incorrect quad at i=0 after upgrade"); 76 ASSERTF(is_2d_persp_quad(list2D[1]), "Incorrect quad at i=1 after upgrade"); 77 ASSERTF(is_3d_persp_quad(list2D[2]), "Incorrect quad at i=2"); 78 } 79 80 TEST(Add3D) { 81 // Now make a list that starts with a 3D persp quad, then has conventional quads added to it 82 // and make sure its state is correct 83 GrQuadList list3D; 84 list3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective); 85 list3D.push_back(make_2d_persp_quad(), GrQuadType::kRect); 86 list3D.push_back(make_2d_quad(), GrQuadType::kRect); 87 88 ASSERTF(list3D.count() == 3, "Unexpected count: %d", list3D.count()); 89 ASSERTF(is_3d_persp_quad(list3D[0]), "Incorrect quad at i=0"); 90 ASSERTF(is_2d_persp_quad(list3D[1]), "Incorrect quad at i=1"); 91 ASSERTF(is_2d_quad(list3D[2]), "Incorrect quad at i=2"); 92 } 93 94 TEST(AddWithMetadata2D) { 95 // As above, but also make sure that the metadata is saved and read properly 96 GrTQuadList<TestData> list2D; 97 // Add a plain quad, a 2D persp quad, and then a 3D persp quad, then read back and make sure 98 // the coordinates make sense (including that the type was lifted to perspective). 99 list2D.push_back(make_2d_quad(), GrQuadType::kRect, {1, 1.f}); 100 list2D.push_back(make_2d_persp_quad(), GrQuadType::kRect, {2, 2.f}); 101 102 // Check 2D state of the list 103 ASSERTF(list2D.count() == 2, "Unexpected count: %d", list2D.count()); 104 ASSERTF(list2D.quadType() == GrQuadType::kRect, "Unexpected quad type: %d", 105 (uint32_t) list2D.quadType()); 106 ASSERTF(is_2d_quad(list2D[0]), "Incorrect quad at i=0"); 107 ASSERTF(list2D.metadata(0).fItem1 == 1 && list2D.metadata(0).fItem2 == 1.f, 108 "Incorrect metadata at i=0"); 109 ASSERTF(is_2d_persp_quad(list2D[1]), "Incorrect quad at i=1"); 110 ASSERTF(list2D.metadata(1).fItem1 == 2 && list2D.metadata(1).fItem2 == 2.f, 111 "Incorrect metadata at i=1"); 112 113 // Force the 2D quads to be updated to store ws by adding a perspective quad 114 list2D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective, {3, 3.f}); 115 ASSERTF(list2D.quadType() == GrQuadType::kPerspective, 116 "Expected 2D list to be upgraded to perspective"); 117 118 // Re-check full state of list after type upgrade 119 ASSERTF(list2D.count() == 3, "Unexpected count: %d", list2D.count()); 120 ASSERTF(is_2d_quad(list2D[0]), "Incorrect quad at i=0 after upgrade"); 121 ASSERTF(list2D.metadata(0).fItem1 == 1 && list2D.metadata(0).fItem2 == 1.f, 122 "Incorrect metadata at i=0"); 123 ASSERTF(is_2d_persp_quad(list2D[1]), "Incorrect quad at i=1 after upgrade"); 124 ASSERTF(list2D.metadata(1).fItem1 == 2 && list2D.metadata(1).fItem2 == 2.f, 125 "Incorrect metadata at i=1"); 126 ASSERTF(is_3d_persp_quad(list2D[2]), "Incorrect quad at i=2"); 127 ASSERTF(list2D.metadata(2).fItem1 == 3 && list2D.metadata(2).fItem2 == 3.f, 128 "Incorrect metadata at i=2"); 129 } 130 131 TEST(AddWithMetadata3D) { 132 // Now make a list that starts with a 3D persp quad, then has conventional quads added to it 133 // and make sure its state is correct 134 GrTQuadList<TestData> list3D; 135 list3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective, {3, 3.f}); 136 list3D.push_back(make_2d_persp_quad(), GrQuadType::kRect, {2, 2.f}); 137 list3D.push_back(make_2d_quad(), GrQuadType::kRect, {1, 1.f}); 138 139 ASSERTF(list3D.count() == 3, "Unexpected count: %d", list3D.count()); 140 ASSERTF(is_3d_persp_quad(list3D[0]), "Incorrect quad at i=0"); 141 ASSERTF(list3D.metadata(0).fItem1 == 3 && list3D.metadata(0).fItem2 == 3.f, 142 "Incorrect metadata at i=0"); 143 ASSERTF(is_2d_persp_quad(list3D[1]), "Incorrect quad at i=1"); 144 ASSERTF(list3D.metadata(1).fItem1 == 2 && list3D.metadata(1).fItem2 == 2.f, 145 "Incorrect metadata at i=1"); 146 ASSERTF(is_2d_quad(list3D[2]), "Incorrect quad at i=2"); 147 ASSERTF(list3D.metadata(2).fItem1 == 1 && list3D.metadata(2).fItem2 == 1.f, 148 "Incorrect metadata at i=2"); 149 } 150 151 TEST(Concat2DWith2D) { 152 GrQuadList a2D; 153 a2D.push_back(make_2d_quad(), GrQuadType::kRect); 154 GrQuadList b2D; 155 b2D.push_back(make_2d_persp_quad(), GrQuadType::kRect); 156 157 a2D.concat(b2D); 158 159 ASSERTF(a2D.count() == 2, "Unexpected count: %d", a2D.count()); 160 ASSERTF(is_2d_quad(a2D[0]), "Incorrect quad at i=0"); 161 ASSERTF(is_2d_persp_quad(a2D[1]), "Incorrect quad at i=1"); 162 } 163 164 TEST(Concat2DWith3D) { 165 GrQuadList a2D; 166 a2D.push_back(make_2d_quad(), GrQuadType::kRect); 167 GrQuadList b3D; 168 b3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective); 169 170 a2D.concat(b3D); 171 172 ASSERTF(a2D.count() == 2, "Unexpected count: %d", a2D.count()); 173 ASSERTF(is_2d_quad(a2D[0]), "Incorrect quad at i=0"); 174 ASSERTF(is_3d_persp_quad(a2D[1]), "Incorrect quad at i=1"); 175 } 176 177 TEST(Concat3DWith2D) { 178 GrQuadList a3D; 179 a3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective); 180 GrQuadList b2D; 181 b2D.push_back(make_2d_quad(), GrQuadType::kRect); 182 183 a3D.concat(b2D); 184 185 ASSERTF(a3D.count() == 2, "Unexpected count: %d", a3D.count()); 186 ASSERTF(is_3d_persp_quad(a3D[0]), "Incorrect quad at i=0"); 187 ASSERTF(is_2d_quad(a3D[1]), "Incorrect quad at i=1"); 188 } 189 190 TEST(Concat3DWith3D) { 191 GrQuadList a3D; 192 a3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective); 193 GrQuadList b3D; 194 b3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective); 195 196 a3D.concat(b3D); 197 198 ASSERTF(a3D.count() == 2, "Unexpected count: %d", a3D.count()); 199 ASSERTF(is_3d_persp_quad(a3D[0]), "Incorrect quad at i=0"); 200 ASSERTF(is_3d_persp_quad(a3D[1]), "Incorrect quad at i=1"); 201 } 202 203 TEST(Concat2DWith2DMetadata) { 204 GrTQuadList<TestData> a2D; 205 a2D.push_back(make_2d_quad(), GrQuadType::kRect, {1, 1.f}); 206 GrTQuadList<TestData> b2D; 207 b2D.push_back(make_2d_persp_quad(), GrQuadType::kRect, {2, 2.f}); 208 209 a2D.concat(b2D); 210 211 ASSERTF(a2D.count() == 2, "Unexpected count: %d", a2D.count()); 212 ASSERTF(is_2d_quad(a2D[0]), "Incorrect quad at i=0"); 213 ASSERTF(a2D.metadata(0).fItem1 == 1 && a2D.metadata(0).fItem2 == 1.f, 214 "Incorrect metadata at i=0"); 215 ASSERTF(is_2d_persp_quad(a2D[1]), "Incorrect quad at i=1"); 216 ASSERTF(a2D.metadata(1).fItem1 == 2 && a2D.metadata(1).fItem2 == 2.f, 217 "Incorrect metadata at i=1"); 218 } 219 220 TEST(Concat2DWith3DMetadata) { 221 GrTQuadList<TestData> a2D; 222 a2D.push_back(make_2d_quad(), GrQuadType::kRect, {1, 1.f}); 223 GrTQuadList<TestData> b3D; 224 b3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective, {2, 2.f}); 225 226 a2D.concat(b3D); 227 228 ASSERTF(a2D.count() == 2, "Unexpected count: %d", a2D.count()); 229 ASSERTF(is_2d_quad(a2D[0]), "Incorrect quad at i=0"); 230 ASSERTF(a2D.metadata(0).fItem1 == 1 && a2D.metadata(0).fItem2 == 1.f, 231 "Incorrect metadata at i=0"); 232 ASSERTF(is_3d_persp_quad(a2D[1]), "Incorrect quad at i=1"); 233 ASSERTF(a2D.metadata(1).fItem1 == 2 && a2D.metadata(1).fItem2 == 2.f, 234 "Incorrect metadata at i=1"); 235 } 236 237 TEST(Concat3DWith2DMetadata) { 238 GrTQuadList<TestData> a3D; 239 a3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective, {1, 1.f}); 240 GrTQuadList<TestData> b2D; 241 b2D.push_back(make_2d_quad(), GrQuadType::kRect, {2, 2.f}); 242 243 a3D.concat(b2D); 244 245 ASSERTF(a3D.count() == 2, "Unexpected count: %d", a3D.count()); 246 ASSERTF(is_3d_persp_quad(a3D[0]), "Incorrect quad at i=0"); 247 ASSERTF(a3D.metadata(0).fItem1 == 1 && a3D.metadata(0).fItem2 == 1.f, 248 "Incorrect metadata at i=0"); 249 ASSERTF(is_2d_quad(a3D[1]), "Incorrect quad at i=1"); 250 ASSERTF(a3D.metadata(1).fItem1 == 2 && a3D.metadata(1).fItem2 == 2.f, 251 "Incorrect metadata at i=1"); 252 } 253 254 TEST(Concat3DWith3DMetadata) { 255 GrTQuadList<TestData> a3D; 256 a3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective, {1, 1.f}); 257 GrTQuadList<TestData> b3D; 258 b3D.push_back(make_3d_persp_quad(), GrQuadType::kPerspective, {2, 2.f}); 259 260 a3D.concat(b3D); 261 262 ASSERTF(a3D.count() == 2, "Unexpected count: %d", a3D.count()); 263 ASSERTF(is_3d_persp_quad(a3D[0]), "Incorrect quad at i=0"); 264 ASSERTF(a3D.metadata(0).fItem1 == 1 && a3D.metadata(0).fItem2 == 1.f, 265 "Incorrect metadata at i=0"); 266 ASSERTF(is_3d_persp_quad(a3D[1]), "Incorrect quad at i=1"); 267 ASSERTF(a3D.metadata(1).fItem1 == 2 && a3D.metadata(1).fItem2 == 2.f, 268 "Incorrect metadata at i=1"); 269 } 270 271 TEST(WriteMetadata) { 272 GrTQuadList<TestData> list; 273 list.push_back(make_2d_quad(), GrQuadType::kRect, {1, 1.f}); 274 ASSERTF(list.metadata(0).fItem1 == 1 && list.metadata(0).fItem2 == 1.f, 275 "Incorrect metadata at i=0"); // Sanity check 276 277 // Rewrite metadata within the list and read back 278 list.metadata(0).fItem1 = 2; 279 list.metadata(0).fItem2 = 2.f; 280 ASSERTF(list.metadata(0).fItem1 == 2 && list.metadata(0).fItem2 == 2.f, 281 "Incorrect metadata at i=0 after edit"); 282 } 283