• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 using ::testing::_;
16 using ::testing::Return;
17 
18 namespace gpu {
19 namespace gles2 {
20 namespace {
21 
22 const GLint kMaxTextureSize = 64;
23 const GLint kMaxCubemapSize = 64;
24 const GLint kMaxRenderbufferSize = 64;
25 const GLint kMaxSamples = 4;
26 const uint32 kMaxDrawBuffers = 16;
27 const uint32 kMaxColorAttachments = 16;
28 const bool kDepth24Supported = false;
29 const bool kUseDefaultTextures = false;
30 
31 }  // namespace
32 
33 class FramebufferManagerTest : public GpuServiceTest {
34  public:
FramebufferManagerTest()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) {}
~FramebufferManagerTest()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 
TEST_F(FramebufferManagerTest,Basic)59 TEST_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 
TEST_F(FramebufferManagerTest,Destroy)86 TEST_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 
103 class FramebufferInfoTest : public GpuServiceTest {
104  public:
105   static const GLuint kClient1Id = 1;
106   static const GLuint kService1Id = 11;
107 
FramebufferInfoTest()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   }
~FramebufferInfoTest()119   virtual ~FramebufferInfoTest() {
120     manager_.Destroy(false);
121     texture_manager_->Destroy(false);
122     renderbuffer_manager_.Destroy(false);
123   }
124 
125  protected:
SetUp()126   virtual void SetUp() {
127     InitializeContext("", "");
128   }
129 
InitializeContext(const char * gl_version,const char * extensions)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
151 const GLuint FramebufferInfoTest::kClient1Id;
152 const GLuint FramebufferInfoTest::kService1Id;
153 #endif
154 
TEST_F(FramebufferInfoTest,Basic)155 TEST_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 
TEST_F(FramebufferInfoTest,AttachRenderbuffer)172 TEST_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 
TEST_F(FramebufferInfoTest,AttachTexture)389 TEST_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 
TEST_F(FramebufferInfoTest,DrawBuffers)578 TEST_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 
671 class FramebufferInfoFloatTest : public FramebufferInfoTest {
672  public:
FramebufferInfoFloatTest()673   FramebufferInfoFloatTest()
674     : FramebufferInfoTest() {
675   }
~FramebufferInfoFloatTest()676   virtual ~FramebufferInfoFloatTest() {
677   }
678 
679  protected:
SetUp()680   virtual void SetUp() {
681     InitializeContext("OpenGL ES 3.0",
682         "GL_OES_texture_float GL_EXT_color_buffer_float");
683   }
684 };
685 
TEST_F(FramebufferInfoFloatTest,AttachFloatTexture)686 TEST_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 
TEST_F(FramebufferInfoTest,UnbindRenderbuffer)730 TEST_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 
TEST_F(FramebufferInfoTest,UnbindTexture)765 TEST_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 
TEST_F(FramebufferInfoTest,IsCompleteMarkAsComplete)803 TEST_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 
TEST_F(FramebufferInfoTest,GetStatus)849 TEST_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