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;
25 const bool kUseDefaultTextures = false;
29 class FramebufferManagerTest : public testing::Test {
31 FramebufferManagerTest()
33 texture_manager_(NULL,
38 renderbuffer_manager_(NULL,
42 virtual ~FramebufferManagerTest() {
43 manager_.Destroy(false);
44 texture_manager_.Destroy(false);
45 renderbuffer_manager_.Destroy(false);
49 virtual void SetUp() {
50 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
51 ::gfx::MockGLInterface::SetGLInterface(gl_.get());
54 virtual void TearDown() {
55 ::gfx::MockGLInterface::SetGLInterface(NULL);
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_;
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());
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)))
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);
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)))
103 .RetiresOnSaturation();
104 manager_.Destroy(true);
105 // Check the resources were released.
106 framebuffer1 = manager_.GetFramebuffer(kClient1Id);
107 ASSERT_TRUE(framebuffer1 == NULL);
110 class FramebufferInfoTest : public testing::Test {
112 static const GLuint kClient1Id = 1;
113 static const GLuint kService1Id = 11;
115 FramebufferInfoTest()
117 feature_info_(new FeatureInfo()),
118 renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
120 texture_manager_.reset(new TextureManager(NULL,
124 kUseDefaultTextures));
126 virtual ~FramebufferInfoTest() {
127 manager_.Destroy(false);
128 texture_manager_->Destroy(false);
129 renderbuffer_manager_.Destroy(false);
133 virtual void SetUp() {
134 InitializeContext("", "");
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);
149 virtual void TearDown() {
150 ::gfx::MockGLInterface::SetGLInterface(NULL);
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_;
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;
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));
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_));
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;
214 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
215 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
216 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
218 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
220 renderbuffer_manager_.CreateRenderbuffer(
221 kRenderbufferClient1Id, kRenderbufferService1Id);
222 Renderbuffer* renderbuffer1 =
223 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
224 ASSERT_TRUE(renderbuffer1 != NULL);
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());
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());
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());
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
272 GLenum status = framebuffer_->IsPossiblyComplete();
274 status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ||
275 status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
276 EXPECT_FALSE(framebuffer_->IsCleared());
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));
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());
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);
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());
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());
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());
334 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
337 manager_.MarkAttachmentsAsCleared(
338 framebuffer_, &renderbuffer_manager_, texture_manager_.get());
339 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
340 EXPECT_TRUE(framebuffer_->IsCleared());
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);
351 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4);
352 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
353 EXPECT_FALSE(framebuffer_->IsCleared());
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());
365 // Check changing an attachment.
366 renderbuffer_manager_.SetInfo(
367 renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4);
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());
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());
388 EXPECT_TRUE(framebuffer_->IsCleared());
389 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
390 framebuffer_->IsPossiblyComplete());
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());
399 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, NULL);
400 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
401 framebuffer_->IsPossiblyComplete());
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));
434 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
435 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
436 framebuffer_->IsPossiblyComplete());
438 texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
439 scoped_refptr<TextureRef> texture1(
440 texture_manager_->GetTexture(kTextureClient1Id));
441 ASSERT_TRUE(texture1.get() != NULL);
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());
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(),
465 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
466 framebuffer_->IsPossiblyComplete());
468 // Try a good format.
469 texture_manager_->SetLevelInfo(texture1.get(),
480 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
481 framebuffer_->IsPossiblyComplete());
482 EXPECT_FALSE(framebuffer_->IsCleared());
483 texture_manager_->SetLevelInfo(texture1.get(),
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());
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());
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(),
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());
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());
543 // Check changing attachment
544 texture_manager_->SetLevelInfo(texture2.get(),
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());
569 texture_manager_->SetLevelInfo(texture2.get(),
580 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
581 framebuffer_->IsPossiblyComplete());
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());
588 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
589 framebuffer_->IsPossiblyComplete());
590 EXPECT_TRUE(framebuffer_->IsCleared());
593 class FramebufferInfoFloatTest : public FramebufferInfoTest {
595 FramebufferInfoFloatTest()
596 : FramebufferInfoTest() {
598 virtual ~FramebufferInfoFloatTest() {
602 virtual void SetUp() {
603 InitializeContext("OpenGL ES 3.0",
604 "GL_OES_texture_float GL_EXT_color_buffer_float");
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));
625 texture_manager_->CreateTexture(kTextureClientId, kTextureServiceId);
626 scoped_refptr<TextureRef> texture(
627 texture_manager_->GetTexture(kTextureClientId));
628 ASSERT_TRUE(texture.get() != NULL);
630 framebuffer_->AttachTexture(
631 GL_COLOR_ATTACHMENT0, texture.get(), kTarget, kLevel, kSamples);
632 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
634 texture_manager_->SetTarget(texture.get(), GL_TEXTURE_2D);
635 texture_manager_->SetLevelInfo(texture.get(),
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());
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;
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);
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);
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);
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;
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);
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());
716 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
717 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
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);
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;
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);
744 // Check MarkAsComlete marks as complete.
745 manager_.MarkAsComplete(framebuffer_);
746 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
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_));
757 // Check MarkAttachmentsAsCleared marks as complete.
758 manager_.MarkAttachmentsAsCleared(
759 framebuffer_, &renderbuffer_manager_, texture_manager_.get());
760 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
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_));
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;
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);
791 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
792 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
793 .RetiresOnSaturation();
794 framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
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();
802 framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
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);
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();
817 framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
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);
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();
831 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
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);
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();
846 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
848 // Check changing the format calls CheckFramebuffferStatus.
849 TestHelper::SetTexParameteriWithExpectations(gl_.get(),
851 texture_manager_.get(),
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);
863 // Check since it did not return FRAMEBUFFER_COMPLETE that it calls
864 // CheckFramebufferStatus
865 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
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();
873 TestHelper::SetTexParameteriWithExpectations(gl_.get(),
875 texture_manager_.get(),
880 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
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();
889 framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);