Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / service / gles2_cmd_decoder_unittest_async_pixel.cc
blobd32870d9a1a1599a0b8132940755438a9208a9dd
1 // Copyright 2014 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.
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
7 #include "base/command_line.h"
8 #include "base/strings/string_number_conversions.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/common/id_allocator.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
14 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
15 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
16 #include "gpu/command_buffer/service/context_group.h"
17 #include "gpu/command_buffer/service/context_state.h"
18 #include "gpu/command_buffer/service/gl_surface_mock.h"
19 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
21 #include "gpu/command_buffer/service/gpu_switches.h"
22 #include "gpu/command_buffer/service/image_manager.h"
23 #include "gpu/command_buffer/service/mailbox_manager.h"
24 #include "gpu/command_buffer/service/mocks.h"
25 #include "gpu/command_buffer/service/program_manager.h"
26 #include "gpu/command_buffer/service/test_helper.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/gl/gl_implementation.h"
29 #include "ui/gl/gl_mock.h"
30 #include "ui/gl/gl_surface_stub.h"
32 #if !defined(GL_DEPTH24_STENCIL8)
33 #define GL_DEPTH24_STENCIL8 0x88F0
34 #endif
36 using ::gfx::MockGLInterface;
37 using ::testing::_;
38 using ::testing::DoAll;
39 using ::testing::InSequence;
40 using ::testing::Invoke;
41 using ::testing::MatcherCast;
42 using ::testing::Mock;
43 using ::testing::Pointee;
44 using ::testing::Return;
45 using ::testing::SaveArg;
46 using ::testing::SetArrayArgument;
47 using ::testing::SetArgumentPointee;
48 using ::testing::SetArgPointee;
49 using ::testing::StrEq;
50 using ::testing::StrictMock;
52 namespace gpu {
53 namespace gles2 {
55 using namespace cmds;
57 TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransfers) {
58 InitState init;
59 init.extensions = "GL_CHROMIUM_async_pixel_transfers";
60 init.gl_version = "3.0";
61 init.bind_generates_resource = true;
62 InitDecoder(init);
64 // Set up the texture.
65 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
66 TextureRef* texture_ref = GetTexture(client_texture_id_);
67 Texture* texture = texture_ref->texture();
69 // Set a mock Async delegate
70 StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
71 new StrictMock<gpu::MockAsyncPixelTransferManager>;
72 manager->Initialize(group().texture_manager());
73 decoder_->SetAsyncPixelTransferManagerForTest(manager);
74 StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
76 // Tex(Sub)Image2D upload commands.
77 AsyncTexImage2DCHROMIUM teximage_cmd;
78 teximage_cmd.Init(GL_TEXTURE_2D,
80 GL_RGBA,
83 GL_RGBA,
84 GL_UNSIGNED_BYTE,
85 kSharedMemoryId,
86 kSharedMemoryOffset,
89 0);
90 AsyncTexSubImage2DCHROMIUM texsubimage_cmd;
91 texsubimage_cmd.Init(GL_TEXTURE_2D,
97 GL_RGBA,
98 GL_UNSIGNED_BYTE,
99 kSharedMemoryId,
100 kSharedMemoryOffset,
104 WaitAsyncTexImage2DCHROMIUM wait_cmd;
105 wait_cmd.Init(GL_TEXTURE_2D);
106 WaitAllAsyncTexImage2DCHROMIUM wait_all_cmd;
107 wait_all_cmd.Init();
109 // No transfer state exists initially.
110 EXPECT_FALSE(
111 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
112 texture_ref));
114 base::Closure bind_callback;
116 // AsyncTexImage2D
118 // Create transfer state since it doesn't exist.
119 EXPECT_EQ(texture_ref->num_observers(), 0);
120 EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
121 .WillOnce(Return(
122 delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
123 .RetiresOnSaturation();
124 EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
125 .WillOnce(SaveArg<2>(&bind_callback))
126 .RetiresOnSaturation();
127 // Command succeeds.
128 EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
129 EXPECT_EQ(GL_NO_ERROR, GetGLError());
130 EXPECT_EQ(
131 delegate,
132 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
133 texture_ref));
134 EXPECT_TRUE(texture->IsImmutable());
135 // The texture is safe but the level has not been defined yet.
136 EXPECT_TRUE(texture->SafeToRenderFrom());
137 GLsizei width, height;
138 EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
139 EXPECT_EQ(texture_ref->num_observers(), 1);
142 // Async redefinitions are not allowed!
143 // Command fails.
144 EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
145 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
146 EXPECT_EQ(
147 delegate,
148 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
149 texture_ref));
150 EXPECT_TRUE(texture->IsImmutable());
151 EXPECT_TRUE(texture->SafeToRenderFrom());
154 // Binding/defining of the async transfer
156 // TODO(epenner): We should check that the manager gets the
157 // BindCompletedAsyncTransfers() call, which is required to
158 // guarantee the delegate calls the bind callback.
160 // Simulate the bind callback from the delegate.
161 bind_callback.Run();
163 // After the bind callback is run, the texture is safe,
164 // and has the right size etc.
165 EXPECT_TRUE(texture->SafeToRenderFrom());
166 GLsizei width, height;
167 EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
168 EXPECT_EQ(width, 8);
169 EXPECT_EQ(height, 8);
172 // AsyncTexSubImage2D
173 EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
174 decoder_->GetAsyncPixelTransferManager()->ClearPixelTransferDelegateForTest(
175 texture_ref);
176 EXPECT_EQ(texture_ref->num_observers(), 0);
177 texture->SetImmutable(false);
179 // Create transfer state since it doesn't exist.
180 EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
181 .WillOnce(Return(
182 delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
183 .RetiresOnSaturation();
184 EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _)).RetiresOnSaturation();
185 // Command succeeds.
186 EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
187 EXPECT_EQ(GL_NO_ERROR, GetGLError());
188 EXPECT_EQ(
189 delegate,
190 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
191 texture_ref));
192 EXPECT_TRUE(texture->IsImmutable());
193 EXPECT_TRUE(texture->SafeToRenderFrom());
196 // No transfer is in progress.
197 EXPECT_CALL(*delegate, TransferIsInProgress())
198 .WillOnce(Return(false)) // texSubImage validation
199 .WillOnce(Return(false)) // async validation
200 .RetiresOnSaturation();
201 EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _)).RetiresOnSaturation();
202 // Command succeeds.
203 EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
204 EXPECT_EQ(GL_NO_ERROR, GetGLError());
205 EXPECT_EQ(
206 delegate,
207 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
208 texture_ref));
209 EXPECT_TRUE(texture->IsImmutable());
210 EXPECT_TRUE(texture->SafeToRenderFrom());
213 // A transfer is still in progress!
214 EXPECT_CALL(*delegate, TransferIsInProgress())
215 .WillOnce(Return(true))
216 .RetiresOnSaturation();
217 // No async call, command fails.
218 EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
219 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
220 EXPECT_EQ(
221 delegate,
222 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
223 texture_ref));
224 EXPECT_TRUE(texture->IsImmutable());
225 EXPECT_TRUE(texture->SafeToRenderFrom());
228 // Delete delegate on DeleteTexture.
230 EXPECT_EQ(texture_ref->num_observers(), 1);
231 EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
232 DoDeleteTexture(client_texture_id_, kServiceTextureId);
233 EXPECT_FALSE(
234 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
235 texture_ref));
236 texture = NULL;
237 texture_ref = NULL;
238 delegate = NULL;
241 // WaitAsyncTexImage2D
243 // Get a fresh texture since the existing texture cannot be respecified
244 // asynchronously and AsyncTexSubImage2D does not involve binding.
245 EXPECT_CALL(*gl_, GenTextures(1, _))
246 .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
247 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
248 texture_ref = GetTexture(client_texture_id_);
249 texture = texture_ref->texture();
250 texture->SetImmutable(false);
251 // Create transfer state since it doesn't exist.
252 EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
253 .WillOnce(Return(
254 delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
255 .RetiresOnSaturation();
256 EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
257 // Start async transfer.
258 EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
259 EXPECT_EQ(GL_NO_ERROR, GetGLError());
260 EXPECT_EQ(
261 delegate,
262 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
263 texture_ref));
265 EXPECT_TRUE(texture->IsImmutable());
266 // Wait for completion.
267 EXPECT_CALL(*delegate, WaitForTransferCompletion());
268 EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
269 EXPECT_EQ(error::kNoError, ExecuteCmd(wait_cmd));
270 EXPECT_EQ(GL_NO_ERROR, GetGLError());
273 // WaitAllAsyncTexImage2D
274 EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
275 DoDeleteTexture(client_texture_id_, kServiceTextureId);
276 EXPECT_FALSE(
277 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
278 texture_ref));
279 texture = NULL;
280 texture_ref = NULL;
281 delegate = NULL;
283 // Get a fresh texture since the existing texture cannot be respecified
284 // asynchronously and AsyncTexSubImage2D does not involve binding.
285 EXPECT_CALL(*gl_, GenTextures(1, _))
286 .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
287 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
288 texture_ref = GetTexture(client_texture_id_);
289 texture = texture_ref->texture();
290 texture->SetImmutable(false);
291 // Create transfer state since it doesn't exist.
292 EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
293 .WillOnce(Return(
294 delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
295 .RetiresOnSaturation();
296 EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
297 // Start async transfer.
298 EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
299 EXPECT_EQ(GL_NO_ERROR, GetGLError());
300 EXPECT_EQ(
301 delegate,
302 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
303 texture_ref));
305 EXPECT_TRUE(texture->IsImmutable());
306 // Wait for completion of all uploads.
307 EXPECT_CALL(*manager, WaitAllAsyncTexImage2D()).RetiresOnSaturation();
308 EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
309 EXPECT_EQ(error::kNoError, ExecuteCmd(wait_all_cmd));
310 EXPECT_EQ(GL_NO_ERROR, GetGLError());
313 // Remove PixelTransferManager before the decoder destroys.
314 EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
315 decoder_->ResetAsyncPixelTransferManagerForTest();
316 manager = NULL;
319 TEST_P(GLES2DecoderManualInitTest, AsyncPixelTransferManager) {
320 InitState init;
321 init.extensions = "GL_CHROMIUM_async_pixel_transfers";
322 init.gl_version = "3.0";
323 init.bind_generates_resource = true;
324 InitDecoder(init);
326 // Set up the texture.
327 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
328 TextureRef* texture_ref = GetTexture(client_texture_id_);
330 // Set a mock Async delegate.
331 StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
332 new StrictMock<gpu::MockAsyncPixelTransferManager>;
333 manager->Initialize(group().texture_manager());
334 decoder_->SetAsyncPixelTransferManagerForTest(manager);
335 StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
337 AsyncTexImage2DCHROMIUM teximage_cmd;
338 teximage_cmd.Init(GL_TEXTURE_2D,
340 GL_RGBA,
343 GL_RGBA,
344 GL_UNSIGNED_BYTE,
345 kSharedMemoryId,
346 kSharedMemoryOffset,
351 // No transfer delegate exists initially.
352 EXPECT_FALSE(
353 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
354 texture_ref));
356 // Create delegate on AsyncTexImage2D.
358 EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
359 .WillOnce(Return(
360 delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
361 .RetiresOnSaturation();
362 EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
364 // Command succeeds.
365 EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
366 EXPECT_EQ(GL_NO_ERROR, GetGLError());
369 // Delegate is cached.
370 EXPECT_EQ(delegate,
371 decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
372 texture_ref));
374 // Delete delegate on manager teardown.
376 EXPECT_EQ(texture_ref->num_observers(), 1);
377 EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
378 decoder_->ResetAsyncPixelTransferManagerForTest();
379 manager = NULL;
381 // Texture ref still valid.
382 EXPECT_EQ(texture_ref, GetTexture(client_texture_id_));
383 EXPECT_EQ(texture_ref->num_observers(), 0);
387 } // namespace gles2
388 } // namespace gpu