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