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 "base/command_line.h"
8#include "base/strings/string_number_conversions.h"
9#include "gpu/command_buffer/common/gles2_cmd_format.h"
10#include "gpu/command_buffer/common/gles2_cmd_utils.h"
11#include "gpu/command_buffer/common/id_allocator.h"
12#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
13#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
14#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
15#include "gpu/command_buffer/service/cmd_buffer_engine.h"
16#include "gpu/command_buffer/service/context_group.h"
17#include "gpu/command_buffer/service/context_state.h"
18#include "gpu/command_buffer/service/gl_surface_mock.h"
19#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
20
21#include "gpu/command_buffer/service/gpu_switches.h"
22#include "gpu/command_buffer/service/image_manager.h"
23#include "gpu/command_buffer/service/mailbox_manager.h"
24#include "gpu/command_buffer/service/mocks.h"
25#include "gpu/command_buffer/service/program_manager.h"
26#include "gpu/command_buffer/service/test_helper.h"
27#include "testing/gtest/include/gtest/gtest.h"
28#include "ui/gl/gl_implementation.h"
29#include "ui/gl/gl_mock.h"
30#include "ui/gl/gl_surface_stub.h"
31
32#if !defined(GL_DEPTH24_STENCIL8)
33#define GL_DEPTH24_STENCIL8 0x88F0
34#endif
35
36using ::gfx::MockGLInterface;
37using ::testing::_;
38using ::testing::DoAll;
39using ::testing::InSequence;
40using ::testing::Invoke;
41using ::testing::MatcherCast;
42using ::testing::Mock;
43using ::testing::Pointee;
44using ::testing::Return;
45using ::testing::SaveArg;
46using ::testing::SetArrayArgument;
47using ::testing::SetArgumentPointee;
48using ::testing::SetArgPointee;
49using ::testing::StrEq;
50using ::testing::StrictMock;
51
52namespace gpu {
53namespace gles2 {
54
55using namespace cmds;
56
57class GLES2DecoderRestoreStateTest : public GLES2DecoderManualInitTest {
58 public:
59  GLES2DecoderRestoreStateTest() {}
60
61 protected:
62  void AddExpectationsForActiveTexture(GLenum unit);
63  void AddExpectationsForBindTexture(GLenum target, GLuint id);
64  void InitializeContextState(ContextState* state,
65                              uint32 non_default_unit,
66                              uint32 active_unit);
67};
68
69INSTANTIATE_TEST_CASE_P(Service,
70                        GLES2DecoderRestoreStateTest,
71                        ::testing::Bool());
72
73void GLES2DecoderRestoreStateTest::AddExpectationsForActiveTexture(
74    GLenum unit) {
75  EXPECT_CALL(*gl_, ActiveTexture(unit)).Times(1).RetiresOnSaturation();
76}
77
78void GLES2DecoderRestoreStateTest::AddExpectationsForBindTexture(GLenum target,
79                                                                 GLuint id) {
80  EXPECT_CALL(*gl_, BindTexture(target, id)).Times(1).RetiresOnSaturation();
81}
82
83void GLES2DecoderRestoreStateTest::InitializeContextState(
84    ContextState* state,
85    uint32 non_default_unit,
86    uint32 active_unit) {
87  state->texture_units.resize(group().max_texture_units());
88  for (uint32 tt = 0; tt < state->texture_units.size(); ++tt) {
89    TextureRef* ref_cube_map =
90        group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
91    state->texture_units[tt].bound_texture_cube_map = ref_cube_map;
92    TextureRef* ref_2d =
93        (tt == non_default_unit)
94            ? group().texture_manager()->GetTexture(client_texture_id_)
95            : group().texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
96    state->texture_units[tt].bound_texture_2d = ref_2d;
97  }
98  state->active_texture_unit = active_unit;
99}
100
101TEST_P(GLES2DecoderRestoreStateTest, NullPreviousStateBGR) {
102  InitState init;
103  init.gl_version = "3.0";
104  init.bind_generates_resource = true;
105  InitDecoder(init);
106  SetupTexture();
107
108  InSequence sequence;
109  // Expect to restore texture bindings for unit GL_TEXTURE0.
110  AddExpectationsForActiveTexture(GL_TEXTURE0);
111  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
112  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
113                                TestHelper::kServiceDefaultTextureCubemapId);
114
115  // Expect to restore texture bindings for remaining units.
116  for (uint32 i = 1; i < group().max_texture_units(); ++i) {
117    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
118    AddExpectationsForBindTexture(GL_TEXTURE_2D,
119                                  TestHelper::kServiceDefaultTexture2dId);
120    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
121                                  TestHelper::kServiceDefaultTextureCubemapId);
122  }
123
124  // Expect to restore the active texture unit to GL_TEXTURE0.
125  AddExpectationsForActiveTexture(GL_TEXTURE0);
126
127  GetDecoder()->RestoreAllTextureUnitBindings(NULL);
128}
129
130TEST_P(GLES2DecoderRestoreStateTest, NullPreviousState) {
131  InitState init;
132  init.gl_version = "3.0";
133  InitDecoder(init);
134  SetupTexture();
135
136  InSequence sequence;
137  // Expect to restore texture bindings for unit GL_TEXTURE0.
138  AddExpectationsForActiveTexture(GL_TEXTURE0);
139  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
140  AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
141
142  // Expect to restore texture bindings for remaining units.
143  for (uint32 i = 1; i < group().max_texture_units(); ++i) {
144    AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
145    AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
146    AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP, 0);
147  }
148
149  // Expect to restore the active texture unit to GL_TEXTURE0.
150  AddExpectationsForActiveTexture(GL_TEXTURE0);
151
152  GetDecoder()->RestoreAllTextureUnitBindings(NULL);
153}
154
155TEST_P(GLES2DecoderRestoreStateTest, WithPreviousStateBGR) {
156  InitState init;
157  init.gl_version = "3.0";
158  init.bind_generates_resource = true;
159  InitDecoder(init);
160  SetupTexture();
161
162  // Construct a previous ContextState with all texture bindings
163  // set to default textures.
164  ContextState prev_state(NULL, NULL, NULL);
165  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
166
167  InSequence sequence;
168  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
169  // since the rest of the bindings haven't changed between the current
170  // state and the |prev_state|.
171  AddExpectationsForActiveTexture(GL_TEXTURE0);
172  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
173
174  // Expect to restore active texture unit to GL_TEXTURE0.
175  AddExpectationsForActiveTexture(GL_TEXTURE0);
176
177  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
178}
179
180TEST_P(GLES2DecoderRestoreStateTest, WithPreviousState) {
181  InitState init;
182  init.gl_version = "3.0";
183  InitDecoder(init);
184  SetupTexture();
185
186  // Construct a previous ContextState with all texture bindings
187  // set to default textures.
188  ContextState prev_state(NULL, NULL, NULL);
189  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
190
191  InSequence sequence;
192  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
193  // since the rest of the bindings haven't changed between the current
194  // state and the |prev_state|.
195  AddExpectationsForActiveTexture(GL_TEXTURE0);
196  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
197
198  // Expect to restore active texture unit to GL_TEXTURE0.
199  AddExpectationsForActiveTexture(GL_TEXTURE0);
200
201  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
202}
203
204TEST_P(GLES2DecoderRestoreStateTest, ActiveUnit1) {
205  InitState init;
206  init.gl_version = "3.0";
207  InitDecoder(init);
208
209  // Bind a non-default texture to GL_TEXTURE1 unit.
210  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
211  ActiveTexture cmd;
212  cmd.Init(GL_TEXTURE1);
213  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
214  EXPECT_EQ(GL_NO_ERROR, GetGLError());
215  SetupTexture();
216
217  // Construct a previous ContextState with all texture bindings
218  // set to default textures.
219  ContextState prev_state(NULL, NULL, NULL);
220  InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
221
222  InSequence sequence;
223  // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE1 unit,
224  // since the rest of the bindings haven't changed between the current
225  // state and the |prev_state|.
226  AddExpectationsForActiveTexture(GL_TEXTURE1);
227  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
228
229  // Expect to restore active texture unit to GL_TEXTURE1.
230  AddExpectationsForActiveTexture(GL_TEXTURE1);
231
232  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
233}
234
235TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit0BGR) {
236  InitState init;
237  init.gl_version = "3.0";
238  init.bind_generates_resource = true;
239  InitDecoder(init);
240
241  // Bind a non-default texture to GL_TEXTURE1 unit.
242  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
243  SpecializedSetup<ActiveTexture, 0>(true);
244  ActiveTexture cmd;
245  cmd.Init(GL_TEXTURE1);
246  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
247  EXPECT_EQ(GL_NO_ERROR, GetGLError());
248  SetupTexture();
249
250  // Construct a previous ContextState with GL_TEXTURE_2D target in
251  // GL_TEXTURE0 unit bound to a non-default texture and the rest
252  // set to default textures.
253  ContextState prev_state(NULL, NULL, NULL);
254  InitializeContextState(&prev_state, 0, kServiceTextureId);
255
256  InSequence sequence;
257  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
258  // a default texture.
259  AddExpectationsForActiveTexture(GL_TEXTURE0);
260  AddExpectationsForBindTexture(GL_TEXTURE_2D,
261                                TestHelper::kServiceDefaultTexture2dId);
262
263  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
264  // non-default.
265  AddExpectationsForActiveTexture(GL_TEXTURE1);
266  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
267
268  // Expect to restore active texture unit to GL_TEXTURE1.
269  AddExpectationsForActiveTexture(GL_TEXTURE1);
270
271  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
272}
273
274TEST_P(GLES2DecoderRestoreStateTest, NonDefaultUnit1BGR) {
275  InitState init;
276  init.gl_version = "3.0";
277  init.bind_generates_resource = true;
278  InitDecoder(init);
279
280  // Bind a non-default texture to GL_TEXTURE0 unit.
281  SetupTexture();
282
283  // Construct a previous ContextState with GL_TEXTURE_2D target in
284  // GL_TEXTURE1 unit bound to a non-default texture and the rest
285  // set to default textures.
286  ContextState prev_state(NULL, NULL, NULL);
287  InitializeContextState(&prev_state, 1, kServiceTextureId);
288
289  InSequence sequence;
290  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
291  // for GL_TEXTURE0 unit.
292  AddExpectationsForActiveTexture(GL_TEXTURE0);
293  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
294
295  // Expect to restore GL_TEXTURE_2D binding to the default texture
296  // for GL_TEXTURE1 unit.
297  AddExpectationsForActiveTexture(GL_TEXTURE1);
298  AddExpectationsForBindTexture(GL_TEXTURE_2D,
299                                TestHelper::kServiceDefaultTexture2dId);
300
301  // Expect to restore active texture unit to GL_TEXTURE0.
302  AddExpectationsForActiveTexture(GL_TEXTURE0);
303
304  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
305}
306
307TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit0) {
308  InitState init;
309  init.gl_version = "3.0";
310  InitDecoder(init);
311
312  // Bind a non-default texture to GL_TEXTURE1 unit.
313  EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
314  SpecializedSetup<ActiveTexture, 0>(true);
315  ActiveTexture cmd;
316  cmd.Init(GL_TEXTURE1);
317  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
318  EXPECT_EQ(GL_NO_ERROR, GetGLError());
319  SetupTexture();
320
321  // Construct a previous ContextState with GL_TEXTURE_2D target in
322  // GL_TEXTURE0 unit bound to a non-default texture and the rest
323  // set to default textures.
324  ContextState prev_state(NULL, NULL, NULL);
325  InitializeContextState(&prev_state, 0, kServiceTextureId);
326
327  InSequence sequence;
328  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
329  // the 0 texture.
330  AddExpectationsForActiveTexture(GL_TEXTURE0);
331  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
332
333  // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
334  // non-default.
335  AddExpectationsForActiveTexture(GL_TEXTURE1);
336  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
337
338  // Expect to restore active texture unit to GL_TEXTURE1.
339  AddExpectationsForActiveTexture(GL_TEXTURE1);
340
341  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
342}
343
344TEST_P(GLES2DecoderRestoreStateTest, DefaultUnit1) {
345  InitState init;
346  init.gl_version = "3.0";
347  InitDecoder(init);
348
349  // Bind a non-default texture to GL_TEXTURE0 unit.
350  SetupTexture();
351
352  // Construct a previous ContextState with GL_TEXTURE_2D target in
353  // GL_TEXTURE1 unit bound to a non-default texture and the rest
354  // set to default textures.
355  ContextState prev_state(NULL, NULL, NULL);
356  InitializeContextState(&prev_state, 1, kServiceTextureId);
357
358  InSequence sequence;
359  // Expect to restore GL_TEXTURE_2D binding to the non-default texture
360  // for GL_TEXTURE0 unit.
361  AddExpectationsForActiveTexture(GL_TEXTURE0);
362  AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
363
364  // Expect to restore GL_TEXTURE_2D binding to the 0 texture
365  // for GL_TEXTURE1 unit.
366  AddExpectationsForActiveTexture(GL_TEXTURE1);
367  AddExpectationsForBindTexture(GL_TEXTURE_2D, 0);
368
369  // Expect to restore active texture unit to GL_TEXTURE0.
370  AddExpectationsForActiveTexture(GL_TEXTURE0);
371
372  GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
373}
374
375TEST_P(GLES2DecoderManualInitTest, ContextStateCapabilityCaching) {
376  struct TestInfo {
377    GLenum gl_enum;
378    bool default_state;
379    bool expect_set;
380  };
381
382  // TODO(vmiura): Should autogen this to match build_gles2_cmd_buffer.py.
383  TestInfo test[] = {{GL_BLEND, false, true},
384                     {GL_CULL_FACE, false, true},
385                     {GL_DEPTH_TEST, false, false},
386                     {GL_DITHER, true, true},
387                     {GL_POLYGON_OFFSET_FILL, false, true},
388                     {GL_SAMPLE_ALPHA_TO_COVERAGE, false, true},
389                     {GL_SAMPLE_COVERAGE, false, true},
390                     {GL_SCISSOR_TEST, false, true},
391                     {GL_STENCIL_TEST, false, false},
392                     {0, false, false}};
393
394  InitState init;
395  init.gl_version = "2.1";
396  InitDecoder(init);
397
398  for (int i = 0; test[i].gl_enum; i++) {
399    bool enable_state = test[i].default_state;
400
401    // Test setting default state initially is ignored.
402    EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
403
404    // Test new and cached state changes.
405    for (int n = 0; n < 3; n++) {
406      enable_state = !enable_state;
407      EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
408      EnableDisableTest(test[i].gl_enum, enable_state, test[i].expect_set);
409    }
410  }
411}
412
413// TODO(vmiura): Tests for VAO restore.
414
415// TODO(vmiura): Tests for ContextState::RestoreAttribute().
416
417// TODO(vmiura): Tests for ContextState::RestoreBufferBindings().
418
419// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().
420
421// TODO(vmiura): Tests for ContextState::RestoreRenderbufferBindings().
422
423// TODO(vmiura): Tests for ContextState::RestoreProgramBindings().
424
425// TODO(vmiura): Tests for ContextState::RestoreGlobalState().
426
427}  // namespace gles2
428}  // namespace gpu
429