Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: content/browser/compositor/buffer_queue_unittest.cc

Issue 1423843003: Make content::BufferQueue use scoped ptrs for AllocatedSurfaces (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@surfaceless_only
Patch Set: And the rest of the feedback Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <set> 5 #include <set>
6 6
7 #include "cc/test/test_context_provider.h" 7 #include "cc/test/test_context_provider.h"
8 #include "cc/test/test_web_graphics_context_3d.h" 8 #include "cc/test/test_web_graphics_context_3d.h"
9 #include "content/browser/compositor/buffer_queue.h" 9 #include "content/browser/compositor/buffer_queue.h"
10 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_s urface.h" 10 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_s urface.h"
(...skipping 30 matching lines...) Expand all
41 gfx::GpuMemoryBufferHandle GetHandle() const override { 41 gfx::GpuMemoryBufferHandle GetHandle() const override {
42 return gfx::GpuMemoryBufferHandle(); 42 return gfx::GpuMemoryBufferHandle();
43 } 43 }
44 ClientBuffer AsClientBuffer() override { 44 ClientBuffer AsClientBuffer() override {
45 return reinterpret_cast<ClientBuffer>(this); 45 return reinterpret_cast<ClientBuffer>(this);
46 } 46 }
47 }; 47 };
48 48
49 class StubBrowserGpuMemoryBufferManager : public BrowserGpuMemoryBufferManager { 49 class StubBrowserGpuMemoryBufferManager : public BrowserGpuMemoryBufferManager {
50 public: 50 public:
51 StubBrowserGpuMemoryBufferManager() : BrowserGpuMemoryBufferManager(1, 1) {} 51 StubBrowserGpuMemoryBufferManager()
52 : BrowserGpuMemoryBufferManager(1, 1), allocate_succeeds_(true) {}
53 bool allocate_succeeds_;
danakj 2015/12/10 19:46:42 nit: make private and add a set_allocate_succeeds(
ccameron 2015/12/11 21:14:23 Done.
52 54
53 scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForScanout( 55 scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBufferForScanout(
54 const gfx::Size& size, 56 const gfx::Size& size,
55 gfx::BufferFormat format, 57 gfx::BufferFormat format,
56 int32 surface_id) override { 58 int32 surface_id) override {
57 return make_scoped_ptr<gfx::GpuMemoryBuffer>(new StubGpuMemoryBufferImpl); 59 if (allocate_succeeds_)
60 return make_scoped_ptr<gfx::GpuMemoryBuffer>(new StubGpuMemoryBufferImpl);
61 return nullptr;
58 } 62 }
59 }; 63 };
60 64
61 class MockBufferQueue : public BufferQueue { 65 class MockBufferQueue : public BufferQueue {
62 public: 66 public:
63 MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider, 67 MockBufferQueue(scoped_refptr<cc::ContextProvider> context_provider,
64 BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager, 68 BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager,
65 unsigned int target, 69 unsigned int target,
66 unsigned int internalformat) 70 unsigned int internalformat)
67 : BufferQueue(context_provider, 71 : BufferQueue(context_provider,
(...skipping 19 matching lines...) Expand all
87 cc::TestContextProvider::Create(context.Pass()); 91 cc::TestContextProvider::Create(context.Pass());
88 context_provider->BindToCurrentThread(); 92 context_provider->BindToCurrentThread();
89 gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager); 93 gpu_memory_buffer_manager_.reset(new StubBrowserGpuMemoryBufferManager);
90 mock_output_surface_ = 94 mock_output_surface_ =
91 new MockBufferQueue(context_provider, gpu_memory_buffer_manager_.get(), 95 new MockBufferQueue(context_provider, gpu_memory_buffer_manager_.get(),
92 GL_TEXTURE_2D, GL_RGBA); 96 GL_TEXTURE_2D, GL_RGBA);
93 output_surface_.reset(mock_output_surface_); 97 output_surface_.reset(mock_output_surface_);
94 output_surface_->Initialize(); 98 output_surface_->Initialize();
95 } 99 }
96 100
97 unsigned current_surface() { return output_surface_->current_surface_.image; } 101 unsigned current_surface() {
98 const std::vector<BufferQueue::AllocatedSurface>& available_surfaces() { 102 return output_surface_->current_surface_
103 ? output_surface_->current_surface_->image
104 : 0;
105 }
106 const std::vector<scoped_ptr<BufferQueue::AllocatedSurface>>&
107 available_surfaces() {
99 return output_surface_->available_surfaces_; 108 return output_surface_->available_surfaces_;
100 } 109 }
101 const std::deque<BufferQueue::AllocatedSurface>& in_flight_surfaces() { 110 std::deque<scoped_ptr<BufferQueue::AllocatedSurface>>& in_flight_surfaces() {
102 return output_surface_->in_flight_surfaces_; 111 return output_surface_->in_flight_surfaces_;
103 } 112 }
104 113
105 const BufferQueue::AllocatedSurface& displayed_frame() { 114 const BufferQueue::AllocatedSurface* displayed_frame() {
106 return output_surface_->displayed_surface_; 115 return output_surface_->displayed_surface_.get();
107 } 116 }
108 const BufferQueue::AllocatedSurface& current_frame() { 117 const BufferQueue::AllocatedSurface* current_frame() {
109 return output_surface_->current_surface_; 118 return output_surface_->current_surface_.get();
110 } 119 }
111 const BufferQueue::AllocatedSurface& last_frame() { 120 const BufferQueue::AllocatedSurface* next_frame() {
112 return output_surface_->in_flight_surfaces_.back(); 121 return output_surface_->available_surfaces_.back().get();
113 }
114 const BufferQueue::AllocatedSurface& next_frame() {
115 return output_surface_->available_surfaces_.back();
116 } 122 }
117 const gfx::Size size() { return output_surface_->size_; } 123 const gfx::Size size() { return output_surface_->size_; }
118 124
119 int CountBuffers() { 125 int CountBuffers() {
120 int n = available_surfaces().size() + in_flight_surfaces().size() + 126 int n = available_surfaces().size() + in_flight_surfaces().size() +
121 (displayed_frame().texture ? 1 : 0); 127 (displayed_frame() ? 1 : 0);
122 if (current_surface()) 128 if (current_surface())
123 n++; 129 n++;
124 return n; 130 return n;
125 } 131 }
126 132
127 // Check that each buffer is unique if present. 133 // Check that each buffer is unique if present.
128 void CheckUnique() { 134 void CheckUnique() {
129 std::set<unsigned> buffers; 135 std::set<unsigned> buffers;
130 EXPECT_TRUE(InsertUnique(&buffers, current_surface())); 136 EXPECT_TRUE(InsertUnique(&buffers, current_surface()));
131 EXPECT_TRUE(InsertUnique(&buffers, displayed_frame().image)); 137 if (displayed_frame())
132 for (size_t i = 0; i < available_surfaces().size(); i++) 138 EXPECT_TRUE(InsertUnique(&buffers, displayed_frame()->image));
133 EXPECT_TRUE(InsertUnique(&buffers, available_surfaces()[i].image)); 139 for (auto& surface : available_surfaces())
134 for (std::deque<BufferQueue::AllocatedSurface>::const_iterator it = 140 EXPECT_TRUE(InsertUnique(&buffers, surface->image));
135 in_flight_surfaces().begin(); 141 for (auto& surface : in_flight_surfaces()) {
136 it != in_flight_surfaces().end(); 142 if (surface)
137 ++it) 143 EXPECT_TRUE(InsertUnique(&buffers, surface->image));
138 EXPECT_TRUE(InsertUnique(&buffers, it->image)); 144 }
139 } 145 }
140 146
141 void SwapBuffers() { 147 void SwapBuffers() {
142 output_surface_->SwapBuffers(gfx::Rect(output_surface_->size_)); 148 output_surface_->SwapBuffers(gfx::Rect(output_surface_->size_));
143 } 149 }
144 150
145 void SendDamagedFrame(const gfx::Rect& damage) { 151 void SendDamagedFrame(const gfx::Rect& damage) {
146 // We don't care about the GL-level implementation here, just how it uses 152 // We don't care about the GL-level implementation here, just how it uses
147 // damage rects. 153 // damage rects.
148 output_surface_->BindFramebuffer(); 154 output_surface_->BindFramebuffer();
149 output_surface_->SwapBuffers(damage); 155 output_surface_->SwapBuffers(damage);
150 if (doublebuffering_ || !first_frame_) 156 if (doublebuffering_ || !first_frame_)
151 output_surface_->PageFlipComplete(); 157 output_surface_->PageFlipComplete();
152 first_frame_ = false; 158 first_frame_ = false;
153 } 159 }
154 160
155 void SendFullFrame() { SendDamagedFrame(gfx::Rect(output_surface_->size_)); } 161 void SendFullFrame() { SendDamagedFrame(gfx::Rect(output_surface_->size_)); }
156 162
157 protected: 163 protected:
158 bool InsertUnique(std::set<unsigned>* set, unsigned value) { 164 bool InsertUnique(std::set<unsigned>* set, unsigned value) {
159 if (!value) 165 if (!value)
160 return true; 166 return true;
161 if (set->find(value) != set->end()) 167 if (set->find(value) != set->end())
162 return false; 168 return false;
163 set->insert(value); 169 set->insert(value);
164 return true; 170 return true;
165 } 171 }
166 172
167 scoped_ptr<BrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_; 173 scoped_ptr<StubBrowserGpuMemoryBufferManager> gpu_memory_buffer_manager_;
168 scoped_ptr<BufferQueue> output_surface_; 174 scoped_ptr<BufferQueue> output_surface_;
169 MockBufferQueue* mock_output_surface_; 175 MockBufferQueue* mock_output_surface_;
170 bool doublebuffering_; 176 bool doublebuffering_;
171 bool first_frame_; 177 bool first_frame_;
172 }; 178 };
173 179
174 namespace { 180 namespace {
175 const gfx::Size screen_size = gfx::Size(30, 30); 181 const gfx::Size screen_size = gfx::Size(30, 30);
176 const gfx::Rect screen_rect = gfx::Rect(screen_size); 182 const gfx::Rect screen_rect = gfx::Rect(screen_size);
177 const gfx::Rect small_damage = gfx::Rect(gfx::Size(10, 10)); 183 const gfx::Rect small_damage = gfx::Rect(gfx::Size(10, 10));
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1); 313 CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1);
308 EXPECT_CALL(*mock_output_surface_, 314 EXPECT_CALL(*mock_output_surface_,
309 CopyBufferDamage(_, _, small_damage, small_damage)).Times(1); 315 CopyBufferDamage(_, _, small_damage, small_damage)).Times(1);
310 EXPECT_CALL(*mock_output_surface_, 316 EXPECT_CALL(*mock_output_surface_,
311 CopyBufferDamage(_, _, large_damage, small_damage)).Times(1); 317 CopyBufferDamage(_, _, large_damage, small_damage)).Times(1);
312 SendFullFrame(); 318 SendFullFrame();
313 SendDamagedFrame(small_damage); 319 SendDamagedFrame(small_damage);
314 SendDamagedFrame(small_damage); 320 SendDamagedFrame(small_damage);
315 SendDamagedFrame(large_damage); 321 SendDamagedFrame(large_damage);
316 // Verify that the damage has propagated. 322 // Verify that the damage has propagated.
317 EXPECT_EQ(next_frame().damage, large_damage); 323 EXPECT_EQ(next_frame()->damage, large_damage);
318 } 324 }
319 325
320 TEST_F(BufferQueueTest, PartialSwapFullFrame) { 326 TEST_F(BufferQueueTest, PartialSwapFullFrame) {
321 output_surface_->Reshape(screen_size, 1.0f); 327 output_surface_->Reshape(screen_size, 1.0f);
322 ASSERT_TRUE(doublebuffering_); 328 ASSERT_TRUE(doublebuffering_);
323 EXPECT_CALL(*mock_output_surface_, 329 EXPECT_CALL(*mock_output_surface_,
324 CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1); 330 CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1);
325 SendFullFrame(); 331 SendFullFrame();
326 SendDamagedFrame(small_damage); 332 SendDamagedFrame(small_damage);
327 SendFullFrame(); 333 SendFullFrame();
328 SendFullFrame(); 334 SendFullFrame();
329 EXPECT_EQ(next_frame().damage, screen_rect); 335 EXPECT_EQ(next_frame()->damage, screen_rect);
330 } 336 }
331 337
332 TEST_F(BufferQueueTest, PartialSwapOverlapping) { 338 TEST_F(BufferQueueTest, PartialSwapOverlapping) {
333 output_surface_->Reshape(screen_size, 1.0f); 339 output_surface_->Reshape(screen_size, 1.0f);
334 ASSERT_TRUE(doublebuffering_); 340 ASSERT_TRUE(doublebuffering_);
335 EXPECT_CALL(*mock_output_surface_, 341 EXPECT_CALL(*mock_output_surface_,
336 CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1); 342 CopyBufferDamage(_, _, small_damage, screen_rect)).Times(1);
337 EXPECT_CALL(*mock_output_surface_, CopyBufferDamage(_, _, overlapping_damage, 343 EXPECT_CALL(*mock_output_surface_, CopyBufferDamage(_, _, overlapping_damage,
338 small_damage)).Times(1); 344 small_damage)).Times(1);
339 345
340 SendFullFrame(); 346 SendFullFrame();
341 SendDamagedFrame(small_damage); 347 SendDamagedFrame(small_damage);
342 SendDamagedFrame(overlapping_damage); 348 SendDamagedFrame(overlapping_damage);
343 EXPECT_EQ(next_frame().damage, overlapping_damage); 349 EXPECT_EQ(next_frame()->damage, overlapping_damage);
344 } 350 }
345 351
346 TEST_F(BufferQueueTest, MultipleBindCalls) { 352 TEST_F(BufferQueueTest, MultipleBindCalls) {
347 // Check that multiple bind calls do not create or change surfaces. 353 // Check that multiple bind calls do not create or change surfaces.
348 output_surface_->BindFramebuffer(); 354 output_surface_->BindFramebuffer();
349 EXPECT_EQ(1, CountBuffers()); 355 EXPECT_EQ(1, CountBuffers());
350 unsigned int fb = current_surface(); 356 unsigned int fb = current_surface();
351 output_surface_->BindFramebuffer(); 357 output_surface_->BindFramebuffer();
352 EXPECT_EQ(1, CountBuffers()); 358 EXPECT_EQ(1, CountBuffers());
353 EXPECT_EQ(fb, current_surface()); 359 EXPECT_EQ(fb, current_surface());
354 } 360 }
355 361
356 TEST_F(BufferQueueTest, CheckDoubleBuffering) { 362 TEST_F(BufferQueueTest, CheckDoubleBuffering) {
357 // Check buffer flow through double buffering path. 363 // Check buffer flow through double buffering path.
358 EXPECT_EQ(0, CountBuffers()); 364 EXPECT_EQ(0, CountBuffers());
359 output_surface_->BindFramebuffer(); 365 output_surface_->BindFramebuffer();
360 EXPECT_EQ(1, CountBuffers()); 366 EXPECT_EQ(1, CountBuffers());
361 EXPECT_NE(0U, current_surface()); 367 EXPECT_NE(0U, current_surface());
362 EXPECT_FALSE(displayed_frame().texture); 368 EXPECT_FALSE(displayed_frame());
363 SwapBuffers(); 369 SwapBuffers();
364 EXPECT_EQ(1U, in_flight_surfaces().size()); 370 EXPECT_EQ(1U, in_flight_surfaces().size());
365 output_surface_->PageFlipComplete(); 371 output_surface_->PageFlipComplete();
366 EXPECT_EQ(0U, in_flight_surfaces().size()); 372 EXPECT_EQ(0U, in_flight_surfaces().size());
367 EXPECT_TRUE(displayed_frame().texture); 373 EXPECT_TRUE(displayed_frame()->texture);
368 output_surface_->BindFramebuffer(); 374 output_surface_->BindFramebuffer();
369 EXPECT_EQ(2, CountBuffers()); 375 EXPECT_EQ(2, CountBuffers());
370 CheckUnique(); 376 CheckUnique();
371 EXPECT_NE(0U, current_surface()); 377 EXPECT_NE(0U, current_surface());
372 EXPECT_EQ(0U, in_flight_surfaces().size()); 378 EXPECT_EQ(0U, in_flight_surfaces().size());
373 EXPECT_TRUE(displayed_frame().texture); 379 EXPECT_TRUE(displayed_frame()->texture);
374 SwapBuffers(); 380 SwapBuffers();
375 CheckUnique(); 381 CheckUnique();
376 EXPECT_EQ(1U, in_flight_surfaces().size()); 382 EXPECT_EQ(1U, in_flight_surfaces().size());
377 EXPECT_TRUE(displayed_frame().texture); 383 EXPECT_TRUE(displayed_frame()->texture);
378 output_surface_->PageFlipComplete(); 384 output_surface_->PageFlipComplete();
379 CheckUnique(); 385 CheckUnique();
380 EXPECT_EQ(0U, in_flight_surfaces().size()); 386 EXPECT_EQ(0U, in_flight_surfaces().size());
381 EXPECT_EQ(1U, available_surfaces().size()); 387 EXPECT_EQ(1U, available_surfaces().size());
382 EXPECT_TRUE(displayed_frame().texture); 388 EXPECT_TRUE(displayed_frame()->texture);
383 output_surface_->BindFramebuffer(); 389 output_surface_->BindFramebuffer();
384 EXPECT_EQ(2, CountBuffers()); 390 EXPECT_EQ(2, CountBuffers());
385 CheckUnique(); 391 CheckUnique();
386 EXPECT_TRUE(available_surfaces().empty()); 392 EXPECT_TRUE(available_surfaces().empty());
387 } 393 }
388 394
389 TEST_F(BufferQueueTest, CheckTripleBuffering) { 395 TEST_F(BufferQueueTest, CheckTripleBuffering) {
390 // Check buffer flow through triple buffering path. 396 // Check buffer flow through triple buffering path.
391 397
392 // This bit is the same sequence tested in the doublebuffering case. 398 // This bit is the same sequence tested in the doublebuffering case.
393 output_surface_->BindFramebuffer(); 399 output_surface_->BindFramebuffer();
394 EXPECT_FALSE(displayed_frame().texture); 400 EXPECT_FALSE(displayed_frame());
395 SwapBuffers(); 401 SwapBuffers();
396 output_surface_->PageFlipComplete(); 402 output_surface_->PageFlipComplete();
397 output_surface_->BindFramebuffer(); 403 output_surface_->BindFramebuffer();
398 SwapBuffers(); 404 SwapBuffers();
399 405
400 EXPECT_EQ(2, CountBuffers()); 406 EXPECT_EQ(2, CountBuffers());
401 CheckUnique(); 407 CheckUnique();
402 EXPECT_EQ(1U, in_flight_surfaces().size()); 408 EXPECT_EQ(1U, in_flight_surfaces().size());
403 EXPECT_TRUE(displayed_frame().texture); 409 EXPECT_TRUE(displayed_frame()->texture);
404 output_surface_->BindFramebuffer(); 410 output_surface_->BindFramebuffer();
405 EXPECT_EQ(3, CountBuffers()); 411 EXPECT_EQ(3, CountBuffers());
406 CheckUnique(); 412 CheckUnique();
407 EXPECT_NE(0U, current_surface()); 413 EXPECT_NE(0U, current_surface());
408 EXPECT_EQ(1U, in_flight_surfaces().size()); 414 EXPECT_EQ(1U, in_flight_surfaces().size());
409 EXPECT_TRUE(displayed_frame().texture); 415 EXPECT_TRUE(displayed_frame()->texture);
410 output_surface_->PageFlipComplete(); 416 output_surface_->PageFlipComplete();
411 EXPECT_EQ(3, CountBuffers()); 417 EXPECT_EQ(3, CountBuffers());
412 CheckUnique(); 418 CheckUnique();
413 EXPECT_NE(0U, current_surface()); 419 EXPECT_NE(0U, current_surface());
414 EXPECT_EQ(0U, in_flight_surfaces().size()); 420 EXPECT_EQ(0U, in_flight_surfaces().size());
415 EXPECT_TRUE(displayed_frame().texture); 421 EXPECT_TRUE(displayed_frame()->texture);
416 EXPECT_EQ(1U, available_surfaces().size()); 422 EXPECT_EQ(1U, available_surfaces().size());
417 } 423 }
418 424
419 TEST_F(BufferQueueTest, CheckCorrectBufferOrdering) { 425 TEST_F(BufferQueueTest, CheckCorrectBufferOrdering) {
420 const size_t kSwapCount = 3; 426 const size_t kSwapCount = 3;
421 for (size_t i = 0; i < kSwapCount; ++i) { 427 for (size_t i = 0; i < kSwapCount; ++i) {
422 output_surface_->BindFramebuffer(); 428 output_surface_->BindFramebuffer();
423 SwapBuffers(); 429 SwapBuffers();
424 } 430 }
425 431
426 EXPECT_EQ(kSwapCount, in_flight_surfaces().size()); 432 EXPECT_EQ(kSwapCount, in_flight_surfaces().size());
427 for (size_t i = 0; i < kSwapCount; ++i) { 433 for (size_t i = 0; i < kSwapCount; ++i) {
428 unsigned int next_texture_id = in_flight_surfaces().front().texture; 434 unsigned int next_texture_id = in_flight_surfaces().front()->texture;
429 output_surface_->PageFlipComplete(); 435 output_surface_->PageFlipComplete();
430 EXPECT_EQ(displayed_frame().texture, next_texture_id); 436 EXPECT_EQ(displayed_frame()->texture, next_texture_id);
431 } 437 }
432 } 438 }
433 439
434 TEST_F(BufferQueueTest, ReshapeWithInFlightSurfaces) { 440 TEST_F(BufferQueueTest, ReshapeWithInFlightSurfaces) {
435 const size_t kSwapCount = 3; 441 const size_t kSwapCount = 3;
436 for (size_t i = 0; i < kSwapCount; ++i) { 442 for (size_t i = 0; i < kSwapCount; ++i) {
437 output_surface_->BindFramebuffer(); 443 output_surface_->BindFramebuffer();
438 SwapBuffers(); 444 SwapBuffers();
439 } 445 }
440 446
441 output_surface_->Reshape(gfx::Size(10, 20), 1.0f); 447 output_surface_->Reshape(gfx::Size(10, 20), 1.0f);
442 EXPECT_EQ(3u, in_flight_surfaces().size()); 448 EXPECT_EQ(3u, in_flight_surfaces().size());
443 449
444 for (size_t i = 0; i < kSwapCount; ++i) { 450 for (size_t i = 0; i < kSwapCount; ++i) {
445 output_surface_->PageFlipComplete(); 451 output_surface_->PageFlipComplete();
446 EXPECT_EQ(0u, displayed_frame().texture); 452 EXPECT_FALSE(displayed_frame());
447 } 453 }
448 454
449 // The dummy surfacess left should be discarded. 455 // The dummy surfacess left should be discarded.
450 EXPECT_EQ(0u, available_surfaces().size()); 456 EXPECT_EQ(0u, available_surfaces().size());
451 } 457 }
452 458
453 TEST_F(BufferQueueTest, SwapAfterReshape) { 459 TEST_F(BufferQueueTest, SwapAfterReshape) {
454 const size_t kSwapCount = 3; 460 const size_t kSwapCount = 3;
455 for (size_t i = 0; i < kSwapCount; ++i) { 461 for (size_t i = 0; i < kSwapCount; ++i) {
456 output_surface_->BindFramebuffer(); 462 output_surface_->BindFramebuffer();
457 SwapBuffers(); 463 SwapBuffers();
458 } 464 }
459 465
460 output_surface_->Reshape(gfx::Size(10, 20), 1.0f); 466 output_surface_->Reshape(gfx::Size(10, 20), 1.0f);
461 467
462 for (size_t i = 0; i < kSwapCount; ++i) { 468 for (size_t i = 0; i < kSwapCount; ++i) {
463 output_surface_->BindFramebuffer(); 469 output_surface_->BindFramebuffer();
464 SwapBuffers(); 470 SwapBuffers();
465 } 471 }
466 472
467 EXPECT_EQ(2 * kSwapCount, in_flight_surfaces().size()); 473 EXPECT_EQ(2 * kSwapCount, in_flight_surfaces().size());
468 474
469 for (size_t i = 0; i < kSwapCount; ++i) { 475 for (size_t i = 0; i < kSwapCount; ++i) {
470 output_surface_->PageFlipComplete(); 476 output_surface_->PageFlipComplete();
471 EXPECT_EQ(0u, displayed_frame().texture); 477 EXPECT_FALSE(displayed_frame());
472 } 478 }
473 479
474 CheckUnique(); 480 CheckUnique();
475 481
476 for (size_t i = 0; i < kSwapCount; ++i) { 482 for (size_t i = 0; i < kSwapCount; ++i) {
477 unsigned int next_texture_id = in_flight_surfaces().front().texture; 483 unsigned int next_texture_id = in_flight_surfaces().front()->texture;
478 output_surface_->PageFlipComplete(); 484 output_surface_->PageFlipComplete();
479 EXPECT_EQ(displayed_frame().texture, next_texture_id); 485 EXPECT_EQ(displayed_frame()->texture, next_texture_id);
480 EXPECT_NE(0u, displayed_frame().texture); 486 EXPECT_TRUE(displayed_frame());
481 } 487 }
482 } 488 }
483 489
484 TEST_F(BufferQueueMockedContextTest, RecreateBuffers) { 490 TEST_F(BufferQueueMockedContextTest, RecreateBuffers) {
485 // This setup is to easily get one frame in each of: 491 // This setup is to easily get one frame in each of:
486 // - currently bound for drawing. 492 // - currently bound for drawing.
487 // - in flight to GPU. 493 // - in flight to GPU.
488 // - currently displayed. 494 // - currently displayed.
489 // - free frame. 495 // - free frame.
490 // This tests buffers in all states. 496 // This tests buffers in all states.
491 // Bind/swap pushes frames into the in flight list, then the PageFlipComplete 497 // Bind/swap pushes frames into the in flight list, then the PageFlipComplete
492 // calls pull one frame into displayed and another into the free list. 498 // calls pull one frame into displayed and another into the free list.
493 output_surface_->BindFramebuffer(); 499 output_surface_->BindFramebuffer();
494 SwapBuffers(); 500 SwapBuffers();
495 output_surface_->BindFramebuffer(); 501 output_surface_->BindFramebuffer();
496 SwapBuffers(); 502 SwapBuffers();
497 output_surface_->BindFramebuffer(); 503 output_surface_->BindFramebuffer();
498 SwapBuffers(); 504 SwapBuffers();
499 output_surface_->BindFramebuffer(); 505 output_surface_->BindFramebuffer();
500 output_surface_->PageFlipComplete(); 506 output_surface_->PageFlipComplete();
501 output_surface_->PageFlipComplete(); 507 output_surface_->PageFlipComplete();
502 // We should have one buffer in each possible state right now, including one 508 // We should have one buffer in each possible state right now, including one
503 // being drawn to. 509 // being drawn to.
504 ASSERT_EQ(1U, in_flight_surfaces().size()); 510 ASSERT_EQ(1U, in_flight_surfaces().size());
505 ASSERT_EQ(1U, available_surfaces().size()); 511 ASSERT_EQ(1U, available_surfaces().size());
506 EXPECT_TRUE(displayed_frame().texture); 512 EXPECT_TRUE(displayed_frame());
507 EXPECT_TRUE(current_frame().texture); 513 EXPECT_TRUE(current_frame());
508 514
509 auto current = current_frame(); 515 auto current = current_frame();
danakj 2015/12/10 19:46:42 should these all be auto*?
ccameron 2015/12/11 21:14:23 That works! Done.
510 auto displayed = displayed_frame(); 516 auto displayed = displayed_frame();
511 auto in_flight = in_flight_surfaces().front(); 517 auto in_flight = in_flight_surfaces().front().get();
512 auto available = available_surfaces().front(); 518 auto available = available_surfaces().front().get();
513 519
514 // Expect all 4 images to be destroyed, 3 of the existing textures to be 520 // Expect all 4 images to be destroyed, 3 of the existing textures to be
515 // copied from and 3 new images to be created. 521 // copied from and 3 new images to be created.
516 EXPECT_CALL(*context_, createImageCHROMIUM(_, 0, 0, GL_RGBA)).Times(3); 522 EXPECT_CALL(*context_, createImageCHROMIUM(_, 0, 0, GL_RGBA)).Times(3);
517 Expectation copy1 = 523 Expectation copy1 = EXPECT_CALL(*mock_output_surface_,
518 EXPECT_CALL(*mock_output_surface_, 524 CopyBufferDamage(_, displayed->texture, _, _))
519 CopyBufferDamage(_, displayed.texture, _, _)).Times(1); 525 .Times(1);
520 Expectation copy2 = 526 Expectation copy2 = EXPECT_CALL(*mock_output_surface_,
521 EXPECT_CALL(*mock_output_surface_, 527 CopyBufferDamage(_, current->texture, _, _))
522 CopyBufferDamage(_, current.texture, _, _)).Times(1); 528 .Times(1);
523 Expectation copy3 = 529 Expectation copy3 = EXPECT_CALL(*mock_output_surface_,
524 EXPECT_CALL(*mock_output_surface_, 530 CopyBufferDamage(_, in_flight->texture, _, _))
525 CopyBufferDamage(_, in_flight.texture, _, _)).Times(1); 531 .Times(1);
526 532
527 EXPECT_CALL(*context_, destroyImageCHROMIUM(displayed.image)) 533 EXPECT_CALL(*context_, destroyImageCHROMIUM(displayed->image))
528 .Times(1) 534 .Times(1)
529 .After(copy1); 535 .After(copy1);
530 EXPECT_CALL(*context_, destroyImageCHROMIUM(current.image)) 536 EXPECT_CALL(*context_, destroyImageCHROMIUM(current->image))
531 .Times(1) 537 .Times(1)
532 .After(copy2); 538 .After(copy2);
533 EXPECT_CALL(*context_, destroyImageCHROMIUM(in_flight.image)) 539 EXPECT_CALL(*context_, destroyImageCHROMIUM(in_flight->image))
534 .Times(1) 540 .Times(1)
535 .After(copy3); 541 .After(copy3);
536 EXPECT_CALL(*context_, destroyImageCHROMIUM(available.image)).Times(1); 542 EXPECT_CALL(*context_, destroyImageCHROMIUM(available->image)).Times(1);
537 // After copying, we expect the framebuffer binding to be updated. 543 // After copying, we expect the framebuffer binding to be updated.
538 EXPECT_CALL(*context_, bindFramebuffer(_, _)) 544 EXPECT_CALL(*context_, bindFramebuffer(_, _))
539 .After(copy1) 545 .After(copy1)
540 .After(copy2) 546 .After(copy2)
541 .After(copy3); 547 .After(copy3);
542 EXPECT_CALL(*context_, framebufferTexture2D(_, _, _, _, _)) 548 EXPECT_CALL(*context_, framebufferTexture2D(_, _, _, _, _))
543 .After(copy1) 549 .After(copy1)
544 .After(copy2) 550 .After(copy2)
545 .After(copy3); 551 .After(copy3);
546 552
547 output_surface_->RecreateBuffers(); 553 output_surface_->RecreateBuffers();
548 testing::Mock::VerifyAndClearExpectations(context_); 554 testing::Mock::VerifyAndClearExpectations(context_);
549 testing::Mock::VerifyAndClearExpectations(mock_output_surface_); 555 testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
550 556
551 // All free buffers should be destroyed, the remaining buffers should all 557 // All free buffers should be destroyed, the remaining buffers should all
552 // be replaced but still valid. 558 // be replaced but still valid.
553 EXPECT_EQ(1U, in_flight_surfaces().size()); 559 EXPECT_EQ(1U, in_flight_surfaces().size());
554 EXPECT_EQ(0U, available_surfaces().size()); 560 EXPECT_EQ(0U, available_surfaces().size());
555 EXPECT_TRUE(displayed_frame().texture); 561 EXPECT_TRUE(displayed_frame());
556 EXPECT_TRUE(current_frame().texture); 562 EXPECT_TRUE(current_frame());
563 }
564
565 TEST_F(BufferQueueTest, AllocateFails) {
566 output_surface_->Reshape(screen_size, 1.0f);
567
568 // Succeed in the two swaps.
569 output_surface_->BindFramebuffer();
570 EXPECT_TRUE(current_frame());
571 output_surface_->SwapBuffers(screen_rect);
572
573 // Fail the next surface allocation.
574 gpu_memory_buffer_manager_->allocate_succeeds_ = false;
575 output_surface_->BindFramebuffer();
576 EXPECT_FALSE(current_frame());
577 output_surface_->SwapBuffers(screen_rect);
578 EXPECT_FALSE(current_frame());
579
580 // Try another swap. It should copy the buffer damage from the back
581 // surface.
582 gpu_memory_buffer_manager_->allocate_succeeds_ = true;
583 output_surface_->BindFramebuffer();
584 unsigned int source_texture = in_flight_surfaces().front()->texture;
585 unsigned int target_texture = current_frame()->texture;
586 testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
587 EXPECT_CALL(*mock_output_surface_,
588 CopyBufferDamage(target_texture, source_texture, small_damage, _))
589 .Times(1);
590 output_surface_->SwapBuffers(small_damage);
591 testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
592
593 // Shoot the just-created buffer, and try another swap. The copy should
danakj 2015/12/10 19:46:42 s/Shoot/Destroy/
ccameron 2015/12/11 21:14:24 Done.
594 // come from the displayed surface (because both in-flight surfaces are
595 // gone now).
596 output_surface_->PageFlipComplete();
597 in_flight_surfaces().back().reset();
598 EXPECT_EQ(2u, in_flight_surfaces().size());
599 for (auto& surface : in_flight_surfaces())
600 EXPECT_FALSE(surface);
601 output_surface_->BindFramebuffer();
602 source_texture = displayed_frame()->texture;
603 EXPECT_TRUE(current_frame());
604 EXPECT_TRUE(displayed_frame());
605 target_texture = current_frame()->texture;
606 testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
607 EXPECT_CALL(*mock_output_surface_,
608 CopyBufferDamage(target_texture, source_texture, small_damage, _))
609 .Times(1);
610 output_surface_->SwapBuffers(small_damage);
611 testing::Mock::VerifyAndClearExpectations(mock_output_surface_);
557 } 612 }
558 613
559 } // namespace 614 } // namespace
560 } // namespace content 615 } // namespace content
OLDNEW
« content/browser/compositor/buffer_queue.cc ('K') | « content/browser/compositor/buffer_queue.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698