OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 6 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
7 #include "gpu/command_buffer/service/gl_mock.h" | 7 #include "gpu/command_buffer/service/gl_mock.h" |
| 8 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
9 | 10 |
10 using ::testing::_; | 11 using ::testing::_; |
11 using ::testing::Return; | 12 using ::testing::Return; |
12 using ::testing::SetArgumentPointee; | 13 using ::testing::SetArgumentPointee; |
| 14 using ::testing::InSequence; |
| 15 using ::testing::Pointee; |
13 | 16 |
14 namespace gpu { | 17 namespace gpu { |
15 namespace gles2 { | 18 namespace gles2 { |
16 | 19 |
17 class GLES2DecoderTest : public testing::Test { | 20 class GLES2DecoderTest : public testing::Test { |
| 21 public: |
| 22 GLES2DecoderTest() |
| 23 : client_buffer_id_(100), |
| 24 client_framebuffer_id_(101), |
| 25 client_program_id_(102), |
| 26 client_renderbuffer_id_(103), |
| 27 client_shader_id_(104), |
| 28 client_texture_id_(105) { |
| 29 memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); |
| 30 } |
| 31 |
18 protected: | 32 protected: |
| 33 static const GLint kNumVertexAttribs = 16; |
| 34 |
| 35 static const GLuint kServiceBufferId = 301; |
| 36 static const GLuint kServiceFramebufferId = 302; |
| 37 static const GLuint kServiceRenderbufferId = 303; |
| 38 static const GLuint kServiceTextureId = 304; |
| 39 static const GLuint kServiceProgramId = 305; |
| 40 static const GLuint kServiceShaderId = 306; |
| 41 |
| 42 static const int32 kSharedMemoryId = 401; |
| 43 static const size_t kSharedBufferSize = 2048; |
| 44 static const uint32 kSharedMemoryOffset = 132; |
| 45 static const int32 kInvalidSharedMemoryId = 402; |
| 46 static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1; |
| 47 |
| 48 static const uint32 kNewClientId = 501; |
| 49 static const uint32 kNewServiceId = 502; |
| 50 static const uint32 kInvalidClientId = 601; |
| 51 |
| 52 // Template to call glGenXXX functions. |
| 53 template <typename T> |
| 54 void GenHelper(GLuint client_id) { |
| 55 int8 buffer[sizeof(T) + sizeof(client_id)]; |
| 56 T& cmd = *reinterpret_cast<T*>(&buffer); |
| 57 cmd.Init(1, &client_id); |
| 58 EXPECT_EQ(parse_error::kParseNoError, |
| 59 ExecuteImmediateCmd(cmd, sizeof(client_id))); |
| 60 } |
| 61 |
| 62 // This template exists solely so we can specialize it for |
| 63 // certain commands. |
| 64 template <typename T, int id> |
| 65 void SpecializedSetup() { |
| 66 } |
| 67 |
| 68 template <typename T> |
| 69 T* GetImmediateAs() { |
| 70 return reinterpret_cast<T*>(immediate_buffer_); |
| 71 } |
| 72 |
| 73 template <typename T, typename Command> |
| 74 T GetImmediateDataAs(Command* cmd) { |
| 75 reinterpret_cast<T>(ImmediateDataAddress(cmd)); |
| 76 } |
| 77 |
19 virtual void SetUp() { | 78 virtual void SetUp() { |
20 gl_ = new ::gles2::MockGLInterface(); | 79 gl_.reset(new ::gles2::MockGLInterface()); |
21 ::gles2::GLInterface::SetGLInterface(gl_); | 80 ::gles2::GLInterface::SetGLInterface(gl_.get()); |
22 | 81 |
23 EXPECT_CALL(*gl_, GetIntegerv(_, _)) | 82 EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _)) |
24 .WillOnce(SetArgumentPointee<1>(16)); | 83 .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs)) |
| 84 .RetiresOnSaturation(); |
25 EXPECT_CALL(*gl_, GetError()) | 85 EXPECT_CALL(*gl_, GetError()) |
26 .WillRepeatedly(Return(GL_NO_ERROR)); | 86 .WillRepeatedly(Return(GL_NO_ERROR)); |
27 | 87 |
28 decoder_ = GLES2Decoder::Create(); | 88 engine_.reset(new MockCommandBufferEngine()); |
| 89 Buffer buffer = engine_->GetSharedMemoryBuffer(kSharedMemoryId); |
| 90 shared_memory_offset_ = kSharedMemoryOffset; |
| 91 shared_memory_address_ = reinterpret_cast<int8*>(buffer.ptr) + |
| 92 shared_memory_offset_; |
| 93 shared_memory_id_ = kSharedMemoryId; |
| 94 |
| 95 decoder_.reset(GLES2Decoder::Create()); |
29 decoder_->Initialize(); | 96 decoder_->Initialize(); |
| 97 decoder_->set_engine(engine_.get()); |
| 98 |
| 99 EXPECT_CALL(*gl_, GenBuffersARB(_, _)) |
| 100 .WillOnce(SetArgumentPointee<1>(kServiceBufferId)) |
| 101 .RetiresOnSaturation(); |
| 102 EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)) |
| 103 .WillOnce(SetArgumentPointee<1>(kServiceFramebufferId)) |
| 104 .RetiresOnSaturation(); |
| 105 EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)) |
| 106 .WillOnce(SetArgumentPointee<1>(kServiceRenderbufferId)) |
| 107 .RetiresOnSaturation(); |
| 108 EXPECT_CALL(*gl_, GenTextures(_, _)) |
| 109 .WillOnce(SetArgumentPointee<1>(kServiceTextureId)) |
| 110 .RetiresOnSaturation(); |
| 111 |
| 112 GenHelper<GenBuffersImmediate>(client_buffer_id_); |
| 113 GenHelper<GenFramebuffersImmediate>(client_framebuffer_id_); |
| 114 GenHelper<GenRenderbuffersImmediate>(client_renderbuffer_id_); |
| 115 GenHelper<GenTexturesImmediate>(client_texture_id_); |
| 116 |
| 117 { |
| 118 EXPECT_CALL(*gl_, CreateProgram()) |
| 119 .Times(1) |
| 120 .WillOnce(Return(kServiceProgramId)) |
| 121 .RetiresOnSaturation(); |
| 122 CreateProgram cmd; |
| 123 cmd.Init(client_program_id_); |
| 124 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 125 } |
| 126 |
| 127 { |
| 128 EXPECT_CALL(*gl_, CreateShader(_)) |
| 129 .Times(1) |
| 130 .WillOnce(Return(kServiceShaderId)) |
| 131 .RetiresOnSaturation(); |
| 132 CreateShader cmd; |
| 133 cmd.Init(GL_VERTEX_SHADER, client_shader_id_); |
| 134 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 135 } |
30 } | 136 } |
31 | 137 |
32 virtual void TearDown() { | 138 virtual void TearDown() { |
33 decoder_->Destroy(); | 139 decoder_->Destroy(); |
34 delete decoder_; | |
35 ::gles2::GLInterface::SetGLInterface(NULL); | 140 ::gles2::GLInterface::SetGLInterface(NULL); |
36 delete gl_; | |
37 } | 141 } |
38 | 142 |
39 template <typename T> | 143 template <typename T> |
40 parse_error::ParseError ExecuteCmd(const T& cmd) { | 144 parse_error::ParseError ExecuteCmd(const T& cmd) { |
41 COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); | 145 COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); |
42 return decoder_->DoCommand(cmd.kCmdId, | 146 return decoder_->DoCommand(cmd.kCmdId, |
43 ComputeNumEntries(sizeof(cmd)) - 1, | 147 ComputeNumEntries(sizeof(cmd)) - 1, |
44 &cmd); | 148 &cmd); |
45 } | 149 } |
46 | 150 |
47 template <typename T> | 151 template <typename T> |
48 parse_error::ParseError ExecuteImmediateCmd(const T& cmd, size_t data_size) { | 152 parse_error::ParseError ExecuteImmediateCmd(const T& cmd, size_t data_size) { |
49 COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); | 153 COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); |
50 return decoder_.DoCommand(cmd.kCmdId, | 154 return decoder_->DoCommand(cmd.kCmdId, |
51 ComputeNumEntries(sizeof(cmd) + data_size) - 1, | 155 ComputeNumEntries(sizeof(cmd) + data_size) - 1, |
52 &cmd); | 156 &cmd); |
53 } | 157 } |
54 | 158 |
55 ::gles2::MockGLInterface* gl_; | 159 template <typename T> |
56 GLES2Decoder* decoder_; | 160 T GetSharedMemoryAs() { |
| 161 return reinterpret_cast<T>(shared_memory_address_); |
| 162 } |
| 163 |
| 164 uint32 GetServiceId(uint32 client_id) { |
| 165 return decoder_->GetServiceIdForTesting(client_id); |
| 166 } |
| 167 |
| 168 scoped_ptr<::gles2::MockGLInterface> gl_; |
| 169 scoped_ptr<GLES2Decoder> decoder_; |
| 170 |
| 171 GLuint client_buffer_id_; |
| 172 GLuint client_framebuffer_id_; |
| 173 GLuint client_program_id_; |
| 174 GLuint client_renderbuffer_id_; |
| 175 GLuint client_shader_id_; |
| 176 GLuint client_texture_id_; |
| 177 |
| 178 uint32 shared_memory_id_; |
| 179 uint32 shared_memory_offset_; |
| 180 void* shared_memory_address_; |
| 181 |
| 182 int8 immediate_buffer_[256]; |
| 183 |
| 184 private: |
| 185 class MockCommandBufferEngine : public CommandBufferEngine { |
| 186 public: |
| 187 MockCommandBufferEngine() { |
| 188 data_.reset(new int8[kSharedBufferSize]); |
| 189 valid_buffer_.ptr = data_.get(); |
| 190 valid_buffer_.size = kSharedBufferSize; |
| 191 } |
| 192 |
| 193 virtual ~MockCommandBufferEngine() { |
| 194 } |
| 195 |
| 196 Buffer GetSharedMemoryBuffer(int32 shm_id) { |
| 197 return shm_id == kSharedMemoryId ? valid_buffer_ : invalid_buffer_; |
| 198 } |
| 199 |
| 200 void set_token(int32 token) { |
| 201 DCHECK(false); |
| 202 } |
| 203 |
| 204 private: |
| 205 scoped_array<int8> data_; |
| 206 Buffer valid_buffer_; |
| 207 Buffer invalid_buffer_; |
| 208 }; |
| 209 |
| 210 scoped_ptr<MockCommandBufferEngine> engine_; |
57 }; | 211 }; |
58 | 212 |
59 TEST_F(GLES2DecoderTest, Enable) { | 213 template <> |
60 EXPECT_CALL(*gl_, Enable(GL_BLEND)); | 214 void GLES2DecoderTest::SpecializedSetup<LinkProgram, 0>() { |
| 215 InSequence dummy; |
| 216 EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) |
| 217 .WillOnce(SetArgumentPointee<2>(0)); |
| 218 EXPECT_CALL( |
| 219 *gl_, |
| 220 GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) |
| 221 .WillOnce(SetArgumentPointee<2>(0)); |
| 222 }; |
61 | 223 |
62 Enable cmd; | 224 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h" |
63 cmd.Init(GL_BLEND); | |
64 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); | |
65 } | |
66 | 225 |
67 } // namespace gles2 | 226 } // namespace gles2 |
68 } // namespace gpu | 227 } // namespace gpu |
69 | 228 |
70 | 229 |
OLD | NEW |