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