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