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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp

Issue 1507863005: [2D Canvas] Send GPU resources into hibernation when page is not visible (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tests 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 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 13 matching lines...) Expand all
24 24
25 #include "config.h" 25 #include "config.h"
26 #include "platform/graphics/Canvas2DLayerBridge.h" 26 #include "platform/graphics/Canvas2DLayerBridge.h"
27 27
28 #include "SkSurface.h" 28 #include "SkSurface.h"
29 #include "platform/graphics/ImageBuffer.h" 29 #include "platform/graphics/ImageBuffer.h"
30 #include "platform/graphics/test/MockWebGraphicsContext3D.h" 30 #include "platform/graphics/test/MockWebGraphicsContext3D.h"
31 #include "public/platform/Platform.h" 31 #include "public/platform/Platform.h"
32 #include "public/platform/WebExternalBitmap.h" 32 #include "public/platform/WebExternalBitmap.h"
33 #include "public/platform/WebGraphicsContext3DProvider.h" 33 #include "public/platform/WebGraphicsContext3DProvider.h"
34 #include "public/platform/WebScheduler.h"
35 #include "public/platform/WebTaskRunner.h"
34 #include "public/platform/WebThread.h" 36 #include "public/platform/WebThread.h"
37 #include "public/platform/WebTraceLocation.h"
35 #include "testing/gmock/include/gmock/gmock.h" 38 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h" 39 #include "testing/gtest/include/gtest/gtest.h"
37 #include "third_party/skia/include/core/SkCanvas.h" 40 #include "third_party/skia/include/core/SkCanvas.h"
38 #include "third_party/skia/include/gpu/GrContext.h" 41 #include "third_party/skia/include/gpu/GrContext.h"
39 #include "third_party/skia/include/gpu/gl/SkNullGLContext.h" 42 #include "third_party/skia/include/gpu/gl/SkNullGLContext.h"
40 #include "wtf/RefPtr.h" 43 #include "wtf/RefPtr.h"
41 44
42 using testing::InSequence; 45 using testing::InSequence;
43 using testing::Return; 46 using testing::Return;
44 using testing::Test; 47 using testing::Test;
(...skipping 29 matching lines...) Expand all
74 return m_grContext.get(); 77 return m_grContext.get();
75 } 78 }
76 79
77 private: 80 private:
78 WebGraphicsContext3D* m_context3d; 81 WebGraphicsContext3D* m_context3d;
79 RefPtr<GrContext> m_grContext; 82 RefPtr<GrContext> m_grContext;
80 }; 83 };
81 84
82 class Canvas2DLayerBridgePtr { 85 class Canvas2DLayerBridgePtr {
83 public: 86 public:
87 Canvas2DLayerBridgePtr() { }
84 Canvas2DLayerBridgePtr(PassRefPtr<Canvas2DLayerBridge> layerBridge) 88 Canvas2DLayerBridgePtr(PassRefPtr<Canvas2DLayerBridge> layerBridge)
85 : m_layerBridge(layerBridge) { } 89 : m_layerBridge(layerBridge) { }
86 90
87 ~Canvas2DLayerBridgePtr() 91 ~Canvas2DLayerBridgePtr()
88 { 92 {
89 m_layerBridge->beginDestruction(); 93 clear();
94 }
95
96 void clear()
97 {
98 if (m_layerBridge) {
99 m_layerBridge->beginDestruction();
100 m_layerBridge.clear();
101 }
102 }
103
104 void operator=(PassRefPtr<Canvas2DLayerBridge> layerBridge)
105 {
106 ASSERT(!m_layerBridge);
107 m_layerBridge = layerBridge;
90 } 108 }
91 109
92 Canvas2DLayerBridge* operator->() { return m_layerBridge.get(); } 110 Canvas2DLayerBridge* operator->() { return m_layerBridge.get(); }
93 Canvas2DLayerBridge* get() { return m_layerBridge.get(); } 111 Canvas2DLayerBridge* get() { return m_layerBridge.get(); }
94 112
95 private: 113 private:
96 RefPtr<Canvas2DLayerBridge> m_layerBridge; 114 RefPtr<Canvas2DLayerBridge> m_layerBridge;
97 }; 115 };
98 116
99 class NullWebExternalBitmap : public WebExternalBitmap { 117 class NullWebExternalBitmap : public WebExternalBitmap {
100 public: 118 public:
101 WebSize size() override 119 WebSize size() override
102 { 120 {
103 return WebSize(); 121 return WebSize();
104 } 122 }
105 123
106 void setSize(WebSize) override 124 void setSize(WebSize) override
107 { 125 {
108 } 126 }
109 127
110 uint8* pixels() override 128 uint8* pixels() override
111 { 129 {
112 return nullptr; 130 return nullptr;
113 } 131 }
114 }; 132 };
115 133
116 } // anonymous namespace 134 } // anonymous namespace
117 135
118 class Canvas2DLayerBridgeTest : public Test { 136 class Canvas2DLayerBridgeTest : public Test {
137 public:
138 PassRefPtr<Canvas2DLayerBridge> makeBridge(PassOwnPtr<MockWebGraphicsContext 3DProvider> provider, const IntSize& size, Canvas2DLayerBridge::AccelerationMode accelerationMode)
139 {
140 return adoptRef(new Canvas2DLayerBridge(provider, size, 0, NonOpaque, ac celerationMode));
141 }
142
119 protected: 143 protected:
120 void fullLifecycleTest() 144 void fullLifecycleTest()
121 { 145 {
122 MockCanvasContext mainMock; 146 MockCanvasContext mainMock;
123 OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock)); 147 OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(&mainMock));
124 148
125 ::testing::Mock::VerifyAndClearExpectations(&mainMock); 149 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
126 150
127 { 151 {
128 Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainM ockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::Dis ableAcceleration))); 152 Canvas2DLayerBridgePtr bridge(adoptRef(new Canvas2DLayerBridge(mainM ockProvider.release(), IntSize(300, 150), 0, NonOpaque, Canvas2DLayerBridge::Dis ableAcceleration)));
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareIfContextLost) 353 TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareIfContextLost)
330 { 354 {
331 fallbackToSoftwareIfContextLost(); 355 fallbackToSoftwareIfContextLost();
332 } 356 }
333 357
334 TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc) 358 TEST_F(Canvas2DLayerBridgeTest, FallbackToSoftwareOnFailedTextureAlloc)
335 { 359 {
336 fallbackToSoftwareOnFailedTextureAlloc(); 360 fallbackToSoftwareOnFailedTextureAlloc();
337 } 361 }
338 362
363 class MockLogger : public Canvas2DLayerBridge::Logger {
364 public:
365 MOCK_METHOD1(reportHibernationEvent, void(Canvas2DLayerBridge::HibernationEv ent));
366 MOCK_METHOD0(didStartHibernating, void());
367 virtual ~MockLogger() { }
368 };
369
370
371 class CreateBridgeTask : public WebTaskRunner::Task {
372 public:
373 CreateBridgeTask(Canvas2DLayerBridgePtr* bridgePtr, MockCanvasContext* mockC anvasContext, Canvas2DLayerBridgeTest* testHost, WebWaitableEvent* doneEvent)
374 : m_bridgePtr(bridgePtr)
375 , m_mockCanvasContext(mockCanvasContext)
376 , m_testHost(testHost)
377 , m_doneEvent(doneEvent)
378 { }
379
380 virtual ~CreateBridgeTask() { }
381
382 void run() override
383 {
384 OwnPtr<MockWebGraphicsContext3DProvider> mainMockProvider = adoptPtr(new MockWebGraphicsContext3DProvider(m_mockCanvasContext));
385 *m_bridgePtr = m_testHost->makeBridge(mainMockProvider.release(), IntSiz e(300, 300), Canvas2DLayerBridge::EnableAcceleration);
386 // draw+flush to trigger the creation of a GPU surface
387 (*m_bridgePtr)->didDraw(FloatRect(0, 0, 1, 1));
388 (*m_bridgePtr)->finalizeFrame(FloatRect(0, 0, 1, 1));
389 (*m_bridgePtr)->flush();
390 m_doneEvent->signal();
391 }
392
393 private:
394 Canvas2DLayerBridgePtr* m_bridgePtr;
395 MockCanvasContext* m_mockCanvasContext;
396 Canvas2DLayerBridgeTest* m_testHost;
397 WebWaitableEvent* m_doneEvent;
398 };
399
400 class DestroyBridgeTask : public WebTaskRunner::Task {
401 public:
402 DestroyBridgeTask(Canvas2DLayerBridgePtr* bridgePtr, WebWaitableEvent* doneE vent = nullptr)
403 : m_bridgePtr(bridgePtr)
404 , m_doneEvent(doneEvent)
405 { }
406
407 virtual ~DestroyBridgeTask() { }
408
409 void run() override
410 {
411 m_bridgePtr->clear();
412 if (m_doneEvent)
413 m_doneEvent->signal();
414 }
415
416 private:
417 Canvas2DLayerBridgePtr* m_bridgePtr;
418 WebWaitableEvent* m_doneEvent;
419 };
420
421 class SetIsHiddenTask : public WebTaskRunner::Task {
422 public:
423 SetIsHiddenTask(Canvas2DLayerBridge* bridge, bool value, WebWaitableEvent* d oneEvent = nullptr)
424 : m_bridge(bridge)
425 , m_value(value)
426 , m_doneEvent(doneEvent)
427 { }
428
429 virtual ~SetIsHiddenTask() { }
430
431 void run() override
432 {
433 m_bridge->setIsHidden(m_value);
434 if (m_doneEvent)
435 m_doneEvent->signal();
436 }
437
438 private:
439 Canvas2DLayerBridge* m_bridge;
440 bool m_value;
441 WebWaitableEvent* m_doneEvent;
442 };
443
444 TEST_F(Canvas2DLayerBridgeTest, HibernationLifeCycle)
445 {
446 MockCanvasContext mainMock;
447 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
448
449 // The Canvas2DLayerBridge has to be created on the thread that will use it
450 // to avoid WeakPtr thread check issues.
451 Canvas2DLayerBridgePtr bridge;
452 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
453 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
454 bridgeCreatedEvent->wait();
455
456 // Register an alternate Logger for tracking hibernation events
457 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
458 MockLogger* mockLoggerPtr = mockLogger.get();
459 bridge->setLoggerForTesting(mockLogger.release());
460
461 // Test entering hibernation
462 OwnPtr<WebWaitableEvent> hibernationStartedEvent = adoptPtr(Platform::curren t()->createWaitableEvent());
463 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
464 EXPECT_CALL(*mockLoggerPtr, didStartHibernating())
465 .WillOnce(testing::Invoke(hibernationStartedEvent.get(), &WebWaitableEve nt::signal));
466 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true));
467 hibernationStartedEvent->wait();
468 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
469 EXPECT_FALSE(bridge->isAccelerated());
470 EXPECT_TRUE(bridge->isHibernating());
471
472 // Test exiting hibernation
473 OwnPtr<WebWaitableEvent> hibernationEndedEvent = adoptPtr(Platform::current( )->createWaitableEvent());
474 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationEndedNormally));
475 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), false, hibernationEndedEvent.get()));
476 hibernationEndedEvent->wait();
477 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
478 EXPECT_TRUE(bridge->isAccelerated());
479 EXPECT_FALSE(bridge->isHibernating());
480
481 // Tear down the bridge on the thread so that 'bridge' can go out of scope
482 // without crashing due to thread checks
483 OwnPtr<WebWaitableEvent> bridgeDestroyedEvent = adoptPtr(Platform::current() ->createWaitableEvent());
484 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge, bridgeDestroyedEvent.get()));
485 bridgeDestroyedEvent->wait();
486
487 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
488 }
489
490 class RenderingTask : public WebTaskRunner::Task {
491 public:
492 RenderingTask(Canvas2DLayerBridge* bridge, WebWaitableEvent* doneEvent)
493 : m_bridge(bridge)
494 , m_doneEvent(doneEvent)
495 { }
496
497 virtual ~RenderingTask() { }
498
499 void run() override
500 {
501 m_bridge->didDraw(FloatRect(0, 0, 1, 1));
502 m_bridge->finalizeFrame(FloatRect(0, 0, 1, 1));
503 m_bridge->flush();
504 m_doneEvent->signal();
505 }
506
507 private:
508 Canvas2DLayerBridge* m_bridge;
509 WebWaitableEvent* m_doneEvent;
510 };
511
512 TEST_F(Canvas2DLayerBridgeTest, BackgroundRenderingWhileHibernating)
513 {
514 MockCanvasContext mainMock;
515 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
516
517 // The Canvas2DLayerBridge has to be created on the thread that will use it
518 // to avoid WeakPtr thread check issues.
519 Canvas2DLayerBridgePtr bridge;
520 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
521 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
522 bridgeCreatedEvent->wait();
523
524 // Register an alternate Logger for tracking hibernation events
525 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
526 MockLogger* mockLoggerPtr = mockLogger.get();
527 bridge->setLoggerForTesting(mockLogger.release());
528
529 // Test entering hibernation
530 OwnPtr<WebWaitableEvent> hibernationStartedEvent = adoptPtr(Platform::curren t()->createWaitableEvent());
531 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
532 EXPECT_CALL(*mockLoggerPtr, didStartHibernating())
533 .WillOnce(testing::Invoke(hibernationStartedEvent.get(), &WebWaitableEve nt::signal));
534 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true));
535 hibernationStartedEvent->wait();
536 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
537 EXPECT_FALSE(bridge->isAccelerated());
538 EXPECT_TRUE(bridge->isHibernating());
539
540 // Rendering in the background -> temp switch to SW
541 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationEndedWithSwitchToBackgroundRendering));
542 OwnPtr<WebWaitableEvent> switchEvent = adoptPtr(Platform::current()->createW aitableEvent());
543 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new RenderingTask(bridge .get(), switchEvent.get()));
544 switchEvent->wait();
545 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
546 EXPECT_FALSE(bridge->isAccelerated());
547 EXPECT_FALSE(bridge->isHibernating());
548
549 // Unhide
550 OwnPtr<WebWaitableEvent> unhideEvent = adoptPtr(Platform::current()->createW aitableEvent());
551 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), false, unhideEvent.get()));
552 unhideEvent->wait();
553 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
554 EXPECT_TRUE(bridge->isAccelerated()); // Becoming visible causes switch back to GPU
555 EXPECT_FALSE(bridge->isHibernating());
556
557 // Tear down the bridge on the thread so that 'bridge' can go out of scope
558 // without crashing due to thread checks
559 OwnPtr<WebWaitableEvent> bridgeDestroyedEvent = adoptPtr(Platform::current() ->createWaitableEvent());
560 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge, bridgeDestroyedEvent.get()));
561 bridgeDestroyedEvent->wait();
562
563 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
564 }
565
566 TEST_F(Canvas2DLayerBridgeTest, TeardownWhileHibernating)
567 {
568 MockCanvasContext mainMock;
569 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
570
571 // The Canvas2DLayerBridge has to be created on the thread that will use it
572 // to avoid WeakPtr thread check issues.
573 Canvas2DLayerBridgePtr bridge;
574 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
575 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
576 bridgeCreatedEvent->wait();
577
578 // Register an alternate Logger for tracking hibernation events
579 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
580 MockLogger* mockLoggerPtr = mockLogger.get();
581 bridge->setLoggerForTesting(mockLogger.release());
582
583 // Test entering hibernation
584 OwnPtr<WebWaitableEvent> hibernationStartedEvent = adoptPtr(Platform::curren t()->createWaitableEvent());
585 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
586 EXPECT_CALL(*mockLoggerPtr, didStartHibernating())
587 .WillOnce(testing::Invoke(hibernationStartedEvent.get(), &WebWaitableEve nt::signal));
588 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true));
589 hibernationStartedEvent->wait();
590 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
591 EXPECT_FALSE(bridge->isAccelerated());
592 EXPECT_TRUE(bridge->isHibernating());
593
594 // Tear down the bridge while hibernating
595 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationEndedWithTeardown));
596 OwnPtr<WebWaitableEvent> bridgeDestroyedEvent = adoptPtr(Platform::current() ->createWaitableEvent());
597 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge, bridgeDestroyedEvent.get()));
598 bridgeDestroyedEvent->wait();
599
600 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
601 }
602
603 class IdleFenceTask : public WebThread::IdleTask {
604 public:
605 IdleFenceTask(WebWaitableEvent* doneEvent)
606 : m_doneEvent(doneEvent)
607 { }
608
609 virtual ~IdleFenceTask() { }
610
611 void run(double /*deadline*/) override
612 {
613 m_doneEvent->signal();
614 }
615
616 private:
617 WebWaitableEvent* m_doneEvent;
618 };
619
620 TEST_F(Canvas2DLayerBridgeTest, TeardownWhileHibernationIsPending)
621 {
622 MockCanvasContext mainMock;
623 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
624
625 // The Canvas2DLayerBridge has to be created on the thread that will use it
626 // to avoid WeakPtr thread check issues.
627 Canvas2DLayerBridgePtr bridge;
628 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
629 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
630 bridgeCreatedEvent->wait();
631
632 // Register an alternate Logger for tracking hibernation events
633 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
634 MockLogger* mockLoggerPtr = mockLogger.get();
635 bridge->setLoggerForTesting(mockLogger.release());
636
637 // Test entering hibernation
638 OwnPtr<WebWaitableEvent> hibernationScheduledEvent = adoptPtr(Platform::curr ent()->createWaitableEvent());
639 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
640 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true, hibernationScheduledEvent.get()));
641 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge));
642 // In production, we would expect a
643 // HibernationAbortedDueToDestructionWhileHibernatePending event to be
644 // fired, but that signal is lost in the unit test due to no longer having
645 // a bridge to hold the mockLogger.
646 hibernationScheduledEvent->wait();
647 // Once we know the hibernation task is scheduled, we can schedule a fence.
648 // Assuming Idle tasks are guaranteed to run in the order they were
649 // submitted, this fence will guarantee the attempt to hibernate runs to
650 // completion before the thread is destroyed.
651 // This test passes by not crashing, which proves that the WeakPtr logic
652 // is sound.
653 OwnPtr<WebWaitableEvent> fenceEvent = adoptPtr(Platform::current()->createWa itableEvent());
654 testThread->scheduler()->postIdleTask(BLINK_FROM_HERE, new IdleFenceTask(fen ceEvent.get()));
655 fenceEvent->wait();
656
657 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
658 }
659
660 class BeginDestroyBridgeTask : public WebTaskRunner::Task {
661 public:
662 BeginDestroyBridgeTask(Canvas2DLayerBridge* bridge)
663 : m_bridge(bridge)
664 { }
665
666 virtual ~BeginDestroyBridgeTask() { }
667
668 void run() override
669 {
670 m_bridge->beginDestruction();
671 }
672
673 private:
674 Canvas2DLayerBridge* m_bridge;
675 };
676
677 TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToPendingTeardown)
678 {
679 MockCanvasContext mainMock;
680 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
681
682 // The Canvas2DLayerBridge has to be created on the thread that will use it
683 // to avoid WeakPtr thread check issues.
684 Canvas2DLayerBridgePtr bridge;
685 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
686 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
687 bridgeCreatedEvent->wait();
688
689 // Register an alternate Logger for tracking hibernation events
690 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
691 MockLogger* mockLoggerPtr = mockLogger.get();
692 bridge->setLoggerForTesting(mockLogger.release());
693
694 // Test entering hibernation
695 OwnPtr<WebWaitableEvent> hibernationAbortedEvent = adoptPtr(Platform::curren t()->createWaitableEvent());
696 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
697 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationAbortedDueToPendingDestruction))
698 .WillOnce(testing::InvokeWithoutArgs(hibernationAbortedEvent.get(), &Web WaitableEvent::signal));
699 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true));
700 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new BeginDestroyBridgeTa sk(bridge.get()));
701 hibernationAbortedEvent->wait();
702
703 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
704
705 // Tear down bridge on thread
706 OwnPtr<WebWaitableEvent> bridgeDestroyedEvent = adoptPtr(Platform::current() ->createWaitableEvent());
707 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge, bridgeDestroyedEvent.get()));
708 bridgeDestroyedEvent->wait();
709
710 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
711 }
712
713 TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToVisibilityChange)
714 {
715 MockCanvasContext mainMock;
716 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
717
718 // The Canvas2DLayerBridge has to be created on the thread that will use it
719 // to avoid WeakPtr thread check issues.
720 Canvas2DLayerBridgePtr bridge;
721 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
722 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
723 bridgeCreatedEvent->wait();
724
725 // Register an alternate Logger for tracking hibernation events
726 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
727 MockLogger* mockLoggerPtr = mockLogger.get();
728 bridge->setLoggerForTesting(mockLogger.release());
729
730 // Test entering hibernation
731 OwnPtr<WebWaitableEvent> hibernationAbortedEvent = adoptPtr(Platform::curren t()->createWaitableEvent());
732 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
733 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationAbortedDueToVisibilityChange))
734 .WillOnce(testing::InvokeWithoutArgs(hibernationAbortedEvent.get(), &Web WaitableEvent::signal));
735 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true));
736 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), false));
737 hibernationAbortedEvent->wait();
738 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
739 EXPECT_TRUE(bridge->isAccelerated());
740 EXPECT_FALSE(bridge->isHibernating());
741
742 // Tear down the bridge on the thread so that 'bridge' can go out of scope
743 // without crashing due to thread checks
744 OwnPtr<WebWaitableEvent> bridgeDestroyedEvent = adoptPtr(Platform::current() ->createWaitableEvent());
745 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge, bridgeDestroyedEvent.get()));
746 bridgeDestroyedEvent->wait();
747
748 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
749 }
750
751 TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToLostContext)
752 {
753 MockCanvasContext mainMock;
754 OwnPtr<WebThread> testThread = adoptPtr(Platform::current()->createThread("T estThread"));
755
756 // The Canvas2DLayerBridge has to be created on the thread that will use it
757 // to avoid WeakPtr thread check issues.
758 Canvas2DLayerBridgePtr bridge;
759 OwnPtr<WebWaitableEvent> bridgeCreatedEvent = adoptPtr(Platform::current()-> createWaitableEvent());
760 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new CreateBridgeTask(&br idge, &mainMock, this, bridgeCreatedEvent.get()));
761 bridgeCreatedEvent->wait();
762
763 // Register an alternate Logger for tracking hibernation events
764 OwnPtr<MockLogger> mockLogger = adoptPtr(new MockLogger);
765 MockLogger* mockLoggerPtr = mockLogger.get();
766 bridge->setLoggerForTesting(mockLogger.release());
767
768 mainMock.fakeContextLost();
769 // Test entering hibernation
770 OwnPtr<WebWaitableEvent> hibernationAbortedEvent = adoptPtr(Platform::curren t()->createWaitableEvent());
771 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationScheduled));
772 EXPECT_CALL(*mockLoggerPtr, reportHibernationEvent(Canvas2DLayerBridge::Hibe rnationAbortedDueGpuContextLoss))
773 .WillOnce(testing::InvokeWithoutArgs(hibernationAbortedEvent.get(), &Web WaitableEvent::signal));
774 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new SetIsHiddenTask(brid ge.get(), true));
775 hibernationAbortedEvent->wait();
776 ::testing::Mock::VerifyAndClearExpectations(mockLoggerPtr);
777 EXPECT_FALSE(bridge->isHibernating());
778
779 // Tear down the bridge on the thread so that 'bridge' can go out of scope
780 // without crashing due to thread checks
781 OwnPtr<WebWaitableEvent> bridgeDestroyedEvent = adoptPtr(Platform::current() ->createWaitableEvent());
782 testThread->taskRunner()->postTask(BLINK_FROM_HERE, new DestroyBridgeTask(&b ridge, bridgeDestroyedEvent.get()));
783 bridgeDestroyedEvent->wait();
784
785 ::testing::Mock::VerifyAndClearExpectations(&mainMock);
786 }
787
339 } // namespace blink 788 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698