OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 8 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 9 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
10 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" | 10 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 { | 104 { |
105 cmds::StencilThenCoverFillPathCHROMIUM cmd; | 105 cmds::StencilThenCoverFillPathCHROMIUM cmd; |
106 cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1, GL_BOUNDING_BOX_CHROMIUM); | 106 cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1, GL_BOUNDING_BOX_CHROMIUM); |
107 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); | 107 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
108 } | 108 } |
109 { | 109 { |
110 cmds::StencilThenCoverStrokePathCHROMIUM cmd; | 110 cmds::StencilThenCoverStrokePathCHROMIUM cmd; |
111 cmd.Init(kClientPathId, 1, 2, GL_BOUNDING_BOX_CHROMIUM); | 111 cmd.Init(kClientPathId, 1, 2, GL_BOUNDING_BOX_CHROMIUM); |
112 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); | 112 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
113 } | 113 } |
| 114 { |
| 115 cmds::StencilFillPathInstancedCHROMIUM cmd; |
| 116 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 117 paths[0] = kClientPathId; |
| 118 cmd.Init(1, GL_UNSIGNED_INT, shared_memory_id_, shared_memory_offset_, 0, |
| 119 GL_COUNT_UP_CHROMIUM, 1, GL_NONE, 0, 0); |
| 120 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
| 121 } |
| 122 { |
| 123 cmds::StencilStrokePathInstancedCHROMIUM cmd; |
| 124 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 125 paths[0] = kClientPathId; |
| 126 cmd.Init(1, GL_UNSIGNED_INT, shared_memory_id_, shared_memory_offset_, 0, |
| 127 0x80, 0x80, GL_NONE, 0, 0); |
| 128 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
| 129 } |
| 130 { |
| 131 cmds::CoverFillPathInstancedCHROMIUM cmd; |
| 132 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 133 paths[0] = kClientPathId; |
| 134 cmd.Init(1, GL_UNSIGNED_INT, shared_memory_id_, shared_memory_offset_, 0, |
| 135 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_NONE, 0, 0); |
| 136 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
| 137 } |
| 138 { |
| 139 cmds::CoverStrokePathInstancedCHROMIUM cmd; |
| 140 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 141 paths[0] = kClientPathId; |
| 142 cmd.Init(1, GL_UNSIGNED_INT, shared_memory_id_, shared_memory_offset_, 0, |
| 143 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_NONE, 0, 0); |
| 144 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
| 145 } |
| 146 { |
| 147 cmds::StencilThenCoverFillPathInstancedCHROMIUM cmd; |
| 148 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 149 paths[0] = kClientPathId; |
| 150 cmd.Init(1, GL_UNSIGNED_INT, shared_memory_id_, shared_memory_offset_, 0, |
| 151 GL_COUNT_UP_CHROMIUM, 1, |
| 152 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_NONE, 0, 0); |
| 153 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
| 154 } |
| 155 { |
| 156 cmds::StencilThenCoverStrokePathInstancedCHROMIUM cmd; |
| 157 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 158 paths[0] = kClientPathId; |
| 159 cmd.Init(1, GL_UNSIGNED_INT, shared_memory_id_, shared_memory_offset_, 0, |
| 160 0x80, 0x80, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_NONE, 0, |
| 161 0); |
| 162 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); |
| 163 } |
114 } | 164 } |
115 | 165 |
116 class GLES2DecoderTestWithCHROMIUMPathRendering : public GLES2DecoderTest { | 166 class GLES2DecoderTestWithCHROMIUMPathRendering : public GLES2DecoderTest { |
117 public: | 167 public: |
118 GLES2DecoderTestWithCHROMIUMPathRendering() : client_path_id_(125) {} | 168 GLES2DecoderTestWithCHROMIUMPathRendering() : client_path_id_(125) {} |
119 | 169 |
120 void SetUp() override { | 170 void SetUp() override { |
121 InitState init; | 171 InitState init; |
122 init.gl_version = "opengl es 3.1"; | 172 init.gl_version = "opengl es 3.1"; |
123 init.has_alpha = true; | 173 init.has_alpha = true; |
124 init.has_depth = true; | 174 init.has_depth = true; |
125 init.request_alpha = true; | 175 init.request_alpha = true; |
126 init.request_depth = true; | 176 init.request_depth = true; |
127 init.bind_generates_resource = true; | 177 init.bind_generates_resource = true; |
128 init.extensions = "GL_NV_path_rendering"; | 178 init.extensions = "GL_NV_path_rendering"; |
129 base::CommandLine command_line(0, NULL); | 179 base::CommandLine command_line(0, NULL); |
130 command_line.AppendSwitch(switches::kEnableGLPathRendering); | 180 command_line.AppendSwitch(switches::kEnableGLPathRendering); |
131 InitDecoderWithCommandLine(init, &command_line); | 181 InitDecoderWithCommandLine(init, &command_line); |
132 | 182 |
133 EXPECT_CALL(*gl_, GenPathsNV(1)) | 183 EXPECT_CALL(*gl_, GenPathsNV(1)) |
134 .WillOnce(Return(kServicePathId)) | 184 .WillOnce(Return(kServicePathId)) |
135 .RetiresOnSaturation(); | 185 .RetiresOnSaturation(); |
136 cmds::GenPathsCHROMIUM cmd; | 186 cmds::GenPathsCHROMIUM cmd; |
137 cmd.Init(client_path_id_, 1); | 187 cmd.Init(client_path_id_, 1); |
138 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 188 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
| 189 |
| 190 // The tests use client_path_id_ to test all sorts of drawing. The NVPR API |
| 191 // behaves differently with a path name that is "used" but not which does |
| 192 // not "allocate path object state" and a path name that is a name of a real |
| 193 // path object. The drawing with former causes GL error while latter works |
| 194 // ok, even if there is nothing in the actual path object. To remain |
| 195 // compatible with the API, we allocate path object state even when using |
| 196 // the mock API. |
| 197 EXPECT_CALL(*gl_, |
| 198 PathCommandsNV(kServicePathId, 0, NULL, 0, GL_FLOAT, NULL)) |
| 199 .RetiresOnSaturation(); |
| 200 cmds::PathCommandsCHROMIUM pcmd; |
| 201 pcmd.Init(client_path_id_, 0, 0, 0, 0, GL_FLOAT, 0, 0); |
| 202 EXPECT_EQ(error::kNoError, ExecuteCmd(pcmd)); |
139 } | 203 } |
140 | 204 |
141 protected: | 205 protected: |
142 template <typename TypeParam> | 206 template <typename TypeParam> |
143 void TestPathCommandsCHROMIUMCoordTypes(); | 207 void TestPathCommandsCHROMIUMCoordTypes(); |
144 | 208 |
| 209 struct InstancedTestcase { |
| 210 GLsizei num_paths; |
| 211 const GLuint* paths; |
| 212 GLuint path_base; |
| 213 GLenum fill_mode; |
| 214 GLuint reference; |
| 215 GLuint mask; |
| 216 GLenum transform_type; |
| 217 const GLfloat* transform_values; |
| 218 size_t sizeof_paths; // Used for copying to shm buffer. |
| 219 size_t sizeof_transform_values; // Used for copying to shm buffer. |
| 220 error::Error expected_error; |
| 221 GLint expected_gl_error; |
| 222 bool expect_gl_call; |
| 223 }; |
| 224 |
| 225 void CallAllInstancedCommands(const InstancedTestcase& testcase) { |
| 226 // Note: for testcases that expect a call, We do not compare the 'paths' |
| 227 // array during EXPECT_CALL due to it being void*. Instead, we rely on the |
| 228 // fact that if the path base was not added correctly, the paths wouldn't |
| 229 // exists and the call wouldn't come through. |
| 230 |
| 231 bool copy_paths = false; // Paths are copied for each call that has paths, |
| 232 // since the implementation modifies the memory |
| 233 // area. |
| 234 GLuint* paths = NULL; |
| 235 uint32 paths_shm_id = 0; |
| 236 uint32 paths_shm_offset = 0; |
| 237 GLfloat* transforms = NULL; |
| 238 uint32 transforms_shm_id = 0; |
| 239 uint32 transforms_shm_offset = 0; |
| 240 |
| 241 if (testcase.transform_values) { |
| 242 transforms = GetSharedMemoryAs<GLfloat*>(); |
| 243 transforms_shm_id = shared_memory_id_; |
| 244 transforms_shm_offset = shared_memory_offset_; |
| 245 memcpy(transforms, testcase.transform_values, |
| 246 testcase.sizeof_transform_values); |
| 247 } else { |
| 248 DCHECK(testcase.sizeof_transform_values == 0); |
| 249 } |
| 250 if (testcase.paths) { |
| 251 paths = GetSharedMemoryAsWithOffset<GLuint*>( |
| 252 testcase.sizeof_transform_values); |
| 253 paths_shm_id = shared_memory_id_; |
| 254 paths_shm_offset = |
| 255 shared_memory_offset_ + testcase.sizeof_transform_values; |
| 256 copy_paths = true; |
| 257 } else { |
| 258 DCHECK(testcase.sizeof_paths == 0); |
| 259 } |
| 260 |
| 261 if (testcase.expect_gl_call) { |
| 262 EXPECT_CALL(*gl_, StencilFillPathInstancedNV( |
| 263 testcase.num_paths, GL_UNSIGNED_INT, paths, 0, |
| 264 testcase.fill_mode, testcase.mask, |
| 265 testcase.transform_type, transforms)) |
| 266 .RetiresOnSaturation(); |
| 267 } |
| 268 if (copy_paths) { |
| 269 memcpy(paths, testcase.paths, testcase.sizeof_paths); |
| 270 } |
| 271 { |
| 272 cmds::StencilFillPathInstancedCHROMIUM sfi_cmd; |
| 273 sfi_cmd.Init(testcase.num_paths, GL_UNSIGNED_INT, paths_shm_id, |
| 274 paths_shm_offset, testcase.path_base, testcase.fill_mode, |
| 275 testcase.mask, testcase.transform_type, transforms_shm_id, |
| 276 transforms_shm_offset); |
| 277 EXPECT_EQ(testcase.expected_error, ExecuteCmd(sfi_cmd)); |
| 278 EXPECT_EQ(testcase.expected_gl_error, GetGLError()); |
| 279 } |
| 280 |
| 281 if (testcase.expect_gl_call) { |
| 282 EXPECT_CALL(*gl_, StencilStrokePathInstancedNV( |
| 283 testcase.num_paths, GL_UNSIGNED_INT, paths, 0, |
| 284 testcase.reference, testcase.mask, |
| 285 testcase.transform_type, transforms)) |
| 286 .RetiresOnSaturation(); |
| 287 } |
| 288 if (copy_paths) { |
| 289 memcpy(paths, testcase.paths, testcase.sizeof_paths); |
| 290 } |
| 291 { |
| 292 cmds::StencilStrokePathInstancedCHROMIUM ssi_cmd; |
| 293 ssi_cmd.Init(testcase.num_paths, GL_UNSIGNED_INT, paths_shm_id, |
| 294 paths_shm_offset, testcase.path_base, testcase.reference, |
| 295 testcase.mask, testcase.transform_type, transforms_shm_id, |
| 296 transforms_shm_offset); |
| 297 EXPECT_EQ(testcase.expected_error, ExecuteCmd(ssi_cmd)); |
| 298 EXPECT_EQ(testcase.expected_gl_error, GetGLError()); |
| 299 } |
| 300 |
| 301 if (testcase.expect_gl_call) { |
| 302 EXPECT_CALL(*gl_, CoverFillPathInstancedNV( |
| 303 testcase.num_paths, GL_UNSIGNED_INT, paths, 0, |
| 304 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, |
| 305 testcase.transform_type, transforms)) |
| 306 .RetiresOnSaturation(); |
| 307 } |
| 308 if (copy_paths) { |
| 309 memcpy(paths, testcase.paths, testcase.sizeof_paths); |
| 310 } |
| 311 { |
| 312 cmds::CoverFillPathInstancedCHROMIUM cfi_cmd; |
| 313 cfi_cmd.Init( |
| 314 testcase.num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 315 testcase.path_base, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, |
| 316 testcase.transform_type, transforms_shm_id, transforms_shm_offset); |
| 317 EXPECT_EQ(testcase.expected_error, ExecuteCmd(cfi_cmd)); |
| 318 EXPECT_EQ(testcase.expected_gl_error, GetGLError()); |
| 319 } |
| 320 if (testcase.expect_gl_call) { |
| 321 EXPECT_CALL(*gl_, CoverStrokePathInstancedNV( |
| 322 testcase.num_paths, GL_UNSIGNED_INT, paths, 0, |
| 323 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, |
| 324 testcase.transform_type, transforms)) |
| 325 .RetiresOnSaturation(); |
| 326 } |
| 327 if (copy_paths) { |
| 328 memcpy(paths, testcase.paths, testcase.sizeof_paths); |
| 329 } |
| 330 |
| 331 { |
| 332 cmds::CoverStrokePathInstancedCHROMIUM csi_cmd; |
| 333 csi_cmd.Init( |
| 334 testcase.num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 335 testcase.path_base, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, |
| 336 testcase.transform_type, transforms_shm_id, transforms_shm_offset); |
| 337 EXPECT_EQ(testcase.expected_error, ExecuteCmd(csi_cmd)); |
| 338 EXPECT_EQ(testcase.expected_gl_error, GetGLError()); |
| 339 } |
| 340 |
| 341 if (testcase.expect_gl_call) { |
| 342 EXPECT_CALL(*gl_, StencilThenCoverFillPathInstancedNV( |
| 343 testcase.num_paths, GL_UNSIGNED_INT, paths, 0, |
| 344 testcase.fill_mode, testcase.mask, |
| 345 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, |
| 346 testcase.transform_type, transforms)) |
| 347 .RetiresOnSaturation(); |
| 348 } |
| 349 if (copy_paths) { |
| 350 memcpy(paths, testcase.paths, testcase.sizeof_paths); |
| 351 } |
| 352 { |
| 353 cmds::StencilThenCoverFillPathInstancedCHROMIUM stcfi_cmd; |
| 354 stcfi_cmd.Init(testcase.num_paths, GL_UNSIGNED_INT, paths_shm_id, |
| 355 paths_shm_offset, testcase.path_base, testcase.fill_mode, |
| 356 testcase.mask, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, |
| 357 testcase.transform_type, transforms_shm_id, |
| 358 transforms_shm_offset); |
| 359 EXPECT_EQ(testcase.expected_error, ExecuteCmd(stcfi_cmd)); |
| 360 EXPECT_EQ(testcase.expected_gl_error, GetGLError()); |
| 361 } |
| 362 |
| 363 if (testcase.expect_gl_call) { |
| 364 EXPECT_CALL(*gl_, StencilThenCoverStrokePathInstancedNV( |
| 365 testcase.num_paths, GL_UNSIGNED_INT, paths, 0, |
| 366 testcase.reference, testcase.mask, |
| 367 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, |
| 368 testcase.transform_type, transforms)) |
| 369 .RetiresOnSaturation(); |
| 370 } |
| 371 if (copy_paths) { |
| 372 memcpy(paths, testcase.paths, testcase.sizeof_paths); |
| 373 } |
| 374 { |
| 375 cmds::StencilThenCoverStrokePathInstancedCHROMIUM stcsi_cmd; |
| 376 stcsi_cmd.Init(testcase.num_paths, GL_UNSIGNED_INT, paths_shm_id, |
| 377 paths_shm_offset, testcase.path_base, testcase.reference, |
| 378 testcase.mask, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, |
| 379 testcase.transform_type, transforms_shm_id, |
| 380 transforms_shm_offset); |
| 381 EXPECT_EQ(testcase.expected_error, ExecuteCmd(stcsi_cmd)); |
| 382 EXPECT_EQ(testcase.expected_gl_error, GetGLError()); |
| 383 } |
| 384 } |
| 385 |
| 386 void CallAllInstancedCommandsWithInvalidSHM(GLsizei num_paths, |
| 387 const GLuint* paths, |
| 388 GLuint* paths_shm, |
| 389 uint32 paths_shm_id, |
| 390 uint32 paths_shm_offset, |
| 391 uint32 transforms_shm_id, |
| 392 uint32 transforms_shm_offset) { |
| 393 const GLuint kPathBase = 0; |
| 394 const GLenum kFillMode = GL_INVERT; |
| 395 const GLuint kMask = 0x80; |
| 396 const GLuint kReference = 0xFF; |
| 397 const GLuint kTransformType = GL_AFFINE_3D_CHROMIUM; |
| 398 memcpy(paths_shm, paths, sizeof(GLuint) * num_paths); |
| 399 { |
| 400 cmds::StencilFillPathInstancedCHROMIUM sfi_cmd; |
| 401 sfi_cmd.Init(num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 402 kPathBase, kFillMode, kMask, kTransformType, |
| 403 transforms_shm_id, transforms_shm_offset); |
| 404 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(sfi_cmd)); |
| 405 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 406 } |
| 407 memcpy(paths_shm, paths, sizeof(GLuint) * num_paths); |
| 408 { |
| 409 cmds::StencilStrokePathInstancedCHROMIUM ssi_cmd; |
| 410 ssi_cmd.Init(num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 411 kPathBase, kReference, kMask, kTransformType, |
| 412 transforms_shm_id, transforms_shm_offset); |
| 413 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(ssi_cmd)); |
| 414 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 415 } |
| 416 memcpy(paths_shm, paths, sizeof(GLuint) * num_paths); |
| 417 { |
| 418 cmds::CoverFillPathInstancedCHROMIUM cfi_cmd; |
| 419 cfi_cmd.Init(num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 420 kPathBase, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, |
| 421 kTransformType, transforms_shm_id, transforms_shm_offset); |
| 422 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cfi_cmd)); |
| 423 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 424 } |
| 425 memcpy(paths_shm, paths, sizeof(GLuint) * num_paths); |
| 426 { |
| 427 cmds::CoverStrokePathInstancedCHROMIUM csi_cmd; |
| 428 csi_cmd.Init(num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 429 kPathBase, GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, |
| 430 kTransformType, transforms_shm_id, transforms_shm_offset); |
| 431 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(csi_cmd)); |
| 432 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 433 } |
| 434 memcpy(paths_shm, paths, sizeof(GLuint) * num_paths); |
| 435 { |
| 436 cmds::StencilThenCoverFillPathInstancedCHROMIUM stcfi_cmd; |
| 437 stcfi_cmd.Init(num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 438 kPathBase, kFillMode, kMask, |
| 439 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, kTransformType, |
| 440 transforms_shm_id, transforms_shm_offset); |
| 441 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(stcfi_cmd)); |
| 442 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 443 } |
| 444 memcpy(paths_shm, paths, sizeof(GLuint) * num_paths); |
| 445 { |
| 446 cmds::StencilThenCoverStrokePathInstancedCHROMIUM stcsi_cmd; |
| 447 stcsi_cmd.Init(num_paths, GL_UNSIGNED_INT, paths_shm_id, paths_shm_offset, |
| 448 kPathBase, kReference, kMask, |
| 449 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, kTransformType, |
| 450 transforms_shm_id, transforms_shm_offset); |
| 451 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(stcsi_cmd)); |
| 452 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 453 } |
| 454 } |
| 455 |
145 GLuint client_path_id_; | 456 GLuint client_path_id_; |
146 static const GLuint kServicePathId = 311; | 457 static const GLuint kServicePathId = 311; |
147 }; | 458 }; |
148 | 459 |
149 INSTANTIATE_TEST_CASE_P(Service, | 460 INSTANTIATE_TEST_CASE_P(Service, |
150 GLES2DecoderTestWithCHROMIUMPathRendering, | 461 GLES2DecoderTestWithCHROMIUMPathRendering, |
151 ::testing::Bool()); | 462 ::testing::Bool()); |
152 | 463 |
153 class GLES2DecoderTestWithBlendEquationAdvanced : public GLES2DecoderTest { | 464 class GLES2DecoderTestWithBlendEquationAdvanced : public GLES2DecoderTest { |
154 public: | 465 public: |
(...skipping 25 matching lines...) Expand all Loading... |
180 gen_cmd.Init(kFirstClientID, 0); | 491 gen_cmd.Init(kFirstClientID, 0); |
181 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); | 492 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
182 EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 493 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
183 | 494 |
184 // DeletePaths range 0 causes no calls. | 495 // DeletePaths range 0 causes no calls. |
185 cmds::DeletePathsCHROMIUM delete_cmd; | 496 cmds::DeletePathsCHROMIUM delete_cmd; |
186 delete_cmd.Init(kFirstClientID, 0); | 497 delete_cmd.Init(kFirstClientID, 0); |
187 EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); | 498 EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
188 EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 499 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
189 | 500 |
190 // DeletePaths client 0 causes no calls and no errors. | 501 // DeletePaths client id 0 causes no calls and no errors. |
191 delete_cmd.Init(0, 1); | 502 delete_cmd.Init(0, 1); |
192 EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); | 503 EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
193 EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 504 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
194 | 505 |
195 // DeletePaths with a big range should not cause any deletes. | 506 // DeletePaths with a big range should not cause any deletes. |
196 delete_cmd.Init(client_path_id_ + 1, | 507 delete_cmd.Init(client_path_id_ + 1, |
197 std::numeric_limits<GLsizei>::max() - client_path_id_ - 1); | 508 std::numeric_limits<GLsizei>::max() - client_path_id_ - 1); |
198 EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); | 509 EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
199 EXPECT_EQ(GL_NO_ERROR, GetGLError()); | 510 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
200 | 511 |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 PathCommandsCHROMIUMCoordTypes) { | 1282 PathCommandsCHROMIUMCoordTypes) { |
972 // Not using a typed test case, because the base class is already parametrized | 1283 // Not using a typed test case, because the base class is already parametrized |
973 // test case and uses GetParam. | 1284 // test case and uses GetParam. |
974 TestPathCommandsCHROMIUMCoordTypes<GLbyte>(); | 1285 TestPathCommandsCHROMIUMCoordTypes<GLbyte>(); |
975 TestPathCommandsCHROMIUMCoordTypes<GLubyte>(); | 1286 TestPathCommandsCHROMIUMCoordTypes<GLubyte>(); |
976 TestPathCommandsCHROMIUMCoordTypes<GLshort>(); | 1287 TestPathCommandsCHROMIUMCoordTypes<GLshort>(); |
977 TestPathCommandsCHROMIUMCoordTypes<GLushort>(); | 1288 TestPathCommandsCHROMIUMCoordTypes<GLushort>(); |
978 TestPathCommandsCHROMIUMCoordTypes<GLfloat>(); | 1289 TestPathCommandsCHROMIUMCoordTypes<GLfloat>(); |
979 } | 1290 } |
980 | 1291 |
| 1292 TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
| 1293 StencilXFillPathInstancedCHROMIUMInvalidArgs) { |
| 1294 cmds::StencilFillPathInstancedCHROMIUM sfi_cmd; |
| 1295 cmds::StencilThenCoverFillPathInstancedCHROMIUM stcfi_cmd; |
| 1296 |
| 1297 const GLuint kPaths[] = {client_path_id_, client_path_id_ + 5, |
| 1298 client_path_id_, client_path_id_ + 18}; |
| 1299 const GLsizei kPathCount = arraysize(kPaths); |
| 1300 |
| 1301 struct { |
| 1302 GLenum fill_mode; |
| 1303 GLuint mask; |
| 1304 GLint expected_error; |
| 1305 } testcases[] = { |
| 1306 // Using invalid fill mode produces invalid enum. |
| 1307 {GL_COUNT_UP_CHROMIUM - 1, 0x7F, GL_INVALID_ENUM}, |
| 1308 {GL_COUNT_DOWN_CHROMIUM + 1, 0x7F, GL_INVALID_ENUM}, |
| 1309 // Using /mask/+1 which is not power of two produces invalid value. |
| 1310 {GL_COUNT_UP_CHROMIUM, 0x80, GL_INVALID_VALUE}, |
| 1311 {GL_COUNT_DOWN_CHROMIUM, 4, GL_INVALID_VALUE}}; |
| 1312 |
| 1313 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 1314 |
| 1315 for (size_t i = 0; i < arraysize(testcases); ++i) { |
| 1316 memcpy(paths, kPaths, sizeof(kPaths)); |
| 1317 sfi_cmd.Init(kPathCount, GL_UNSIGNED_INT, shared_memory_id_, |
| 1318 shared_memory_offset_, 0, testcases[i].fill_mode, |
| 1319 testcases[i].mask, GL_NONE, 0, 0); |
| 1320 EXPECT_EQ(error::kNoError, ExecuteCmd(sfi_cmd)); |
| 1321 EXPECT_EQ(testcases[i].expected_error, GetGLError()); |
| 1322 |
| 1323 memcpy(paths, kPaths, sizeof(kPaths)); |
| 1324 stcfi_cmd.Init(kPathCount, GL_UNSIGNED_INT, shared_memory_id_, |
| 1325 shared_memory_offset_, 0, testcases[i].fill_mode, |
| 1326 testcases[i].mask, |
| 1327 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_NONE, 0, 0); |
| 1328 EXPECT_EQ(error::kNoError, ExecuteCmd(stcfi_cmd)); |
| 1329 EXPECT_EQ(testcases[i].expected_error, GetGLError()); |
| 1330 } |
| 1331 } |
| 1332 |
| 1333 TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
| 1334 StencilXFillPathInstancedCHROMIUMFillMode) { |
| 1335 SetupExpectationsForApplyingDefaultDirtyState(); |
| 1336 |
| 1337 // Test different fill modes. |
| 1338 cmds::StencilFillPathInstancedCHROMIUM sfi_cmd; |
| 1339 cmds::StencilThenCoverFillPathInstancedCHROMIUM stcfi_cmd; |
| 1340 |
| 1341 const GLuint kPaths[] = {client_path_id_, client_path_id_ + 5, |
| 1342 client_path_id_, client_path_id_ + 18}; |
| 1343 const GLsizei kPathCount = arraysize(kPaths); |
| 1344 |
| 1345 static const GLenum kFillModes[] = {GL_INVERT, GL_COUNT_UP_CHROMIUM, |
| 1346 GL_COUNT_DOWN_CHROMIUM}; |
| 1347 const GLuint kMask = 0x7F; |
| 1348 |
| 1349 GLuint* paths = GetSharedMemoryAs<GLuint*>(); |
| 1350 |
| 1351 for (size_t i = 0; i < arraysize(kFillModes); ++i) { |
| 1352 memcpy(paths, kPaths, sizeof(kPaths)); |
| 1353 EXPECT_CALL( |
| 1354 *gl_, StencilFillPathInstancedNV(kPathCount, GL_UNSIGNED_INT, paths, 0, |
| 1355 kFillModes[i], kMask, GL_NONE, NULL)) |
| 1356 .RetiresOnSaturation(); |
| 1357 sfi_cmd.Init(kPathCount, GL_UNSIGNED_INT, shared_memory_id_, |
| 1358 shared_memory_offset_, 0, kFillModes[i], kMask, GL_NONE, 0, 0); |
| 1359 EXPECT_EQ(error::kNoError, ExecuteCmd(sfi_cmd)); |
| 1360 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 1361 |
| 1362 memcpy(paths, kPaths, sizeof(kPaths)); |
| 1363 EXPECT_CALL(*gl_, |
| 1364 StencilThenCoverFillPathInstancedNV( |
| 1365 kPathCount, GL_UNSIGNED_INT, paths, 0, kFillModes[i], kMask, |
| 1366 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV, GL_NONE, NULL)) |
| 1367 .RetiresOnSaturation(); |
| 1368 stcfi_cmd.Init(kPathCount, GL_UNSIGNED_INT, shared_memory_id_, |
| 1369 shared_memory_offset_, 0, kFillModes[i], kMask, |
| 1370 GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_NONE, 0, 0); |
| 1371 EXPECT_EQ(error::kNoError, ExecuteCmd(stcfi_cmd)); |
| 1372 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 1373 } |
| 1374 } |
| 1375 |
| 1376 TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, InstancedCalls) { |
| 1377 SetupExpectationsForApplyingDefaultDirtyState(); |
| 1378 |
| 1379 const GLuint kPaths[] = {0, client_path_id_, 15, client_path_id_}; |
| 1380 const GLsizei kPathCount = arraysize(kPaths); |
| 1381 |
| 1382 // The path base will be client_path_id_, and so 0 is a |
| 1383 // valid path. |
| 1384 const GLuint kPathBase = client_path_id_; |
| 1385 const GLuint kPathsWithBase[] = {0, 5, 0, 18}; |
| 1386 |
| 1387 const GLenum kFillMode = GL_INVERT; |
| 1388 const GLuint kMask = 0x80; |
| 1389 const GLuint kReference = 0xFF; |
| 1390 |
| 1391 GLfloat transform_values[12 * kPathCount]; |
| 1392 for (GLsizei i = 0; i < kPathCount; ++i) { |
| 1393 for (int j = 0; j < 12; ++j) { |
| 1394 transform_values[i * 12 + j] = 0.1f * j + i; |
| 1395 } |
| 1396 } |
| 1397 |
| 1398 InstancedTestcase testcases[] = { |
| 1399 // Test a normal call. |
| 1400 {kPathCount, kPaths, 0, kFillMode, kReference, kMask, GL_NONE, NULL, |
| 1401 sizeof(kPaths), 0, error::kNoError, GL_NO_ERROR, true}, |
| 1402 // Test that the path base is applied correctly for each instanced call. |
| 1403 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1404 GL_NONE, NULL, sizeof(kPaths), 0, error::kNoError, GL_NO_ERROR, true}, |
| 1405 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1406 |
| 1407 // Test all possible transform types. The float array is big enough for |
| 1408 // all the variants. The contents of the array in call is not checked, |
| 1409 // though. |
| 1410 GL_TRANSLATE_X_CHROMIUM, transform_values, sizeof(kPaths), |
| 1411 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1412 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1413 GL_TRANSLATE_Y_CHROMIUM, transform_values, sizeof(kPaths), |
| 1414 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1415 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1416 GL_TRANSLATE_2D_CHROMIUM, transform_values, sizeof(kPaths), |
| 1417 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1418 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1419 GL_TRANSLATE_3D_CHROMIUM, transform_values, sizeof(kPaths), |
| 1420 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1421 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1422 GL_AFFINE_2D_CHROMIUM, transform_values, sizeof(kPaths), |
| 1423 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1424 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1425 GL_AFFINE_3D_CHROMIUM, transform_values, sizeof(kPaths), |
| 1426 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1427 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1428 GL_TRANSPOSE_AFFINE_2D_CHROMIUM, transform_values, sizeof(kPaths), |
| 1429 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}, |
| 1430 {kPathCount, kPathsWithBase, kPathBase, kFillMode, kReference, kMask, |
| 1431 GL_TRANSPOSE_AFFINE_3D_CHROMIUM, transform_values, sizeof(kPaths), |
| 1432 sizeof(transform_values), error::kNoError, GL_NO_ERROR, true}}; |
| 1433 |
| 1434 for (size_t i = 0; i < arraysize(testcases); ++i) { |
| 1435 SCOPED_TRACE(testing::Message() << "InstancedCalls testcase " << i); |
| 1436 CallAllInstancedCommands(testcases[i]); |
| 1437 } |
| 1438 } |
| 1439 |
| 1440 TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, InstancedNoCalls) { |
| 1441 const GLuint kPaths[] = {1, client_path_id_, 5, client_path_id_}; |
| 1442 const GLsizei kPathCount = arraysize(kPaths); |
| 1443 |
| 1444 const GLenum kFillMode = GL_INVERT; |
| 1445 const GLuint kMask = 0x80; |
| 1446 const GLuint kReference = 0xFF; |
| 1447 GLfloat transform_values[12 * kPathCount]; |
| 1448 for (GLsizei i = 0; i < kPathCount; ++i) { |
| 1449 for (int j = 0; j < 12; ++j) { |
| 1450 transform_values[i * 12 + j] = 0.1f * j + i; |
| 1451 } |
| 1452 } |
| 1453 |
| 1454 // The path base will be client_path_id_, and so 0 is a valid path and others |
| 1455 // should be invalid. |
| 1456 const GLuint kInvalidPathBase = client_path_id_; |
| 1457 const GLuint kInvalidPathsWithBase[] = {1, client_path_id_, 5, 18}; |
| 1458 |
| 1459 const GLuint kBigInvalidPathBase = std::numeric_limits<GLuint>::max() - 5; |
| 1460 |
| 1461 InstancedTestcase testcases[] = { |
| 1462 // Zero path count produces no error, no call. |
| 1463 {0, NULL, 0, kFillMode, kReference, kMask, GL_NONE, NULL, 0, 0, |
| 1464 error::kNoError, GL_NO_ERROR, false}, |
| 1465 |
| 1466 // Zero path count, even with path data, produces no error, no call. |
| 1467 {0, kPaths, 0, kFillMode, kReference, kMask, GL_TRANSLATE_X_CHROMIUM, |
| 1468 transform_values, sizeof(kPaths), sizeof(transform_values), |
| 1469 error::kNoError, GL_NO_ERROR, false}, |
| 1470 |
| 1471 // Negative path count produces error. |
| 1472 {-1, kPaths, 0, kFillMode, kReference, kMask, GL_TRANSLATE_X_CHROMIUM, |
| 1473 transform_values, sizeof(kPaths), sizeof(transform_values), |
| 1474 error::kNoError, GL_INVALID_VALUE, false}, |
| 1475 |
| 1476 // Passing paths count but not having the shm data is a connection error. |
| 1477 {kPathCount, NULL, 0, kFillMode, kReference, kMask, |
| 1478 GL_TRANSLATE_X_CHROMIUM, transform_values, 0, sizeof(transform_values), |
| 1479 error::kOutOfBounds, GL_NO_ERROR, false}, |
| 1480 |
| 1481 // Huge path count would cause huge transfer buffer, it does not go |
| 1482 // through. |
| 1483 {std::numeric_limits<GLsizei>::max() - 3, kPaths, 0, kFillMode, |
| 1484 kReference, kMask, GL_TRANSLATE_X_CHROMIUM, transform_values, |
| 1485 sizeof(kPaths), sizeof(transform_values), error::kOutOfBounds, |
| 1486 GL_NO_ERROR, false}, |
| 1487 |
| 1488 // Test that the path base is applied correctly for each instanced call. |
| 1489 // In this case no path is marked as used, and so no GL function should be |
| 1490 // called and no error should be generated. |
| 1491 {kPathCount, kInvalidPathsWithBase, kInvalidPathBase, kFillMode, |
| 1492 kReference, kMask, GL_TRANSLATE_X_CHROMIUM, transform_values, |
| 1493 sizeof(kInvalidPathsWithBase), sizeof(transform_values), error::kNoError, |
| 1494 GL_NO_ERROR, false}, |
| 1495 |
| 1496 // Test that if using path base causes path id to overflow, we get gl |
| 1497 // invalid operation error. |
| 1498 {kPathCount, kInvalidPathsWithBase, kBigInvalidPathBase, kFillMode, |
| 1499 kReference, kMask, GL_TRANSLATE_X_CHROMIUM, transform_values, |
| 1500 sizeof(kInvalidPathsWithBase), sizeof(transform_values), error::kNoError, |
| 1501 GL_INVALID_OPERATION, false}, |
| 1502 |
| 1503 // Test that using correct paths but invalid transform type produces |
| 1504 // invalid enum. |
| 1505 {kPathCount, kPaths, 0, kFillMode, kReference, kMask, |
| 1506 GL_TRANSLATE_X_CHROMIUM - 1, transform_values, sizeof(kPaths), |
| 1507 sizeof(transform_values), error::kNoError, GL_INVALID_ENUM, false}, |
| 1508 |
| 1509 // Test that if we have transform, not having the shm data is a connection |
| 1510 // error. |
| 1511 {kPathCount, kPaths, 0, kFillMode, kReference, kMask, |
| 1512 GL_TRANSLATE_X_CHROMIUM, NULL, sizeof(kPaths), 0, error::kOutOfBounds, |
| 1513 GL_NO_ERROR, false}}; |
| 1514 for (size_t i = 0; i < arraysize(testcases); ++i) { |
| 1515 SCOPED_TRACE(testing::Message() << "InstancedNoCalls testcase " << i); |
| 1516 CallAllInstancedCommands(testcases[i]); |
| 1517 } |
| 1518 } |
| 1519 |
| 1520 TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, InstancedInvalidSHMValues) { |
| 1521 const GLuint kPaths[] = {1, client_path_id_, 5, client_path_id_}; |
| 1522 const GLsizei kPathCount = arraysize(kPaths); |
| 1523 GLfloat transform_values[12 * kPathCount]; |
| 1524 for (GLsizei i = 0; i < kPathCount; ++i) { |
| 1525 for (int j = 0; j < 12; ++j) { |
| 1526 transform_values[i * 12 + j] = 0.1f * j + i; |
| 1527 } |
| 1528 } |
| 1529 enum { |
| 1530 kPathsSHMIdInvalid = 1, |
| 1531 kPathsSHMOffsetInvalid = 1 << 1, |
| 1532 kTransformsHMIdInvalid = 1 << 2, |
| 1533 kTransformsHMOffsetInvalid = 1 << 3, |
| 1534 kFirstTestcase = kPathsSHMIdInvalid, |
| 1535 kLastTestcase = kTransformsHMOffsetInvalid |
| 1536 }; |
| 1537 |
| 1538 for (int testcase = kFirstTestcase; testcase <= kLastTestcase; ++testcase) { |
| 1539 GLfloat* transforms = GetSharedMemoryAs<GLfloat*>(); |
| 1540 uint32 transforms_shm_id = shared_memory_id_; |
| 1541 uint32 transforms_shm_offset = shared_memory_offset_; |
| 1542 memcpy(transforms, transform_values, sizeof(transform_values)); |
| 1543 |
| 1544 GLuint* paths = |
| 1545 GetSharedMemoryAsWithOffset<GLuint*>(sizeof(transform_values)); |
| 1546 uint32 paths_shm_id = shared_memory_id_; |
| 1547 uint32 paths_shm_offset = shared_memory_offset_ + sizeof(transform_values); |
| 1548 |
| 1549 if (testcase & kPathsSHMIdInvalid) { |
| 1550 paths_shm_id = kInvalidSharedMemoryId; |
| 1551 } |
| 1552 if (testcase & kPathsSHMOffsetInvalid) { |
| 1553 paths_shm_offset = kInvalidSharedMemoryOffset; |
| 1554 } |
| 1555 if (testcase & kTransformsHMIdInvalid) { |
| 1556 transforms_shm_id = kInvalidSharedMemoryId; |
| 1557 } |
| 1558 if (testcase & kTransformsHMOffsetInvalid) { |
| 1559 transforms_shm_offset = kInvalidSharedMemoryOffset; |
| 1560 } |
| 1561 SCOPED_TRACE(testing::Message() << "InstancedInvalidSHMValues testcase " |
| 1562 << testcase); |
| 1563 CallAllInstancedCommandsWithInvalidSHM( |
| 1564 kPathCount, kPaths, paths, paths_shm_id, paths_shm_offset, |
| 1565 transforms_shm_id, transforms_shm_offset); |
| 1566 } |
| 1567 } |
| 1568 |
981 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autog
en.h" | 1569 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autog
en.h" |
982 | 1570 |
983 } // namespace gles2 | 1571 } // namespace gles2 |
984 } // namespace gpu | 1572 } // namespace gpu |
985 | 1573 |
OLD | NEW |