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,
38 virtual ~FramebufferManagerTest() {
39 manager_.Destroy(false);
40 texture_manager_.Destroy(false);
41 renderbuffer_manager_.Destroy(false);
45 virtual void SetUp() {
46 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
47 ::gfx::GLInterface::SetGLInterface(gl_.get());
50 virtual void TearDown() {
51 ::gfx::GLInterface::SetGLInterface(NULL);
55 // Use StrictMock to make 100% sure we know how GL will be called.
56 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
57 FramebufferManager manager_;
58 TextureManager texture_manager_;
59 RenderbufferManager renderbuffer_manager_;
62 TEST_F(FramebufferManagerTest, Basic) {
63 const GLuint kClient1Id = 1;
64 const GLuint kService1Id = 11;
65 const GLuint kClient2Id = 2;
66 // Check we can create framebuffer.
67 manager_.CreateFramebuffer(kClient1Id, kService1Id);
68 // Check framebuffer got created.
69 Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
70 ASSERT_TRUE(framebuffer1 != NULL);
71 EXPECT_FALSE(framebuffer1->IsDeleted());
72 EXPECT_EQ(kService1Id, framebuffer1->service_id());
74 EXPECT_TRUE(manager_.GetClientId(framebuffer1->service_id(), &client_id));
75 EXPECT_EQ(kClient1Id, client_id);
76 // Check we get nothing for a non-existent framebuffer.
77 EXPECT_TRUE(manager_.GetFramebuffer(kClient2Id) == NULL);
78 // Check trying to a remove non-existent framebuffers does not crash.
79 manager_.RemoveFramebuffer(kClient2Id);
80 // Check framebuffer gets deleted when last reference is released.
81 EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
83 .RetiresOnSaturation();
84 // Check we can't get the framebuffer after we remove it.
85 manager_.RemoveFramebuffer(kClient1Id);
86 EXPECT_TRUE(manager_.GetFramebuffer(kClient1Id) == NULL);
89 TEST_F(FramebufferManagerTest, Destroy) {
90 const GLuint kClient1Id = 1;
91 const GLuint kService1Id = 11;
92 // Check we can create framebuffer.
93 manager_.CreateFramebuffer(kClient1Id, kService1Id);
94 // Check framebuffer got created.
95 Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
96 ASSERT_TRUE(framebuffer1 != NULL);
97 EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
99 .RetiresOnSaturation();
100 manager_.Destroy(true);
101 // Check the resources were released.
102 framebuffer1 = manager_.GetFramebuffer(kClient1Id);
103 ASSERT_TRUE(framebuffer1 == NULL);
106 class FramebufferInfoTest : public testing::Test {
108 static const GLuint kClient1Id = 1;
109 static const GLuint kService1Id = 11;
111 FramebufferInfoTest()
114 NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize),
115 renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
118 virtual ~FramebufferInfoTest() {
119 manager_.Destroy(false);
120 texture_manager_.Destroy(false);
121 renderbuffer_manager_.Destroy(false);
125 virtual void SetUp() {
126 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
127 ::gfx::GLInterface::SetGLInterface(gl_.get());
128 manager_.CreateFramebuffer(kClient1Id, kService1Id);
129 error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
130 framebuffer_ = manager_.GetFramebuffer(kClient1Id);
131 ASSERT_TRUE(framebuffer_ != NULL);
134 virtual void TearDown() {
135 ::gfx::GLInterface::SetGLInterface(NULL);
139 // Use StrictMock to make 100% sure we know how GL will be called.
140 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
141 FramebufferManager manager_;
142 Framebuffer* framebuffer_;
143 TextureManager texture_manager_;
144 RenderbufferManager renderbuffer_manager_;
145 scoped_ptr<MockErrorState> error_state_;
148 // GCC requires these declarations, but MSVC requires they not be present
149 #ifndef COMPILER_MSVC
150 const GLuint FramebufferInfoTest::kClient1Id;
151 const GLuint FramebufferInfoTest::kService1Id;
154 TEST_F(FramebufferInfoTest, Basic) {
155 EXPECT_EQ(kService1Id, framebuffer_->service_id());
156 EXPECT_FALSE(framebuffer_->IsDeleted());
157 EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0));
158 EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT));
159 EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT));
161 NULL == framebuffer_->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
162 EXPECT_FALSE(framebuffer_->HasDepthAttachment());
163 EXPECT_FALSE(framebuffer_->HasStencilAttachment());
164 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
165 framebuffer_->IsPossiblyComplete());
166 EXPECT_TRUE(framebuffer_->IsCleared());
167 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
168 EXPECT_FALSE(manager_.IsComplete(framebuffer_));
171 TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
172 const GLuint kRenderbufferClient1Id = 33;
173 const GLuint kRenderbufferService1Id = 333;
174 const GLuint kRenderbufferClient2Id = 34;
175 const GLuint kRenderbufferService2Id = 334;
176 const GLuint kRenderbufferClient3Id = 35;
177 const GLuint kRenderbufferService3Id = 335;
178 const GLuint kRenderbufferClient4Id = 36;
179 const GLuint kRenderbufferService4Id = 336;
180 const GLsizei kWidth1 = 16;
181 const GLsizei kHeight1 = 32;
182 const GLenum kFormat1 = GL_RGBA4;
183 const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16;
184 const GLsizei kSamples1 = 0;
185 const GLsizei kWidth2 = 16;
186 const GLsizei kHeight2 = 32;
187 const GLenum kFormat2 = GL_DEPTH_COMPONENT16;
188 const GLsizei kSamples2 = 0;
189 const GLsizei kWidth3 = 16;
190 const GLsizei kHeight3 = 32;
191 const GLenum kFormat3 = GL_STENCIL_INDEX8;
192 const GLsizei kSamples3 = 0;
193 const GLsizei kWidth4 = 16;
194 const GLsizei kHeight4 = 32;
195 const GLenum kFormat4 = GL_STENCIL_INDEX8;
196 const GLsizei kSamples4 = 0;
198 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
199 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
200 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
202 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
204 renderbuffer_manager_.CreateRenderbuffer(
205 kRenderbufferClient1Id, kRenderbufferService1Id);
206 Renderbuffer* renderbuffer1 =
207 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
208 ASSERT_TRUE(renderbuffer1 != NULL);
210 // check adding one attachment
211 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
212 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
213 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
214 EXPECT_EQ(static_cast<GLenum>(GL_RGBA4),
215 framebuffer_->GetColorAttachmentFormat());
216 EXPECT_FALSE(framebuffer_->HasDepthAttachment());
217 EXPECT_FALSE(framebuffer_->HasStencilAttachment());
218 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
219 framebuffer_->IsPossiblyComplete());
220 EXPECT_TRUE(framebuffer_->IsCleared());
222 // Try a format that's not good for COLOR_ATTACHMENT0.
223 renderbuffer_manager_.SetInfo(
224 renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1);
225 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
226 framebuffer_->IsPossiblyComplete());
228 // Try a good format.
229 renderbuffer_manager_.SetInfo(
230 renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
231 EXPECT_EQ(static_cast<GLenum>(kFormat1),
232 framebuffer_->GetColorAttachmentFormat());
233 EXPECT_FALSE(framebuffer_->HasDepthAttachment());
234 EXPECT_FALSE(framebuffer_->HasStencilAttachment());
235 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
236 framebuffer_->IsPossiblyComplete());
237 EXPECT_FALSE(framebuffer_->IsCleared());
239 // check adding another
240 renderbuffer_manager_.CreateRenderbuffer(
241 kRenderbufferClient2Id, kRenderbufferService2Id);
242 Renderbuffer* renderbuffer2 =
243 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
244 ASSERT_TRUE(renderbuffer2 != NULL);
245 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2);
246 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
247 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
248 EXPECT_EQ(static_cast<GLenum>(kFormat1),
249 framebuffer_->GetColorAttachmentFormat());
250 EXPECT_TRUE(framebuffer_->HasDepthAttachment());
251 EXPECT_FALSE(framebuffer_->HasStencilAttachment());
252 // The attachment has a size of 0,0 so depending on the order of the map
253 // of attachments it could either get INCOMPLETE_ATTACHMENT because it's 0,0
254 // or INCOMPLETE_DIMENSIONS because it's not the same size as the other
256 GLenum status = framebuffer_->IsPossiblyComplete();
258 status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ||
259 status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
260 EXPECT_FALSE(framebuffer_->IsCleared());
262 renderbuffer_manager_.SetInfo(
263 renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2);
264 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
265 framebuffer_->IsPossiblyComplete());
266 EXPECT_FALSE(framebuffer_->IsCleared());
267 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
269 // check marking them as cleared.
270 manager_.MarkAttachmentsAsCleared(
271 framebuffer_, &renderbuffer_manager_, &texture_manager_);
272 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
273 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
274 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
275 framebuffer_->IsPossiblyComplete());
276 EXPECT_TRUE(framebuffer_->IsCleared());
278 // Check adding one that is already cleared.
279 renderbuffer_manager_.CreateRenderbuffer(
280 kRenderbufferClient3Id, kRenderbufferService3Id);
281 Renderbuffer* renderbuffer3 =
282 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id);
283 ASSERT_TRUE(renderbuffer3 != NULL);
284 renderbuffer_manager_.SetInfo(
285 renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3);
286 renderbuffer_manager_.SetCleared(renderbuffer3, true);
288 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3);
289 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
290 EXPECT_EQ(static_cast<GLenum>(kFormat1),
291 framebuffer_->GetColorAttachmentFormat());
292 EXPECT_TRUE(framebuffer_->HasDepthAttachment());
293 EXPECT_TRUE(framebuffer_->HasStencilAttachment());
294 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
295 framebuffer_->IsPossiblyComplete());
296 EXPECT_TRUE(framebuffer_->IsCleared());
298 // Check marking the renderbuffer as unclared.
299 renderbuffer_manager_.SetInfo(
300 renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
301 EXPECT_EQ(static_cast<GLenum>(kFormat1),
302 framebuffer_->GetColorAttachmentFormat());
303 EXPECT_TRUE(framebuffer_->HasDepthAttachment());
304 EXPECT_TRUE(framebuffer_->HasStencilAttachment());
305 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
306 framebuffer_->IsPossiblyComplete());
307 EXPECT_FALSE(framebuffer_->IsCleared());
309 const Framebuffer::Attachment* attachment =
310 framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
311 ASSERT_TRUE(attachment != NULL);
312 EXPECT_EQ(kWidth1, attachment->width());
313 EXPECT_EQ(kHeight1, attachment->height());
314 EXPECT_EQ(kSamples1, attachment->samples());
315 EXPECT_EQ(kFormat1, attachment->internal_format());
316 EXPECT_FALSE(attachment->cleared());
318 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
321 manager_.MarkAttachmentsAsCleared(
322 framebuffer_, &renderbuffer_manager_, &texture_manager_);
323 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
324 EXPECT_TRUE(framebuffer_->IsCleared());
326 // Check replacing an attachment
327 renderbuffer_manager_.CreateRenderbuffer(
328 kRenderbufferClient4Id, kRenderbufferService4Id);
329 Renderbuffer* renderbuffer4 =
330 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id);
331 ASSERT_TRUE(renderbuffer4 != NULL);
332 renderbuffer_manager_.SetInfo(
333 renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4);
335 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4);
336 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
337 EXPECT_FALSE(framebuffer_->IsCleared());
339 attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
340 ASSERT_TRUE(attachment != NULL);
341 EXPECT_EQ(kWidth4, attachment->width());
342 EXPECT_EQ(kHeight4, attachment->height());
343 EXPECT_EQ(kSamples4, attachment->samples());
344 EXPECT_EQ(kFormat4, attachment->internal_format());
345 EXPECT_FALSE(attachment->cleared());
346 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
347 framebuffer_->IsPossiblyComplete());
349 // Check changing an attachment.
350 renderbuffer_manager_.SetInfo(
351 renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4);
353 attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
354 ASSERT_TRUE(attachment != NULL);
355 EXPECT_EQ(kWidth4 + 1, attachment->width());
356 EXPECT_EQ(kHeight4, attachment->height());
357 EXPECT_EQ(kSamples4, attachment->samples());
358 EXPECT_EQ(kFormat4, attachment->internal_format());
359 EXPECT_FALSE(attachment->cleared());
360 EXPECT_FALSE(framebuffer_->IsCleared());
361 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT),
362 framebuffer_->IsPossiblyComplete());
364 // Check removing it.
365 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, NULL);
366 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
367 EXPECT_EQ(static_cast<GLenum>(kFormat1),
368 framebuffer_->GetColorAttachmentFormat());
369 EXPECT_TRUE(framebuffer_->HasDepthAttachment());
370 EXPECT_FALSE(framebuffer_->HasStencilAttachment());
372 EXPECT_TRUE(framebuffer_->IsCleared());
373 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
374 framebuffer_->IsPossiblyComplete());
376 // Remove depth, Set color to 0 size.
377 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL);
378 renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0);
379 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
380 framebuffer_->IsPossiblyComplete());
383 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, NULL);
384 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
385 framebuffer_->IsPossiblyComplete());
388 TEST_F(FramebufferInfoTest, AttachTexture) {
389 const GLuint kTextureClient1Id = 33;
390 const GLuint kTextureService1Id = 333;
391 const GLuint kTextureClient2Id = 34;
392 const GLuint kTextureService2Id = 334;
393 const GLint kDepth = 1;
394 const GLint kBorder = 0;
395 const GLenum kType = GL_UNSIGNED_BYTE;
396 const GLsizei kWidth1 = 16;
397 const GLsizei kHeight1 = 32;
398 const GLint kLevel1 = 0;
399 const GLenum kFormat1 = GL_RGBA;
400 const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16;
401 const GLenum kTarget1 = GL_TEXTURE_2D;
402 const GLsizei kSamples1 = 0;
403 const GLsizei kWidth2 = 16;
404 const GLsizei kHeight2 = 32;
405 const GLint kLevel2 = 0;
406 const GLenum kFormat2 = GL_RGB;
407 const GLenum kTarget2 = GL_TEXTURE_2D;
408 const GLsizei kSamples2 = 0;
409 const GLsizei kWidth3 = 75;
410 const GLsizei kHeight3 = 123;
411 const GLint kLevel3 = 0;
412 const GLenum kFormat3 = GL_RGB565;
413 const GLsizei kSamples3 = 0;
414 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
415 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
416 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
418 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
419 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
420 framebuffer_->IsPossiblyComplete());
422 texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id);
423 scoped_refptr<TextureRef> texture1(
424 texture_manager_.GetTexture(kTextureClient1Id));
425 ASSERT_TRUE(texture1.get() != NULL);
427 // check adding one attachment
428 framebuffer_->AttachTexture(
429 GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
430 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
431 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
432 framebuffer_->IsPossiblyComplete());
433 EXPECT_TRUE(framebuffer_->IsCleared());
434 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
436 // Try format that doesn't work with COLOR_ATTACHMENT0
437 texture_manager_.SetTarget(texture1.get(), GL_TEXTURE_2D);
438 texture_manager_.SetLevelInfo(texture1.get(),
449 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
450 framebuffer_->IsPossiblyComplete());
452 // Try a good format.
453 texture_manager_.SetLevelInfo(texture1.get(),
464 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
465 framebuffer_->IsPossiblyComplete());
466 EXPECT_FALSE(framebuffer_->IsCleared());
467 texture_manager_.SetLevelInfo(texture1.get(),
478 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
479 framebuffer_->IsPossiblyComplete());
480 EXPECT_TRUE(framebuffer_->IsCleared());
481 EXPECT_EQ(static_cast<GLenum>(kFormat1),
482 framebuffer_->GetColorAttachmentFormat());
484 const Framebuffer::Attachment* attachment =
485 framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
486 ASSERT_TRUE(attachment != NULL);
487 EXPECT_EQ(kWidth1, attachment->width());
488 EXPECT_EQ(kHeight1, attachment->height());
489 EXPECT_EQ(kSamples1, attachment->samples());
490 EXPECT_EQ(kFormat1, attachment->internal_format());
491 EXPECT_TRUE(attachment->cleared());
493 // Check replacing an attachment
494 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
495 scoped_refptr<TextureRef> texture2(
496 texture_manager_.GetTexture(kTextureClient2Id));
497 ASSERT_TRUE(texture2.get() != NULL);
498 texture_manager_.SetTarget(texture2.get(), GL_TEXTURE_2D);
499 texture_manager_.SetLevelInfo(texture2.get(),
511 framebuffer_->AttachTexture(
512 GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2, kSamples2);
513 EXPECT_EQ(static_cast<GLenum>(kFormat2),
514 framebuffer_->GetColorAttachmentFormat());
515 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
516 framebuffer_->IsPossiblyComplete());
517 EXPECT_TRUE(framebuffer_->IsCleared());
519 attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
520 ASSERT_TRUE(attachment != NULL);
521 EXPECT_EQ(kWidth2, attachment->width());
522 EXPECT_EQ(kHeight2, attachment->height());
523 EXPECT_EQ(kSamples2, attachment->samples());
524 EXPECT_EQ(kFormat2, attachment->internal_format());
525 EXPECT_TRUE(attachment->cleared());
527 // Check changing attachment
528 texture_manager_.SetLevelInfo(texture2.get(),
539 attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
540 ASSERT_TRUE(attachment != NULL);
541 EXPECT_EQ(kWidth3, attachment->width());
542 EXPECT_EQ(kHeight3, attachment->height());
543 EXPECT_EQ(kSamples3, attachment->samples());
544 EXPECT_EQ(kFormat3, attachment->internal_format());
545 EXPECT_FALSE(attachment->cleared());
546 EXPECT_EQ(static_cast<GLenum>(kFormat3),
547 framebuffer_->GetColorAttachmentFormat());
548 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
549 framebuffer_->IsPossiblyComplete());
550 EXPECT_FALSE(framebuffer_->IsCleared());
553 texture_manager_.SetLevelInfo(texture2.get(),
564 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
565 framebuffer_->IsPossiblyComplete());
567 // Check removing it.
568 framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0, 0);
569 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
570 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
572 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
573 framebuffer_->IsPossiblyComplete());
574 EXPECT_TRUE(framebuffer_->IsCleared());
577 TEST_F(FramebufferInfoTest, UnbindRenderbuffer) {
578 const GLuint kRenderbufferClient1Id = 33;
579 const GLuint kRenderbufferService1Id = 333;
580 const GLuint kRenderbufferClient2Id = 34;
581 const GLuint kRenderbufferService2Id = 334;
583 renderbuffer_manager_.CreateRenderbuffer(
584 kRenderbufferClient1Id, kRenderbufferService1Id);
585 Renderbuffer* renderbuffer1 =
586 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
587 ASSERT_TRUE(renderbuffer1 != NULL);
588 renderbuffer_manager_.CreateRenderbuffer(
589 kRenderbufferClient2Id, kRenderbufferService2Id);
590 Renderbuffer* renderbuffer2 =
591 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
592 ASSERT_TRUE(renderbuffer2 != NULL);
594 // Attach to 2 attachment points.
595 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
596 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
597 // Check they were attached.
598 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
599 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
600 // Unbind unattached renderbuffer.
601 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer2);
603 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
604 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
605 // Unbind renderbuffer.
606 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
607 // Check they were detached
608 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
609 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL);
612 TEST_F(FramebufferInfoTest, UnbindTexture) {
613 const GLuint kTextureClient1Id = 33;
614 const GLuint kTextureService1Id = 333;
615 const GLuint kTextureClient2Id = 34;
616 const GLuint kTextureService2Id = 334;
617 const GLenum kTarget1 = GL_TEXTURE_2D;
618 const GLint kLevel1 = 0;
619 const GLint kSamples1 = 0;
621 texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id);
622 scoped_refptr<TextureRef> texture1(
623 texture_manager_.GetTexture(kTextureClient1Id));
624 ASSERT_TRUE(texture1.get() != NULL);
625 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
626 scoped_refptr<TextureRef> texture2(
627 texture_manager_.GetTexture(kTextureClient2Id));
628 ASSERT_TRUE(texture2.get() != NULL);
630 // Attach to 2 attachment points.
631 framebuffer_->AttachTexture(
632 GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
633 framebuffer_->AttachTexture(
634 GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1, kSamples1);
635 // Check they were attached.
636 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
637 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
638 // Unbind unattached texture.
639 framebuffer_->UnbindTexture(kTarget1, texture2.get());
641 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
642 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
644 framebuffer_->UnbindTexture(kTarget1, texture1.get());
645 // Check they were detached
646 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
647 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL);
650 TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
651 const GLuint kRenderbufferClient1Id = 33;
652 const GLuint kRenderbufferService1Id = 333;
653 const GLuint kTextureClient2Id = 34;
654 const GLuint kTextureService2Id = 334;
655 const GLenum kTarget1 = GL_TEXTURE_2D;
656 const GLint kLevel1 = 0;
657 const GLint kSamples1 = 0;
659 renderbuffer_manager_.CreateRenderbuffer(
660 kRenderbufferClient1Id, kRenderbufferService1Id);
661 Renderbuffer* renderbuffer1 =
662 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
663 ASSERT_TRUE(renderbuffer1 != NULL);
664 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
665 scoped_refptr<TextureRef> texture2(
666 texture_manager_.GetTexture(kTextureClient2Id));
667 ASSERT_TRUE(texture2.get() != NULL);
669 // Check MarkAsComlete marks as complete.
670 manager_.MarkAsComplete(framebuffer_);
671 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
673 // Check at attaching marks as not complete.
674 framebuffer_->AttachTexture(
675 GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
676 EXPECT_FALSE(manager_.IsComplete(framebuffer_));
677 manager_.MarkAsComplete(framebuffer_);
678 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
679 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
680 EXPECT_FALSE(manager_.IsComplete(framebuffer_));
682 // Check MarkAttachmentsAsCleared marks as complete.
683 manager_.MarkAttachmentsAsCleared(
684 framebuffer_, &renderbuffer_manager_, &texture_manager_);
685 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
687 // Check Unbind marks as not complete.
688 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
689 EXPECT_FALSE(manager_.IsComplete(framebuffer_));
690 manager_.MarkAsComplete(framebuffer_);
691 EXPECT_TRUE(manager_.IsComplete(framebuffer_));
692 framebuffer_->UnbindTexture(kTarget1, texture2.get());
693 EXPECT_FALSE(manager_.IsComplete(framebuffer_));
696 TEST_F(FramebufferInfoTest, GetStatus) {
697 const GLuint kRenderbufferClient1Id = 33;
698 const GLuint kRenderbufferService1Id = 333;
699 const GLuint kTextureClient2Id = 34;
700 const GLuint kTextureService2Id = 334;
701 const GLenum kTarget1 = GL_TEXTURE_2D;
702 const GLint kLevel1 = 0;
703 const GLint kSamples1 = 0;
705 renderbuffer_manager_.CreateRenderbuffer(
706 kRenderbufferClient1Id, kRenderbufferService1Id);
707 Renderbuffer* renderbuffer1 =
708 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
709 ASSERT_TRUE(renderbuffer1 != NULL);
710 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id);
711 scoped_refptr<TextureRef> texture2(
712 texture_manager_.GetTexture(kTextureClient2Id));
713 ASSERT_TRUE(texture2.get() != NULL);
714 texture_manager_.SetTarget(texture2.get(), GL_TEXTURE_2D);
716 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
717 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
718 .RetiresOnSaturation();
719 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
721 // Check a second call for the same type does not call anything
722 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
723 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
724 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
725 .RetiresOnSaturation();
727 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
729 // Check changing the attachments calls CheckFramebufferStatus.
730 framebuffer_->AttachTexture(
731 GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
732 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
733 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)).RetiresOnSaturation();
734 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
736 // Check a second call for the same type does not call anything.
737 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
738 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
739 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
740 .RetiresOnSaturation();
742 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER);
744 // Check a second call with a different target calls CheckFramebufferStatus.
745 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
746 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
747 .RetiresOnSaturation();
748 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
750 // Check a second call for the same type does not call anything.
751 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
752 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
753 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
754 .RetiresOnSaturation();
756 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
758 // Check adding another attachment calls CheckFramebufferStatus.
759 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
760 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
761 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
762 .RetiresOnSaturation();
763 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
765 // Check a second call for the same type does not call anything.
766 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
767 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
768 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
769 .RetiresOnSaturation();
771 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
773 // Check changing the format calls CheckFramebuffferStatus.
774 TestHelper::SetTexParameterWithExpectations(gl_.get(),
782 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
783 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
784 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
785 .RetiresOnSaturation();
786 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
788 // Check since it did not return FRAMEBUFFER_COMPLETE that it calls
789 // CheckFramebufferStatus
790 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
792 // Check putting it back does not call CheckFramebufferStatus.
793 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
794 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
795 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
796 .RetiresOnSaturation();
798 TestHelper::SetTexParameterWithExpectations(gl_.get(),
805 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);
807 // Check Unbinding does not call CheckFramebufferStatus
808 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
809 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
810 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
811 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
812 .RetiresOnSaturation();
814 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER);