gles2_cmd_decoder_unittest_base.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_BASE_H_ 6#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_BASE_H_ 7 8#include "gpu/command_buffer/common/gl_mock.h" 9#include "gpu/command_buffer/common/gles2_cmd_format.h" 10#include "gpu/command_buffer/common/gles2_cmd_utils.h" 11#include "gpu/command_buffer/service/buffer_manager.h" 12#include "gpu/command_buffer/service/cmd_buffer_engine.h" 13#include "gpu/command_buffer/service/context_group.h" 14#include "gpu/command_buffer/service/framebuffer_manager.h" 15#include "gpu/command_buffer/service/gles2_cmd_decoder.h" 16#include "gpu/command_buffer/service/program_manager.h" 17#include "gpu/command_buffer/service/query_manager.h" 18#include "gpu/command_buffer/service/renderbuffer_manager.h" 19#include "gpu/command_buffer/service/shader_manager.h" 20#include "gpu/command_buffer/service/test_helper.h" 21#include "gpu/command_buffer/service/texture_manager.h" 22#include "gpu/command_buffer/service/vertex_array_manager.h" 23#include "testing/gtest/include/gtest/gtest.h" 24#include "ui/gl/gl_context_stub.h" 25#include "ui/gl/gl_surface_stub.h" 26 27namespace gpu { 28namespace gles2 { 29 30class GLES2DecoderTestBase : public testing::Test { 31 public: 32 GLES2DecoderTestBase(); 33 virtual ~GLES2DecoderTestBase(); 34 35 // Template to call glGenXXX functions. 36 template <typename T> 37 void GenHelper(GLuint client_id) { 38 int8 buffer[sizeof(T) + sizeof(client_id)]; 39 T& cmd = *reinterpret_cast<T*>(&buffer); 40 cmd.Init(1, &client_id); 41 EXPECT_EQ(error::kNoError, 42 ExecuteImmediateCmd(cmd, sizeof(client_id))); 43 } 44 45 // This template exists solely so we can specialize it for 46 // certain commands. 47 template <typename T, int id> 48 void SpecializedSetup(bool valid) { 49 } 50 51 template <typename T> 52 T* GetImmediateAs() { 53 return reinterpret_cast<T*>(immediate_buffer_); 54 } 55 56 template <typename T, typename Command> 57 T GetImmediateDataAs(Command* cmd) { 58 return reinterpret_cast<T>(ImmediateDataAddress(cmd)); 59 } 60 61 void ClearSharedMemory() { 62 engine_->ClearSharedMemory(); 63 } 64 65 virtual void SetUp() OVERRIDE; 66 virtual void TearDown() OVERRIDE; 67 68 template <typename T> 69 error::Error ExecuteCmd(const T& cmd) { 70 COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); 71 return decoder_->DoCommand(cmd.kCmdId, 72 ComputeNumEntries(sizeof(cmd)) - 1, 73 &cmd); 74 } 75 76 template <typename T> 77 error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) { 78 COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); 79 return decoder_->DoCommand(cmd.kCmdId, 80 ComputeNumEntries(sizeof(cmd) + data_size) - 1, 81 &cmd); 82 } 83 84 template <typename T> 85 T GetSharedMemoryAs() { 86 return reinterpret_cast<T>(shared_memory_address_); 87 } 88 89 template <typename T> 90 T GetSharedMemoryAsWithOffset(uint32 offset) { 91 void* ptr = reinterpret_cast<int8*>(shared_memory_address_) + offset; 92 return reinterpret_cast<T>(ptr); 93 } 94 95 IdAllocatorInterface* GetIdAllocator(GLuint namespace_id) { 96 return group_->GetIdAllocator(namespace_id); 97 } 98 99 BufferManager::BufferInfo* GetBufferInfo(GLuint service_id) { 100 return group_->buffer_manager()->GetBufferInfo(service_id); 101 } 102 103 FramebufferManager::FramebufferInfo* GetFramebufferInfo(GLuint service_id) { 104 return group_->framebuffer_manager()->GetFramebufferInfo(service_id); 105 } 106 107 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfo( 108 GLuint service_id) { 109 return group_->renderbuffer_manager()->GetRenderbufferInfo(service_id); 110 } 111 112 TextureManager::TextureInfo* GetTextureInfo(GLuint client_id) { 113 return group_->texture_manager()->GetTextureInfo(client_id); 114 } 115 116 ShaderManager::ShaderInfo* GetShaderInfo(GLuint client_id) { 117 return group_->shader_manager()->GetShaderInfo(client_id); 118 } 119 120 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) { 121 return group_->program_manager()->GetProgramInfo(client_id); 122 } 123 124 QueryManager::Query* GetQueryInfo(GLuint client_id) { 125 return decoder_->GetQueryManager()->GetQuery(client_id); 126 } 127 128 // This name doesn't match the underlying function, but doing it this way 129 // prevents the need to special-case the unit test generation 130 VertexAttribManager* GetVertexArrayInfo(GLuint client_id) { 131 return decoder_->GetVertexArrayManager()->GetVertexAttribManager(client_id); 132 } 133 134 ProgramManager* program_manager() { 135 return group_->program_manager(); 136 } 137 138 void DoCreateProgram(GLuint client_id, GLuint service_id); 139 void DoCreateShader(GLenum shader_type, GLuint client_id, GLuint service_id); 140 141 void SetBucketAsCString(uint32 bucket_id, const char* str); 142 143 void InitDecoder( 144 const char* extensions, 145 bool has_alpha, 146 bool has_depth, 147 bool has_stencil, 148 bool request_alpha, 149 bool request_depth, 150 bool request_stencil, 151 bool bind_generates_resource); 152 153 const ContextGroup& group() const { 154 return *group_.get(); 155 } 156 157 ::testing::StrictMock< ::gfx::MockGLInterface>* GetGLMock() const { 158 return gl_.get(); 159 } 160 161 GLES2Decoder* GetDecoder() const { 162 return decoder_.get(); 163 } 164 165 typedef TestHelper::AttribInfo AttribInfo; 166 typedef TestHelper::UniformInfo UniformInfo; 167 168 void SetupShader( 169 AttribInfo* attribs, size_t num_attribs, 170 UniformInfo* uniforms, size_t num_uniforms, 171 GLuint client_id, GLuint service_id, 172 GLuint vertex_shader_client_id, GLuint vertex_shader_service_id, 173 GLuint fragment_shader_client_id, GLuint fragment_shader_service_id); 174 175 void SetupExpectationsForClearingUniforms( 176 UniformInfo* uniforms, size_t num_uniforms) { 177 TestHelper::SetupExpectationsForClearingUniforms( 178 gl_.get(), uniforms, num_uniforms); 179 } 180 181 void SetupInitCapabilitiesExpectations(); 182 void SetupInitStateExpectations(); 183 void ExpectEnableDisable(GLenum cap, bool enable); 184 185 // Setups up a shader for testing glUniform. 186 void SetupShaderForUniform(); 187 void SetupDefaultProgram(); 188 void SetupCubemapProgram(); 189 void SetupTexture(); 190 191 // Note that the error is returned as GLint instead of GLenum. 192 // This is because there is a mismatch in the types of GLenum and 193 // the error values GL_NO_ERROR, GL_INVALID_ENUM, etc. GLenum is 194 // typedef'd as unsigned int while the error values are defined as 195 // integers. This is problematic for template functions such as 196 // EXPECT_EQ that expect both types to be the same. 197 GLint GetGLError(); 198 199 void DoBindBuffer(GLenum target, GLuint client_id, GLuint service_id); 200 void DoBindFramebuffer(GLenum target, GLuint client_id, GLuint service_id); 201 void DoBindRenderbuffer(GLenum target, GLuint client_id, GLuint service_id); 202 void DoBindTexture(GLenum target, GLuint client_id, GLuint service_id); 203 void DoBindVertexArrayOES(GLuint client_id, GLuint service_id); 204 205 bool DoIsBuffer(GLuint client_id); 206 bool DoIsFramebuffer(GLuint client_id); 207 bool DoIsProgram(GLuint client_id); 208 bool DoIsRenderbuffer(GLuint client_id); 209 bool DoIsShader(GLuint client_id); 210 bool DoIsTexture(GLuint client_id); 211 212 void DoDeleteBuffer(GLuint client_id, GLuint service_id); 213 void DoDeleteFramebuffer( 214 GLuint client_id, GLuint service_id, 215 bool reset_draw, GLenum draw_target, GLuint draw_id, 216 bool reset_read, GLenum read_target, GLuint read_id); 217 void DoDeleteProgram(GLuint client_id, GLuint service_id); 218 void DoDeleteRenderbuffer(GLuint client_id, GLuint service_id); 219 void DoDeleteShader(GLuint client_id, GLuint service_id); 220 void DoDeleteTexture(GLuint client_id, GLuint service_id); 221 222 void DoCompressedTexImage2D( 223 GLenum target, GLint level, GLenum format, 224 GLsizei width, GLsizei height, GLint border, 225 GLsizei size, uint32 bucket_id); 226 void DoTexImage2D( 227 GLenum target, GLint level, GLenum internal_format, 228 GLsizei width, GLsizei height, GLint border, 229 GLenum format, GLenum type, 230 uint32 shared_memory_id, uint32 shared_memory_offset); 231 void DoTexImage2DSameSize( 232 GLenum target, GLint level, GLenum internal_format, 233 GLsizei width, GLsizei height, GLint border, 234 GLenum format, GLenum type, 235 uint32 shared_memory_id, uint32 shared_memory_offset); 236 void DoRenderbufferStorage( 237 GLenum target, GLenum internal_format, GLenum actual_format, 238 GLsizei width, GLsizei height, GLenum error); 239 void DoFramebufferRenderbuffer( 240 GLenum target, 241 GLenum attachment, 242 GLenum renderbuffer_target, 243 GLuint renderbuffer_client_id, 244 GLuint renderbuffer_service_id, 245 GLenum error); 246 void DoFramebufferTexture2D( 247 GLenum target, GLenum attachment, GLenum tex_target, 248 GLuint texture_client_id, GLuint texture_service_id, 249 GLint level, GLenum error); 250 void DoVertexAttribPointer( 251 GLuint index, GLint size, GLenum type, GLsizei stride, GLuint offset); 252 void DoVertexAttribDivisorANGLE(GLuint index, GLuint divisor); 253 254 void DoEnableVertexAttribArray(GLint index); 255 256 void DoBufferData(GLenum target, GLsizei size); 257 258 void DoBufferSubData( 259 GLenum target, GLint offset, GLsizei size, const void* data); 260 261 void SetupVertexBuffer(); 262 void SetupAllNeededVertexBuffers(); 263 264 void SetupIndexBuffer(); 265 266 void DeleteVertexBuffer(); 267 268 void DeleteIndexBuffer(); 269 270 void SetupClearTextureExpections( 271 GLuint service_id, 272 GLuint old_service_id, 273 GLenum bind_target, 274 GLenum target, 275 GLint level, 276 GLenum format, 277 GLenum type, 278 GLsizei width, 279 GLsizei height); 280 281 void SetupExpectationsForRestoreClearState( 282 GLclampf restore_red, 283 GLclampf restore_green, 284 GLclampf restore_blue, 285 GLclampf restore_alpha, 286 GLuint restore_stencil, 287 GLclampf restore_depth, 288 bool restore_scissor_test); 289 290 void SetupExpectationsForFramebufferClearing( 291 GLenum target, 292 GLuint clear_bits, 293 GLclampf restore_red, 294 GLclampf restore_green, 295 GLclampf restore_blue, 296 GLclampf restore_alpha, 297 GLuint restore_stencil, 298 GLclampf restore_depth, 299 bool restore_scissor_test); 300 301 void SetupExpectationsForFramebufferClearingMulti( 302 GLuint read_framebuffer_service_id, 303 GLuint draw_framebuffer_service_id, 304 GLenum target, 305 GLuint clear_bits, 306 GLclampf restore_red, 307 GLclampf restore_green, 308 GLclampf restore_blue, 309 GLclampf restore_alpha, 310 GLuint restore_stencil, 311 GLclampf restore_depth, 312 bool restore_scissor_test); 313 314 void SetupExpectationsForApplyingDirtyState( 315 bool framebuffer_is_rgb, 316 bool framebuffer_has_depth, 317 bool framebuffer_has_stencil, 318 GLuint color_bits, // NOTE! bits are 0x1000, 0x0100, 0x0010, and 0x0001 319 bool depth_mask, 320 bool depth_enabled, 321 GLuint front_stencil_mask, 322 GLuint back_stencil_mask, 323 bool stencil_enabled, 324 bool cull_face_enabled, 325 bool scissor_test_enabled, 326 bool blend_enabled); 327 328 void SetupExpectationsForApplyingDefaultDirtyState(); 329 330 void AddExpectationsForSimulatedAttrib0WithError( 331 GLsizei num_vertices, GLuint buffer_id, GLenum error); 332 333 void AddExpectationsForSimulatedAttrib0( 334 GLsizei num_vertices, GLuint buffer_id); 335 336 void AddExpectationsForGenVertexArraysOES(); 337 void AddExpectationsForDeleteVertexArraysOES(); 338 void AddExpectationsForBindVertexArrayOES(); 339 void AddExpectationsForRestoreAttribState(GLuint attrib); 340 341 GLvoid* BufferOffset(unsigned i) { 342 return static_cast<int8 *>(NULL)+(i); 343 } 344 345 template <typename Command, typename Result> 346 bool IsObjectHelper(GLuint client_id) { 347 Result* result = static_cast<Result*>(shared_memory_address_); 348 Command cmd; 349 cmd.Init(client_id, kSharedMemoryId, kSharedMemoryOffset); 350 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 351 bool isObject = static_cast<bool>(*result); 352 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 353 return isObject; 354 } 355 356 protected: 357 static const int kBackBufferWidth = 128; 358 static const int kBackBufferHeight = 64; 359 360 static const GLint kMaxTextureSize = 2048; 361 static const GLint kMaxCubeMapTextureSize = 256; 362 static const GLint kNumVertexAttribs = 16; 363 static const GLint kNumTextureUnits = 8; 364 static const GLint kMaxTextureImageUnits = 8; 365 static const GLint kMaxVertexTextureImageUnits = 2; 366 static const GLint kMaxFragmentUniformVectors = 16; 367 static const GLint kMaxVaryingVectors = 8; 368 static const GLint kMaxVertexUniformVectors = 128; 369 static const GLint kMaxViewportWidth = 8192; 370 static const GLint kMaxViewportHeight = 8192; 371 372 static const GLint kViewportX = 0; 373 static const GLint kViewportY = 0; 374 static const GLint kViewportWidth = kBackBufferWidth; 375 static const GLint kViewportHeight = kBackBufferHeight; 376 377 static const GLuint kServiceAttrib0BufferId = 801; 378 static const GLuint kServiceFixedAttribBufferId = 802; 379 380 static const GLuint kServiceBufferId = 301; 381 static const GLuint kServiceFramebufferId = 302; 382 static const GLuint kServiceRenderbufferId = 303; 383 static const GLuint kServiceTextureId = 304; 384 static const GLuint kServiceProgramId = 305; 385 static const GLuint kServiceShaderId = 306; 386 static const GLuint kServiceElementBufferId = 308; 387 static const GLuint kServiceQueryId = 309; 388 static const GLuint kServiceVertexArrayId = 310; 389 390 static const int32 kSharedMemoryId = 401; 391 static const size_t kSharedBufferSize = 2048; 392 static const uint32 kSharedMemoryOffset = 132; 393 static const int32 kInvalidSharedMemoryId = 402; 394 static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1; 395 static const uint32 kInitialResult = 0xBDBDBDBDu; 396 static const uint8 kInitialMemoryValue = 0xBDu; 397 398 static const uint32 kNewClientId = 501; 399 static const uint32 kNewServiceId = 502; 400 static const uint32 kInvalidClientId = 601; 401 402 static const GLuint kServiceVertexShaderId = 321; 403 static const GLuint kServiceFragmentShaderId = 322; 404 405 static const GLuint kServiceCopyTextureChromiumShaderId = 701; 406 static const GLuint kServiceCopyTextureChromiumProgramId = 721; 407 408 static const GLuint kServiceCopyTextureChromiumTextureBufferId = 751; 409 static const GLuint kServiceCopyTextureChromiumVertexBufferId = 752; 410 static const GLuint kServiceCopyTextureChromiumFBOId = 753; 411 static const GLuint kServiceCopyTextureChromiumPositionAttrib = 761; 412 static const GLuint kServiceCopyTextureChromiumTexAttrib = 762; 413 static const GLuint kServiceCopyTextureChromiumSamplerLocation = 763; 414 415 static const GLsizei kNumVertices = 100; 416 static const GLsizei kNumIndices = 10; 417 static const int kValidIndexRangeStart = 1; 418 static const int kValidIndexRangeCount = 7; 419 static const int kInvalidIndexRangeStart = 0; 420 static const int kInvalidIndexRangeCount = 7; 421 static const int kOutOfRangeIndexRangeEnd = 10; 422 static const GLuint kMaxValidIndex = 7; 423 424 static const GLint kMaxAttribLength = 10; 425 static const char* kAttrib1Name; 426 static const char* kAttrib2Name; 427 static const char* kAttrib3Name; 428 static const GLint kAttrib1Size = 1; 429 static const GLint kAttrib2Size = 1; 430 static const GLint kAttrib3Size = 1; 431 static const GLint kAttrib1Location = 0; 432 static const GLint kAttrib2Location = 1; 433 static const GLint kAttrib3Location = 2; 434 static const GLenum kAttrib1Type = GL_FLOAT_VEC4; 435 static const GLenum kAttrib2Type = GL_FLOAT_VEC2; 436 static const GLenum kAttrib3Type = GL_FLOAT_VEC3; 437 static const GLint kInvalidAttribLocation = 30; 438 static const GLint kBadAttribIndex = kNumVertexAttribs; 439 440 static const GLint kMaxUniformLength = 12; 441 static const char* kUniform1Name; 442 static const char* kUniform2Name; 443 static const char* kUniform3Name; 444 static const GLint kUniform1Size = 1; 445 static const GLint kUniform2Size = 3; 446 static const GLint kUniform3Size = 2; 447 static const GLint kUniform1RealLocation = 3; 448 static const GLint kUniform2RealLocation = 10; 449 static const GLint kUniform2ElementRealLocation = 12; 450 static const GLint kUniform3RealLocation = 20; 451 static const GLint kUniform1FakeLocation = 0; // These are 452 static const GLint kUniform2FakeLocation = 1; // hardcoded 453 static const GLint kUniform2ElementFakeLocation = 0x10001; // to match 454 static const GLint kUniform3FakeLocation = 2; // ProgramManager. 455 static const GLint kUniform1DesiredLocation = -1; 456 static const GLint kUniform2DesiredLocation = -1; 457 static const GLint kUniform3DesiredLocation = -1; 458 static const GLenum kUniform1Type = GL_SAMPLER_2D; 459 static const GLenum kUniform2Type = GL_INT_VEC2; 460 static const GLenum kUniform3Type = GL_FLOAT_VEC3; 461 static const GLenum kUniformCubemapType = GL_SAMPLER_CUBE; 462 static const GLint kInvalidUniformLocation = 30; 463 static const GLint kBadUniformIndex = 1000; 464 465 // Use StrictMock to make 100% sure we know how GL will be called. 466 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 467 scoped_refptr<gfx::GLSurfaceStub> surface_; 468 scoped_refptr<gfx::GLContextStub> context_; 469 scoped_ptr<GLES2Decoder> decoder_; 470 471 GLuint client_buffer_id_; 472 GLuint client_framebuffer_id_; 473 GLuint client_program_id_; 474 GLuint client_renderbuffer_id_; 475 GLuint client_shader_id_; 476 GLuint client_texture_id_; 477 GLuint client_element_buffer_id_; 478 GLuint client_vertex_shader_id_; 479 GLuint client_fragment_shader_id_; 480 GLuint client_query_id_; 481 GLuint client_vertexarray_id_; 482 483 uint32 shared_memory_id_; 484 uint32 shared_memory_offset_; 485 void* shared_memory_address_; 486 void* shared_memory_base_; 487 488 int8 immediate_buffer_[256]; 489 490 private: 491 class MockCommandBufferEngine : public CommandBufferEngine { 492 public: 493 MockCommandBufferEngine(); 494 495 virtual ~MockCommandBufferEngine(); 496 497 virtual Buffer GetSharedMemoryBuffer(int32 shm_id) OVERRIDE; 498 499 void ClearSharedMemory() { 500 memset(data_.get(), kInitialMemoryValue, kSharedBufferSize); 501 } 502 503 virtual void set_token(int32 token) OVERRIDE; 504 505 virtual bool SetGetBuffer(int32 /* transfer_buffer_id */) OVERRIDE; 506 507 // Overridden from CommandBufferEngine. 508 virtual bool SetGetOffset(int32 offset) OVERRIDE; 509 510 // Overridden from CommandBufferEngine. 511 virtual int32 GetGetOffset() OVERRIDE; 512 513 private: 514 scoped_array<int8> data_; 515 Buffer valid_buffer_; 516 Buffer invalid_buffer_; 517 }; 518 519 void AddExpectationsForVertexAttribManager(); 520 521 scoped_ptr< ::testing::StrictMock<MockCommandBufferEngine> > engine_; 522 ContextGroup::Ref group_; 523}; 524 525class GLES2DecoderWithShaderTestBase : public GLES2DecoderTestBase { 526 public: 527 GLES2DecoderWithShaderTestBase() 528 : GLES2DecoderTestBase() { 529 } 530 531 protected: 532 virtual void SetUp() OVERRIDE; 533 virtual void TearDown() OVERRIDE; 534 535}; 536 537} // namespace gles2 538} // namespace gpu 539 540#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_BASE_H_ 541