1// Copyright (c) 2012 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/error_state_mock.h"
6#include "gpu/command_buffer/service/framebuffer_manager.h"
7#include "gpu/command_buffer/service/feature_info.h"
8#include "gpu/command_buffer/service/gpu_service_test.h"
9#include "gpu/command_buffer/service/renderbuffer_manager.h"
10#include "gpu/command_buffer/service/test_helper.h"
11#include "gpu/command_buffer/service/texture_manager.h"
12#include "testing/gtest/include/gtest/gtest.h"
13#include "ui/gl/gl_mock.h"
14
15using ::testing::_;
16using ::testing::Return;
17
18namespace gpu {
19namespace gles2 {
20namespace {
21
22const GLint kMaxTextureSize = 64;
23const GLint kMaxCubemapSize = 64;
24const GLint kMaxRenderbufferSize = 64;
25const GLint kMaxSamples = 4;
26const uint32 kMaxDrawBuffers = 16;
27const uint32 kMaxColorAttachments = 16;
28const bool kDepth24Supported = false;
29const bool kUseDefaultTextures = false;
30
31}  // namespace
32
33class FramebufferManagerTest : public GpuServiceTest {
34 public:
35  FramebufferManagerTest()
36      : manager_(1, 1),
37        texture_manager_(NULL,
38                         new FeatureInfo(),
39                         kMaxTextureSize,
40                         kMaxCubemapSize,
41                         kUseDefaultTextures),
42        renderbuffer_manager_(NULL,
43                              kMaxRenderbufferSize,
44                              kMaxSamples,
45                              kDepth24Supported) {}
46  virtual ~FramebufferManagerTest() {
47    manager_.Destroy(false);
48    texture_manager_.Destroy(false);
49    renderbuffer_manager_.Destroy(false);
50  }
51
52 protected:
53
54  FramebufferManager manager_;
55  TextureManager texture_manager_;
56  RenderbufferManager renderbuffer_manager_;
57};
58
59TEST_F(FramebufferManagerTest, Basic) {
60  const GLuint kClient1Id = 1;
61  const GLuint kService1Id = 11;
62  const GLuint kClient2Id = 2;
63  // Check we can create framebuffer.
64  manager_.CreateFramebuffer(kClient1Id, kService1Id);
65  // Check framebuffer got created.
66  Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
67  ASSERT_TRUE(framebuffer1 != NULL);
68  EXPECT_FALSE(framebuffer1->IsDeleted());
69  EXPECT_EQ(kService1Id, framebuffer1->service_id());
70  GLuint client_id = 0;
71  EXPECT_TRUE(manager_.GetClientId(framebuffer1->service_id(), &client_id));
72  EXPECT_EQ(kClient1Id, client_id);
73  // Check we get nothing for a non-existent framebuffer.
74  EXPECT_TRUE(manager_.GetFramebuffer(kClient2Id) == NULL);
75  // Check trying to a remove non-existent framebuffers does not crash.
76  manager_.RemoveFramebuffer(kClient2Id);
77  // Check framebuffer gets deleted when last reference is released.
78  EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
79      .Times(1)
80      .RetiresOnSaturation();
81  // Check we can't get the framebuffer after we remove it.
82  manager_.RemoveFramebuffer(kClient1Id);
83  EXPECT_TRUE(manager_.GetFramebuffer(kClient1Id) == NULL);
84}
85
86TEST_F(FramebufferManagerTest, Destroy) {
87  const GLuint kClient1Id = 1;
88  const GLuint kService1Id = 11;
89  // Check we can create framebuffer.
90  manager_.CreateFramebuffer(kClient1Id, kService1Id);
91  // Check framebuffer got created.
92  Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
93  ASSERT_TRUE(framebuffer1 != NULL);
94  EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
95      .Times(1)
96      .RetiresOnSaturation();
97  manager_.Destroy(true);
98  // Check the resources were released.
99  framebuffer1 = manager_.GetFramebuffer(kClient1Id);
100  ASSERT_TRUE(framebuffer1 == NULL);
101}
102
103class FramebufferInfoTest : public GpuServiceTest {
104 public:
105  static const GLuint kClient1Id = 1;
106  static const GLuint kService1Id = 11;
107
108  FramebufferInfoTest()
109      : manager_(kMaxDrawBuffers,  kMaxColorAttachments),
110        feature_info_(new FeatureInfo()),
111        renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
112                              kDepth24Supported) {
113    texture_manager_.reset(new TextureManager(NULL,
114                                              feature_info_.get(),
115                                              kMaxTextureSize,
116                                              kMaxCubemapSize,
117                                              kUseDefaultTextures));
118  }
119  virtual ~FramebufferInfoTest() {
120    manager_.Destroy(false);
121    texture_manager_->Destroy(false);
122    renderbuffer_manager_.Destroy(false);
123  }
124
125 protected:
126  virtual void SetUp() {
127    InitializeContext("", "");
128  }
129
130  void InitializeContext(const char* gl_version, const char* extensions) {
131    GpuServiceTest::SetUp();
132    TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(),
133        extensions, "", gl_version);
134    feature_info_->Initialize();
135    manager_.CreateFramebuffer(kClient1Id, kService1Id);
136    error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
137    framebuffer_ = manager_.GetFramebuffer(kClient1Id);
138    ASSERT_TRUE(framebuffer_ != NULL);
139  }
140
141  FramebufferManager manager_;
142  Framebuffer* framebuffer_;
143  scoped_refptr<FeatureInfo> feature_info_;
144  scoped_ptr<TextureManager> texture_manager_;
145  RenderbufferManager renderbuffer_manager_;
146  scoped_ptr<MockErrorState> error_state_;
147};
148
149// GCC requires these declarations, but MSVC requires they not be present
150#ifndef COMPILER_MSVC
151const GLuint FramebufferInfoTest::kClient1Id;
152const GLuint FramebufferInfoTest::kService1Id;
153#endif
154
155TEST_F(FramebufferInfoTest, Basic) {
156  EXPECT_EQ(kService1Id, framebuffer_->service_id());
157  EXPECT_FALSE(framebuffer_->IsDeleted());
158  EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0));
159  EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT));
160  EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT));
161  EXPECT_TRUE(
162      NULL == framebuffer_->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
163  EXPECT_FALSE(framebuffer_->HasDepthAttachment());
164  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
165  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
166            framebuffer_->IsPossiblyComplete());
167  EXPECT_TRUE(framebuffer_->IsCleared());
168  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
169  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
170}
171
172TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
173  const GLuint kRenderbufferClient1Id = 33;
174  const GLuint kRenderbufferService1Id = 333;
175  const GLuint kRenderbufferClient2Id = 34;
176  const GLuint kRenderbufferService2Id = 334;
177  const GLuint kRenderbufferClient3Id = 35;
178  const GLuint kRenderbufferService3Id = 335;
179  const GLuint kRenderbufferClient4Id = 36;
180  const GLuint kRenderbufferService4Id = 336;
181  const GLsizei kWidth1 = 16;
182  const GLsizei kHeight1 = 32;
183  const GLenum kFormat1 = GL_RGBA4;
184  const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16;
185  const GLsizei kSamples1 = 0;
186  const GLsizei kWidth2 = 16;
187  const GLsizei kHeight2 = 32;
188  const GLenum kFormat2 = GL_DEPTH_COMPONENT16;
189  const GLsizei kSamples2 = 0;
190  const GLsizei kWidth3 = 16;
191  const GLsizei kHeight3 = 32;
192  const GLenum kFormat3 = GL_STENCIL_INDEX8;
193  const GLsizei kSamples3 = 0;
194  const GLsizei kWidth4 = 16;
195  const GLsizei kHeight4 = 32;
196  const GLenum kFormat4 = GL_STENCIL_INDEX8;
197  const GLsizei kSamples4 = 0;
198
199  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
200  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
201  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
202  EXPECT_FALSE(
203      framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
204
205  renderbuffer_manager_.CreateRenderbuffer(
206      kRenderbufferClient1Id, kRenderbufferService1Id);
207  Renderbuffer* renderbuffer1 =
208      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
209  ASSERT_TRUE(renderbuffer1 != NULL);
210
211  // check adding one attachment
212  framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
213  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
214  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
215  EXPECT_EQ(static_cast<GLenum>(GL_RGBA4),
216            framebuffer_->GetColorAttachmentFormat());
217  EXPECT_FALSE(framebuffer_->HasDepthAttachment());
218  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
219  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
220            framebuffer_->IsPossiblyComplete());
221  EXPECT_TRUE(framebuffer_->IsCleared());
222
223  // Try a format that's not good for COLOR_ATTACHMENT0.
224  renderbuffer_manager_.SetInfo(
225      renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1);
226  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
227            framebuffer_->IsPossiblyComplete());
228
229  // Try a good format.
230  renderbuffer_manager_.SetInfo(
231      renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
232  EXPECT_EQ(static_cast<GLenum>(kFormat1),
233            framebuffer_->GetColorAttachmentFormat());
234  EXPECT_FALSE(framebuffer_->HasDepthAttachment());
235  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
236  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
237            framebuffer_->IsPossiblyComplete());
238  EXPECT_FALSE(framebuffer_->IsCleared());
239
240  // check adding another
241  renderbuffer_manager_.CreateRenderbuffer(
242      kRenderbufferClient2Id, kRenderbufferService2Id);
243  Renderbuffer* renderbuffer2 =
244      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
245  ASSERT_TRUE(renderbuffer2 != NULL);
246  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2);
247  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
248  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
249  EXPECT_EQ(static_cast<GLenum>(kFormat1),
250            framebuffer_->GetColorAttachmentFormat());
251  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
252  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
253  // The attachment has a size of 0,0 so depending on the order of the map
254  // of attachments it could either get INCOMPLETE_ATTACHMENT because it's 0,0
255  // or INCOMPLETE_DIMENSIONS because it's not the same size as the other
256  // attachment.
257  GLenum status = framebuffer_->IsPossiblyComplete();
258  EXPECT_TRUE(
259      status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ||
260      status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
261  EXPECT_FALSE(framebuffer_->IsCleared());
262
263  renderbuffer_manager_.SetInfo(
264      renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2);
265  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
266            framebuffer_->IsPossiblyComplete());
267  EXPECT_FALSE(framebuffer_->IsCleared());
268  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
269
270  // check marking them as cleared.
271  manager_.MarkAttachmentsAsCleared(
272      framebuffer_, &renderbuffer_manager_, texture_manager_.get());
273  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
274  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
275  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
276            framebuffer_->IsPossiblyComplete());
277  EXPECT_TRUE(framebuffer_->IsCleared());
278
279  // Check adding one that is already cleared.
280  renderbuffer_manager_.CreateRenderbuffer(
281      kRenderbufferClient3Id, kRenderbufferService3Id);
282  Renderbuffer* renderbuffer3 =
283      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id);
284  ASSERT_TRUE(renderbuffer3 != NULL);
285  renderbuffer_manager_.SetInfo(
286      renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3);
287  renderbuffer_manager_.SetCleared(renderbuffer3, true);
288
289  framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3);
290  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
291  EXPECT_EQ(static_cast<GLenum>(kFormat1),
292            framebuffer_->GetColorAttachmentFormat());
293  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
294  EXPECT_TRUE(framebuffer_->HasStencilAttachment());
295  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
296            framebuffer_->IsPossiblyComplete());
297  EXPECT_TRUE(framebuffer_->IsCleared());
298
299  // Check marking the renderbuffer as unclared.
300  renderbuffer_manager_.SetInfo(
301      renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
302  EXPECT_EQ(static_cast<GLenum>(kFormat1),
303            framebuffer_->GetColorAttachmentFormat());
304  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
305  EXPECT_TRUE(framebuffer_->HasStencilAttachment());
306  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
307            framebuffer_->IsPossiblyComplete());
308  EXPECT_FALSE(framebuffer_->IsCleared());
309
310  const Framebuffer::Attachment* attachment =
311      framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
312  ASSERT_TRUE(attachment != NULL);
313  EXPECT_EQ(kWidth1, attachment->width());
314  EXPECT_EQ(kHeight1, attachment->height());
315  EXPECT_EQ(kSamples1, attachment->samples());
316  EXPECT_EQ(kFormat1, attachment->internal_format());
317  EXPECT_FALSE(attachment->cleared());
318
319  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
320
321  // Clear it.
322  manager_.MarkAttachmentsAsCleared(
323      framebuffer_, &renderbuffer_manager_, texture_manager_.get());
324  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
325  EXPECT_TRUE(framebuffer_->IsCleared());
326
327  // Check replacing an attachment
328  renderbuffer_manager_.CreateRenderbuffer(
329      kRenderbufferClient4Id, kRenderbufferService4Id);
330  Renderbuffer* renderbuffer4 =
331      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id);
332  ASSERT_TRUE(renderbuffer4 != NULL);
333  renderbuffer_manager_.SetInfo(
334      renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4);
335
336  framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4);
337  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
338  EXPECT_FALSE(framebuffer_->IsCleared());
339
340  attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
341  ASSERT_TRUE(attachment != NULL);
342  EXPECT_EQ(kWidth4, attachment->width());
343  EXPECT_EQ(kHeight4, attachment->height());
344  EXPECT_EQ(kSamples4, attachment->samples());
345  EXPECT_EQ(kFormat4, attachment->internal_format());
346  EXPECT_FALSE(attachment->cleared());
347  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
348            framebuffer_->IsPossiblyComplete());
349
350  // Check changing an attachment.
351  renderbuffer_manager_.SetInfo(
352      renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4);
353
354  attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
355  ASSERT_TRUE(attachment != NULL);
356  EXPECT_EQ(kWidth4 + 1, attachment->width());
357  EXPECT_EQ(kHeight4, attachment->height());
358  EXPECT_EQ(kSamples4, attachment->samples());
359  EXPECT_EQ(kFormat4, attachment->internal_format());
360  EXPECT_FALSE(attachment->cleared());
361  EXPECT_FALSE(framebuffer_->IsCleared());
362  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT),
363            framebuffer_->IsPossiblyComplete());
364
365  // Check removing it.
366  framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, NULL);
367  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
368  EXPECT_EQ(static_cast<GLenum>(kFormat1),
369            framebuffer_->GetColorAttachmentFormat());
370  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
371  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
372
373  EXPECT_TRUE(framebuffer_->IsCleared());
374  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
375            framebuffer_->IsPossiblyComplete());
376
377  // Remove depth, Set color to 0 size.
378  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL);
379  renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0);
380  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
381            framebuffer_->IsPossiblyComplete());
382
383  // Remove color.
384  framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, NULL);
385  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
386            framebuffer_->IsPossiblyComplete());
387}
388
389TEST_F(FramebufferInfoTest, AttachTexture) {
390  const GLuint kTextureClient1Id = 33;
391  const GLuint kTextureService1Id = 333;
392  const GLuint kTextureClient2Id = 34;
393  const GLuint kTextureService2Id = 334;
394  const GLint kDepth = 1;
395  const GLint kBorder = 0;
396  const GLenum kType = GL_UNSIGNED_BYTE;
397  const GLsizei kWidth1 = 16;
398  const GLsizei kHeight1 = 32;
399  const GLint kLevel1 = 0;
400  const GLenum kFormat1 = GL_RGBA;
401  const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16;
402  const GLenum kTarget1 = GL_TEXTURE_2D;
403  const GLsizei kSamples1 = 0;
404  const GLsizei kWidth2 = 16;
405  const GLsizei kHeight2 = 32;
406  const GLint kLevel2 = 0;
407  const GLenum kFormat2 = GL_RGB;
408  const GLenum kTarget2 = GL_TEXTURE_2D;
409  const GLsizei kSamples2 = 0;
410  const GLsizei kWidth3 = 75;
411  const GLsizei kHeight3 = 123;
412  const GLint kLevel3 = 0;
413  const GLenum kFormat3 = GL_RGB565;
414  const GLsizei kSamples3 = 0;
415  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
416  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
417  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
418  EXPECT_FALSE(
419      framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
420  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
421            framebuffer_->IsPossiblyComplete());
422
423  texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
424  scoped_refptr<TextureRef> texture1(
425      texture_manager_->GetTexture(kTextureClient1Id));
426  ASSERT_TRUE(texture1.get() != NULL);
427
428  // check adding one attachment
429  framebuffer_->AttachTexture(
430      GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
431  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
432  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
433            framebuffer_->IsPossiblyComplete());
434  EXPECT_TRUE(framebuffer_->IsCleared());
435  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
436
437  // Try format that doesn't work with COLOR_ATTACHMENT0
438  texture_manager_->SetTarget(texture1.get(), GL_TEXTURE_2D);
439  texture_manager_->SetLevelInfo(texture1.get(),
440                                GL_TEXTURE_2D,
441                                kLevel1,
442                                kBadFormat1,
443                                kWidth1,
444                                kHeight1,
445                                kDepth,
446                                kBorder,
447                                kBadFormat1,
448                                kType,
449                                true);
450  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
451            framebuffer_->IsPossiblyComplete());
452
453  // Try a good format.
454  texture_manager_->SetLevelInfo(texture1.get(),
455                                GL_TEXTURE_2D,
456                                kLevel1,
457                                kFormat1,
458                                kWidth1,
459                                kHeight1,
460                                kDepth,
461                                kBorder,
462                                kFormat1,
463                                kType,
464                                false);
465  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
466            framebuffer_->IsPossiblyComplete());
467  EXPECT_FALSE(framebuffer_->IsCleared());
468  texture_manager_->SetLevelInfo(texture1.get(),
469                                GL_TEXTURE_2D,
470                                kLevel1,
471                                kFormat1,
472                                kWidth1,
473                                kHeight1,
474                                kDepth,
475                                kBorder,
476                                kFormat1,
477                                kType,
478                                true);
479  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
480            framebuffer_->IsPossiblyComplete());
481  EXPECT_TRUE(framebuffer_->IsCleared());
482  EXPECT_EQ(static_cast<GLenum>(kFormat1),
483            framebuffer_->GetColorAttachmentFormat());
484
485  const Framebuffer::Attachment* attachment =
486      framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
487  ASSERT_TRUE(attachment != NULL);
488  EXPECT_EQ(kWidth1, attachment->width());
489  EXPECT_EQ(kHeight1, attachment->height());
490  EXPECT_EQ(kSamples1, attachment->samples());
491  EXPECT_EQ(kFormat1, attachment->internal_format());
492  EXPECT_TRUE(attachment->cleared());
493
494  // Check replacing an attachment
495  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
496  scoped_refptr<TextureRef> texture2(
497      texture_manager_->GetTexture(kTextureClient2Id));
498  ASSERT_TRUE(texture2.get() != NULL);
499  texture_manager_->SetTarget(texture2.get(), GL_TEXTURE_2D);
500  texture_manager_->SetLevelInfo(texture2.get(),
501                                GL_TEXTURE_2D,
502                                kLevel2,
503                                kFormat2,
504                                kWidth2,
505                                kHeight2,
506                                kDepth,
507                                kBorder,
508                                kFormat2,
509                                kType,
510                                true);
511
512  framebuffer_->AttachTexture(
513      GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2, kSamples2);
514  EXPECT_EQ(static_cast<GLenum>(kFormat2),
515            framebuffer_->GetColorAttachmentFormat());
516  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
517            framebuffer_->IsPossiblyComplete());
518  EXPECT_TRUE(framebuffer_->IsCleared());
519
520  attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
521  ASSERT_TRUE(attachment != NULL);
522  EXPECT_EQ(kWidth2, attachment->width());
523  EXPECT_EQ(kHeight2, attachment->height());
524  EXPECT_EQ(kSamples2, attachment->samples());
525  EXPECT_EQ(kFormat2, attachment->internal_format());
526  EXPECT_TRUE(attachment->cleared());
527
528  // Check changing attachment
529  texture_manager_->SetLevelInfo(texture2.get(),
530                                GL_TEXTURE_2D,
531                                kLevel3,
532                                kFormat3,
533                                kWidth3,
534                                kHeight3,
535                                kDepth,
536                                kBorder,
537                                kFormat3,
538                                kType,
539                                false);
540  attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
541  ASSERT_TRUE(attachment != NULL);
542  EXPECT_EQ(kWidth3, attachment->width());
543  EXPECT_EQ(kHeight3, attachment->height());
544  EXPECT_EQ(kSamples3, attachment->samples());
545  EXPECT_EQ(kFormat3, attachment->internal_format());
546  EXPECT_FALSE(attachment->cleared());
547  EXPECT_EQ(static_cast<GLenum>(kFormat3),
548            framebuffer_->GetColorAttachmentFormat());
549  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
550            framebuffer_->IsPossiblyComplete());
551  EXPECT_FALSE(framebuffer_->IsCleared());
552
553  // Set to size 0
554  texture_manager_->SetLevelInfo(texture2.get(),
555                                GL_TEXTURE_2D,
556                                kLevel3,
557                                kFormat3,
558                                0,
559                                0,
560                                kDepth,
561                                kBorder,
562                                kFormat3,
563                                kType,
564                                false);
565  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
566            framebuffer_->IsPossiblyComplete());
567
568  // Check removing it.
569  framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0, 0);
570  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
571  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
572
573  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
574            framebuffer_->IsPossiblyComplete());
575  EXPECT_TRUE(framebuffer_->IsCleared());
576}
577
578TEST_F(FramebufferInfoTest, DrawBuffers) {
579  const GLuint kTextureClientId[] = { 33, 34 };
580  const GLuint kTextureServiceId[] = { 333, 334 };
581
582  for (GLenum i = GL_COLOR_ATTACHMENT0;
583       i < GL_COLOR_ATTACHMENT0 + kMaxColorAttachments; ++i) {
584    EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(i));
585  }
586  EXPECT_FALSE(framebuffer_->HasUnclearedColorAttachments());
587
588  EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT0),
589            framebuffer_->GetDrawBuffer(GL_DRAW_BUFFER0_ARB));
590  for (GLenum i = GL_DRAW_BUFFER1_ARB;
591       i < GL_DRAW_BUFFER0_ARB + kMaxDrawBuffers; ++i) {
592    EXPECT_EQ(static_cast<GLenum>(GL_NONE),
593              framebuffer_->GetDrawBuffer(i));
594  }
595
596  for (size_t ii = 0; ii < arraysize(kTextureClientId); ++ii) {
597    texture_manager_->CreateTexture(
598        kTextureClientId[ii], kTextureServiceId[ii]);
599    scoped_refptr<TextureRef> texture(
600        texture_manager_->GetTexture(kTextureClientId[ii]));
601    ASSERT_TRUE(texture.get() != NULL);
602
603    framebuffer_->AttachTexture(
604        GL_COLOR_ATTACHMENT0 + ii, texture.get(), GL_TEXTURE_2D, 0, 0);
605    EXPECT_FALSE(
606        framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0 + ii));
607
608    const Framebuffer::Attachment* attachment =
609        framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0 + ii);
610    ASSERT_TRUE(attachment != NULL);
611    EXPECT_TRUE(attachment->cleared());
612  }
613  EXPECT_TRUE(framebuffer_->IsCleared());
614  EXPECT_FALSE(framebuffer_->HasUnclearedColorAttachments());
615
616  // Set a texture as uncleared.
617  scoped_refptr<TextureRef> texture1(
618      texture_manager_->GetTexture(kTextureClientId[1]));
619  texture_manager_->SetTarget(texture1.get(), GL_TEXTURE_2D);
620  texture_manager_->SetLevelInfo(
621      texture1.get(), GL_TEXTURE_2D, 0, GL_RGBA, 4, 4,
622      1, 0, GL_RGBA, GL_UNSIGNED_BYTE, false);
623
624  const Framebuffer::Attachment* attachment1 =
625      framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT1);
626  ASSERT_TRUE(attachment1 != NULL);
627  EXPECT_FALSE(attachment1->cleared());
628  EXPECT_FALSE(framebuffer_->IsCleared());
629  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT1));
630  EXPECT_TRUE(framebuffer_->HasUnclearedColorAttachments());
631
632  GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
633  framebuffer_->SetDrawBuffers(2, buffers);
634  EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT0),
635            framebuffer_->GetDrawBuffer(GL_DRAW_BUFFER0_ARB));
636  EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT1),
637            framebuffer_->GetDrawBuffer(GL_DRAW_BUFFER1_ARB));
638  for (GLenum i = GL_DRAW_BUFFER2_ARB;
639       i < GL_DRAW_BUFFER0_ARB + kMaxDrawBuffers; ++i) {
640    EXPECT_EQ(static_cast<GLenum>(GL_NONE),
641              framebuffer_->GetDrawBuffer(i));
642  }
643
644  // Nothing happens.
645  framebuffer_->PrepareDrawBuffersForClear();
646  framebuffer_->RestoreDrawBuffersAfterClear();
647
648  // Now we disable a draw buffer 1.
649  buffers[1] = GL_NONE;
650  framebuffer_->SetDrawBuffers(2, buffers);
651  // We will enable the disabled draw buffer for clear(), and disable it
652  // after the clear.
653  EXPECT_CALL(*gl_, DrawBuffersARB(kMaxDrawBuffers, _))
654      .Times(1)
655      .RetiresOnSaturation();
656  framebuffer_->PrepareDrawBuffersForClear();
657  EXPECT_CALL(*gl_, DrawBuffersARB(kMaxDrawBuffers, _))
658      .Times(1)
659      .RetiresOnSaturation();
660  framebuffer_->RestoreDrawBuffersAfterClear();
661
662  // Now remove draw buffer 1's attachment.
663  framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT1, NULL, 0, 0, 0);
664  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT1) == NULL);
665
666  // Nothing happens.
667  framebuffer_->PrepareDrawBuffersForClear();
668  framebuffer_->RestoreDrawBuffersAfterClear();
669}
670
671class FramebufferInfoFloatTest : public FramebufferInfoTest {
672 public:
673  FramebufferInfoFloatTest()
674    : FramebufferInfoTest() {
675  }
676  virtual ~FramebufferInfoFloatTest() {
677  }
678
679 protected:
680  virtual void SetUp() {
681    InitializeContext("OpenGL ES 3.0",
682        "GL_OES_texture_float GL_EXT_color_buffer_float");
683  }
684};
685
686TEST_F(FramebufferInfoFloatTest, AttachFloatTexture) {
687  const GLuint kTextureClientId = 33;
688  const GLuint kTextureServiceId = 333;
689  const GLint kDepth = 1;
690  const GLint kBorder = 0;
691  const GLenum kType = GL_FLOAT;
692  const GLsizei kWidth = 16;
693  const GLsizei kHeight = 32;
694  const GLint kLevel = 0;
695  const GLenum kFormat = GL_RGBA;
696  const GLenum kInternalFormat = GL_RGBA32F;
697  const GLenum kTarget = GL_TEXTURE_2D;
698  const GLsizei kSamples = 0;
699  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
700  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
701  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
702
703  texture_manager_->CreateTexture(kTextureClientId, kTextureServiceId);
704  scoped_refptr<TextureRef> texture(
705      texture_manager_->GetTexture(kTextureClientId));
706  ASSERT_TRUE(texture.get() != NULL);
707
708  framebuffer_->AttachTexture(
709      GL_COLOR_ATTACHMENT0, texture.get(), kTarget, kLevel, kSamples);
710  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
711
712  texture_manager_->SetTarget(texture.get(), GL_TEXTURE_2D);
713  texture_manager_->SetLevelInfo(texture.get(),
714                                GL_TEXTURE_2D,
715                                kLevel,
716                                kInternalFormat,
717                                kWidth,
718                                kHeight,
719                                kDepth,
720                                kBorder,
721                                kFormat,
722                                kType,
723                                false);
724  // Texture with a sized float internalformat is allowed as an attachment
725  // since float color attachment extension is present.
726  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
727            framebuffer_->IsPossiblyComplete());
728}
729
730TEST_F(FramebufferInfoTest, UnbindRenderbuffer) {
731  const GLuint kRenderbufferClient1Id = 33;
732  const GLuint kRenderbufferService1Id = 333;
733  const GLuint kRenderbufferClient2Id = 34;
734  const GLuint kRenderbufferService2Id = 334;
735
736  renderbuffer_manager_.CreateRenderbuffer(
737      kRenderbufferClient1Id, kRenderbufferService1Id);
738  Renderbuffer* renderbuffer1 =
739      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
740  ASSERT_TRUE(renderbuffer1 != NULL);
741  renderbuffer_manager_.CreateRenderbuffer(
742      kRenderbufferClient2Id, kRenderbufferService2Id);
743  Renderbuffer* renderbuffer2 =
744      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
745  ASSERT_TRUE(renderbuffer2 != NULL);
746
747  // Attach to 2 attachment points.
748  framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
749  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
750  // Check they were attached.
751  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
752  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
753  // Unbind unattached renderbuffer.
754  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer2);
755  // Should be no-op.
756  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
757  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
758  // Unbind renderbuffer.
759  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
760  // Check they were detached
761  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
762  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL);
763}
764
765TEST_F(FramebufferInfoTest, UnbindTexture) {
766  const GLuint kTextureClient1Id = 33;
767  const GLuint kTextureService1Id = 333;
768  const GLuint kTextureClient2Id = 34;
769  const GLuint kTextureService2Id = 334;
770  const GLenum kTarget1 = GL_TEXTURE_2D;
771  const GLint kLevel1 = 0;
772  const GLint kSamples1 = 0;
773
774  texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
775  scoped_refptr<TextureRef> texture1(
776      texture_manager_->GetTexture(kTextureClient1Id));
777  ASSERT_TRUE(texture1.get() != NULL);
778  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
779  scoped_refptr<TextureRef> texture2(
780      texture_manager_->GetTexture(kTextureClient2Id));
781  ASSERT_TRUE(texture2.get() != NULL);
782
783  // Attach to 2 attachment points.
784  framebuffer_->AttachTexture(
785      GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
786  framebuffer_->AttachTexture(
787      GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1, kSamples1);
788  // Check they were attached.
789  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
790  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
791  // Unbind unattached texture.
792  framebuffer_->UnbindTexture(kTarget1, texture2.get());
793  // Should be no-op.
794  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
795  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
796  // Unbind texture.
797  framebuffer_->UnbindTexture(kTarget1, texture1.get());
798  // Check they were detached
799  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
800  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL);
801}
802
803TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
804  const GLuint kRenderbufferClient1Id = 33;
805  const GLuint kRenderbufferService1Id = 333;
806  const GLuint kTextureClient2Id = 34;
807  const GLuint kTextureService2Id = 334;
808  const GLenum kTarget1 = GL_TEXTURE_2D;
809  const GLint kLevel1 = 0;
810  const GLint kSamples1 = 0;
811
812  renderbuffer_manager_.CreateRenderbuffer(
813      kRenderbufferClient1Id, kRenderbufferService1Id);
814  Renderbuffer* renderbuffer1 =
815      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
816  ASSERT_TRUE(renderbuffer1 != NULL);
817  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
818  scoped_refptr<TextureRef> texture2(
819      texture_manager_->GetTexture(kTextureClient2Id));
820  ASSERT_TRUE(texture2.get() != NULL);
821
822  // Check MarkAsComlete marks as complete.
823  manager_.MarkAsComplete(framebuffer_);
824  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
825
826  // Check at attaching marks as not complete.
827  framebuffer_->AttachTexture(
828      GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
829  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
830  manager_.MarkAsComplete(framebuffer_);
831  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
832  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
833  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
834
835  // Check MarkAttachmentsAsCleared marks as complete.
836  manager_.MarkAttachmentsAsCleared(
837      framebuffer_, &renderbuffer_manager_, texture_manager_.get());
838  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
839
840  // Check Unbind marks as not complete.
841  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
842  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
843  manager_.MarkAsComplete(framebuffer_);
844  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
845  framebuffer_->UnbindTexture(kTarget1, texture2.get());
846  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
847}
848
849TEST_F(FramebufferInfoTest, GetStatus) {
850  const GLuint kRenderbufferClient1Id = 33;
851  const GLuint kRenderbufferService1Id = 333;
852  const GLuint kTextureClient2Id = 34;
853  const GLuint kTextureService2Id = 334;
854  const GLenum kTarget1 = GL_TEXTURE_2D;
855  const GLint kLevel1 = 0;
856  const GLint kSamples1 = 0;
857
858  renderbuffer_manager_.CreateRenderbuffer(
859      kRenderbufferClient1Id, kRenderbufferService1Id);
860  Renderbuffer* renderbuffer1 =
861      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
862  ASSERT_TRUE(renderbuffer1 != NULL);
863  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
864  scoped_refptr<TextureRef> texture2(
865      texture_manager_->GetTexture(kTextureClient2Id));
866  ASSERT_TRUE(texture2.get() != NULL);
867  texture_manager_->SetTarget(texture2.get(), GL_TEXTURE_2D);
868
869  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
870      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
871      .RetiresOnSaturation();
872  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
873
874  // Check a second call for the same type does not call anything
875  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
876    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
877        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
878        .RetiresOnSaturation();
879  }
880  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
881
882  // Check changing the attachments calls CheckFramebufferStatus.
883  framebuffer_->AttachTexture(
884      GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
885  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
886      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)).RetiresOnSaturation();
887  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
888
889  // Check a second call for the same type does not call anything.
890  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
891    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
892        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
893        .RetiresOnSaturation();
894  }
895  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
896
897  // Check a second call with a different target calls CheckFramebufferStatus.
898  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
899      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
900      .RetiresOnSaturation();
901  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
902
903  // Check a second call for the same type does not call anything.
904  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
905    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
906        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
907        .RetiresOnSaturation();
908  }
909  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
910
911  // Check adding another attachment calls CheckFramebufferStatus.
912  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
913  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
914      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
915      .RetiresOnSaturation();
916  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
917
918  // Check a second call for the same type does not call anything.
919  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
920    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
921        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
922        .RetiresOnSaturation();
923  }
924  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
925
926  // Check changing the format calls CheckFramebuffferStatus.
927  TestHelper::SetTexParameteriWithExpectations(gl_.get(),
928                                               error_state_.get(),
929                                               texture_manager_.get(),
930                                               texture2.get(),
931                                               GL_TEXTURE_WRAP_S,
932                                               GL_CLAMP_TO_EDGE,
933                                               GL_NO_ERROR);
934
935  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
936      .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
937      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
938      .RetiresOnSaturation();
939  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
940
941  // Check since it did not return FRAMEBUFFER_COMPLETE that it calls
942  // CheckFramebufferStatus
943  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
944
945  // Check putting it back does not call CheckFramebufferStatus.
946  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
947    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
948        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
949        .RetiresOnSaturation();
950  }
951  TestHelper::SetTexParameteriWithExpectations(gl_.get(),
952                                               error_state_.get(),
953                                               texture_manager_.get(),
954                                               texture2.get(),
955                                               GL_TEXTURE_WRAP_S,
956                                               GL_REPEAT,
957                                               GL_NO_ERROR);
958  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
959
960  // Check Unbinding does not call CheckFramebufferStatus
961  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
962  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
963    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
964        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
965        .RetiresOnSaturation();
966  }
967  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
968}
969
970}  // namespace gles2
971}  // namespace gpu
972
973
974