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.
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"
14 using ::testing::Return;
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;
28 class FramebufferManagerTest : public testing::Test {
30 FramebufferManagerTest()
33 NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize),
34 renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
37 virtual ~FramebufferManagerTest() {
38 manager_.Destroy(false);
39 texture_manager_.Destroy(false);
40 renderbuffer_manager_.Destroy(false);
44 virtual void SetUp() {
45 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
46 ::gfx::MockGLInterface::SetGLInterface(gl_.get());
49 virtual void TearDown() {
50 ::gfx::MockGLInterface::SetGLInterface(NULL);
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_;
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());
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)))
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);
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)))
98 .RetiresOnSaturation();
99 manager_.Destroy(true);
100 // Check the resources were released.
101 framebuffer1 = manager_.GetFramebuffer(kClient1Id);
102 ASSERT_TRUE(framebuffer1 == NULL);
105 class FramebufferInfoTest : public testing::Test {
107 static const GLuint kClient1Id = 1;
108 static const GLuint kService1Id = 11;
110 FramebufferInfoTest()
112 feature_info_(new FeatureInfo()),
113 renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
115 texture_manager_.reset(new TextureManager(NULL, feature_info_.get(),
116 kMaxTextureSize, kMaxCubemapSize));
118 virtual ~FramebufferInfoTest() {
119 manager_.Destroy(false);
120 texture_manager_->Destroy(false);
121 renderbuffer_manager_.Destroy(false);
125 virtual void SetUp() {
126 InitializeContext("", "");
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);
141 virtual void TearDown() {
142 ::gfx::MockGLInterface::SetGLInterface(NULL);
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_;
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;
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));
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_));
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;
206 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
207 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
208 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
210 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
212 renderbuffer_manager_.CreateRenderbuffer(
213 kRenderbufferClient1Id, kRenderbufferService1Id);
214 Renderbuffer* renderbuffer1 =
215 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
216 ASSERT_TRUE(renderbuffer1 != NULL);
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());
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());
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());
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
264 GLenum status = framebuffer_->IsPossiblyComplete();
266 status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ||
267 status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
268 EXPECT_FALSE(framebuffer_->IsCleared());
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));
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());
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);
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());
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());
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());
326 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
329 manager_.MarkAttachmentsAsCleared(
330 framebuffer_, &renderbuffer_manager_, texture_manager_.get());
331 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
332 EXPECT_TRUE(framebuffer_->IsCleared());
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);
343 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4);
344 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
345 EXPECT_FALSE(framebuffer_->IsCleared());
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());
357 // Check changing an attachment.
358 renderbuffer_manager_.SetInfo(
359 renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4);
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());
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());
380 EXPECT_TRUE(framebuffer_->IsCleared());
381 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
382 framebuffer_->IsPossiblyComplete());
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());
391 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, NULL);
392 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
393 framebuffer_->IsPossiblyComplete());
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));
426 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
427 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
428 framebuffer_->IsPossiblyComplete());
430 texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
431 scoped_refptr<TextureRef> texture1(
432 texture_manager_->GetTexture(kTextureClient1Id));
433 ASSERT_TRUE(texture1.get() != NULL);
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());
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(),
457 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
458 framebuffer_->IsPossiblyComplete());
460 // Try a good format.
461 texture_manager_->SetLevelInfo(texture1.get(),
472 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
473 framebuffer_->IsPossiblyComplete());
474 EXPECT_FALSE(framebuffer_->IsCleared());
475 texture_manager_->SetLevelInfo(texture1.get(),
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());
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());
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(),
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());
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());
535 // Check changing attachment
536 texture_manager_->SetLevelInfo(texture2.get(),
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());
561 texture_manager_->SetLevelInfo(texture2.get(),
572 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
573 framebuffer_->IsPossiblyComplete());
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());
580 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
581 framebuffer_->IsPossiblyComplete());
582 EXPECT_TRUE(framebuffer_->IsCleared());
585 class FramebufferInfoFloatTest : public FramebufferInfoTest {
587 FramebufferInfoFloatTest()
588 : FramebufferInfoTest() {
590 virtual ~FramebufferInfoFloatTest() {
594 virtual void SetUp() {
595 InitializeContext("OpenGL ES 3.0",
596 "GL_OES_texture_float GL_EXT_color_buffer_float");
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));
617 texture_manager_->CreateTexture(kTextureClientId, kTextureServiceId);
618 scoped_refptr<TextureRef> texture(
619 texture_manager_->GetTexture(kTextureClientId));
620 ASSERT_TRUE(texture.get() != NULL);
622 framebuffer_->AttachTexture(
623 GL_COLOR_ATTACHMENT0, texture.get(), kTarget, kLevel, kSamples);
624 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
626 texture_manager_->SetTarget(texture.get(), GL_TEXTURE_2D);
627 texture_manager_->SetLevelInfo(texture.get(),
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());
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;
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);
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);
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);
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;
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);
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());
708 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
709 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
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);
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;
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);
736 // Check MarkAsComlete marks as complete.
737 manager_.MarkAsComplete(framebuffer_);
738 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
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_));
749 // Check MarkAttachmentsAsCleared marks as complete.
750 manager_.MarkAttachmentsAsCleared(
751 framebuffer_, &renderbuffer_manager_, texture_manager_.get());
752 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
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_));
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;
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);
783 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
784 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
785 .RetiresOnSaturation();
786 framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
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();
794 framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
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);
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();
809 framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
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);
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();
823 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
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);
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();
838 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
840 // Check changing the format calls CheckFramebuffferStatus.
841 TestHelper::SetTexParameterWithExpectations(gl_.get(),
843 texture_manager_.get(),
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);
855 // Check since it did not return FRAMEBUFFER_COMPLETE that it calls
856 // CheckFramebufferStatus
857 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
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();
865 TestHelper::SetTexParameterWithExpectations(gl_.get(),
867 texture_manager_.get(),
872 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
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();
881 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);