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