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.
4
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6
7 #include <limits.h>
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <memory>
12
13 #include "base/command_line.h"
14 #include "base/numerics/ranges.h"
15 #include "base/stl_util.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "gpu/command_buffer/common/gles2_cmd_format.h"
18 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
19 #include "gpu/command_buffer/service/context_group.h"
20 #include "gpu/command_buffer/service/context_state.h"
21 #include "gpu/command_buffer/service/gl_surface_mock.h"
22 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
23 #include "gpu/command_buffer/service/gpu_switches.h"
24 #include "gpu/command_buffer/service/image_manager.h"
25 #include "gpu/command_buffer/service/mailbox_manager.h"
26 #include "gpu/command_buffer/service/mocks.h"
27 #include "gpu/command_buffer/service/program_manager.h"
28 #include "gpu/command_buffer/service/test_helper.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "ui/gl/gl_implementation.h"
31 #include "ui/gl/gl_mock.h"
32 #include "ui/gl/gl_surface_stub.h"
33
34 #if !defined(GL_DEPTH24_STENCIL8)
35 #define GL_DEPTH24_STENCIL8 0x88F0
36 #endif
37
38 using ::gl::MockGLInterface;
39 using ::testing::_;
40 using ::testing::AnyNumber;
41 using ::testing::DoAll;
42 using ::testing::InSequence;
43 using ::testing::Invoke;
44 using ::testing::MatcherCast;
45 using ::testing::Mock;
46 using ::testing::Pointee;
47 using ::testing::Return;
48 using ::testing::SaveArg;
49 using ::testing::SetArrayArgument;
50 using ::testing::SetArgPointee;
51 using ::testing::StrEq;
52 using ::testing::StrictMock;
53
54 namespace gpu {
55 namespace gles2 {
56
57 class GLES2DecoderTestWithExtensionsOnGLES2 : public GLES2DecoderTest {
58 public:
59 GLES2DecoderTestWithExtensionsOnGLES2() = default;
60
SetUp()61 void SetUp() override {}
Init(const char * extensions)62 void Init(const char* extensions) {
63 InitState init;
64 init.extensions = extensions;
65 init.gl_version = "OpenGL ES 2.0";
66 init.has_alpha = true;
67 init.has_depth = true;
68 init.request_alpha = true;
69 init.request_depth = true;
70 InitDecoder(init);
71 }
72 };
73
TEST_P(GLES2DecoderTest,CheckFramebufferStatusWithNoBoundTarget)74 TEST_P(GLES2DecoderTest, CheckFramebufferStatusWithNoBoundTarget) {
75 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0);
76 auto* result = static_cast<cmds::CheckFramebufferStatus::Result*>(
77 shared_memory_address_);
78 *result = 0;
79 cmds::CheckFramebufferStatus cmd;
80 cmd.Init(GL_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_);
81 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
82 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), *result);
83 }
84
TEST_P(GLES2DecoderWithShaderTest,BindAndDeleteFramebuffer)85 TEST_P(GLES2DecoderWithShaderTest, BindAndDeleteFramebuffer) {
86 SetupTexture();
87 AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
88 SetupExpectationsForApplyingDefaultDirtyState();
89 DoBindFramebuffer(
90 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
91 DoDeleteFramebuffer(client_framebuffer_id_,
92 kServiceFramebufferId,
93 true,
94 GL_FRAMEBUFFER,
95 0,
96 true,
97 GL_FRAMEBUFFER,
98 0);
99 EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
100 .Times(1)
101 .RetiresOnSaturation();
102 cmds::DrawArrays cmd;
103 cmd.Init(GL_TRIANGLES, 0, kNumVertices);
104 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
105 EXPECT_EQ(GL_NO_ERROR, GetGLError());
106 }
107
TEST_P(GLES2DecoderTest,FramebufferRenderbufferWithNoBoundTarget)108 TEST_P(GLES2DecoderTest, FramebufferRenderbufferWithNoBoundTarget) {
109 EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0);
110 cmds::FramebufferRenderbuffer cmd;
111 cmd.Init(GL_FRAMEBUFFER,
112 GL_COLOR_ATTACHMENT0,
113 GL_RENDERBUFFER,
114 client_renderbuffer_id_);
115 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
116 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
117 }
118
TEST_P(GLES2DecoderTest,FramebufferTexture2DWithNoBoundTarget)119 TEST_P(GLES2DecoderTest, FramebufferTexture2DWithNoBoundTarget) {
120 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
121 cmds::FramebufferTexture2D cmd;
122 cmd.Init(GL_FRAMEBUFFER,
123 GL_COLOR_ATTACHMENT0,
124 GL_TEXTURE_2D,
125 client_texture_id_,
126 0);
127 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
128 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
129 }
130
TEST_P(GLES3DecoderTest,FramebufferTexture2DWithNoBoundTarget)131 TEST_P(GLES3DecoderTest, FramebufferTexture2DWithNoBoundTarget) {
132 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
133 cmds::FramebufferTexture2D cmd;
134 cmd.Init(GL_FRAMEBUFFER,
135 GL_COLOR_ATTACHMENT0,
136 GL_TEXTURE_2D,
137 client_texture_id_,
138 1);
139 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
140 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
141 }
142
TEST_P(GLES2DecoderTest,FramebufferTexture2DValidArgs)143 TEST_P(GLES2DecoderTest, FramebufferTexture2DValidArgs) {
144 EXPECT_CALL(*gl_,
145 FramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
146 GL_TEXTURE_2D, kServiceTextureId, 0));
147 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
148 DoBindFramebuffer(
149 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
150 EXPECT_CALL(*gl_, GetError())
151 .WillOnce(Return(GL_NO_ERROR))
152 .WillOnce(Return(GL_NO_ERROR))
153 .RetiresOnSaturation();
154 cmds::FramebufferTexture2D cmd;
155 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
156 client_texture_id_, 0);
157 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
158 EXPECT_EQ(GL_NO_ERROR, GetGLError());
159 }
160
TEST_P(GLES3DecoderTest,FramebufferTexture2DValidArgs)161 TEST_P(GLES3DecoderTest, FramebufferTexture2DValidArgs) {
162 EXPECT_CALL(*gl_,
163 FramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
164 GL_TEXTURE_2D, kServiceTextureId, 1));
165 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
166 DoBindFramebuffer(
167 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
168 EXPECT_CALL(*gl_, GetError())
169 .WillOnce(Return(GL_NO_ERROR))
170 .WillOnce(Return(GL_NO_ERROR))
171 .RetiresOnSaturation();
172 cmds::FramebufferTexture2D cmd;
173 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
174 client_texture_id_, 1);
175 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
176 EXPECT_EQ(GL_NO_ERROR, GetGLError());
177 }
178
TEST_P(GLES3DecoderTest,FramebufferTexture2DDepthStencil)179 TEST_P(GLES3DecoderTest, FramebufferTexture2DDepthStencil) {
180 DoBindFramebuffer(
181 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
182 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
183 EXPECT_CALL(*gl_, GetError())
184 .WillOnce(Return(GL_NO_ERROR))
185 .WillOnce(Return(GL_NO_ERROR))
186 .WillOnce(Return(GL_NO_ERROR))
187 .RetiresOnSaturation();
188 EXPECT_CALL(*gl_,
189 FramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
190 GL_TEXTURE_2D, kServiceTextureId, 4))
191 .Times(1)
192 .RetiresOnSaturation();
193 EXPECT_CALL(*gl_,
194 FramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
195 GL_TEXTURE_2D, kServiceTextureId, 4))
196 .Times(1)
197 .RetiresOnSaturation();
198 cmds::FramebufferTexture2D cmd;
199 cmd.Init(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
200 client_texture_id_, 4);
201 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
202 EXPECT_EQ(GL_NO_ERROR, GetGLError());
203 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
204 ASSERT_TRUE(framebuffer);
205 ASSERT_FALSE(framebuffer->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
206 ASSERT_TRUE(framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT));
207 ASSERT_TRUE(framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT));
208 }
209
TEST_P(GLES2DecoderTest,FramebufferTexture2DInvalidArgs0_0)210 TEST_P(GLES2DecoderTest, FramebufferTexture2DInvalidArgs0_0) {
211 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
212 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
213 DoBindFramebuffer(
214 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
215 cmds::FramebufferTexture2D cmd;
216 cmd.Init(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
217 client_texture_id_, 0);
218 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
219 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
220 }
221
TEST_P(GLES3DecoderTest,FramebufferTexture2DInvalidArgs0_0)222 TEST_P(GLES3DecoderTest, FramebufferTexture2DInvalidArgs0_0) {
223 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
224 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
225 DoBindFramebuffer(
226 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
227 cmds::FramebufferTexture2D cmd;
228 cmd.Init(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
229 client_texture_id_, 1);
230 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
231 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
232 }
233
TEST_P(GLES2DecoderTest,FramebufferTexture2DInvalidArgs1_0)234 TEST_P(GLES2DecoderTest, FramebufferTexture2DInvalidArgs1_0) {
235 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
236 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
237 DoBindFramebuffer(
238 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
239 cmds::FramebufferTexture2D cmd;
240 cmd.Init(GL_FRAMEBUFFER, GL_COLOR, GL_TEXTURE_2D, client_texture_id_, 1);
241 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
242 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
243 }
244
TEST_P(GLES3DecoderTest,FramebufferTexture2DInvalidArgs1_0)245 TEST_P(GLES3DecoderTest, FramebufferTexture2DInvalidArgs1_0) {
246 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
247 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
248 DoBindFramebuffer(
249 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
250 cmds::FramebufferTexture2D cmd;
251 cmd.Init(GL_FRAMEBUFFER, GL_COLOR, GL_TEXTURE_2D, client_texture_id_, 1);
252 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
253 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
254 }
255
TEST_P(GLES2DecoderTest,FramebufferTexture2DInvalidArgs2_0)256 TEST_P(GLES2DecoderTest, FramebufferTexture2DInvalidArgs2_0) {
257 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
258 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
259 DoBindFramebuffer(
260 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
261 cmds::FramebufferTexture2D cmd;
262 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_PROXY_TEXTURE_CUBE_MAP,
263 client_texture_id_, 0);
264 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
265 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
266 }
267
TEST_P(GLES3DecoderTest,FramebufferTexture2DInvalidArgs2_0)268 TEST_P(GLES3DecoderTest, FramebufferTexture2DInvalidArgs2_0) {
269 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
270 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
271 DoBindFramebuffer(
272 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
273 cmds::FramebufferTexture2D cmd;
274 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_PROXY_TEXTURE_CUBE_MAP,
275 client_texture_id_, 1);
276 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
277 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
278 }
279
TEST_P(GLES2DecoderTest,FramebufferTexture2DInvalidArgs4_0)280 TEST_P(GLES2DecoderTest, FramebufferTexture2DInvalidArgs4_0) {
281 EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
282 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
283 DoBindFramebuffer(
284 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
285 cmds::FramebufferTexture2D cmd;
286 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
287 client_texture_id_, 1);
288 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
289 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
290 }
291
TEST_P(GLES3DecoderTest,FramebufferTexture2DValidArgs4_0)292 TEST_P(GLES3DecoderTest, FramebufferTexture2DValidArgs4_0) {
293 EXPECT_CALL(*gl_,
294 FramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
295 GL_TEXTURE_2D, kServiceTextureId, 0));
296 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
297 DoBindFramebuffer(
298 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
299 EXPECT_CALL(*gl_, GetError())
300 .WillOnce(Return(GL_NO_ERROR))
301 .WillOnce(Return(GL_NO_ERROR))
302 .RetiresOnSaturation();
303 cmds::FramebufferTexture2D cmd;
304 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
305 client_texture_id_, 0);
306 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
307 EXPECT_EQ(GL_NO_ERROR, GetGLError());
308 }
309
TEST_P(GLES2DecoderTest,FramebufferTexture2DMismatchedTexture1)310 TEST_P(GLES2DecoderTest, FramebufferTexture2DMismatchedTexture1) {
311 EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
312 .Times(0);
313 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
314 DoBindFramebuffer(
315 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
316 cmds::FramebufferTexture2D cmd;
317 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
318 client_texture_id_, 0);
319 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
320 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
321 }
322
TEST_P(GLES2DecoderTest,FramebufferTexture2DMismatchedTexture2)323 TEST_P(GLES2DecoderTest, FramebufferTexture2DMismatchedTexture2) {
324 EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
325 .Times(0);
326 DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
327 DoBindFramebuffer(
328 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
329 cmds::FramebufferTexture2D cmd;
330 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
331 client_texture_id_, 0);
332 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
333 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
334 }
335
TEST_P(GLES2DecoderTest,GetFramebufferAttachmentParameterivWithNoBoundTarget)336 TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithNoBoundTarget) {
337 EXPECT_CALL(*gl_, GetError())
338 .WillOnce(Return(GL_NO_ERROR))
339 .WillOnce(Return(GL_NO_ERROR))
340 .RetiresOnSaturation();
341 EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
342 .Times(0);
343 cmds::GetFramebufferAttachmentParameteriv cmd;
344 cmd.Init(GL_FRAMEBUFFER,
345 GL_COLOR_ATTACHMENT0,
346 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
347 shared_memory_id_,
348 shared_memory_offset_);
349 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
350 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
351 }
352
TEST_P(GLES2DecoderTest,GetFramebufferAttachmentParameterivWithRenderbuffer)353 TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithRenderbuffer) {
354 DoBindFramebuffer(
355 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
356 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
357 kServiceRenderbufferId);
358 EXPECT_CALL(*gl_, GetError())
359 .WillRepeatedly(Return(GL_NO_ERROR));
360 EXPECT_CALL(*gl_,
361 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
362 GL_COLOR_ATTACHMENT0,
363 GL_RENDERBUFFER,
364 kServiceRenderbufferId))
365 .Times(1)
366 .RetiresOnSaturation();
367 auto* result =
368 static_cast<cmds::GetFramebufferAttachmentParameteriv::Result*>(
369 shared_memory_address_);
370 result->size = 0;
371 const GLint* result_value = result->GetData();
372 cmds::FramebufferRenderbuffer fbrb_cmd;
373 cmds::GetFramebufferAttachmentParameteriv cmd;
374 fbrb_cmd.Init(GL_FRAMEBUFFER,
375 GL_COLOR_ATTACHMENT0,
376 GL_RENDERBUFFER,
377 client_renderbuffer_id_);
378 cmd.Init(GL_FRAMEBUFFER,
379 GL_COLOR_ATTACHMENT0,
380 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
381 shared_memory_id_,
382 shared_memory_offset_);
383 EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
384 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
385 EXPECT_EQ(GL_NO_ERROR, GetGLError());
386 EXPECT_EQ(client_renderbuffer_id_, static_cast<GLuint>(*result_value));
387 }
388
TEST_P(GLES2DecoderTest,GetFramebufferAttachmentParameterivWithTexture)389 TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithTexture) {
390 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
391 DoBindFramebuffer(
392 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
393 EXPECT_CALL(*gl_, GetError())
394 .WillRepeatedly(Return(GL_NO_ERROR));
395 EXPECT_CALL(*gl_,
396 FramebufferTexture2DEXT(GL_FRAMEBUFFER,
397 GL_COLOR_ATTACHMENT0,
398 GL_TEXTURE_2D,
399 kServiceTextureId,
400 0))
401 .Times(1)
402 .RetiresOnSaturation();
403 auto* result =
404 static_cast<cmds::GetFramebufferAttachmentParameteriv::Result*>(
405 shared_memory_address_);
406 result->SetNumResults(0);
407 const GLint* result_value = result->GetData();
408 cmds::FramebufferTexture2D fbtex_cmd;
409 cmds::GetFramebufferAttachmentParameteriv cmd;
410 fbtex_cmd.Init(GL_FRAMEBUFFER,
411 GL_COLOR_ATTACHMENT0,
412 GL_TEXTURE_2D,
413 client_texture_id_,
414 0);
415 cmd.Init(GL_FRAMEBUFFER,
416 GL_COLOR_ATTACHMENT0,
417 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
418 shared_memory_id_,
419 shared_memory_offset_);
420 EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
421 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
422 EXPECT_EQ(GL_NO_ERROR, GetGLError());
423 EXPECT_EQ(client_texture_id_, static_cast<GLuint>(*result_value));
424 }
425
TEST_P(GLES2DecoderWithShaderTest,GetRenderbufferParameterivRebindRenderbuffer)426 TEST_P(GLES2DecoderWithShaderTest,
427 GetRenderbufferParameterivRebindRenderbuffer) {
428 SetupTexture();
429 DoBindRenderbuffer(
430 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
431 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
432
433 cmds::GetRenderbufferParameteriv cmd;
434 cmd.Init(GL_RENDERBUFFER,
435 GL_RENDERBUFFER_RED_SIZE,
436 shared_memory_id_,
437 shared_memory_offset_);
438
439 RestoreRenderbufferBindings();
440 EnsureRenderbufferBound(true);
441
442 EXPECT_CALL(*gl_, GetError())
443 .WillOnce(Return(GL_NO_ERROR))
444 .WillOnce(Return(GL_NO_ERROR))
445 .RetiresOnSaturation();
446 EXPECT_CALL(*gl_,
447 GetRenderbufferParameterivEXT(
448 GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, _));
449 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
450 EXPECT_EQ(GL_NO_ERROR, GetGLError());
451 }
452
TEST_P(GLES2DecoderTest,GetRenderbufferParameterivWithNoBoundTarget)453 TEST_P(GLES2DecoderTest, GetRenderbufferParameterivWithNoBoundTarget) {
454 EXPECT_CALL(*gl_, GetError())
455 .WillOnce(Return(GL_NO_ERROR))
456 .WillOnce(Return(GL_NO_ERROR))
457 .RetiresOnSaturation();
458 EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0);
459 cmds::GetRenderbufferParameteriv cmd;
460 cmd.Init(GL_RENDERBUFFER,
461 GL_RENDERBUFFER_WIDTH,
462 shared_memory_id_,
463 shared_memory_offset_);
464 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
465 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
466 }
467
TEST_P(GLES2DecoderWithShaderTest,RenderbufferStorageRebindRenderbuffer)468 TEST_P(GLES2DecoderWithShaderTest, RenderbufferStorageRebindRenderbuffer) {
469 SetupTexture();
470 DoBindRenderbuffer(
471 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
472 RestoreRenderbufferBindings();
473 EnsureRenderbufferBound(true);
474 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
475 }
476
TEST_P(GLES2DecoderTest,RenderbufferStorageWithNoBoundTarget)477 TEST_P(GLES2DecoderTest, RenderbufferStorageWithNoBoundTarget) {
478 EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0);
479 cmds::RenderbufferStorage cmd;
480 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4);
481 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
482 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
483 }
484
485 namespace {
486
487 // A class to emulate glReadPixels
488 class ReadPixelsEmulator {
489 public:
490 // pack_alignment is the alignment you want ReadPixels to use
491 // when copying. The actual data passed in pixels should be contiguous.
ReadPixelsEmulator(GLsizei width,GLsizei height,GLint bytes_per_pixel,const void * src_pixels,const void * expected_pixels,GLint pack_alignment)492 ReadPixelsEmulator(GLsizei width,
493 GLsizei height,
494 GLint bytes_per_pixel,
495 const void* src_pixels,
496 const void* expected_pixels,
497 GLint pack_alignment)
498 : width_(width),
499 height_(height),
500 pack_alignment_(pack_alignment),
501 bytes_per_pixel_(bytes_per_pixel),
502 src_pixels_(reinterpret_cast<const int8_t*>(src_pixels)),
503 expected_pixels_(reinterpret_cast<const int8_t*>(expected_pixels)) {}
504
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,void * pixels) const505 void ReadPixels(GLint x,
506 GLint y,
507 GLsizei width,
508 GLsizei height,
509 GLenum format,
510 GLenum type,
511 void* pixels) const {
512 DCHECK_GE(x, 0);
513 DCHECK_GE(y, 0);
514 DCHECK_LE(x + width, width_);
515 DCHECK_LE(y + height, height_);
516 for (GLint yy = 0; yy < height; ++yy) {
517 const int8_t* src = GetPixelAddress(src_pixels_, x, y + yy);
518 const void* dst = ComputePackAlignmentAddress(0, yy, width, pixels);
519 memcpy(const_cast<void*>(dst), src, width * bytes_per_pixel_);
520 }
521 }
522
CompareRowSegment(GLint x,GLint y,GLsizei width,const void * data) const523 bool CompareRowSegment(GLint x,
524 GLint y,
525 GLsizei width,
526 const void* data) const {
527 DCHECK(x + width <= width_ || width == 0);
528 return memcmp(data,
529 GetPixelAddress(expected_pixels_, x, y),
530 width * bytes_per_pixel_) == 0;
531 }
532
533 // Helper to compute address of pixel in pack aligned data.
ComputePackAlignmentAddress(GLint x,GLint y,GLsizei width,const void * address) const534 const void* ComputePackAlignmentAddress(GLint x,
535 GLint y,
536 GLsizei width,
537 const void* address) const {
538 GLint unpadded_row_size = ComputeImageDataSize(width, 1);
539 GLint two_rows_size = ComputeImageDataSize(width, 2);
540 GLsizei padded_row_size = two_rows_size - unpadded_row_size;
541 GLint offset = y * padded_row_size + x * bytes_per_pixel_;
542 return static_cast<const int8_t*>(address) + offset;
543 }
544
ComputeImageDataSize(GLint width,GLint height) const545 GLint ComputeImageDataSize(GLint width, GLint height) const {
546 GLint row_size = width * bytes_per_pixel_;
547 if (height > 1) {
548 GLint temp = row_size + pack_alignment_ - 1;
549 GLint padded_row_size = (temp / pack_alignment_) * pack_alignment_;
550 GLint size_of_all_but_last_row = (height - 1) * padded_row_size;
551 return size_of_all_but_last_row + row_size;
552 } else {
553 return height * row_size;
554 }
555 }
556
557 private:
GetPixelAddress(const int8_t * base,GLint x,GLint y) const558 const int8_t* GetPixelAddress(const int8_t* base, GLint x, GLint y) const {
559 return base + (width_ * y + x) * bytes_per_pixel_;
560 }
561
562 GLsizei width_;
563 GLsizei height_;
564 GLint pack_alignment_;
565 GLint bytes_per_pixel_;
566 const int8_t* src_pixels_;
567 const int8_t* expected_pixels_;
568 };
569
570 } // anonymous namespace
571
CheckReadPixelsOutOfRange(GLint in_read_x,GLint in_read_y,GLsizei in_read_width,GLsizei in_read_height,bool init)572 void GLES2DecoderTest::CheckReadPixelsOutOfRange(GLint in_read_x,
573 GLint in_read_y,
574 GLsizei in_read_width,
575 GLsizei in_read_height,
576 bool init) {
577 const GLsizei kWidth = 5;
578 const GLsizei kHeight = 3;
579 const GLint kBytesPerPixel = 4;
580 const GLint kPackAlignment = 4;
581 const GLenum kFormat = GL_RGBA;
582 static const uint8_t kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
583 12, 13, 14, 255, 18, 19, 18, 255, 19, 12, 13, 255, 14, 18, 19, 255,
584 18, 19, 13, 255, 29, 28, 23, 255, 22, 21, 22, 255, 21, 29, 28, 255,
585 23, 22, 21, 255, 22, 21, 28, 255, 31, 34, 39, 255, 37, 32, 37, 255,
586 32, 31, 34, 255, 39, 37, 32, 255, 37, 32, 34, 255};
587
588 ClearSharedMemory();
589
590 // We need to setup an FBO so we can know the max size that ReadPixels will
591 // access
592 if (init) {
593 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
594 DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0, kFormat,
595 GL_UNSIGNED_BYTE, shared_memory_id_, kSharedMemoryOffset);
596 DoBindFramebuffer(
597 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
598 DoFramebufferTexture2D(GL_FRAMEBUFFER,
599 GL_COLOR_ATTACHMENT0,
600 GL_TEXTURE_2D,
601 client_texture_id_,
602 kServiceTextureId,
603 0,
604 GL_NO_ERROR);
605 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
606 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
607 .RetiresOnSaturation();
608 }
609
610 ReadPixelsEmulator emu(
611 kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
612 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
613 uint32_t result_shm_id = shared_memory_id_;
614 uint32_t result_shm_offset = kSharedMemoryOffset;
615 uint32_t pixels_shm_id = shared_memory_id_;
616 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
617 void* dest = &result[1];
618
619 EXPECT_CALL(*gl_, GetError())
620 .WillOnce(Return(GL_NO_ERROR))
621 .WillOnce(Return(GL_NO_ERROR))
622 .RetiresOnSaturation();
623 // ReadPixels will be called for valid size only even though the command
624 // is requesting a larger size.
625 GLint read_x = std::max(0, in_read_x);
626 GLint read_y = std::max(0, in_read_y);
627 GLint read_end_x = base::ClampToRange(in_read_x + in_read_width, 0, kWidth);
628 GLint read_end_y = base::ClampToRange(in_read_y + in_read_height, 0, kHeight);
629 GLint read_width = read_end_x - read_x;
630 GLint read_height = read_end_y - read_y;
631 if (read_width > 0 && read_height > 0) {
632 for (GLint yy = read_y; yy < read_end_y; ++yy) {
633 EXPECT_CALL(
634 *gl_,
635 ReadPixels(read_x, yy, read_width, 1, kFormat, GL_UNSIGNED_BYTE, _))
636 .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels))
637 .RetiresOnSaturation();
638 }
639 }
640 cmds::ReadPixels cmd;
641 cmd.Init(in_read_x,
642 in_read_y,
643 in_read_width,
644 in_read_height,
645 kFormat,
646 GL_UNSIGNED_BYTE,
647 pixels_shm_id,
648 pixels_shm_offset,
649 result_shm_id,
650 result_shm_offset,
651 false);
652 result->success = 0;
653 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
654
655 GLint unpadded_row_size = emu.ComputeImageDataSize(in_read_width, 1);
656 std::unique_ptr<int8_t[]> zero(new int8_t[unpadded_row_size]);
657 std::unique_ptr<int8_t[]> pack(new int8_t[kPackAlignment]);
658 memset(zero.get(), kInitialMemoryValue, unpadded_row_size);
659 memset(pack.get(), kInitialMemoryValue, kPackAlignment);
660 for (GLint yy = 0; yy < in_read_height; ++yy) {
661 const int8_t* row = static_cast<const int8_t*>(
662 emu.ComputePackAlignmentAddress(0, yy, in_read_width, dest));
663 GLint y = in_read_y + yy;
664 if (y < 0 || y >= kHeight) {
665 EXPECT_EQ(0, memcmp(zero.get(), row, unpadded_row_size));
666 } else {
667 // check off left.
668 GLint num_left_pixels = std::max(-in_read_x, 0);
669 GLint num_left_bytes = num_left_pixels * kBytesPerPixel;
670 EXPECT_EQ(0, memcmp(zero.get(), row, num_left_bytes));
671
672 // check off right.
673 GLint num_right_pixels = std::max(in_read_x + in_read_width - kWidth, 0);
674 GLint num_right_bytes = num_right_pixels * kBytesPerPixel;
675 EXPECT_EQ(0,
676 memcmp(zero.get(),
677 row + unpadded_row_size - num_right_bytes,
678 num_right_bytes));
679
680 // check middle.
681 GLint x = std::max(in_read_x, 0);
682 GLint num_middle_pixels =
683 std::max(in_read_width - num_left_pixels - num_right_pixels, 0);
684 EXPECT_TRUE(
685 emu.CompareRowSegment(x, y, num_middle_pixels, row + num_left_bytes));
686 }
687
688 // check padding
689 if (yy != in_read_height - 1) {
690 GLint temp = unpadded_row_size + kPackAlignment - 1;
691 GLint padded_row_size = (temp / kPackAlignment ) * kPackAlignment;
692 GLint num_padding_bytes = padded_row_size - unpadded_row_size;
693 if (num_padding_bytes) {
694 EXPECT_EQ(0, memcmp(pack.get(),
695 row + unpadded_row_size, num_padding_bytes));
696 }
697 }
698 }
699 }
700
TEST_P(GLES2DecoderTest,ReadPixels)701 TEST_P(GLES2DecoderTest, ReadPixels) {
702 const GLsizei kWidth = 5;
703 const GLsizei kHeight = 3;
704 const GLint kBytesPerPixel = 4;
705 const GLint kPackAlignment = 4;
706 static const uint8_t kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
707 12, 13, 14, 255, 18, 19, 18, 255, 19, 12, 13, 255, 14, 18, 19, 255,
708 18, 19, 13, 255, 29, 28, 23, 255, 22, 21, 22, 255, 21, 29, 28, 255,
709 23, 22, 21, 255, 22, 21, 28, 255, 31, 34, 39, 255, 37, 32, 37, 255,
710 32, 31, 34, 255, 39, 37, 32, 255, 37, 32, 34, 255};
711
712 surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
713
714 ReadPixelsEmulator emu(
715 kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
716 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
717 uint32_t result_shm_id = shared_memory_id_;
718 uint32_t result_shm_offset = kSharedMemoryOffset;
719 uint32_t pixels_shm_id = shared_memory_id_;
720 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
721 void* dest = &result[1];
722 EXPECT_CALL(*gl_, GetError())
723 .WillOnce(Return(GL_NO_ERROR))
724 .WillOnce(Return(GL_NO_ERROR))
725 .RetiresOnSaturation();
726 EXPECT_CALL(*gl_,
727 ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
728 .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
729 cmds::ReadPixels cmd;
730 cmd.Init(0,
731 0,
732 kWidth,
733 kHeight,
734 GL_RGBA,
735 GL_UNSIGNED_BYTE,
736 pixels_shm_id,
737 pixels_shm_offset,
738 result_shm_id,
739 result_shm_offset,
740 false);
741 result->success = 1;
742 EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
743 result->success = 0;
744 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
745 for (GLint yy = 0; yy < kHeight; ++yy) {
746 EXPECT_TRUE(emu.CompareRowSegment(
747 0, yy, kWidth, emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
748 }
749 }
750
TEST_P(GLES3DecoderTest,ReadPixels2PixelPackBufferNoBufferBound)751 TEST_P(GLES3DecoderTest, ReadPixels2PixelPackBufferNoBufferBound) {
752 const GLsizei kWidth = 5;
753 const GLsizei kHeight = 3;
754 EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
755
756 cmds::ReadPixels cmd;
757 cmd.Init(0,
758 0,
759 kWidth,
760 kHeight,
761 GL_RGBA,
762 GL_UNSIGNED_BYTE,
763 0,
764 0,
765 0,
766 0,
767 false);
768 EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
769 EXPECT_EQ(GL_NO_ERROR, GetGLError());
770 }
771
TEST_P(GLES3DecoderTest,ReadPixelsBufferBound)772 TEST_P(GLES3DecoderTest, ReadPixelsBufferBound) {
773 const GLsizei kWidth = 5;
774 const GLsizei kHeight = 3;
775 const GLint kBytesPerPixel = 4;
776 GLint size = kWidth * kHeight * kBytesPerPixel;
777 EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
778 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
779 uint32_t result_shm_id = shared_memory_id_;
780 uint32_t result_shm_offset = kSharedMemoryOffset;
781 uint32_t pixels_shm_id = shared_memory_id_;
782 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
783
784 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
785 DoBufferData(GL_PIXEL_PACK_BUFFER, size);
786
787 cmds::ReadPixels cmd;
788 cmd.Init(0,
789 0,
790 kWidth,
791 kHeight,
792 GL_RGBA,
793 GL_UNSIGNED_BYTE,
794 pixels_shm_id,
795 pixels_shm_offset,
796 result_shm_id,
797 result_shm_offset,
798 false);
799 result->success = 0;
800 EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
801 EXPECT_EQ(GL_NO_ERROR, GetGLError());
802 }
803
TEST_P(GLES3DecoderTest,ReadPixels2PixelPackBuffer)804 TEST_P(GLES3DecoderTest, ReadPixels2PixelPackBuffer) {
805 const GLsizei kWidth = 5;
806 const GLsizei kHeight = 3;
807 const GLint kBytesPerPixel = 4;
808 GLint size = kWidth * kHeight * kBytesPerPixel;
809
810 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
811 DoBufferData(GL_PIXEL_PACK_BUFFER, size);
812
813 EXPECT_CALL(*gl_, GetError())
814 .WillOnce(Return(GL_NO_ERROR))
815 .RetiresOnSaturation();
816 EXPECT_CALL(*gl_,
817 ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _));
818 cmds::ReadPixels cmd;
819 cmd.Init(0,
820 0,
821 kWidth,
822 kHeight,
823 GL_RGBA,
824 GL_UNSIGNED_BYTE,
825 0,
826 0,
827 0,
828 0,
829 false);
830 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
831 EXPECT_EQ(GL_NO_ERROR, GetGLError());
832 }
833
TEST_P(GLES3DecoderTest,ReadPixelsPixelPackBufferMapped)834 TEST_P(GLES3DecoderTest, ReadPixelsPixelPackBufferMapped) {
835 const GLsizei kWidth = 5;
836 const GLsizei kHeight = 3;
837 const GLint kBytesPerPixel = 4;
838 GLint size = kWidth * kHeight * kBytesPerPixel;
839
840 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
841 DoBufferData(GL_PIXEL_PACK_BUFFER, size);
842
843 std::vector<int8_t> mapped_data(size);
844
845 uint32_t result_shm_id = shared_memory_id_;
846 uint32_t result_shm_offset = kSharedMemoryOffset;
847 uint32_t data_shm_id = shared_memory_id_;
848 // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
849 uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
850 EXPECT_CALL(*gl_,
851 MapBufferRange(GL_PIXEL_PACK_BUFFER, 0, size, GL_MAP_READ_BIT))
852 .WillOnce(Return(mapped_data.data()))
853 .RetiresOnSaturation();
854 cmds::MapBufferRange map_buffer_range;
855 map_buffer_range.Init(GL_PIXEL_PACK_BUFFER, 0, size, GL_MAP_READ_BIT,
856 data_shm_id, data_shm_offset,
857 result_shm_id, result_shm_offset);
858 EXPECT_EQ(error::kNoError, ExecuteCmd(map_buffer_range));
859 EXPECT_EQ(GL_NO_ERROR, GetGLError());
860
861 EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
862 cmds::ReadPixels cmd;
863 cmd.Init(0,
864 0,
865 kWidth,
866 kHeight,
867 GL_RGBA,
868 GL_UNSIGNED_BYTE,
869 0,
870 0,
871 0,
872 0,
873 false);
874 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
875 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
876 }
877
TEST_P(GLES3DecoderTest,ReadPixelsPixelPackBufferIsNotLargeEnough)878 TEST_P(GLES3DecoderTest, ReadPixelsPixelPackBufferIsNotLargeEnough) {
879 const GLsizei kWidth = 5;
880 const GLsizei kHeight = 3;
881 const GLint kBytesPerPixel = 4;
882 GLint size = kWidth * kHeight * kBytesPerPixel;
883
884 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
885
886 DoBufferData(GL_PIXEL_PACK_BUFFER, size - 4);
887 EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
888
889 cmds::ReadPixels cmd;
890 cmd.Init(0,
891 0,
892 kWidth,
893 kHeight,
894 GL_RGBA,
895 GL_UNSIGNED_BYTE,
896 0,
897 0,
898 0,
899 0,
900 false);
901 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
902 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
903 }
904
TEST_P(GLES2DecoderManualInitTest,ReadPixels2RowLengthWorkaround)905 TEST_P(GLES2DecoderManualInitTest, ReadPixels2RowLengthWorkaround) {
906 gpu::GpuDriverBugWorkarounds workarounds;
907 workarounds.pack_parameters_workaround_with_pack_buffer = true;
908 InitState init;
909 init.gl_version = "OpenGL ES 3.0";
910 init.bind_generates_resource = true;
911 init.context_type = CONTEXT_TYPE_OPENGLES3;
912 InitDecoderWithWorkarounds(init, workarounds);
913
914 const GLsizei kWidth = 5;
915 const GLsizei kHeight = 3;
916 const GLint kBytesPerPixel = 4;
917 const GLenum kFormat = GL_RGBA;
918 const GLenum kType = GL_UNSIGNED_BYTE;
919 const GLint kRowLength = 4;
920 GLint size = (kRowLength * (kHeight - 1) + kWidth) * kBytesPerPixel;
921
922 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
923 DoBufferData(GL_PIXEL_PACK_BUFFER, size);
924
925 DoPixelStorei(GL_PACK_ROW_LENGTH, kRowLength);
926
927 EXPECT_CALL(*gl_, GetError())
928 .WillOnce(Return(GL_NO_ERROR))
929 .RetiresOnSaturation();
930 for (GLint ii = 0; ii < kHeight; ++ii) {
931 if (ii + 1 == kHeight) {
932 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ROW_LENGTH, kWidth))
933 .Times(1)
934 .RetiresOnSaturation();
935 }
936 void* offset = reinterpret_cast<void*>(ii * kRowLength * kBytesPerPixel);
937 EXPECT_CALL(*gl_, ReadPixels(0, ii, kWidth, 1, kFormat, kType, offset))
938 .Times(1)
939 .RetiresOnSaturation();
940 if (ii + 1 == kHeight) {
941 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ROW_LENGTH, kRowLength))
942 .Times(1)
943 .RetiresOnSaturation();
944 }
945 }
946
947 cmds::ReadPixels cmd;
948 cmd.Init(0, 0, kWidth, kHeight,
949 kFormat, kType,
950 0, 0, 0, 0,
951 false);
952 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
953 EXPECT_EQ(GL_NO_ERROR, GetGLError());
954 }
955
TEST_P(GLES2DecoderManualInitTest,ReadPixels2AlignmentWorkaround)956 TEST_P(GLES2DecoderManualInitTest, ReadPixels2AlignmentWorkaround) {
957 gpu::GpuDriverBugWorkarounds workarounds;
958 workarounds.pack_parameters_workaround_with_pack_buffer = true;
959 InitState init;
960 init.gl_version = "OpenGL ES 3.0";
961 init.bind_generates_resource = true;
962 init.context_type = CONTEXT_TYPE_OPENGLES3;
963 InitDecoderWithWorkarounds(init, workarounds);
964
965 const GLsizei kWidth = 5;
966 const GLsizei kHeight = 3;
967 const GLint kBytesPerPixel = 4;
968 const GLenum kFormat = GL_RGBA;
969 const GLenum kType = GL_UNSIGNED_BYTE;
970 const GLint kAlignment = 8;
971 const GLint kPadding = 4;
972 GLint size = kWidth * kBytesPerPixel * kHeight + kPadding * (kHeight - 1);
973
974 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
975 DoBufferData(GL_PIXEL_PACK_BUFFER, size);
976
977 DoPixelStorei(GL_PACK_ALIGNMENT, kAlignment);
978
979 EXPECT_CALL(*gl_, GetError())
980 .WillOnce(Return(GL_NO_ERROR))
981 .RetiresOnSaturation();
982 uint8_t* offset = reinterpret_cast<uint8_t*>(0);
983 EXPECT_CALL(*gl_,
984 ReadPixels(0, 0, kWidth, kHeight - 1, kFormat, kType, offset))
985 .Times(1)
986 .RetiresOnSaturation();
987 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, 1))
988 .Times(1)
989 .RetiresOnSaturation();
990 offset += (kWidth * kBytesPerPixel + kPadding) * (kHeight - 1);
991 EXPECT_CALL(*gl_,
992 ReadPixels(0, kHeight - 1, kWidth, 1, kFormat, kType, offset))
993 .Times(1)
994 .RetiresOnSaturation();
995 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, kAlignment))
996 .Times(1)
997 .RetiresOnSaturation();
998
999 cmds::ReadPixels cmd;
1000 cmd.Init(0, 0, kWidth, kHeight,
1001 kFormat, kType,
1002 0, 0, 0, 0,
1003 false);
1004 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1005 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1006 }
1007
TEST_P(GLES2DecoderManualInitTest,ReadPixels2RowLengthAndAlignmentWorkarounds)1008 TEST_P(GLES2DecoderManualInitTest,
1009 ReadPixels2RowLengthAndAlignmentWorkarounds) {
1010 gpu::GpuDriverBugWorkarounds workarounds;
1011 workarounds.pack_parameters_workaround_with_pack_buffer = true;
1012 InitState init;
1013 init.gl_version = "OpenGL ES 3.0";
1014 init.bind_generates_resource = true;
1015 init.context_type = CONTEXT_TYPE_OPENGLES3;
1016 InitDecoderWithWorkarounds(init, workarounds);
1017
1018 const GLsizei kWidth = 5;
1019 const GLsizei kHeight = 3;
1020 const GLint kBytesPerPixel = 4;
1021 const GLenum kFormat = GL_RGBA;
1022 const GLenum kType = GL_UNSIGNED_BYTE;
1023 const GLint kAlignment = 8;
1024 const GLint kRowLength = 3;
1025 const GLint kPadding = 4;
1026 GLint padded_row_size = kRowLength * kBytesPerPixel + kPadding;
1027 GLint unpadded_row_size = kWidth * kBytesPerPixel;
1028 GLint size = padded_row_size * (kHeight - 1) + unpadded_row_size;
1029
1030 DoBindBuffer(GL_PIXEL_PACK_BUFFER, client_buffer_id_, kServiceBufferId);
1031 DoBufferData(GL_PIXEL_PACK_BUFFER, size);
1032
1033 DoPixelStorei(GL_PACK_ALIGNMENT, kAlignment);
1034 DoPixelStorei(GL_PACK_ROW_LENGTH, kRowLength);
1035
1036 EXPECT_CALL(*gl_, GetError())
1037 .WillOnce(Return(GL_NO_ERROR))
1038 .RetiresOnSaturation();
1039 for (GLint ii = 0; ii < kHeight - 1; ++ii) {
1040 void* offset = reinterpret_cast<void*>(ii * padded_row_size);
1041 EXPECT_CALL(*gl_, ReadPixels(0, ii, kWidth, 1, kFormat, kType, offset))
1042 .Times(1)
1043 .RetiresOnSaturation();
1044 }
1045 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, 1))
1046 .Times(1)
1047 .RetiresOnSaturation();
1048 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ROW_LENGTH, kWidth))
1049 .Times(1)
1050 .RetiresOnSaturation();
1051 void* offset = reinterpret_cast<void*>((kHeight - 1) * padded_row_size);
1052 EXPECT_CALL(*gl_,
1053 ReadPixels(0, kHeight - 1, kWidth, 1, kFormat, kType, offset))
1054 .Times(1)
1055 .RetiresOnSaturation();
1056 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, kAlignment))
1057 .Times(1)
1058 .RetiresOnSaturation();
1059 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ROW_LENGTH, kRowLength))
1060 .Times(1)
1061 .RetiresOnSaturation();
1062
1063 cmds::ReadPixels cmd;
1064 cmd.Init(0, 0, kWidth, kHeight,
1065 kFormat, kType,
1066 0, 0, 0, 0,
1067 false);
1068 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1069 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1070 }
1071
TEST_P(GLES2DecoderRGBBackbufferTest,ReadPixelsNoAlphaBackbuffer)1072 TEST_P(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) {
1073 const GLsizei kWidth = 3;
1074 const GLsizei kHeight = 3;
1075 const GLint kBytesPerPixel = 4;
1076 const GLint kPackAlignment = 4;
1077 static const uint8_t kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
1078 12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 29, 28, 23, 22, 21, 22,
1079 21, 29, 28, 23, 22, 21, 31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32,
1080 };
1081
1082 surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
1083
1084 ReadPixelsEmulator emu(kWidth, kHeight, kBytesPerPixel, kSrcPixels,
1085 kSrcPixels, kPackAlignment);
1086 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
1087 uint32_t result_shm_id = shared_memory_id_;
1088 uint32_t result_shm_offset = kSharedMemoryOffset;
1089 uint32_t pixels_shm_id = shared_memory_id_;
1090 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1091 void* dest = &result[1];
1092 EXPECT_CALL(*gl_, GetError())
1093 .WillOnce(Return(GL_NO_ERROR))
1094 .WillOnce(Return(GL_NO_ERROR))
1095 .RetiresOnSaturation();
1096 EXPECT_CALL(*gl_,
1097 ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
1098 .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
1099 cmds::ReadPixels cmd;
1100 cmd.Init(0,
1101 0,
1102 kWidth,
1103 kHeight,
1104 GL_RGBA,
1105 GL_UNSIGNED_BYTE,
1106 pixels_shm_id,
1107 pixels_shm_offset,
1108 result_shm_id,
1109 result_shm_offset,
1110 false);
1111 result->success = 0;
1112 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1113 for (GLint yy = 0; yy < kHeight; ++yy) {
1114 EXPECT_TRUE(emu.CompareRowSegment(
1115 0, yy, kWidth, emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
1116 }
1117 }
1118
TEST_P(GLES2DecoderTest,ReadPixelsOutOfRange)1119 TEST_P(GLES2DecoderTest, ReadPixelsOutOfRange) {
1120 static GLint tests[][4] = {
1121 {
1122 -2, -1, 9, 5,
1123 }, // out of range on all sides
1124 {
1125 2, 1, 9, 5,
1126 }, // out of range on right, bottom
1127 {
1128 -7, -4, 9, 5,
1129 }, // out of range on left, top
1130 {
1131 0, -5, 9, 5,
1132 }, // completely off top
1133 {
1134 0, 3, 9, 5,
1135 }, // completely off bottom
1136 {
1137 -9, 0, 9, 5,
1138 }, // completely off left
1139 {
1140 5, 0, 9, 5,
1141 }, // completely off right
1142 };
1143
1144 for (size_t tt = 0; tt < base::size(tests); ++tt) {
1145 CheckReadPixelsOutOfRange(
1146 tests[tt][0], tests[tt][1], tests[tt][2], tests[tt][3], tt == 0);
1147 }
1148 }
1149
TEST_P(GLES2DecoderTest,ReadPixelsInvalidArgs)1150 TEST_P(GLES2DecoderTest, ReadPixelsInvalidArgs) {
1151 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
1152 uint32_t result_shm_id = shared_memory_id_;
1153 uint32_t result_shm_offset = kSharedMemoryOffset;
1154 uint32_t pixels_shm_id = shared_memory_id_;
1155 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1156 EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
1157 cmds::ReadPixels cmd;
1158 cmd.Init(0,
1159 0,
1160 -1,
1161 1,
1162 GL_RGB,
1163 GL_UNSIGNED_BYTE,
1164 pixels_shm_id,
1165 pixels_shm_offset,
1166 result_shm_id,
1167 result_shm_offset,
1168 false);
1169 result->success = 0;
1170 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1171 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1172 cmd.Init(0,
1173 0,
1174 1,
1175 -1,
1176 GL_RGB,
1177 GL_UNSIGNED_BYTE,
1178 pixels_shm_id,
1179 pixels_shm_offset,
1180 result_shm_id,
1181 result_shm_offset,
1182 false);
1183 result->success = 0;
1184 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1185 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1186 cmd.Init(0,
1187 0,
1188 1,
1189 1,
1190 GL_RGB,
1191 GL_INT,
1192 pixels_shm_id,
1193 pixels_shm_offset,
1194 result_shm_id,
1195 result_shm_offset,
1196 false);
1197 result->success = 0;
1198 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1199 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1200 cmd.Init(0,
1201 0,
1202 1,
1203 1,
1204 GL_RGB,
1205 GL_UNSIGNED_BYTE,
1206 kInvalidSharedMemoryId,
1207 pixels_shm_offset,
1208 result_shm_id,
1209 result_shm_offset,
1210 false);
1211 result->success = 0;
1212 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1213 cmd.Init(0,
1214 0,
1215 1,
1216 1,
1217 GL_RGB,
1218 GL_UNSIGNED_BYTE,
1219 pixels_shm_id,
1220 kInvalidSharedMemoryOffset,
1221 result_shm_id,
1222 result_shm_offset,
1223 false);
1224 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1225 cmd.Init(0,
1226 0,
1227 1,
1228 1,
1229 GL_RGB,
1230 GL_UNSIGNED_BYTE,
1231 pixels_shm_id,
1232 pixels_shm_offset,
1233 kInvalidSharedMemoryId,
1234 result_shm_offset,
1235 false);
1236 result->success = 0;
1237 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1238 cmd.Init(0,
1239 0,
1240 1,
1241 1,
1242 GL_RGB,
1243 GL_UNSIGNED_BYTE,
1244 pixels_shm_id,
1245 pixels_shm_offset,
1246 result_shm_id,
1247 kInvalidSharedMemoryOffset,
1248 false);
1249 result->success = 0;
1250 EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1251 }
1252
TEST_P(GLES2DecoderManualInitTest,ReadPixelsAsyncError)1253 TEST_P(GLES2DecoderManualInitTest, ReadPixelsAsyncError) {
1254 InitState init;
1255 init.extensions = "GL_ARB_sync";
1256 init.gl_version = "OpenGL ES 3.0";
1257 init.has_alpha = true;
1258 init.request_alpha = true;
1259 init.bind_generates_resource = true;
1260 InitDecoder(init);
1261
1262 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
1263 const GLsizei kWidth = 4;
1264 const GLsizei kHeight = 4;
1265 uint32_t result_shm_id = shared_memory_id_;
1266 uint32_t result_shm_offset = kSharedMemoryOffset;
1267 uint32_t pixels_shm_id = shared_memory_id_;
1268 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1269
1270 EXPECT_CALL(*gl_, GetError())
1271 // first error check must pass to get to the test
1272 .WillOnce(Return(GL_NO_ERROR))
1273 // second check is after BufferData, simulate fail here
1274 .WillOnce(Return(GL_INVALID_OPERATION))
1275 // third error check is fall-through call to sync ReadPixels
1276 .WillOnce(Return(GL_NO_ERROR))
1277 .RetiresOnSaturation();
1278
1279 EXPECT_CALL(*gl_,
1280 ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
1281 .Times(1);
1282 EXPECT_CALL(*gl_, GenBuffersARB(1, _)).Times(1);
1283 EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)).Times(1);
1284 EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _)).Times(2);
1285 EXPECT_CALL(*gl_,
1286 BufferData(GL_PIXEL_PACK_BUFFER_ARB, _, nullptr, GL_STREAM_READ))
1287 .Times(1);
1288
1289 cmds::ReadPixels cmd;
1290 cmd.Init(0,
1291 0,
1292 kWidth,
1293 kHeight,
1294 GL_RGBA,
1295 GL_UNSIGNED_BYTE,
1296 pixels_shm_id,
1297 pixels_shm_offset,
1298 result_shm_id,
1299 result_shm_offset,
1300 true);
1301 result->success = 0;
1302 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1303 }
1304
1305 class GLES2ReadPixelsAsyncTest : public GLES2DecoderManualInitTest {
1306 public:
SetUp()1307 void SetUp() override {
1308 InitState init;
1309 init.extensions = "GL_ARB_sync";
1310 init.gl_version = "OpenGL ES 3.0";
1311 init.has_alpha = true;
1312 init.request_alpha = true;
1313 init.bind_generates_resource = true;
1314 InitDecoder(init);
1315 }
1316
SetupReadPixelsAsyncExpectation(GLsizei width,GLsizei height)1317 void SetupReadPixelsAsyncExpectation(GLsizei width, GLsizei height) {
1318 const size_t kBufferSize = width * height * 4;
1319 EXPECT_CALL(*gl_, GetError())
1320 .WillRepeatedly(Return(GL_NO_ERROR))
1321 .RetiresOnSaturation();
1322
1323 EXPECT_CALL(*gl_,
1324 ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, _))
1325 .Times(1);
1326 EXPECT_CALL(*gl_, GenBuffersARB(1, _))
1327 .WillOnce(SetArgPointee<1>(kServiceBufferId))
1328 .RetiresOnSaturation();
1329 EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, kServiceBufferId))
1330 .Times(1);
1331 EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0)).Times(1);
1332 EXPECT_CALL(*gl_, BufferData(GL_PIXEL_PACK_BUFFER_ARB, kBufferSize, nullptr,
1333 GL_STREAM_READ))
1334 .Times(1);
1335 GLsync sync = reinterpret_cast<GLsync>(kServiceSyncId);
1336 EXPECT_CALL(*gl_, FenceSync(0x9117, 0)).WillOnce(Return(sync));
1337 EXPECT_CALL(*gl_, IsSync(sync)).WillRepeatedly(Return(GL_TRUE));
1338 EXPECT_CALL(*gl_, Flush()).Times(1);
1339 }
1340
FinishReadPixelsAndCheckResult(GLsizei width,GLsizei height,char * pixels)1341 void FinishReadPixelsAndCheckResult(GLsizei width,
1342 GLsizei height,
1343 char* pixels) {
1344 EXPECT_TRUE(decoder_->HasMoreIdleWork());
1345
1346 const size_t kBufferSize = width * height * 4;
1347 auto buffer = std::make_unique<char[]>(kBufferSize);
1348 for (size_t i = 0; i < kBufferSize; ++i)
1349 buffer[i] = i;
1350
1351 GLsync sync = reinterpret_cast<GLsync>(kServiceSyncId);
1352 EXPECT_CALL(*gl_, ClientWaitSync(sync, 0, 0))
1353 .WillOnce(Return(GL_CONDITION_SATISFIED));
1354 EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, kServiceBufferId))
1355 .Times(1);
1356 EXPECT_CALL(*gl_, MapBufferRange(GL_PIXEL_PACK_BUFFER_ARB, 0, kBufferSize,
1357 GL_MAP_READ_BIT))
1358 .WillOnce(Return(buffer.get()))
1359 .RetiresOnSaturation();
1360 EXPECT_CALL(*gl_, UnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB)).Times(1);
1361 EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0)).Times(1);
1362 EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)).Times(1);
1363 EXPECT_CALL(*gl_, DeleteSync(sync)).Times(1);
1364 decoder_->PerformIdleWork();
1365 EXPECT_FALSE(decoder_->HasMoreIdleWork());
1366 EXPECT_EQ(0, memcmp(pixels, buffer.get(), kBufferSize));
1367 }
1368 };
1369
TEST_P(GLES2ReadPixelsAsyncTest,ReadPixelsAsync)1370 TEST_P(GLES2ReadPixelsAsyncTest, ReadPixelsAsync) {
1371 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
1372 const GLsizei kWidth = 4;
1373 const GLsizei kHeight = 4;
1374 uint32_t result_shm_id = shared_memory_id_;
1375 uint32_t result_shm_offset = kSharedMemoryOffset;
1376 uint32_t pixels_shm_id = shared_memory_id_;
1377 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1378 char* pixels = reinterpret_cast<char*>(result + 1);
1379
1380 SetupReadPixelsAsyncExpectation(kWidth, kHeight);
1381
1382 cmds::ReadPixels cmd;
1383 cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id,
1384 pixels_shm_offset, result_shm_id, result_shm_offset, true);
1385 result->success = 0;
1386
1387 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1388 EXPECT_TRUE(decoder_->HasMoreIdleWork());
1389
1390 GLsync sync = reinterpret_cast<GLsync>(kServiceSyncId);
1391 EXPECT_CALL(*gl_, ClientWaitSync(sync, 0, 0))
1392 .WillOnce(Return(GL_TIMEOUT_EXPIRED));
1393 decoder_->PerformIdleWork();
1394
1395 FinishReadPixelsAndCheckResult(kWidth, kHeight, pixels);
1396 }
1397
TEST_P(GLES2ReadPixelsAsyncTest,ReadPixelsAsyncModifyCommand)1398 TEST_P(GLES2ReadPixelsAsyncTest, ReadPixelsAsyncModifyCommand) {
1399 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
1400 const GLsizei kWidth = 4;
1401 const GLsizei kHeight = 4;
1402 uint32_t result_shm_id = shared_memory_id_;
1403 uint32_t result_shm_offset = kSharedMemoryOffset;
1404 uint32_t pixels_shm_id = shared_memory_id_;
1405 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1406 char* pixels = reinterpret_cast<char*>(result + 1);
1407
1408 SetupReadPixelsAsyncExpectation(kWidth, kHeight);
1409
1410 cmds::ReadPixels cmd;
1411 cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id,
1412 pixels_shm_offset, result_shm_id, result_shm_offset, true);
1413 result->success = 0;
1414
1415 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1416 EXPECT_TRUE(decoder_->HasMoreIdleWork());
1417
1418 // Change command after ReadPixels issued, but before we finish the read,
1419 // should have no impact.
1420 cmd.Init(1, 2, 6, 7, GL_RGB, GL_UNSIGNED_SHORT, pixels_shm_id,
1421 pixels_shm_offset, result_shm_id, result_shm_offset, false);
1422
1423 FinishReadPixelsAndCheckResult(kWidth, kHeight, pixels);
1424 }
1425
TEST_P(GLES2ReadPixelsAsyncTest,ReadPixelsAsyncChangePackAlignment)1426 TEST_P(GLES2ReadPixelsAsyncTest, ReadPixelsAsyncChangePackAlignment) {
1427 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
1428 const GLsizei kWidth = 1;
1429 const GLsizei kHeight = 4;
1430 uint32_t result_shm_id = shared_memory_id_;
1431 uint32_t result_shm_offset = kSharedMemoryOffset;
1432 uint32_t pixels_shm_id = shared_memory_id_;
1433 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1434 char* pixels = reinterpret_cast<char*>(result + 1);
1435
1436 SetupReadPixelsAsyncExpectation(kWidth, kHeight);
1437
1438 {
1439 cmds::ReadPixels cmd;
1440 cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels_shm_id,
1441 pixels_shm_offset, result_shm_id, result_shm_offset, true);
1442 result->success = 0;
1443
1444 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1445 }
1446 EXPECT_TRUE(decoder_->HasMoreIdleWork());
1447
1448 // Changing the pack alignment after the ReadPixels is issued but before we
1449 // finish the read should have no impact.
1450 {
1451 cmds::PixelStorei cmd;
1452 cmd.Init(GL_PACK_ALIGNMENT, 8);
1453
1454 EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, 8)).Times(1);
1455 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1456 }
1457
1458 FinishReadPixelsAndCheckResult(kWidth, kHeight, pixels);
1459 }
1460
1461 INSTANTIATE_TEST_SUITE_P(Service, GLES2ReadPixelsAsyncTest, ::testing::Bool());
1462
1463 // Check that if a renderbuffer is attached and GL returns
1464 // GL_FRAMEBUFFER_COMPLETE that the buffer is cleared and state is restored.
TEST_P(GLES2DecoderTest,FramebufferRenderbufferClearColor)1465 TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearColor) {
1466 DoBindFramebuffer(
1467 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1468 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
1469 kServiceRenderbufferId);
1470 cmds::ClearColor color_cmd;
1471 cmds::ColorMask color_mask_cmd;
1472 cmds::Enable enable_cmd;
1473 cmds::FramebufferRenderbuffer cmd;
1474 color_cmd.Init(0.1f, 0.2f, 0.3f, 0.4f);
1475 color_mask_cmd.Init(0, 1, 0, 1);
1476 enable_cmd.Init(GL_SCISSOR_TEST);
1477 cmd.Init(GL_FRAMEBUFFER,
1478 GL_COLOR_ATTACHMENT0,
1479 GL_RENDERBUFFER,
1480 client_renderbuffer_id_);
1481 InSequence sequence;
1482 EXPECT_CALL(*gl_, ClearColor(0.1f, 0.2f, 0.3f, 0.4f))
1483 .Times(1)
1484 .RetiresOnSaturation();
1485 SetupExpectationsForEnableDisable(GL_SCISSOR_TEST, true);
1486 EXPECT_CALL(*gl_, GetError())
1487 .WillOnce(Return(GL_NO_ERROR))
1488 .RetiresOnSaturation();
1489 EXPECT_CALL(*gl_,
1490 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1491 GL_COLOR_ATTACHMENT0,
1492 GL_RENDERBUFFER,
1493 kServiceRenderbufferId))
1494 .Times(1)
1495 .RetiresOnSaturation();
1496 EXPECT_CALL(*gl_, GetError())
1497 .WillOnce(Return(GL_NO_ERROR))
1498 .RetiresOnSaturation();
1499 EXPECT_EQ(error::kNoError, ExecuteCmd(color_cmd));
1500 EXPECT_EQ(error::kNoError, ExecuteCmd(color_mask_cmd));
1501 EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
1502 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1503 }
1504
TEST_P(GLES2DecoderTest,FramebufferRenderbufferClearDepth)1505 TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearDepth) {
1506 DoBindFramebuffer(
1507 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1508 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
1509 kServiceRenderbufferId);
1510 cmds::ClearDepthf depth_cmd;
1511 cmds::DepthMask depth_mask_cmd;
1512 cmds::FramebufferRenderbuffer cmd;
1513 depth_cmd.Init(0.5f);
1514 depth_mask_cmd.Init(false);
1515 cmd.Init(GL_FRAMEBUFFER,
1516 GL_DEPTH_ATTACHMENT,
1517 GL_RENDERBUFFER,
1518 client_renderbuffer_id_);
1519 InSequence sequence;
1520 EXPECT_CALL(*gl_, ClearDepth(0.5f)).Times(1).RetiresOnSaturation();
1521 EXPECT_CALL(*gl_, GetError())
1522 .WillOnce(Return(GL_NO_ERROR))
1523 .RetiresOnSaturation();
1524 EXPECT_CALL(*gl_,
1525 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1526 GL_DEPTH_ATTACHMENT,
1527 GL_RENDERBUFFER,
1528 kServiceRenderbufferId))
1529 .Times(1)
1530 .RetiresOnSaturation();
1531 EXPECT_CALL(*gl_, GetError())
1532 .WillOnce(Return(GL_NO_ERROR))
1533 .RetiresOnSaturation();
1534 EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
1535 EXPECT_EQ(error::kNoError, ExecuteCmd(depth_mask_cmd));
1536 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1537 }
1538
TEST_P(GLES2DecoderTest,FramebufferRenderbufferClearStencil)1539 TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearStencil) {
1540 DoBindFramebuffer(
1541 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1542 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
1543 kServiceRenderbufferId);
1544 cmds::ClearStencil stencil_cmd;
1545 cmds::StencilMaskSeparate stencil_mask_separate_cmd;
1546 cmds::FramebufferRenderbuffer cmd;
1547 stencil_cmd.Init(123);
1548 stencil_mask_separate_cmd.Init(GL_BACK, 0x1234u);
1549 cmd.Init(GL_FRAMEBUFFER,
1550 GL_STENCIL_ATTACHMENT,
1551 GL_RENDERBUFFER,
1552 client_renderbuffer_id_);
1553 InSequence sequence;
1554 EXPECT_CALL(*gl_, ClearStencil(123)).Times(1).RetiresOnSaturation();
1555 EXPECT_CALL(*gl_, GetError())
1556 .WillOnce(Return(GL_NO_ERROR))
1557 .RetiresOnSaturation();
1558 EXPECT_CALL(*gl_,
1559 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1560 GL_STENCIL_ATTACHMENT,
1561 GL_RENDERBUFFER,
1562 kServiceRenderbufferId))
1563 .Times(1)
1564 .RetiresOnSaturation();
1565 EXPECT_CALL(*gl_, GetError())
1566 .WillOnce(Return(GL_NO_ERROR))
1567 .RetiresOnSaturation();
1568 EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
1569 EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_mask_separate_cmd));
1570 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1571 }
1572
TEST_P(GLES3DecoderTest,FramebufferRenderbufferClearDepthStencil)1573 TEST_P(GLES3DecoderTest, FramebufferRenderbufferClearDepthStencil) {
1574 DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
1575 kServiceFramebufferId);
1576 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
1577 kServiceRenderbufferId);
1578 cmds::ClearDepthf depth_cmd;
1579 cmds::ClearStencil stencil_cmd;
1580 cmds::FramebufferRenderbuffer cmd;
1581 depth_cmd.Init(0.5f);
1582 stencil_cmd.Init(123);
1583 cmd.Init(
1584 GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1585 client_renderbuffer_id_);
1586 InSequence sequence;
1587 EXPECT_CALL(*gl_, ClearDepth(0.5f))
1588 .Times(1)
1589 .RetiresOnSaturation();
1590 EXPECT_CALL(*gl_, ClearStencil(123))
1591 .Times(1)
1592 .RetiresOnSaturation();
1593 EXPECT_CALL(*gl_, GetError())
1594 .WillOnce(Return(GL_NO_ERROR))
1595 .RetiresOnSaturation();
1596 EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
1597 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1598 kServiceRenderbufferId))
1599 .Times(1)
1600 .RetiresOnSaturation();
1601 EXPECT_CALL(*gl_, GetError())
1602 .WillOnce(Return(GL_NO_ERROR))
1603 .RetiresOnSaturation();
1604 EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
1605 GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1606 kServiceRenderbufferId))
1607 .Times(1)
1608 .RetiresOnSaturation();
1609 EXPECT_CALL(*gl_, GetError())
1610 .WillOnce(Return(GL_NO_ERROR))
1611 .RetiresOnSaturation();
1612 EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
1613 EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
1614 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1615 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
1616 ASSERT_TRUE(framebuffer);
1617 ASSERT_FALSE(framebuffer->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
1618 ASSERT_TRUE(framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT));
1619 ASSERT_TRUE(framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT));
1620 }
1621
TEST_P(GLES2DecoderManualInitTest,ActualAlphaMatchesRequestedAlpha)1622 TEST_P(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) {
1623 InitState init;
1624 init.has_alpha = true;
1625 init.request_alpha = true;
1626 init.bind_generates_resource = true;
1627 InitDecoder(init);
1628
1629 EXPECT_CALL(*gl_, GetError())
1630 .WillOnce(Return(GL_NO_ERROR))
1631 .WillOnce(Return(GL_NO_ERROR))
1632 .RetiresOnSaturation();
1633 auto* result =
1634 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1635 result->size = 0;
1636 cmds::GetIntegerv cmd2;
1637 cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
1638 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1639 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
1640 result->GetNumResults());
1641 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1642 EXPECT_EQ(8, result->GetData()[0]);
1643 }
1644
TEST_P(GLES2DecoderManualInitTest,ActualAlphaDoesNotMatchRequestedAlpha)1645 TEST_P(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) {
1646 InitState init;
1647 init.has_alpha = true;
1648 init.bind_generates_resource = true;
1649 InitDecoder(init);
1650
1651 EXPECT_CALL(*gl_, GetError())
1652 .WillOnce(Return(GL_NO_ERROR))
1653 .WillOnce(Return(GL_NO_ERROR))
1654 .RetiresOnSaturation();
1655 auto* result =
1656 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1657 result->size = 0;
1658 cmds::GetIntegerv cmd2;
1659 cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
1660 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1661 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
1662 result->GetNumResults());
1663 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1664 EXPECT_EQ(0, result->GetData()[0]);
1665 }
1666
TEST_P(GLES2DecoderManualInitTest,ActualDepthMatchesRequestedDepth)1667 TEST_P(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) {
1668 InitState init;
1669 init.has_depth = true;
1670 init.request_depth = true;
1671 init.bind_generates_resource = true;
1672 InitDecoder(init);
1673
1674 EXPECT_CALL(*gl_, GetError())
1675 .WillOnce(Return(GL_NO_ERROR))
1676 .WillOnce(Return(GL_NO_ERROR))
1677 .RetiresOnSaturation();
1678 auto* result =
1679 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1680 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1681 .WillOnce(SetArgPointee<1>(24))
1682 .RetiresOnSaturation();
1683 result->size = 0;
1684 cmds::GetIntegerv cmd2;
1685 cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1686 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1687 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1688 result->GetNumResults());
1689 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1690 EXPECT_EQ(24, result->GetData()[0]);
1691 }
1692
TEST_P(GLES2DecoderManualInitTest,ActualDepthDoesNotMatchRequestedDepth)1693 TEST_P(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) {
1694 InitState init;
1695 init.has_depth = true;
1696 init.bind_generates_resource = true;
1697 InitDecoder(init);
1698
1699 EXPECT_CALL(*gl_, GetError())
1700 .WillOnce(Return(GL_NO_ERROR))
1701 .WillOnce(Return(GL_NO_ERROR))
1702 .RetiresOnSaturation();
1703 auto* result =
1704 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1705 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1706 .WillOnce(SetArgPointee<1>(24))
1707 .RetiresOnSaturation();
1708 result->size = 0;
1709 cmds::GetIntegerv cmd2;
1710 cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1711 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1712 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1713 result->GetNumResults());
1714 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1715 EXPECT_EQ(0, result->GetData()[0]);
1716 }
1717
TEST_P(GLES2DecoderManualInitTest,ActualStencilMatchesRequestedStencil)1718 TEST_P(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) {
1719 InitState init;
1720 init.has_stencil = true;
1721 init.request_stencil = true;
1722 init.bind_generates_resource = true;
1723 InitDecoder(init);
1724
1725 EXPECT_CALL(*gl_, GetError())
1726 .WillOnce(Return(GL_NO_ERROR))
1727 .WillOnce(Return(GL_NO_ERROR))
1728 .RetiresOnSaturation();
1729 auto* result =
1730 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1731 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1732 .WillOnce(SetArgPointee<1>(8))
1733 .RetiresOnSaturation();
1734 result->size = 0;
1735 cmds::GetIntegerv cmd2;
1736 cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1737 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1738 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1739 result->GetNumResults());
1740 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1741 EXPECT_EQ(8, result->GetData()[0]);
1742 }
1743
TEST_P(GLES2DecoderManualInitTest,ActualStencilDoesNotMatchRequestedStencil)1744 TEST_P(GLES2DecoderManualInitTest, ActualStencilDoesNotMatchRequestedStencil) {
1745 InitState init;
1746 init.has_stencil = true;
1747 init.bind_generates_resource = true;
1748 InitDecoder(init);
1749
1750 EXPECT_CALL(*gl_, GetError())
1751 .WillOnce(Return(GL_NO_ERROR))
1752 .WillOnce(Return(GL_NO_ERROR))
1753 .RetiresOnSaturation();
1754 auto* result =
1755 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1756 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1757 .WillOnce(SetArgPointee<1>(8))
1758 .RetiresOnSaturation();
1759 result->size = 0;
1760 cmds::GetIntegerv cmd2;
1761 cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1762 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1763 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1764 result->GetNumResults());
1765 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1766 EXPECT_EQ(0, result->GetData()[0]);
1767 }
1768
TEST_P(GLES2DecoderManualInitTest,PackedDepthStencilReportsCorrectValues)1769 TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilReportsCorrectValues) {
1770 InitState init;
1771 init.extensions = "GL_OES_packed_depth_stencil";
1772 init.gl_version = "OpenGL ES 2.0";
1773 init.has_depth = true;
1774 init.has_stencil = true;
1775 init.request_depth = true;
1776 init.request_stencil = true;
1777 init.bind_generates_resource = true;
1778 InitDecoder(init);
1779
1780 EXPECT_CALL(*gl_, GetError())
1781 .WillOnce(Return(GL_NO_ERROR))
1782 .WillOnce(Return(GL_NO_ERROR))
1783 .WillOnce(Return(GL_NO_ERROR))
1784 .WillOnce(Return(GL_NO_ERROR))
1785 .RetiresOnSaturation();
1786 auto* result =
1787 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1788 result->size = 0;
1789 cmds::GetIntegerv cmd2;
1790 cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1791 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1792 .WillOnce(SetArgPointee<1>(8))
1793 .RetiresOnSaturation();
1794 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1795 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1796 result->GetNumResults());
1797 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1798 EXPECT_EQ(8, result->GetData()[0]);
1799 result->size = 0;
1800 cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1801 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1802 .WillOnce(SetArgPointee<1>(24))
1803 .RetiresOnSaturation();
1804 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1805 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1806 result->GetNumResults());
1807 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1808 EXPECT_EQ(24, result->GetData()[0]);
1809 }
1810
TEST_P(GLES2DecoderManualInitTest,PackedDepthStencilNoRequestedStencil)1811 TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilNoRequestedStencil) {
1812 InitState init;
1813 init.extensions = "GL_OES_packed_depth_stencil";
1814 init.gl_version = "OpenGL ES 2.0";
1815 init.has_depth = true;
1816 init.has_stencil = true;
1817 init.request_depth = true;
1818 init.bind_generates_resource = true;
1819 InitDecoder(init);
1820
1821 EXPECT_CALL(*gl_, GetError())
1822 .WillOnce(Return(GL_NO_ERROR))
1823 .WillOnce(Return(GL_NO_ERROR))
1824 .WillOnce(Return(GL_NO_ERROR))
1825 .WillOnce(Return(GL_NO_ERROR))
1826 .RetiresOnSaturation();
1827 auto* result =
1828 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1829 result->size = 0;
1830 cmds::GetIntegerv cmd2;
1831 cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1832 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1833 .WillOnce(SetArgPointee<1>(8))
1834 .RetiresOnSaturation();
1835 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1836 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1837 result->GetNumResults());
1838 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1839 EXPECT_EQ(0, result->GetData()[0]);
1840 result->size = 0;
1841 cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1842 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1843 .WillOnce(SetArgPointee<1>(24))
1844 .RetiresOnSaturation();
1845 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1846 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1847 result->GetNumResults());
1848 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1849 EXPECT_EQ(24, result->GetData()[0]);
1850 }
1851
TEST_P(GLES2DecoderManualInitTest,PackedDepthStencilRenderbufferDepth)1852 TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferDepth) {
1853 InitState init;
1854 init.extensions = "GL_OES_packed_depth_stencil";
1855 init.gl_version = "OpenGL ES 2.0";
1856 init.bind_generates_resource = true;
1857 InitDecoder(init);
1858 DoBindRenderbuffer(
1859 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1860 DoBindFramebuffer(
1861 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1862
1863 EnsureRenderbufferBound(false);
1864 EXPECT_CALL(*gl_, GetError())
1865 .WillOnce(Return(GL_NO_ERROR)) // for RenderbufferStoage
1866 .WillOnce(Return(GL_NO_ERROR))
1867 .WillOnce(Return(GL_NO_ERROR)) // for FramebufferRenderbuffer
1868 .WillOnce(Return(GL_NO_ERROR))
1869 .WillOnce(Return(GL_NO_ERROR)) // for GetIntegerv
1870 .WillOnce(Return(GL_NO_ERROR))
1871 .WillOnce(Return(GL_NO_ERROR)) // for GetIntegerv
1872 .WillOnce(Return(GL_NO_ERROR))
1873 .RetiresOnSaturation();
1874
1875 EXPECT_CALL(
1876 *gl_,
1877 RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
1878 .Times(1)
1879 .RetiresOnSaturation();
1880 cmds::RenderbufferStorage cmd;
1881 cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
1882 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1883 EXPECT_CALL(*gl_,
1884 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1885 GL_DEPTH_ATTACHMENT,
1886 GL_RENDERBUFFER,
1887 kServiceRenderbufferId))
1888 .Times(1)
1889 .RetiresOnSaturation();
1890 cmds::FramebufferRenderbuffer fbrb_cmd;
1891 fbrb_cmd.Init(GL_FRAMEBUFFER,
1892 GL_DEPTH_ATTACHMENT,
1893 GL_RENDERBUFFER,
1894 client_renderbuffer_id_);
1895 EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
1896
1897 auto* result =
1898 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1899 result->size = 0;
1900 cmds::GetIntegerv cmd2;
1901 cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1902 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1903 .WillOnce(SetArgPointee<1>(8))
1904 .RetiresOnSaturation();
1905 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1906 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1907 result->GetNumResults());
1908 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1909 EXPECT_EQ(0, result->GetData()[0]);
1910 result->size = 0;
1911 cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1912 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1913 .WillOnce(SetArgPointee<1>(24))
1914 .RetiresOnSaturation();
1915 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1916 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1917 result->GetNumResults());
1918 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1919 EXPECT_EQ(24, result->GetData()[0]);
1920 }
1921
TEST_P(GLES2DecoderManualInitTest,PackedDepthStencilRenderbufferStencil)1922 TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferStencil) {
1923 InitState init;
1924 init.extensions = "GL_OES_packed_depth_stencil";
1925 init.gl_version = "OpenGL ES 2.0";
1926 init.bind_generates_resource = true;
1927 InitDecoder(init);
1928 DoBindRenderbuffer(
1929 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1930 DoBindFramebuffer(
1931 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1932
1933 EnsureRenderbufferBound(false);
1934 EXPECT_CALL(*gl_, GetError())
1935 .WillOnce(Return(GL_NO_ERROR)) // for RenderbufferStoage
1936 .WillOnce(Return(GL_NO_ERROR))
1937 .WillOnce(Return(GL_NO_ERROR)) // for FramebufferRenderbuffer
1938 .WillOnce(Return(GL_NO_ERROR))
1939 .WillOnce(Return(GL_NO_ERROR)) // for GetIntegerv
1940 .WillOnce(Return(GL_NO_ERROR))
1941 .WillOnce(Return(GL_NO_ERROR)) // for GetIntegerv
1942 .WillOnce(Return(GL_NO_ERROR))
1943 .RetiresOnSaturation();
1944
1945 EXPECT_CALL(
1946 *gl_,
1947 RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
1948 .Times(1)
1949 .RetiresOnSaturation();
1950 cmds::RenderbufferStorage cmd;
1951 cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
1952 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1953 EXPECT_CALL(*gl_,
1954 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1955 GL_STENCIL_ATTACHMENT,
1956 GL_RENDERBUFFER,
1957 kServiceRenderbufferId))
1958 .Times(1)
1959 .RetiresOnSaturation();
1960 cmds::FramebufferRenderbuffer fbrb_cmd;
1961 fbrb_cmd.Init(GL_FRAMEBUFFER,
1962 GL_STENCIL_ATTACHMENT,
1963 GL_RENDERBUFFER,
1964 client_renderbuffer_id_);
1965 EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
1966
1967 auto* result =
1968 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
1969 result->size = 0;
1970 cmds::GetIntegerv cmd2;
1971 cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1972 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1973 .WillOnce(SetArgPointee<1>(8))
1974 .RetiresOnSaturation();
1975 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1976 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1977 result->GetNumResults());
1978 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1979 EXPECT_EQ(8, result->GetData()[0]);
1980 result->size = 0;
1981 cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1982 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1983 .WillOnce(SetArgPointee<1>(24))
1984 .RetiresOnSaturation();
1985 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1986 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1987 result->GetNumResults());
1988 EXPECT_EQ(GL_NO_ERROR, GetGLError());
1989 EXPECT_EQ(0, result->GetData()[0]);
1990 }
1991
TEST_P(GLES2DecoderTest,FramebufferRenderbufferGLError)1992 TEST_P(GLES2DecoderTest, FramebufferRenderbufferGLError) {
1993 DoBindFramebuffer(
1994 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1995 cmds::FramebufferRenderbuffer cmd;
1996 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1997 client_renderbuffer_id_);
1998 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1999 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2000
2001 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
2002 kServiceRenderbufferId);
2003 EXPECT_CALL(*gl_, GetError())
2004 .WillOnce(Return(GL_NO_ERROR))
2005 .WillOnce(Return(GL_OUT_OF_MEMORY))
2006 .RetiresOnSaturation();
2007 EXPECT_CALL(*gl_,
2008 FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
2009 GL_COLOR_ATTACHMENT0,
2010 GL_RENDERBUFFER,
2011 kServiceRenderbufferId))
2012 .Times(1)
2013 .RetiresOnSaturation();
2014 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2015 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
2016 }
2017
TEST_P(GLES2DecoderTest,FramebufferTexture2DGLError)2018 TEST_P(GLES2DecoderTest, FramebufferTexture2DGLError) {
2019 const GLsizei kWidth = 5;
2020 const GLsizei kHeight = 3;
2021 const GLenum kFormat = GL_RGB;
2022 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2023 DoTexImage2D(GL_TEXTURE_2D,
2024 0,
2025 kFormat,
2026 kWidth,
2027 kHeight,
2028 0,
2029 kFormat,
2030 GL_UNSIGNED_BYTE,
2031 0,
2032 0);
2033 DoBindFramebuffer(
2034 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2035 EXPECT_CALL(*gl_, GetError())
2036 .WillOnce(Return(GL_NO_ERROR))
2037 .WillOnce(Return(GL_OUT_OF_MEMORY))
2038 .RetiresOnSaturation();
2039 EXPECT_CALL(*gl_,
2040 FramebufferTexture2DEXT(GL_FRAMEBUFFER,
2041 GL_COLOR_ATTACHMENT0,
2042 GL_TEXTURE_2D,
2043 kServiceTextureId,
2044 0))
2045 .Times(1)
2046 .RetiresOnSaturation();
2047 cmds::FramebufferTexture2D fbtex_cmd;
2048 fbtex_cmd.Init(GL_FRAMEBUFFER,
2049 GL_COLOR_ATTACHMENT0,
2050 GL_TEXTURE_2D,
2051 client_texture_id_,
2052 0);
2053 EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
2054 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
2055 }
2056
TEST_P(GLES2DecoderTest,RenderbufferStorageGLError)2057 TEST_P(GLES2DecoderTest, RenderbufferStorageGLError) {
2058 DoBindRenderbuffer(
2059 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2060 EnsureRenderbufferBound(false);
2061 EXPECT_CALL(*gl_, GetError())
2062 .WillOnce(Return(GL_NO_ERROR))
2063 .WillOnce(Return(GL_OUT_OF_MEMORY))
2064 .RetiresOnSaturation();
2065 EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 100, 50))
2066 .Times(1)
2067 .RetiresOnSaturation();
2068 cmds::RenderbufferStorage cmd;
2069 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 100, 50);
2070 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2071 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
2072 }
2073
TEST_P(GLES2DecoderTest,RenderbufferStorageBadArgs)2074 TEST_P(GLES2DecoderTest, RenderbufferStorageBadArgs) {
2075 DoBindRenderbuffer(
2076 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2077 EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
2078 .Times(0)
2079 .RetiresOnSaturation();
2080 cmds::RenderbufferStorage cmd;
2081 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
2082 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2083 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2084 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
2085 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2086 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2087 }
2088
TEST_P(GLES3DecoderTest,ClearBufferivImmediateValidArgs)2089 TEST_P(GLES3DecoderTest, ClearBufferivImmediateValidArgs) {
2090 DoBindFramebuffer(
2091 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2092 DoBindRenderbuffer(
2093 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2094 DoRenderbufferStorage(
2095 GL_RENDERBUFFER, GL_RGBA8I, GL_RGBA8I, 1, 1, GL_NO_ERROR);
2096 DoFramebufferRenderbuffer(
2097 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2098 client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
2099
2100 // TODO(zmo): Set up expectations for the path where the attachment isn't
2101 // marked as cleared.
2102 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
2103 framebuffer->MarkAttachmentAsCleared(
2104 group().renderbuffer_manager(), nullptr, GL_COLOR_ATTACHMENT0, true);
2105
2106 auto& cmd = *GetImmediateAs<cmds::ClearBufferivImmediate>();
2107 GLint temp[4] = { 0 };
2108 cmd.Init(GL_COLOR, 0, &temp[0]);
2109 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER))
2110 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2111 .RetiresOnSaturation();
2112 SetupExpectationsForApplyingDirtyState(
2113 false, false, false, 0x1111, false, false, 0, 0, false);
2114 EXPECT_CALL(*gl_, ClearBufferiv(GL_COLOR, 0, PointsToArray(temp, 4)));
2115 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
2116 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2117 }
2118
TEST_P(GLES3DecoderTest,ClearBufferuivImmediateValidArgs)2119 TEST_P(GLES3DecoderTest, ClearBufferuivImmediateValidArgs) {
2120 DoBindFramebuffer(
2121 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2122 DoBindRenderbuffer(
2123 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2124 DoRenderbufferStorage(
2125 GL_RENDERBUFFER, GL_RGBA8UI, GL_RGBA8UI, 1, 1, GL_NO_ERROR);
2126 DoFramebufferRenderbuffer(
2127 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2128 client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
2129
2130 // TODO(zmo): Set up expectations for the path where the attachment isn't
2131 // marked as cleared.
2132 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
2133 framebuffer->MarkAttachmentAsCleared(
2134 group().renderbuffer_manager(), nullptr, GL_COLOR_ATTACHMENT0, true);
2135
2136 auto& cmd = *GetImmediateAs<cmds::ClearBufferuivImmediate>();
2137 GLuint temp[4] = { 0u };
2138 cmd.Init(GL_COLOR, 0, &temp[0]);
2139 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER))
2140 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2141 .RetiresOnSaturation();
2142 SetupExpectationsForApplyingDirtyState(
2143 false, false, false, 0x1111, false, false, 0, 0, false);
2144 EXPECT_CALL(*gl_, ClearBufferuiv(GL_COLOR, 0, PointsToArray(temp, 4)));
2145 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
2146 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2147 }
2148
TEST_P(GLES3DecoderTest,ClearBufferfvImmediateValidArgs)2149 TEST_P(GLES3DecoderTest, ClearBufferfvImmediateValidArgs) {
2150 DoBindFramebuffer(
2151 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2152 DoBindRenderbuffer(
2153 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2154 DoRenderbufferStorage(
2155 GL_RENDERBUFFER, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F,
2156 1, 1, GL_NO_ERROR);
2157 DoFramebufferRenderbuffer(
2158 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
2159 client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
2160
2161 // TODO(zmo): Set up expectations for the path where the attachment isn't
2162 // marked as cleared.
2163 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
2164 framebuffer->MarkAttachmentAsCleared(
2165 group().renderbuffer_manager(), nullptr, GL_DEPTH_ATTACHMENT, true);
2166
2167 cmds::Enable cmd_enable;
2168 cmd_enable.Init(GL_DEPTH_TEST);
2169 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd_enable));
2170 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2171
2172 auto& cmd = *GetImmediateAs<cmds::ClearBufferfvImmediate>();
2173 GLfloat temp[4] = { 1.0f };
2174 cmd.Init(GL_DEPTH, 0, &temp[0]);
2175 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER))
2176 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2177 .RetiresOnSaturation();
2178 SetupExpectationsForApplyingDirtyState(
2179 true, true, false, 0x1110, true, true, 0, 0, false);
2180 EXPECT_CALL(*gl_, ClearBufferfv(GL_DEPTH, 0, PointsToArray(temp, 4)));
2181 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
2182 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2183 }
2184
TEST_P(GLES3DecoderTest,ClearBufferfiValidArgs)2185 TEST_P(GLES3DecoderTest, ClearBufferfiValidArgs) {
2186 DoBindFramebuffer(
2187 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2188 DoBindRenderbuffer(
2189 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2190 DoRenderbufferStorage(
2191 GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8,
2192 1, 1, GL_NO_ERROR);
2193 DoFramebufferRenderbuffer(
2194 GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2195 client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
2196
2197 // TODO(zmo): Set up expectations for the path where the attachment isn't
2198 // marked as cleared.
2199 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
2200 framebuffer->MarkAttachmentAsCleared(group().renderbuffer_manager(), nullptr,
2201 GL_DEPTH_ATTACHMENT, true);
2202 framebuffer->MarkAttachmentAsCleared(group().renderbuffer_manager(), nullptr,
2203 GL_STENCIL_ATTACHMENT, true);
2204
2205 cmds::Enable cmd_enable;
2206 cmd_enable.Init(GL_STENCIL_TEST);
2207 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd_enable));
2208 cmd_enable.Init(GL_DEPTH_TEST);
2209 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd_enable));
2210 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2211
2212 cmds::ClearBufferfi cmd;
2213 cmd.Init(GL_DEPTH_STENCIL, 0, 1.0f, 0);
2214 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER))
2215 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2216 .RetiresOnSaturation();
2217 SetupExpectationsForApplyingDirtyState(
2218 true, true, true, 0x1110, true, true,
2219 GLES2Decoder::kDefaultStencilMask, GLES2Decoder::kDefaultStencilMask,
2220 true);
2221 EXPECT_CALL(*gl_, ClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0));
2222 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2223 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2224 }
2225
TEST_P(GLES2DecoderManualInitTest,RenderbufferStorageMultisampleCHROMIUMGLError)2226 TEST_P(GLES2DecoderManualInitTest,
2227 RenderbufferStorageMultisampleCHROMIUMGLError) {
2228 InitState init;
2229 init.extensions = "GL_ARB_framebuffer_object";
2230 init.bind_generates_resource = true;
2231 InitDecoder(init);
2232 DoBindRenderbuffer(
2233 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2234 EnsureRenderbufferBound(false);
2235 EXPECT_CALL(*gl_, GetError())
2236 .WillOnce(Return(GL_NO_ERROR))
2237 .WillOnce(Return(GL_OUT_OF_MEMORY))
2238 .RetiresOnSaturation();
2239 EXPECT_CALL(*gl_, RenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA,
2240 100, 50))
2241 .Times(1)
2242 .RetiresOnSaturation();
2243 cmds::RenderbufferStorageMultisampleCHROMIUM cmd;
2244 cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50);
2245 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2246 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
2247 }
2248
TEST_P(GLES2DecoderManualInitTest,RenderbufferStorageMultisampleCHROMIUMBadArgs)2249 TEST_P(GLES2DecoderManualInitTest,
2250 RenderbufferStorageMultisampleCHROMIUMBadArgs) {
2251 InitState init;
2252 init.extensions = "GL_ARB_framebuffer_object";
2253 init.bind_generates_resource = true;
2254 InitDecoder(init);
2255 DoBindRenderbuffer(
2256 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2257 EXPECT_CALL(*gl_, RenderbufferStorageMultisample(_, _, _, _, _))
2258 .Times(0)
2259 .RetiresOnSaturation();
2260 cmds::RenderbufferStorageMultisampleCHROMIUM cmd;
2261 cmd.Init(GL_RENDERBUFFER,
2262 TestHelper::kMaxSamples + 1,
2263 GL_RGBA4,
2264 TestHelper::kMaxRenderbufferSize,
2265 1);
2266 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2267 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2268 cmd.Init(GL_RENDERBUFFER,
2269 TestHelper::kMaxSamples,
2270 GL_RGBA4,
2271 TestHelper::kMaxRenderbufferSize + 1,
2272 1);
2273 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2274 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2275 cmd.Init(GL_RENDERBUFFER,
2276 TestHelper::kMaxSamples,
2277 GL_RGBA4,
2278 1,
2279 TestHelper::kMaxRenderbufferSize + 1);
2280 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2281 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2282 }
2283
TEST_P(GLES2DecoderManualInitTest,RenderbufferStorageMultisampleCHROMIUM)2284 TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUM) {
2285 InitState init;
2286 init.extensions = "GL_ARB_framebuffer_object";
2287 InitDecoder(init);
2288 DoBindRenderbuffer(
2289 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2290 InSequence sequence;
2291 DoRenderbufferStorageMultisampleCHROMIUM(
2292 GL_RENDERBUFFER, TestHelper::kMaxSamples, GL_RGBA4, GL_RGBA,
2293 TestHelper::kMaxRenderbufferSize, 1, false);
2294 }
2295
TEST_P(GLES2DecoderManualInitTest,RenderbufferStorageMultisampleCHROMIUMRebindRenderbuffer)2296 TEST_P(GLES2DecoderManualInitTest,
2297 RenderbufferStorageMultisampleCHROMIUMRebindRenderbuffer) {
2298 InitState init;
2299 init.extensions = "GL_ARB_framebuffer_object";
2300 InitDecoder(init);
2301 DoBindRenderbuffer(
2302 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2303 RestoreRenderbufferBindings();
2304 InSequence sequence;
2305 DoRenderbufferStorageMultisampleCHROMIUM(
2306 GL_RENDERBUFFER, TestHelper::kMaxSamples, GL_RGBA4, GL_RGBA,
2307 TestHelper::kMaxRenderbufferSize, 1, true);
2308 }
2309
TEST_P(GLES2DecoderManualInitTest,RenderbufferStorageMultisampleEXTNotSupported)2310 TEST_P(GLES2DecoderManualInitTest,
2311 RenderbufferStorageMultisampleEXTNotSupported) {
2312 InitState init;
2313 init.extensions = "GL_ARB_framebuffer_object";
2314 init.bind_generates_resource = true;
2315 InitDecoder(init);
2316 DoBindRenderbuffer(
2317 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2318 InSequence sequence;
2319 // GL_CHROMIUM_framebuffer_multisample uses
2320 // RenderbufferStorageMultisampleCHROMIUM.
2321 cmds::RenderbufferStorageMultisampleEXT cmd;
2322 cmd.Init(GL_RENDERBUFFER,
2323 TestHelper::kMaxSamples,
2324 GL_RGBA4,
2325 TestHelper::kMaxRenderbufferSize,
2326 1);
2327 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
2328 }
2329
2330 class GLES2DecoderMultisampledRenderToTextureTest
2331 : public GLES2DecoderTestWithExtensionsOnGLES2 {
2332 public:
TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM()2333 void TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM() {
2334 DoBindRenderbuffer(
2335 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2336 cmds::RenderbufferStorageMultisampleCHROMIUM cmd;
2337 cmd.Init(GL_RENDERBUFFER,
2338 TestHelper::kMaxSamples,
2339 GL_RGBA4,
2340 TestHelper::kMaxRenderbufferSize,
2341 1);
2342 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
2343 }
2344
TestRenderbufferStorageMultisampleEXT(const char * extension,bool rb_rebind)2345 void TestRenderbufferStorageMultisampleEXT(const char* extension,
2346 bool rb_rebind) {
2347 DoBindRenderbuffer(
2348 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2349 InSequence sequence;
2350
2351 EXPECT_CALL(*gl_, GetError())
2352 .WillOnce(Return(GL_NO_ERROR))
2353 .RetiresOnSaturation();
2354 if (rb_rebind) {
2355 RestoreRenderbufferBindings();
2356 EnsureRenderbufferBound(true);
2357 } else {
2358 EnsureRenderbufferBound(false);
2359 }
2360 EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(
2361 GL_RENDERBUFFER, TestHelper::kMaxSamples, GL_RGBA4,
2362 TestHelper::kMaxRenderbufferSize, 1))
2363 .Times(1)
2364 .RetiresOnSaturation();
2365 EXPECT_CALL(*gl_, GetError())
2366 .WillOnce(Return(GL_NO_ERROR))
2367 .RetiresOnSaturation();
2368 cmds::RenderbufferStorageMultisampleEXT cmd;
2369 cmd.Init(GL_RENDERBUFFER,
2370 TestHelper::kMaxSamples,
2371 GL_RGBA4,
2372 TestHelper::kMaxRenderbufferSize,
2373 1);
2374 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2375 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2376 }
2377 };
2378
2379 INSTANTIATE_TEST_SUITE_P(Service,
2380 GLES2DecoderMultisampledRenderToTextureTest,
2381 ::testing::Bool());
2382
TEST_P(GLES2DecoderMultisampledRenderToTextureTest,NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_EXT)2383 TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
2384 NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_EXT) {
2385 Init("GL_EXT_multisampled_render_to_texture");
2386 TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM();
2387 }
2388
TEST_P(GLES2DecoderMultisampledRenderToTextureTest,NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_IMG)2389 TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
2390 NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_IMG) {
2391 Init("GL_IMG_multisampled_render_to_texture");
2392 TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM();
2393 }
2394
TEST_P(GLES2DecoderMultisampledRenderToTextureTest,RenderbufferStorageMultisampleEXT_EXT)2395 TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
2396 RenderbufferStorageMultisampleEXT_EXT) {
2397 Init("GL_EXT_multisampled_render_to_texture");
2398 TestRenderbufferStorageMultisampleEXT("GL_EXT_multisampled_render_to_texture",
2399 false);
2400 }
2401
TEST_P(GLES2DecoderMultisampledRenderToTextureTest,RenderbufferStorageMultisampleEXT_IMG)2402 TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
2403 RenderbufferStorageMultisampleEXT_IMG) {
2404 Init("GL_IMG_multisampled_render_to_texture");
2405 TestRenderbufferStorageMultisampleEXT("GL_IMG_multisampled_render_to_texture",
2406 false);
2407 }
2408
TEST_P(GLES2DecoderMultisampledRenderToTextureTest,RenderbufferStorageMultisampleEXT_EXT_RebindRenderbuffer)2409 TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
2410 RenderbufferStorageMultisampleEXT_EXT_RebindRenderbuffer) {
2411 Init("GL_EXT_multisampled_render_to_texture");
2412 TestRenderbufferStorageMultisampleEXT("GL_EXT_multisampled_render_to_texture",
2413 true);
2414 }
2415
TEST_P(GLES2DecoderMultisampledRenderToTextureTest,RenderbufferStorageMultisampleEXT_IMG_RebindRenderbuffer)2416 TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
2417 RenderbufferStorageMultisampleEXT_IMG_RebindRenderbuffer) {
2418 Init("GL_IMG_multisampled_render_to_texture");
2419 TestRenderbufferStorageMultisampleEXT("GL_IMG_multisampled_render_to_texture",
2420 true);
2421 }
2422
TEST_P(GLES2DecoderTest,ReadPixelsGLError)2423 TEST_P(GLES2DecoderTest, ReadPixelsGLError) {
2424 GLenum kFormat = GL_RGBA;
2425 GLint x = 0;
2426 GLint y = 0;
2427 GLsizei width = 2;
2428 GLsizei height = 4;
2429 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
2430 uint32_t result_shm_id = shared_memory_id_;
2431 uint32_t result_shm_offset = kSharedMemoryOffset;
2432 uint32_t pixels_shm_id = shared_memory_id_;
2433 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2434 EXPECT_CALL(*gl_, GetError())
2435 .WillOnce(Return(GL_NO_ERROR))
2436 .WillOnce(Return(GL_OUT_OF_MEMORY))
2437 .RetiresOnSaturation();
2438 EXPECT_CALL(*gl_,
2439 ReadPixels(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, _))
2440 .Times(1)
2441 .RetiresOnSaturation();
2442 cmds::ReadPixels cmd;
2443 cmd.Init(x,
2444 y,
2445 width,
2446 height,
2447 kFormat,
2448 GL_UNSIGNED_BYTE,
2449 pixels_shm_id,
2450 pixels_shm_offset,
2451 result_shm_id,
2452 result_shm_offset,
2453 false);
2454 result->success = 0;
2455 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2456 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
2457 }
2458
TEST_P(GLES2DecoderWithShaderTest,UnClearedAttachmentsGetClearedOnClear)2459 TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) {
2460 const GLuint kFBOClientTextureId = 4100;
2461 const GLuint kFBOServiceTextureId = 4101;
2462
2463 // Register a texture id.
2464 EXPECT_CALL(*gl_, GenTextures(_, _))
2465 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2466 .RetiresOnSaturation();
2467 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2468
2469 // Setup "render to" texture.
2470 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2471 DoTexImage2D(
2472 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
2473 DoBindFramebuffer(
2474 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2475 DoFramebufferTexture2D(GL_FRAMEBUFFER,
2476 GL_COLOR_ATTACHMENT0,
2477 GL_TEXTURE_2D,
2478 kFBOClientTextureId,
2479 kFBOServiceTextureId,
2480 0,
2481 GL_NO_ERROR);
2482 // Set scissor rect and enable GL_SCISSOR_TEST to make sure we re-enable it
2483 // and restore the rect again after the clear.
2484 DoEnableDisable(GL_SCISSOR_TEST, true);
2485 DoScissor(0, 0, 64, 64);
2486
2487 // Setup "render from" texture.
2488 SetupTexture();
2489
2490 SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER, // target
2491 GL_COLOR_BUFFER_BIT, // clear bits
2492 0, 0, 0,
2493 0, // color
2494 0, // stencil
2495 1.0f, // depth
2496 true, // scissor test
2497 0, 0, 64, 64);
2498 SetupExpectationsForApplyingDirtyState(false, // Framebuffer is RGB
2499 false, // Framebuffer has depth
2500 false, // Framebuffer has stencil
2501 0x1111, // color bits
2502 false, // depth mask
2503 false, // depth enabled
2504 0, // front stencil mask
2505 0, // back stencil mask
2506 false); // stencil enabled
2507
2508 EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)).Times(1).RetiresOnSaturation();
2509
2510 cmds::Clear cmd;
2511 cmd.Init(GL_COLOR_BUFFER_BIT);
2512 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2513 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2514 }
2515
TEST_P(GLES2DecoderWithShaderTest,UnClearedAttachmentsGetClearedOnReadPixels)2516 TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) {
2517 const GLuint kFBOClientTextureId = 4100;
2518 const GLuint kFBOServiceTextureId = 4101;
2519
2520 // Register a texture id.
2521 EXPECT_CALL(*gl_, GenTextures(_, _))
2522 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2523 .RetiresOnSaturation();
2524 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2525
2526 // Setup "render to" texture.
2527 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2528 DoTexImage2D(
2529 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
2530 DoBindFramebuffer(
2531 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2532 DoFramebufferTexture2D(GL_FRAMEBUFFER,
2533 GL_COLOR_ATTACHMENT0,
2534 GL_TEXTURE_2D,
2535 kFBOClientTextureId,
2536 kFBOServiceTextureId,
2537 0,
2538 GL_NO_ERROR);
2539 DoEnableDisable(GL_SCISSOR_TEST, false);
2540 DoScissor(0, 0, 1, 1);
2541
2542 // Setup "render from" texture.
2543 SetupTexture();
2544
2545 SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER, // target
2546 GL_COLOR_BUFFER_BIT, // clear bits
2547 0, 0, 0,
2548 0, // color
2549 0, // stencil
2550 1.0f, // depth
2551 false, // scissor test
2552 0, 0, 1, 1);
2553
2554 EXPECT_CALL(*gl_, GetError())
2555 .WillOnce(Return(GL_NO_ERROR))
2556 .WillOnce(Return(GL_NO_ERROR))
2557 .RetiresOnSaturation();
2558 EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
2559 .Times(1)
2560 .RetiresOnSaturation();
2561 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
2562 uint32_t result_shm_id = shared_memory_id_;
2563 uint32_t result_shm_offset = kSharedMemoryOffset;
2564 uint32_t pixels_shm_id = shared_memory_id_;
2565 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2566 cmds::ReadPixels cmd;
2567 cmd.Init(0,
2568 0,
2569 1,
2570 1,
2571 GL_RGBA,
2572 GL_UNSIGNED_BYTE,
2573 pixels_shm_id,
2574 pixels_shm_offset,
2575 result_shm_id,
2576 result_shm_offset,
2577 false);
2578 result->success = 0;
2579 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2580 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2581 }
2582
TEST_P(GLES3DecoderTest,CopyTexImage2DValidInternalFormat)2583 TEST_P(GLES3DecoderTest, CopyTexImage2DValidInternalFormat) {
2584 const GLuint kFBOClientTextureId = 4100;
2585 const GLuint kFBOServiceTextureId = 4101;
2586
2587 GLenum target = GL_TEXTURE_2D;
2588 GLint level = 0;
2589 GLenum internal_format = GL_RG32I;
2590 GLenum format = GL_RG_INTEGER;
2591 GLenum type = GL_INT;
2592 GLsizei width = 16;
2593 GLsizei height = 8;
2594 GLint border = 0;
2595
2596 EXPECT_CALL(*gl_, GenTextures(_, _))
2597 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2598 .RetiresOnSaturation();
2599 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2600
2601 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2602 DoTexImage2D(GL_TEXTURE_2D, level, internal_format, width, height, 0, format,
2603 type, shared_memory_id_, kSharedMemoryOffset);
2604 DoBindFramebuffer(
2605 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2606 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2607 GL_COLOR_ATTACHMENT0,
2608 GL_TEXTURE_2D,
2609 kFBOClientTextureId,
2610 kFBOServiceTextureId,
2611 0,
2612 GL_NO_ERROR);
2613 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
2614 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2615 .RetiresOnSaturation();
2616
2617 EXPECT_CALL(*gl_,
2618 CopyTexImage2D(
2619 target, level, internal_format, 0, 0, width, height, border))
2620 .Times(1)
2621 .RetiresOnSaturation();
2622 EXPECT_CALL(*gl_, GetError())
2623 .WillOnce(Return(GL_NO_ERROR))
2624 .WillOnce(Return(GL_NO_ERROR))
2625 .RetiresOnSaturation();
2626
2627 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2628 cmds::CopyTexImage2D cmd;
2629 cmd.Init(target, level, internal_format, 0, 0, width, height);
2630 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2631 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2632 }
2633
TEST_P(GLES3DecoderManualInitTest,CopyTexImage2DValidInternalFormat_FloatEXT)2634 TEST_P(GLES3DecoderManualInitTest, CopyTexImage2DValidInternalFormat_FloatEXT) {
2635 InitState init;
2636 init.extensions = "GL_EXT_color_buffer_float";
2637 init.gl_version = "OpenGL ES 3.0";
2638 init.bind_generates_resource = true;
2639 init.context_type = CONTEXT_TYPE_OPENGLES3;
2640 InitDecoder(init);
2641
2642 const GLuint kFBOClientTextureId = 4100;
2643 const GLuint kFBOServiceTextureId = 4101;
2644
2645 GLenum target = GL_TEXTURE_2D;
2646 GLint level = 0;
2647 GLenum internal_format = GL_RG16F;
2648 GLenum format = GL_RGBA;
2649 GLenum type = GL_HALF_FLOAT;
2650 GLsizei width = 16;
2651 GLsizei height = 8;
2652 GLint border = 0;
2653
2654 EXPECT_CALL(*gl_, GenTextures(_, _))
2655 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2656 .RetiresOnSaturation();
2657 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2658
2659 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2660 DoTexImage2D(GL_TEXTURE_2D, level, GL_RGBA16F, width, height, 0, format, type,
2661 shared_memory_id_, kSharedMemoryOffset);
2662 DoBindFramebuffer(
2663 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2664 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2665 GL_COLOR_ATTACHMENT0,
2666 GL_TEXTURE_2D,
2667 kFBOClientTextureId,
2668 kFBOServiceTextureId,
2669 0,
2670 GL_NO_ERROR);
2671 EXPECT_CALL(*gl_,
2672 CopyTexImage2D(
2673 target, level, internal_format, 0, 0, width, height, border))
2674 .Times(1)
2675 .RetiresOnSaturation();
2676 EXPECT_CALL(*gl_, GetError())
2677 .WillOnce(Return(GL_NO_ERROR))
2678 .WillOnce(Return(GL_NO_ERROR))
2679 .RetiresOnSaturation();
2680 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
2681 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2682 .RetiresOnSaturation();
2683 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2684 cmds::CopyTexImage2D cmd;
2685 cmd.Init(target, level, internal_format, 0, 0, width, height);
2686 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2687 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2688 }
2689
TEST_P(GLES3DecoderManualInitTest,CopyTexImage2DInvalidInternalFormat_FloatEXT)2690 TEST_P(GLES3DecoderManualInitTest,
2691 CopyTexImage2DInvalidInternalFormat_FloatEXT) {
2692 InitState init;
2693 init.extensions = "GL_EXT_color_buffer_float";
2694 init.gl_version = "OpenGL ES 3.0";
2695 init.bind_generates_resource = true;
2696 init.context_type = CONTEXT_TYPE_OPENGLES3;
2697 InitDecoder(init);
2698
2699 const GLuint kFBOClientTextureId = 4100;
2700 const GLuint kFBOServiceTextureId = 4101;
2701
2702 GLenum target = GL_TEXTURE_2D;
2703 GLint level = 0;
2704 GLenum internal_format = GL_RG16F;
2705 GLenum format = GL_RGBA;
2706 GLenum type = GL_UNSIGNED_BYTE;
2707 GLsizei width = 16;
2708 GLsizei height = 8;
2709 GLint border = 0;
2710
2711 EXPECT_CALL(*gl_, GenTextures(_, _))
2712 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2713 .RetiresOnSaturation();
2714 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2715
2716 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2717 DoTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, width, height, 0, format, type,
2718 shared_memory_id_, kSharedMemoryOffset);
2719 DoBindFramebuffer(
2720 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2721 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2722 GL_COLOR_ATTACHMENT0,
2723 GL_TEXTURE_2D,
2724 kFBOClientTextureId,
2725 kFBOServiceTextureId,
2726 0,
2727 GL_NO_ERROR);
2728 EXPECT_CALL(*gl_,
2729 CopyTexImage2D(
2730 target, level, internal_format, 0, 0, width, height, border))
2731 .Times(0);
2732 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
2733 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2734 .RetiresOnSaturation();
2735 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2736 cmds::CopyTexImage2D cmd;
2737 cmd.Init(target, level, internal_format, 0, 0, width, height);
2738 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2739 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2740 }
2741
TEST_P(GLES3DecoderTest,CopyTexImage2DInvalidInternalFormat)2742 TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat) {
2743 const GLuint kFBOClientTextureId = 4100;
2744 const GLuint kFBOServiceTextureId = 4101;
2745
2746 GLenum target = GL_TEXTURE_2D;
2747 GLint level = 0;
2748 GLenum internal_format = GL_RG_INTEGER;
2749 GLenum format = GL_RG;
2750 GLenum type = GL_UNSIGNED_BYTE;
2751 GLsizei width = 16;
2752 GLsizei height = 8;
2753 GLint border = 0;
2754
2755 EXPECT_CALL(*gl_, GenTextures(_, _))
2756 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2757 .RetiresOnSaturation();
2758 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2759
2760 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2761 DoTexImage2D(GL_TEXTURE_2D, level, GL_RG8, width, height, 0, format, type,
2762 shared_memory_id_, kSharedMemoryOffset);
2763 DoBindFramebuffer(
2764 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2765 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2766 GL_COLOR_ATTACHMENT0,
2767 GL_TEXTURE_2D,
2768 kFBOClientTextureId,
2769 kFBOServiceTextureId,
2770 0,
2771 GL_NO_ERROR);
2772 EXPECT_CALL(*gl_,
2773 CopyTexImage2D(
2774 target, level, internal_format, 0, 0, width, height, border))
2775 .Times(0);
2776 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2777 cmds::CopyTexImage2D cmd;
2778 cmd.Init(target, level, internal_format, 0, 0, width, height);
2779 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2780 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
2781 }
2782
TEST_P(GLES3DecoderTest,CopyTexImage2DInvalidInternalFormat_Float)2783 TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat_Float) {
2784 const GLuint kFBOClientTextureId = 4100;
2785 const GLuint kFBOServiceTextureId = 4101;
2786
2787 GLenum target = GL_TEXTURE_2D;
2788 GLint level = 0;
2789 GLenum internal_format = GL_RG16F;
2790 GLenum format = GL_RGBA;
2791 GLenum type = GL_UNSIGNED_BYTE;
2792 GLsizei width = 16;
2793 GLsizei height = 8;
2794 GLint border = 0;
2795
2796 EXPECT_CALL(*gl_, GenTextures(_, _))
2797 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2798 .RetiresOnSaturation();
2799 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2800
2801 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2802 DoTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, width, height, 0, format, type,
2803 shared_memory_id_, kSharedMemoryOffset);
2804 DoBindFramebuffer(
2805 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2806 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2807 GL_COLOR_ATTACHMENT0,
2808 GL_TEXTURE_2D,
2809 kFBOClientTextureId,
2810 kFBOServiceTextureId,
2811 0,
2812 GL_NO_ERROR);
2813 EXPECT_CALL(*gl_,
2814 CopyTexImage2D(
2815 target, level, internal_format, 0, 0, width, height, border))
2816 .Times(0);
2817 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
2818 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2819 .RetiresOnSaturation();
2820 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2821 cmds::CopyTexImage2D cmd;
2822 cmd.Init(target, level, internal_format, 0, 0, width, height);
2823 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2824 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2825 }
2826
TEST_P(GLES3DecoderTest,CopyTexImage2DInvalidInternalFormat_Integer)2827 TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat_Integer) {
2828 const GLuint kFBOClientTextureId = 4100;
2829 const GLuint kFBOServiceTextureId = 4101;
2830
2831 GLenum target = GL_TEXTURE_2D;
2832 GLint level = 0;
2833 GLenum internal_format = GL_RG8I;
2834 GLenum format = GL_RG_INTEGER;
2835 GLenum type = GL_UNSIGNED_BYTE;
2836 GLsizei width = 16;
2837 GLsizei height = 8;
2838 GLint border = 0;
2839
2840 EXPECT_CALL(*gl_, GenTextures(_, _))
2841 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2842 .RetiresOnSaturation();
2843 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2844
2845 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2846 DoTexImage2D(GL_TEXTURE_2D, level, GL_RG8UI, width, height, 0, format, type,
2847 shared_memory_id_, kSharedMemoryOffset);
2848 DoBindFramebuffer(
2849 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2850 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2851 GL_COLOR_ATTACHMENT0,
2852 GL_TEXTURE_2D,
2853 kFBOClientTextureId,
2854 kFBOServiceTextureId,
2855 0,
2856 GL_NO_ERROR);
2857 EXPECT_CALL(*gl_,
2858 CopyTexImage2D(
2859 target, level, internal_format, 0, 0, width, height, border))
2860 .Times(0);
2861 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
2862 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2863 .RetiresOnSaturation();
2864 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2865 cmds::CopyTexImage2D cmd;
2866 cmd.Init(target, level, internal_format, 0, 0, width, height);
2867 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2868 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2869 }
2870
TEST_P(GLES3DecoderTest,CopyTexImage2DInvalidInternalFormat_sRGB)2871 TEST_P(GLES3DecoderTest, CopyTexImage2DInvalidInternalFormat_sRGB) {
2872 const GLuint kFBOClientTextureId = 4100;
2873 const GLuint kFBOServiceTextureId = 4101;
2874
2875 GLenum target = GL_TEXTURE_2D;
2876 GLint level = 0;
2877 GLenum internal_format = GL_SRGB8;
2878 GLenum format = GL_RGB;
2879 GLenum type = GL_UNSIGNED_BYTE;
2880 GLsizei width = 16;
2881 GLsizei height = 8;
2882 GLint border = 0;
2883
2884 EXPECT_CALL(*gl_, GenTextures(_, _))
2885 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2886 .RetiresOnSaturation();
2887 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2888
2889 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2890 DoTexImage2D(GL_TEXTURE_2D, level, GL_RGB, width, height, 0, format, type,
2891 shared_memory_id_, kSharedMemoryOffset);
2892 DoBindFramebuffer(
2893 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2894 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2895 GL_COLOR_ATTACHMENT0,
2896 GL_TEXTURE_2D,
2897 kFBOClientTextureId,
2898 kFBOServiceTextureId,
2899 0,
2900 GL_NO_ERROR);
2901 EXPECT_CALL(*gl_,
2902 CopyTexImage2D(
2903 target, level, internal_format, 0, 0, width, height, border))
2904 .Times(0);
2905 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
2906 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2907 .RetiresOnSaturation();
2908 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2909 cmds::CopyTexImage2D cmd;
2910 cmd.Init(target, level, internal_format, 0, 0, width, height);
2911 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2912 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2913 }
2914
TEST_P(GLES2DecoderManualInitTest,UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored)2915 TEST_P(GLES2DecoderManualInitTest,
2916 UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) {
2917 InitState init;
2918 init.extensions = "GL_ARB_framebuffer_object";
2919 init.bind_generates_resource = true;
2920 InitDecoder(init);
2921 const GLuint kFBOClientTextureId = 4100;
2922 const GLuint kFBOServiceTextureId = 4101;
2923
2924 // Register a texture id.
2925 EXPECT_CALL(*gl_, GenTextures(_, _))
2926 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
2927 .RetiresOnSaturation();
2928 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
2929
2930 // Setup "render from" texture.
2931 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2932 DoTexImage2D(
2933 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
2934 DoBindFramebuffer(
2935 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2936 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
2937 GL_COLOR_ATTACHMENT0,
2938 GL_TEXTURE_2D,
2939 kFBOClientTextureId,
2940 kFBOServiceTextureId,
2941 0,
2942 GL_NO_ERROR);
2943
2944 // Set scissor rect and disable GL_SCISSOR_TEST to make sure we enable it in
2945 // the clear, then disable it and restore the rect again.
2946 DoScissor(0, 0, 32, 32);
2947 DoEnableDisable(GL_SCISSOR_TEST, false);
2948
2949 SetupExpectationsForFramebufferClearingMulti(
2950 kServiceFramebufferId, // read framebuffer service id
2951 0, // backbuffer service id
2952 GL_READ_FRAMEBUFFER, // target
2953 GL_COLOR_BUFFER_BIT, // clear bits
2954 0, 0, 0,
2955 0, // color
2956 0, // stencil
2957 1.0f, // depth
2958 false, // scissor test
2959 0, 0, 32, 32);
2960
2961 EXPECT_CALL(*gl_, GetError())
2962 .WillOnce(Return(GL_NO_ERROR))
2963 .WillOnce(Return(GL_NO_ERROR))
2964 .RetiresOnSaturation();
2965 EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
2966 .Times(1)
2967 .RetiresOnSaturation();
2968 auto* result = GetSharedMemoryAs<cmds::ReadPixels::Result*>();
2969 uint32_t result_shm_id = shared_memory_id_;
2970 uint32_t result_shm_offset = kSharedMemoryOffset;
2971 uint32_t pixels_shm_id = shared_memory_id_;
2972 uint32_t pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2973 cmds::ReadPixels cmd;
2974 cmd.Init(0,
2975 0,
2976 1,
2977 1,
2978 GL_RGBA,
2979 GL_UNSIGNED_BYTE,
2980 pixels_shm_id,
2981 pixels_shm_offset,
2982 result_shm_id,
2983 result_shm_offset,
2984 false);
2985 result->success = 0;
2986 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2987 EXPECT_EQ(GL_NO_ERROR, GetGLError());
2988 }
2989
TEST_P(GLES2DecoderWithShaderTest,CopyTexImageWithInCompleteFBOFails)2990 TEST_P(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) {
2991 GLenum target = GL_TEXTURE_2D;
2992 GLint level = 0;
2993 GLenum internal_format = GL_RGBA;
2994 GLsizei width = 2;
2995 GLsizei height = 4;
2996 SetupTexture();
2997 DoBindRenderbuffer(
2998 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
2999 DoBindFramebuffer(
3000 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3001 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 0, 0, GL_NO_ERROR);
3002 DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
3003 GL_COLOR_ATTACHMENT0,
3004 GL_RENDERBUFFER,
3005 client_renderbuffer_id_,
3006 kServiceRenderbufferId,
3007 GL_NO_ERROR);
3008
3009 EXPECT_CALL(*gl_, CopyTexImage2D(_, _, _, _, _, _, _, _))
3010 .Times(0)
3011 .RetiresOnSaturation();
3012 cmds::CopyTexImage2D cmd;
3013 cmd.Init(target, level, internal_format, 0, 0, width, height);
3014 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3015 EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
3016 }
3017
CheckRenderbufferChangesMarkFBOAsNotComplete(bool bound_fbo)3018 void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete(
3019 bool bound_fbo) {
3020 FramebufferManager* framebuffer_manager = GetFramebufferManager();
3021 SetupTexture();
3022 DoBindRenderbuffer(
3023 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
3024 DoBindFramebuffer(
3025 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3026 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
3027 DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
3028 GL_COLOR_ATTACHMENT0,
3029 GL_RENDERBUFFER,
3030 client_renderbuffer_id_,
3031 kServiceRenderbufferId,
3032 GL_NO_ERROR);
3033
3034 if (!bound_fbo) {
3035 DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
3036 }
3037
3038 Framebuffer* framebuffer =
3039 framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
3040 ASSERT_TRUE(framebuffer != nullptr);
3041 framebuffer_manager->MarkAsComplete(framebuffer);
3042 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3043
3044 // Test that renderbufferStorage marks fbo as not complete.
3045 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
3046 EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
3047 framebuffer_manager->MarkAsComplete(framebuffer);
3048 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3049
3050 // Test deleting renderbuffer marks fbo as not complete.
3051 DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
3052 if (bound_fbo) {
3053 EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
3054 } else {
3055 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3056 }
3057 // Cleanup
3058 DoDeleteFramebuffer(client_framebuffer_id_,
3059 kServiceFramebufferId,
3060 bound_fbo,
3061 GL_FRAMEBUFFER,
3062 0,
3063 bound_fbo,
3064 GL_FRAMEBUFFER,
3065 0);
3066 }
3067
TEST_P(GLES2DecoderWithShaderTest,RenderbufferChangesMarkFBOAsNotCompleteBoundFBO)3068 TEST_P(GLES2DecoderWithShaderTest,
3069 RenderbufferChangesMarkFBOAsNotCompleteBoundFBO) {
3070 CheckRenderbufferChangesMarkFBOAsNotComplete(true);
3071 }
3072
TEST_P(GLES2DecoderWithShaderTest,RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO)3073 TEST_P(GLES2DecoderWithShaderTest,
3074 RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO) {
3075 CheckRenderbufferChangesMarkFBOAsNotComplete(false);
3076 }
3077
CheckTextureChangesMarkFBOAsNotComplete(bool bound_fbo)3078 void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete(
3079 bool bound_fbo) {
3080 FramebufferManager* framebuffer_manager = GetFramebufferManager();
3081 const GLuint kFBOClientTextureId = 4100;
3082 const GLuint kFBOServiceTextureId = 4101;
3083
3084 // Register a texture id.
3085 EXPECT_CALL(*gl_, GenTextures(_, _))
3086 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
3087 .RetiresOnSaturation();
3088 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
3089
3090 SetupTexture();
3091
3092 // Setup "render to" texture.
3093 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
3094 DoTexImage2D(
3095 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
3096 DoBindFramebuffer(
3097 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3098 DoFramebufferTexture2D(GL_FRAMEBUFFER,
3099 GL_COLOR_ATTACHMENT0,
3100 GL_TEXTURE_2D,
3101 kFBOClientTextureId,
3102 kFBOServiceTextureId,
3103 0,
3104 GL_NO_ERROR);
3105
3106 DoBindRenderbuffer(
3107 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
3108 DoBindFramebuffer(
3109 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3110 DoRenderbufferStorage(GL_RENDERBUFFER,
3111 GL_DEPTH_COMPONENT16,
3112 GL_DEPTH_COMPONENT,
3113 1,
3114 1,
3115 GL_NO_ERROR);
3116 DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
3117 GL_DEPTH_ATTACHMENT,
3118 GL_RENDERBUFFER,
3119 client_renderbuffer_id_,
3120 kServiceRenderbufferId,
3121 GL_NO_ERROR);
3122
3123 if (!bound_fbo) {
3124 DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
3125 }
3126
3127 Framebuffer* framebuffer =
3128 framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
3129 ASSERT_TRUE(framebuffer != nullptr);
3130 framebuffer_manager->MarkAsComplete(framebuffer);
3131 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3132
3133 // Test TexImage2D marks fbo as not complete.
3134 DoTexImage2D(
3135 GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
3136 EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
3137 framebuffer_manager->MarkAsComplete(framebuffer);
3138 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3139
3140 // Test CopyImage2D marks fbo as not complete.
3141 EXPECT_CALL(*gl_, GetError())
3142 .WillOnce(Return(GL_NO_ERROR))
3143 .RetiresOnSaturation();
3144 EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0))
3145 .Times(1)
3146 .RetiresOnSaturation();
3147 EXPECT_CALL(*gl_, GetError())
3148 .WillOnce(Return(GL_NO_ERROR))
3149 .RetiresOnSaturation();
3150 cmds::CopyTexImage2D cmd;
3151 cmd.Init(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1);
3152 // Unbind fbo and bind again after CopyTexImage2D tp avoid feedback loops.
3153 if (bound_fbo) {
3154 DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
3155 }
3156 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3157 if (bound_fbo) {
3158 DoBindFramebuffer(
3159 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3160 }
3161 EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
3162
3163 // Test deleting texture marks fbo as not complete.
3164 framebuffer_manager->MarkAsComplete(framebuffer);
3165 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3166 DoDeleteTexture(kFBOClientTextureId, kFBOServiceTextureId);
3167
3168 if (bound_fbo) {
3169 EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
3170 } else {
3171 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3172 }
3173 // Cleanup
3174 DoDeleteFramebuffer(client_framebuffer_id_,
3175 kServiceFramebufferId,
3176 bound_fbo,
3177 GL_FRAMEBUFFER,
3178 0,
3179 bound_fbo,
3180 GL_FRAMEBUFFER,
3181 0);
3182 }
3183
TEST_P(GLES2DecoderWithShaderTest,TextureChangesMarkFBOAsNotCompleteBoundFBO)3184 TEST_P(GLES2DecoderWithShaderTest, TextureChangesMarkFBOAsNotCompleteBoundFBO) {
3185 CheckTextureChangesMarkFBOAsNotComplete(true);
3186 }
3187
TEST_P(GLES2DecoderWithShaderTest,TextureChangesMarkFBOAsNotCompleteUnboundFBO)3188 TEST_P(GLES2DecoderWithShaderTest,
3189 TextureChangesMarkFBOAsNotCompleteUnboundFBO) {
3190 CheckTextureChangesMarkFBOAsNotComplete(false);
3191 }
3192
TEST_P(GLES2DecoderTest,CanChangeSurface)3193 TEST_P(GLES2DecoderTest, CanChangeSurface) {
3194 scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
3195 EXPECT_CALL(*other_surface.get(), GetBackingFramebufferObject())
3196 .WillOnce(Return(7));
3197 EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
3198
3199 decoder_->SetSurface(other_surface);
3200 }
3201
TEST_P(GLES2DecoderTest,DrawBuffersEXTImmediateSuccceeds)3202 TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateSuccceeds) {
3203 const GLsizei count = 1;
3204 const GLenum bufs[] = {GL_COLOR_ATTACHMENT0};
3205 auto& cmd = *GetImmediateAs<cmds::DrawBuffersEXTImmediate>();
3206 cmd.Init(count, bufs);
3207
3208 DoBindFramebuffer(
3209 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3210 EXPECT_CALL(*gl_, DrawBuffersARB(count, _)).Times(1).RetiresOnSaturation();
3211 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
3212 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3213 }
3214
TEST_P(GLES2DecoderTest,DrawBuffersEXTImmediateFails)3215 TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateFails) {
3216 const GLsizei count = 1;
3217 const GLenum bufs[] = {GL_COLOR_ATTACHMENT1_EXT};
3218 auto& cmd = *GetImmediateAs<cmds::DrawBuffersEXTImmediate>();
3219 cmd.Init(count, bufs);
3220
3221 DoBindFramebuffer(
3222 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3223 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
3224 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3225 }
3226
TEST_P(GLES2DecoderTest,DrawBuffersEXTImmediateBackbuffer)3227 TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) {
3228 const GLsizei count = 1;
3229 const GLenum bufs[] = {GL_BACK};
3230 auto& cmd = *GetImmediateAs<cmds::DrawBuffersEXTImmediate>();
3231 cmd.Init(count, bufs);
3232
3233 DoBindFramebuffer(
3234 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3235 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
3236 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3237
3238 DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0); // unbind
3239
3240 EXPECT_CALL(*gl_, DrawBuffersARB(count, _)).Times(1).RetiresOnSaturation();
3241
3242 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
3243 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3244 }
3245
TEST_P(GLES2DecoderTest,DrawBuffersEXTMainFramebuffer)3246 TEST_P(GLES2DecoderTest, DrawBuffersEXTMainFramebuffer) {
3247 auto& cmd = *GetImmediateAs<cmds::DrawBuffersEXTImmediate>();
3248 {
3249 const GLenum bufs[] = {GL_BACK};
3250 const GLsizei count = base::size(bufs);
3251 cmd.Init(count, bufs);
3252
3253 EXPECT_CALL(*gl_, DrawBuffersARB(count, Pointee(GL_BACK)))
3254 .Times(1)
3255 .RetiresOnSaturation();
3256 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
3257 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3258 }
3259 {
3260 const GLsizei count = 0;
3261 cmd.Init(count, nullptr);
3262
3263 EXPECT_CALL(*gl_, DrawBuffersARB(_, _))
3264 .Times(0)
3265 .RetiresOnSaturation();
3266 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, 0));
3267 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3268 }
3269 {
3270 const GLenum bufs[] = {GL_BACK, GL_NONE};
3271 const GLsizei count = base::size(bufs);
3272 cmd.Init(count, bufs);
3273
3274 EXPECT_CALL(*gl_, DrawBuffersARB(_, _)).Times(0).RetiresOnSaturation();
3275 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
3276 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3277 }
3278 }
3279
TEST_P(GLES2DecoderManualInitTest,InvalidateFramebufferBinding)3280 TEST_P(GLES2DecoderManualInitTest, InvalidateFramebufferBinding) {
3281 InitState init;
3282 init.gl_version = "OpenGL ES 3.0";
3283 InitDecoder(init);
3284
3285 // EXPECT_EQ can't be used to compare function pointers
3286 EXPECT_TRUE(
3287 gl::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") !=
3288 reinterpret_cast<gl::GLFunctionPointerType>(
3289 gl::g_current_gl_driver->fn.glDiscardFramebufferEXTFn));
3290 EXPECT_TRUE(
3291 gl::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") !=
3292 gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT"));
3293 }
3294
TEST_P(GLES2DecoderTest,ClearBackbufferBitsOnFlipSwap)3295 TEST_P(GLES2DecoderTest, ClearBackbufferBitsOnFlipSwap) {
3296 surface_->set_buffers_flipped(true);
3297
3298 EXPECT_EQ(0u, GetAndClearBackbufferClearBitsForTest());
3299
3300 auto& cmd = *GetImmediateAs<cmds::SwapBuffers>();
3301 cmd.Init(1, 0);
3302 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3303 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3304 EXPECT_EQ(static_cast<uint32_t>(GL_COLOR_BUFFER_BIT),
3305 GetAndClearBackbufferClearBitsForTest());
3306
3307 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3308 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3309 EXPECT_EQ(0u, GetAndClearBackbufferClearBitsForTest());
3310
3311 EXPECT_CALL(*gl_, Finish()).Times(AnyNumber());
3312 auto& resize_cmd = *GetImmediateAs<cmds::ResizeCHROMIUM>();
3313 resize_cmd.Init(1, 1, 1.0f, GL_TRUE, 0, 0, 0);
3314 EXPECT_EQ(error::kNoError, ExecuteCmd(resize_cmd));
3315 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3316 EXPECT_EQ(static_cast<uint32_t>(GL_COLOR_BUFFER_BIT),
3317 GetAndClearBackbufferClearBitsForTest());
3318
3319 cmd.Init(1, 0);
3320 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3321 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3322 EXPECT_EQ(static_cast<uint32_t>(GL_COLOR_BUFFER_BIT),
3323 GetAndClearBackbufferClearBitsForTest());
3324
3325 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3326 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3327 EXPECT_EQ(0u, GetAndClearBackbufferClearBitsForTest());
3328 }
3329
TEST_P(GLES2DecoderManualInitTest,DiscardFramebufferEXT)3330 TEST_P(GLES2DecoderManualInitTest, DiscardFramebufferEXT) {
3331 InitState init;
3332 init.extensions = "GL_EXT_discard_framebuffer";
3333 init.gl_version = "OpenGL ES 2.0";
3334 InitDecoder(init);
3335
3336 // EXPECT_EQ can't be used to compare function pointers
3337 EXPECT_TRUE(
3338 gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
3339 reinterpret_cast<gl::GLFunctionPointerType>(
3340 gl::g_current_gl_driver->fn.glDiscardFramebufferEXTFn));
3341
3342 const GLenum target = GL_FRAMEBUFFER;
3343 const GLsizei count = 1;
3344 const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
3345
3346 SetupTexture();
3347 DoBindFramebuffer(
3348 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3349 DoFramebufferTexture2D(GL_FRAMEBUFFER,
3350 GL_COLOR_ATTACHMENT0,
3351 GL_TEXTURE_2D,
3352 client_texture_id_,
3353 kServiceTextureId,
3354 0,
3355 GL_NO_ERROR);
3356 FramebufferManager* framebuffer_manager = GetFramebufferManager();
3357 Framebuffer* framebuffer =
3358 framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
3359 EXPECT_TRUE(framebuffer->IsCleared());
3360
3361 EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
3362 .Times(1)
3363 .RetiresOnSaturation();
3364 auto& cmd = *GetImmediateAs<cmds::DiscardFramebufferEXTImmediate>();
3365 cmd.Init(target, count, attachments);
3366
3367 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3368 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3369 EXPECT_FALSE(framebuffer->IsCleared());
3370 }
3371
TEST_P(GLES2DecoderManualInitTest,ClearBackbufferBitsOnDiscardFramebufferEXT)3372 TEST_P(GLES2DecoderManualInitTest, ClearBackbufferBitsOnDiscardFramebufferEXT) {
3373 InitState init;
3374 init.extensions = "GL_EXT_discard_framebuffer";
3375 init.gl_version = "OpenGL ES 2.0";
3376 InitDecoder(init);
3377
3378 // EXPECT_EQ can't be used to compare function pointers.
3379 EXPECT_TRUE(
3380 gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
3381 reinterpret_cast<gl::GLFunctionPointerType>(
3382 gl::g_current_gl_driver->fn.glDiscardFramebufferEXTFn));
3383
3384 const GLenum target = GL_FRAMEBUFFER;
3385 const GLsizei count = 1;
3386 GLenum attachments[] = {GL_COLOR_EXT};
3387
3388 EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
3389 .Times(1)
3390 .RetiresOnSaturation();
3391 auto& cmd = *GetImmediateAs<cmds::DiscardFramebufferEXTImmediate>();
3392 cmd.Init(target, count, attachments);
3393 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3394 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3395 EXPECT_EQ(static_cast<uint32_t>(GL_COLOR_BUFFER_BIT),
3396 GetAndClearBackbufferClearBitsForTest());
3397
3398 attachments[0] = GL_DEPTH_EXT;
3399 EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
3400 .Times(1)
3401 .RetiresOnSaturation();
3402 cmd.Init(target, count, attachments);
3403 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3404 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3405 EXPECT_EQ(static_cast<uint32_t>(GL_DEPTH_BUFFER_BIT),
3406 GetAndClearBackbufferClearBitsForTest());
3407
3408 attachments[0] = GL_STENCIL_EXT;
3409 EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
3410 .Times(1)
3411 .RetiresOnSaturation();
3412 cmd.Init(target, count, attachments);
3413 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3414 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3415 EXPECT_EQ(static_cast<uint32_t>(GL_STENCIL_BUFFER_BIT),
3416 GetAndClearBackbufferClearBitsForTest());
3417
3418 const GLsizei count0 = 3;
3419 const GLenum attachments0[] = {GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT};
3420 EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count0, _))
3421 .Times(1)
3422 .RetiresOnSaturation();
3423 cmd.Init(target, count0, attachments0);
3424 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments0)));
3425 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3426 EXPECT_EQ(static_cast<uint32_t>(GL_COLOR_BUFFER_BIT |
3427 GL_DEPTH_BUFFER_BIT |
3428 GL_STENCIL_BUFFER_BIT),
3429 GetAndClearBackbufferClearBitsForTest());
3430 }
3431
TEST_P(GLES2DecoderTest,DiscardFramebufferEXTUnsupported)3432 TEST_P(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) {
3433 const GLenum target = GL_FRAMEBUFFER;
3434 const GLsizei count = 1;
3435 const GLenum attachments[] = {GL_COLOR_EXT};
3436 auto& cmd = *GetImmediateAs<cmds::DiscardFramebufferEXTImmediate>();
3437 cmd.Init(target, count, attachments);
3438
3439 // Should not result into a call into GL.
3440 EXPECT_EQ(error::kUnknownCommand,
3441 ExecuteImmediateCmd(cmd, sizeof(attachments)));
3442 }
3443
TEST_P(GLES3DecoderTest,DiscardFramebufferEXTInvalidTarget)3444 TEST_P(GLES3DecoderTest, DiscardFramebufferEXTInvalidTarget) {
3445 const GLenum target = GL_RED; // Invalid
3446 const GLsizei count = 1;
3447 const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
3448
3449 SetupTexture();
3450 DoBindFramebuffer(
3451 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3452 DoFramebufferTexture2D(GL_FRAMEBUFFER,
3453 GL_COLOR_ATTACHMENT0,
3454 GL_TEXTURE_2D,
3455 client_texture_id_,
3456 kServiceTextureId,
3457 0,
3458 GL_NO_ERROR);
3459 FramebufferManager* framebuffer_manager = GetFramebufferManager();
3460 Framebuffer* framebuffer =
3461 framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
3462 EXPECT_TRUE(framebuffer->IsCleared());
3463
3464 EXPECT_CALL(*gl_, InvalidateFramebuffer(target, count, _)).Times(0);
3465 auto& cmd = *GetImmediateAs<cmds::DiscardFramebufferEXTImmediate>();
3466 cmd.Init(target, count, attachments);
3467
3468 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3469 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
3470 EXPECT_TRUE(framebuffer->IsCleared());
3471 }
3472
TEST_P(GLES3DecoderTest,DiscardFramebufferEXTUseCorrectTarget)3473 TEST_P(GLES3DecoderTest, DiscardFramebufferEXTUseCorrectTarget) {
3474 const GLenum target = GL_READ_FRAMEBUFFER;
3475 const GLsizei count = 1;
3476 const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
3477
3478 SetupTexture();
3479 DoBindFramebuffer(
3480 GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3481 DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
3482 GL_COLOR_ATTACHMENT0,
3483 GL_TEXTURE_2D,
3484 client_texture_id_,
3485 kServiceTextureId,
3486 0,
3487 GL_NO_ERROR);
3488
3489 EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _))
3490 .WillOnce(SetArgPointee<1>(kServiceFramebufferId + 1))
3491 .RetiresOnSaturation();
3492 DoBindFramebuffer(GL_DRAW_FRAMEBUFFER, client_framebuffer_id_ + 1,
3493 kServiceFramebufferId + 1);
3494 EXPECT_CALL(*gl_, GenTextures(_, _))
3495 .WillOnce(SetArgPointee<1>(kServiceTextureId + 1))
3496 .RetiresOnSaturation();
3497 DoBindTexture(GL_TEXTURE_2D, client_texture_id_ + 1, kServiceTextureId + 1);
3498 DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3499 shared_memory_id_, kSharedMemoryOffset);
3500 DoFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
3501 GL_COLOR_ATTACHMENT0,
3502 GL_TEXTURE_2D,
3503 client_texture_id_ + 1,
3504 kServiceTextureId + 1,
3505 0,
3506 GL_NO_ERROR);
3507
3508 FramebufferManager* framebuffer_manager = GetFramebufferManager();
3509 Framebuffer* framebuffer =
3510 framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
3511 EXPECT_TRUE(framebuffer->IsCleared());
3512 Framebuffer* other_framebuffer =
3513 framebuffer_manager->GetFramebuffer(client_framebuffer_id_ + 1);
3514 EXPECT_TRUE(other_framebuffer->IsCleared());
3515
3516 EXPECT_CALL(*gl_, InvalidateFramebuffer(target, count, _))
3517 .Times(1)
3518 .RetiresOnSaturation();
3519 auto& cmd = *GetImmediateAs<cmds::DiscardFramebufferEXTImmediate>();
3520 cmd.Init(target, count, attachments);
3521
3522 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3523 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3524 EXPECT_FALSE(framebuffer->IsCleared());
3525 EXPECT_TRUE(other_framebuffer->IsCleared());
3526 }
3527
TEST_P(GLES2DecoderManualInitTest,DiscardedAttachmentsEXTMarksFramebufferIncomplete)3528 TEST_P(GLES2DecoderManualInitTest,
3529 DiscardedAttachmentsEXTMarksFramebufferIncomplete) {
3530 InitState init;
3531 init.extensions = "GL_EXT_discard_framebuffer";
3532 init.gl_version = "OpenGL ES 2.0";
3533 init.has_alpha = true;
3534 init.bind_generates_resource = true;
3535 InitDecoder(init);
3536
3537 const GLuint kFBOClientTextureId = 4100;
3538 const GLuint kFBOServiceTextureId = 4101;
3539
3540 // Register a texture id.
3541 EXPECT_CALL(*gl_, GenTextures(_, _))
3542 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
3543 .RetiresOnSaturation();
3544 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
3545
3546 // Setup "render to" texture.
3547 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
3548 DoTexImage2D(
3549 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
3550 DoBindFramebuffer(
3551 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3552 DoFramebufferTexture2D(GL_FRAMEBUFFER,
3553 GL_COLOR_ATTACHMENT0,
3554 GL_TEXTURE_2D,
3555 kFBOClientTextureId,
3556 kFBOServiceTextureId,
3557 0,
3558 GL_NO_ERROR);
3559 DoEnableDisable(GL_SCISSOR_TEST, false);
3560 DoScissor(0, 0, 1, 1);
3561
3562 // Setup "render from" texture.
3563 SetupTexture();
3564
3565 SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER, // target
3566 GL_COLOR_BUFFER_BIT, // clear bits
3567 0, 0, 0,
3568 0, // color
3569 0, // stencil
3570 1.0f, // depth
3571 false, // scissor test
3572 0, 0, 1, 1);
3573 SetupExpectationsForApplyingDirtyState(false, // Framebuffer is RGB
3574 false, // Framebuffer has depth
3575 false, // Framebuffer has stencil
3576 0x1111, // color bits
3577 false, // depth mask
3578 false, // depth enabled
3579 0, // front stencil mask
3580 0, // back stencil mask
3581 false); // stencil enabled
3582
3583 EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)).Times(1).RetiresOnSaturation();
3584
3585 cmds::Clear clear_cmd;
3586 clear_cmd.Init(GL_COLOR_BUFFER_BIT);
3587 EXPECT_EQ(error::kNoError, ExecuteCmd(clear_cmd));
3588 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3589
3590 // Check that framebuffer is cleared and complete.
3591 FramebufferManager* framebuffer_manager = GetFramebufferManager();
3592 Framebuffer* framebuffer =
3593 framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
3594 EXPECT_TRUE(framebuffer->IsCleared());
3595 EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
3596
3597 // Check that Discard GL_COLOR_ATTACHMENT0, sets the attachment as uncleared
3598 // and the framebuffer as incomplete.
3599 EXPECT_TRUE(
3600 gl::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
3601 reinterpret_cast<gl::GLFunctionPointerType>(
3602 gl::g_current_gl_driver->fn.glDiscardFramebufferEXTFn));
3603
3604 const GLenum target = GL_FRAMEBUFFER;
3605 const GLsizei count = 1;
3606 const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
3607
3608 auto& discard_cmd = *GetImmediateAs<cmds::DiscardFramebufferEXTImmediate>();
3609 discard_cmd.Init(target, count, attachments);
3610
3611 EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
3612 .Times(1)
3613 .RetiresOnSaturation();
3614 EXPECT_EQ(error::kNoError,
3615 ExecuteImmediateCmd(discard_cmd, sizeof(attachments)));
3616 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3617 EXPECT_FALSE(framebuffer->IsCleared());
3618 EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
3619 }
3620
TEST_P(GLES2DecoderTest,ImplementationReadColorFormatAndType)3621 TEST_P(GLES2DecoderTest, ImplementationReadColorFormatAndType) {
3622 ClearSharedMemory();
3623 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3624 DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3625 shared_memory_id_, kSharedMemoryOffset);
3626 DoBindFramebuffer(
3627 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3628 DoFramebufferTexture2D(GL_FRAMEBUFFER,
3629 GL_COLOR_ATTACHMENT0,
3630 GL_TEXTURE_2D,
3631 client_texture_id_,
3632 kServiceTextureId,
3633 0,
3634 GL_NO_ERROR);
3635
3636 auto* result =
3637 static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
3638 cmds::GetIntegerv cmd;
3639
3640 result->size = 0;
3641 EXPECT_CALL(*gl_, GetError())
3642 .WillOnce(Return(GL_NO_ERROR))
3643 .WillOnce(Return(GL_NO_ERROR))
3644 .RetiresOnSaturation();
3645 cmd.Init(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
3646 shared_memory_id_,
3647 shared_memory_offset_);
3648 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3649 EXPECT_EQ(1, result->GetNumResults());
3650 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3651
3652 result->size = 0;
3653 EXPECT_CALL(*gl_, GetError())
3654 .WillOnce(Return(GL_NO_ERROR))
3655 .WillOnce(Return(GL_NO_ERROR))
3656 .RetiresOnSaturation();
3657 cmd.Init(GL_IMPLEMENTATION_COLOR_READ_TYPE,
3658 shared_memory_id_,
3659 shared_memory_offset_);
3660 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3661 EXPECT_EQ(1, result->GetNumResults());
3662 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3663 }
3664
TEST_P(GLES3DecoderTest,FramebufferTextureLayerNoBoundFramebuffer)3665 TEST_P(GLES3DecoderTest, FramebufferTextureLayerNoBoundFramebuffer) {
3666 DoBindTexture(GL_TEXTURE_3D, client_texture_id_, kServiceTextureId);
3667 EXPECT_CALL(*gl_, FramebufferTextureLayer(_, _, _, _, _)).Times(0);
3668 cmds::FramebufferTextureLayer cmd;
3669 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, 4, 5);
3670 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3671 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3672 }
3673
TEST_P(GLES3DecoderTest,FramebufferTextureLayerInvalidTextureTarget)3674 TEST_P(GLES3DecoderTest, FramebufferTextureLayerInvalidTextureTarget) {
3675 DoBindFramebuffer(
3676 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3677 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3678 EXPECT_CALL(*gl_, FramebufferTextureLayer(_, _, _, _, _)).Times(0);
3679 cmds::FramebufferTextureLayer cmd;
3680 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, 4, 5);
3681 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3682 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3683 }
3684
TEST_P(GLES3DecoderTest,FramebufferTextureLayerValidArgs)3685 TEST_P(GLES3DecoderTest, FramebufferTextureLayerValidArgs) {
3686 DoBindFramebuffer(
3687 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3688 DoBindTexture(GL_TEXTURE_3D, client_texture_id_, kServiceTextureId);
3689 EXPECT_CALL(*gl_, FramebufferTextureLayer(GL_FRAMEBUFFER,
3690 GL_COLOR_ATTACHMENT0,
3691 kServiceTextureId, 4, 5))
3692 .Times(1)
3693 .RetiresOnSaturation();
3694 cmds::FramebufferTextureLayer cmd;
3695 cmd.Init(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, client_texture_id_, 4, 5);
3696 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3697 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3698 }
3699
TEST_P(GLES3DecoderTest,FramebufferTextureLayerDepthStencil)3700 TEST_P(GLES3DecoderTest, FramebufferTextureLayerDepthStencil) {
3701 DoBindFramebuffer(
3702 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3703 DoBindTexture(GL_TEXTURE_2D_ARRAY, client_texture_id_, kServiceTextureId);
3704 EXPECT_CALL(*gl_, FramebufferTextureLayer(GL_FRAMEBUFFER,
3705 GL_DEPTH_STENCIL_ATTACHMENT,
3706 kServiceTextureId, 4, 5))
3707 .Times(1)
3708 .RetiresOnSaturation();
3709 cmds::FramebufferTextureLayer cmd;
3710 cmd.Init(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, client_texture_id_, 4,
3711 5);
3712 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3713 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3714 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
3715 ASSERT_TRUE(framebuffer);
3716 ASSERT_FALSE(framebuffer->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
3717 ASSERT_TRUE(framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT));
3718 ASSERT_TRUE(framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT));
3719 }
3720
TEST_P(GLES3DecoderTest,InvalidateFramebufferDepthStencilAttachment)3721 TEST_P(GLES3DecoderTest, InvalidateFramebufferDepthStencilAttachment) {
3722 DoBindFramebuffer(
3723 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3724 DoBindRenderbuffer(
3725 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
3726 DoRenderbufferStorage(
3727 GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8,
3728 1, 1, GL_NO_ERROR);
3729 DoFramebufferRenderbuffer(
3730 GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3731 client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
3732
3733 Framebuffer* framebuffer = GetFramebuffer(client_framebuffer_id_);
3734 ASSERT_TRUE(framebuffer);
3735 ASSERT_FALSE(framebuffer->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
3736 ASSERT_TRUE(framebuffer->GetAttachment(GL_DEPTH_ATTACHMENT));
3737 ASSERT_TRUE(framebuffer->GetAttachment(GL_STENCIL_ATTACHMENT));
3738 framebuffer->MarkAttachmentAsCleared(group().renderbuffer_manager(), nullptr,
3739 GL_DEPTH_ATTACHMENT, true);
3740 framebuffer->MarkAttachmentAsCleared(group().renderbuffer_manager(), nullptr,
3741 GL_STENCIL_ATTACHMENT, true);
3742 EXPECT_TRUE(framebuffer->IsCleared());
3743
3744 const GLenum target = GL_FRAMEBUFFER;
3745 const GLsizei count = 1;
3746 GLenum attachments[] = {GL_DEPTH_ATTACHMENT};
3747 EXPECT_CALL(*gl_, InvalidateFramebuffer(target, 0, _))
3748 .Times(1)
3749 .RetiresOnSaturation();
3750 auto& cmd = *GetImmediateAs<cmds::InvalidateFramebufferImmediate>();
3751 cmd.Init(target, count, attachments);
3752
3753 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3754 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3755 // Invalidating part of DEPTH_STENCIL attachment doesn't change framebuffer
3756 // clearance status.
3757 EXPECT_TRUE(framebuffer->IsCleared());
3758 EXPECT_FALSE(framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
3759 EXPECT_FALSE(framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
3760
3761 attachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
3762 EXPECT_CALL(*gl_, InvalidateFramebuffer(target, 2, _))
3763 .Times(1)
3764 .RetiresOnSaturation();
3765 cmd.Init(target, count, attachments);
3766
3767 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
3768 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3769 // Invalidating DEPTH_STENCIL attachment should make framebuffer uncleared.
3770 EXPECT_FALSE(framebuffer->IsCleared());
3771 EXPECT_TRUE(framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
3772 EXPECT_TRUE(framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
3773 }
3774
TEST_P(GLES3DecoderTest,BlitFramebufferFeedbackLoopDefaultFramebuffer)3775 TEST_P(GLES3DecoderTest, BlitFramebufferFeedbackLoopDefaultFramebuffer) {
3776 // Run BlitFramebufferCHROMIUM targetting the default framebuffer for both
3777 // read and draw, should result in a feedback loop.
3778 cmds::BlitFramebufferCHROMIUM cmd;
3779 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_LINEAR);
3780 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3781 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3782
3783 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_DEPTH_BUFFER_BIT, GL_LINEAR);
3784 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3785 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3786
3787 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_STENCIL_BUFFER_BIT, GL_LINEAR);
3788 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3789 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3790 }
3791
TEST_P(GLES3DecoderTest,BlitFramebufferDisabledReadBuffer)3792 TEST_P(GLES3DecoderTest, BlitFramebufferDisabledReadBuffer) {
3793 // Run BlitFramebufferCHROMIUM from a disabled read buffer. Even though the
3794 // read and draw framebuffer use the same attachment, since the read buffer is
3795 // disabled, no feedback loop happens.
3796 DoBindFramebuffer(GL_DRAW_FRAMEBUFFER, client_framebuffer_id_,
3797 kServiceFramebufferId);
3798 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
3799 kServiceRenderbufferId);
3800 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, GL_RGBA8, 1, 1, GL_NO_ERROR);
3801 DoFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3802 GL_RENDERBUFFER, client_renderbuffer_id_,
3803 kServiceRenderbufferId, GL_NO_ERROR);
3804
3805 EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
3806 .WillOnce(SetArgPointee<1>(kNewServiceId))
3807 .RetiresOnSaturation();
3808 GLuint read_fbo = client_framebuffer_id_ + 1;
3809 DoBindFramebuffer(GL_READ_FRAMEBUFFER, read_fbo, kNewServiceId);
3810 DoFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3811 GL_RENDERBUFFER, client_renderbuffer_id_,
3812 kServiceRenderbufferId, GL_NO_ERROR);
3813 {
3814 EXPECT_CALL(*gl_, ReadBuffer(GL_NONE))
3815 .Times(1)
3816 .RetiresOnSaturation();
3817 cmds::ReadBuffer cmd;
3818 cmd.Init(GL_NONE);
3819 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3820 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3821 }
3822
3823 {
3824 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
3825 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
3826 .RetiresOnSaturation();
3827 SetupExpectationsForFramebufferClearing(GL_DRAW_FRAMEBUFFER, // target
3828 GL_COLOR_BUFFER_BIT, // clear bits
3829 0, 0, 0, 0, // color
3830 0, // stencil
3831 1.0f, // depth
3832 false, // scissor test
3833 0, 0, 128, 64);
3834 cmds::BlitFramebufferCHROMIUM cmd;
3835 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_LINEAR);
3836 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3837 // Generate INVALID_OPERATION because of missing read buffer image.
3838 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3839 }
3840 }
3841
TEST_P(GLES3DecoderTest,BlitFramebufferMissingDepthOrStencil)3842 TEST_P(GLES3DecoderTest, BlitFramebufferMissingDepthOrStencil) {
3843 // Run BlitFramebufferCHROMIUM with depth or stencil bits, from/to a read/draw
3844 // framebuffer that doesn't have depth/stencil. It should generate
3845 // INVALID_OPERATION.
3846 DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
3847 kServiceRenderbufferId);
3848 DoRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
3849 GL_DEPTH24_STENCIL8, 1, 1, GL_NO_ERROR);
3850 GLuint color_renderbuffer = client_renderbuffer_id_ + 1;
3851 GLuint color_renderbuffer_service = kServiceRenderbufferId + 1;
3852 EXPECT_CALL(*gl_, GenRenderbuffersEXT(1, _))
3853 .WillOnce(SetArgPointee<1>(color_renderbuffer_service))
3854 .RetiresOnSaturation();
3855 DoBindRenderbuffer(GL_RENDERBUFFER, color_renderbuffer,
3856 color_renderbuffer_service);
3857 DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, GL_RGBA8, 1, 1, GL_NO_ERROR);
3858 DoBindFramebuffer(GL_DRAW_FRAMEBUFFER, client_framebuffer_id_,
3859 kServiceFramebufferId);
3860 DoFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
3861 GL_RENDERBUFFER, client_renderbuffer_id_,
3862 kServiceRenderbufferId, GL_NO_ERROR);
3863 DoFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
3864 GL_RENDERBUFFER, client_renderbuffer_id_,
3865 kServiceRenderbufferId, GL_NO_ERROR);
3866 DoFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3867 GL_RENDERBUFFER, color_renderbuffer,
3868 color_renderbuffer_service, GL_NO_ERROR);
3869
3870 EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
3871 .WillOnce(SetArgPointee<1>(kNewServiceId))
3872 .RetiresOnSaturation();
3873 GLuint color_fbo = client_framebuffer_id_ + 1;
3874 DoBindFramebuffer(GL_READ_FRAMEBUFFER, color_fbo, kNewServiceId);
3875 DoFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3876 GL_RENDERBUFFER, color_renderbuffer,
3877 color_renderbuffer_service, GL_NO_ERROR);
3878
3879 {
3880 SetupExpectationsForFramebufferClearing(
3881 GL_DRAW_FRAMEBUFFER, // target
3882 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
3883 GL_STENCIL_BUFFER_BIT, // clear bits
3884 0,
3885 0, 0, 0, // color
3886 0, // stencil
3887 1.0f, // depth
3888 false, // scissor test
3889 0, 0, 128, 64);
3890 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
3891 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
3892 .RetiresOnSaturation();
3893 cmds::BlitFramebufferCHROMIUM cmd;
3894 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3895 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3896 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3897 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3898 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3899 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3900 }
3901
3902 // Switch FBOs and try the same.
3903 DoBindFramebuffer(GL_READ_FRAMEBUFFER, client_framebuffer_id_,
3904 kServiceFramebufferId);
3905 DoBindFramebuffer(GL_DRAW_FRAMEBUFFER, color_fbo, kNewServiceId);
3906 {
3907 EXPECT_CALL(*gl_, BlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, _, _)).Times(0);
3908 cmds::BlitFramebufferCHROMIUM cmd;
3909 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3910 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3911 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3912 cmd.Init(0, 0, 1, 1, 0, 0, 1, 1, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3913 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3914 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3915 }
3916 }
3917
3918 class GLES2DecoderTestWithDrawRectangle : public GLES2DecoderTest {
SetUp()3919 void SetUp() override {
3920 surface_supports_draw_rectangle_ = true;
3921 GLES2DecoderTest::SetUp();
3922 }
3923 };
3924
3925 // Test that the draw offset is correctly honored when SetDrawRectangle is
3926 // supported.
TEST_P(GLES2DecoderTestWithDrawRectangle,FramebufferDrawRectangleClear)3927 TEST_P(GLES2DecoderTestWithDrawRectangle, FramebufferDrawRectangleClear) {
3928 EXPECT_CALL(*gl_, Scissor(101, 202, 3, 4)).Times(1).RetiresOnSaturation();
3929 cmds::Scissor scissor_cmd;
3930 scissor_cmd.Init(1, 2, 3, 4);
3931 EXPECT_EQ(error::kNoError, ExecuteCmd(scissor_cmd));
3932
3933 // Scissor and Viewport should be restored to (0,0) offset on when clearing
3934 // a framebuffer.
3935 {
3936 const GLuint kFBOClientTextureId = 4100;
3937 const GLuint kFBOServiceTextureId = 4101;
3938
3939 // Register a texture id.
3940 EXPECT_CALL(*gl_, GenTextures(_, _))
3941 .WillOnce(SetArgPointee<1>(kFBOServiceTextureId))
3942 .RetiresOnSaturation();
3943 GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId);
3944
3945 // Setup "render to" texture.
3946 DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
3947 DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3948 0, 0);
3949 DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
3950 kServiceFramebufferId);
3951 DoFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3952 kFBOClientTextureId, kFBOServiceTextureId, 0,
3953 GL_NO_ERROR);
3954 // Set scissor rect and enable GL_SCISSOR_TEST to make sure we re-enable it
3955 // and restore the rect again after the clear.
3956 DoEnableDisable(GL_SCISSOR_TEST, true);
3957 EXPECT_CALL(*gl_, Viewport(0, 0, 128, 64)).Times(1).RetiresOnSaturation();
3958 EXPECT_CALL(*gl_, Scissor(1, 2, 3, 4)).Times(1).RetiresOnSaturation();
3959
3960 // Setup "render from" texture.
3961 SetupTexture();
3962
3963 SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER, // target
3964 GL_COLOR_BUFFER_BIT, // clear bits
3965 0, 0, 0,
3966 0, // color
3967 0, // stencil
3968 1.0f, // depth
3969 true, // scissor test
3970 1, 2, 3, 4);
3971 SetupExpectationsForApplyingDirtyState(false, // Framebuffer is RGB
3972 false, // Framebuffer has depth
3973 false, // Framebuffer has stencil
3974 0x1111, // color bits
3975 false, // depth mask
3976 false, // depth enabled
3977 0, // front stencil mask
3978 0, // back stencil mask
3979 false); // stencil enabled
3980
3981 EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT))
3982 .Times(1)
3983 .RetiresOnSaturation();
3984
3985 cmds::Clear cmd;
3986 cmd.Init(GL_COLOR_BUFFER_BIT);
3987 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3988 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3989 }
3990
3991 // Check that the draw offset is used when switching to the default
3992 // framebuffer and clearing it.
3993 {
3994 DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
3995 EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT))
3996 .Times(1)
3997 .RetiresOnSaturation();
3998 SetupExpectationsForColorMask(true, true, true, true);
3999 SetupExpectationsForDepthMask(true);
4000 SetupExpectationsForStencilMask(0, 0);
4001 SetupExpectationsForEnableDisable(GL_DEPTH_TEST, false);
4002 SetupExpectationsForEnableDisable(GL_STENCIL_TEST, false);
4003 EXPECT_CALL(*gl_, Viewport(100, 200, 128, 64))
4004 .Times(1)
4005 .RetiresOnSaturation();
4006 EXPECT_CALL(*gl_, Scissor(101, 202, 3, 4)).Times(1).RetiresOnSaturation();
4007 cmds::Clear cmd;
4008 cmd.Init(GL_COLOR_BUFFER_BIT);
4009 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4010 EXPECT_EQ(GL_NO_ERROR, GetGLError());
4011 }
4012 }
4013
4014 INSTANTIATE_TEST_SUITE_P(Service,
4015 GLES2DecoderTestWithDrawRectangle,
4016 ::testing::Bool());
4017
TEST_P(GLES2DecoderManualInitTest,MESAFramebufferFlipYExtensionEnabled)4018 TEST_P(GLES2DecoderManualInitTest, MESAFramebufferFlipYExtensionEnabled) {
4019 InitState init;
4020 init.gl_version = "OpenGL ES 3.1";
4021 init.context_type = CONTEXT_TYPE_WEBGL1;
4022 init.extensions = "GL_MESA_framebuffer_flip_y";
4023 InitDecoder(init);
4024
4025 EXPECT_TRUE(feature_info()->validators()->framebuffer_parameter.IsValid(
4026 GL_FRAMEBUFFER_FLIP_Y_MESA));
4027
4028 EXPECT_CALL(*gl_, FramebufferParameteri(_, _, _))
4029 .Times(1)
4030 .RetiresOnSaturation();
4031
4032 DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
4033 kServiceFramebufferId);
4034 cmds::FramebufferParameteri cmd;
4035 cmd.Init(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
4036 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4037 EXPECT_EQ(GL_NO_ERROR, GetGLError());
4038 }
4039
TEST_P(GLES2DecoderManualInitTest,MESAFramebufferFlipYExtensionDisabled)4040 TEST_P(GLES2DecoderManualInitTest, MESAFramebufferFlipYExtensionDisabled) {
4041 InitState init;
4042 init.gl_version = "OpenGL ES 3.1";
4043 init.context_type = CONTEXT_TYPE_WEBGL1;
4044 InitDecoder(init);
4045
4046 EXPECT_FALSE(feature_info()->validators()->framebuffer_parameter.IsValid(
4047 GL_FRAMEBUFFER_FLIP_Y_MESA));
4048
4049 EXPECT_CALL(*gl_, FramebufferParameteri(_, _, _))
4050 .Times(0)
4051 .RetiresOnSaturation();
4052
4053 DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
4054 kServiceFramebufferId);
4055 cmds::FramebufferParameteri cmd;
4056 cmd.Init(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
4057 EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
4058 EXPECT_EQ(GL_NO_ERROR, GetGLError());
4059 }
4060
4061 // TODO(gman): PixelStorei
4062
4063 // TODO(gman): SwapBuffers
4064
4065 } // namespace gles2
4066 } // namespace gpu
4067