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