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