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

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

Powered by Google App Engine
This is Rietveld 408576698