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