Don't consider a Bluetooth adapter present until it has an address.
[chromium-blink-merge.git] / cc / CCThreadedTest.cpp
blob5c5723ef2c2a53c274d512518ae1426b1791e4c3
1 // Copyright 2011 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 "config.h"
7 #include "CCThreadedTest.h"
9 #include "CCActiveAnimation.h"
10 #include "CCAnimationTestCommon.h"
11 #include "CCInputHandler.h"
12 #include "CCLayerAnimationController.h"
13 #include "CCLayerImpl.h"
14 #include "CCLayerTreeHostImpl.h"
15 #include "CCOcclusionTrackerTestCommon.h"
16 #include "CCScopedThreadProxy.h"
17 #include "CCSingleThreadProxy.h"
18 #include "CCTextureUpdateQueue.h"
19 #include "CCThreadTask.h"
20 #include "CCTiledLayerTestCommon.h"
21 #include "CCTimingFunction.h"
22 #include "ContentLayerChromium.h"
23 #include "FakeWebCompositorOutputSurface.h"
24 #include "FakeWebGraphicsContext3D.h"
25 #include "LayerChromium.h"
26 #include <gmock/gmock.h>
27 #include <public/Platform.h>
28 #include <public/WebCompositorSupport.h>
29 #include <public/WebFilterOperation.h>
30 #include <public/WebFilterOperations.h>
31 #include <public/WebThread.h>
32 #include <wtf/Locker.h>
33 #include <wtf/MainThread.h>
34 #include <wtf/PassRefPtr.h>
35 #include <wtf/ThreadingPrimitives.h>
36 #include <wtf/Vector.h>
38 using namespace WebCore;
39 using namespace WebKit;
41 namespace WebKitTests {
43 PassOwnPtr<CompositorFakeWebGraphicsContext3DWithTextureTracking> CompositorFakeWebGraphicsContext3DWithTextureTracking::create(Attributes attrs)
45 return adoptPtr(new CompositorFakeWebGraphicsContext3DWithTextureTracking(attrs));
48 WebGLId CompositorFakeWebGraphicsContext3DWithTextureTracking::createTexture()
50 WebGLId texture = m_textures.size() + 1;
51 m_textures.append(texture);
52 return texture;
55 void CompositorFakeWebGraphicsContext3DWithTextureTracking::deleteTexture(WebGLId texture)
57 for (size_t i = 0; i < m_textures.size(); i++) {
58 if (m_textures[i] == texture) {
59 m_textures.remove(i);
60 break;
65 void CompositorFakeWebGraphicsContext3DWithTextureTracking::bindTexture(WGC3Denum /* target */, WebGLId texture)
67 m_usedTextures.add(texture);
70 int CompositorFakeWebGraphicsContext3DWithTextureTracking::numTextures() const { return static_cast<int>(m_textures.size()); }
71 int CompositorFakeWebGraphicsContext3DWithTextureTracking::texture(int i) const { return m_textures[i]; }
72 void CompositorFakeWebGraphicsContext3DWithTextureTracking::resetTextures() { m_textures.clear(); }
74 int CompositorFakeWebGraphicsContext3DWithTextureTracking::numUsedTextures() const { return static_cast<int>(m_usedTextures.size()); }
75 bool CompositorFakeWebGraphicsContext3DWithTextureTracking::usedTexture(int texture) const { return m_usedTextures.find(texture) != m_usedTextures.end(); }
76 void CompositorFakeWebGraphicsContext3DWithTextureTracking::resetUsedTextures() { m_usedTextures.clear(); }
78 CompositorFakeWebGraphicsContext3DWithTextureTracking::CompositorFakeWebGraphicsContext3DWithTextureTracking(Attributes attrs) : CompositorFakeWebGraphicsContext3D(attrs)
82 PassOwnPtr<WebCompositorOutputSurface> TestHooks::createOutputSurface()
84 return FakeWebCompositorOutputSurface::create(CompositorFakeWebGraphicsContext3DWithTextureTracking::create(WebGraphicsContext3D::Attributes()));
87 PassOwnPtr<MockLayerTreeHostImpl> MockLayerTreeHostImpl::create(TestHooks* testHooks, const CCLayerTreeSettings& settings, CCLayerTreeHostImplClient* client)
89 return adoptPtr(new MockLayerTreeHostImpl(testHooks, settings, client));
92 void MockLayerTreeHostImpl::beginCommit()
94 CCLayerTreeHostImpl::beginCommit();
95 m_testHooks->beginCommitOnCCThread(this);
98 void MockLayerTreeHostImpl::commitComplete()
100 CCLayerTreeHostImpl::commitComplete();
101 m_testHooks->commitCompleteOnCCThread(this);
104 bool MockLayerTreeHostImpl::prepareToDraw(FrameData& frame)
106 bool result = CCLayerTreeHostImpl::prepareToDraw(frame);
107 if (!m_testHooks->prepareToDrawOnCCThread(this))
108 result = false;
109 return result;
112 void MockLayerTreeHostImpl::drawLayers(const FrameData& frame)
114 CCLayerTreeHostImpl::drawLayers(frame);
115 m_testHooks->drawLayersOnCCThread(this);
118 void MockLayerTreeHostImpl::animateLayers(double monotonicTime, double wallClockTime)
120 m_testHooks->willAnimateLayers(this, monotonicTime);
121 CCLayerTreeHostImpl::animateLayers(monotonicTime, wallClockTime);
122 m_testHooks->animateLayers(this, monotonicTime);
125 double MockLayerTreeHostImpl::lowFrequencyAnimationInterval() const
127 return 1.0 / 60;
130 MockLayerTreeHostImpl::MockLayerTreeHostImpl(TestHooks* testHooks, const CCLayerTreeSettings& settings, CCLayerTreeHostImplClient* client)
131 : CCLayerTreeHostImpl(settings, client)
132 , m_testHooks(testHooks)
136 // Adapts CCLayerTreeHost for test. Injects MockLayerTreeHostImpl.
137 class MockLayerTreeHost : public WebCore::CCLayerTreeHost {
138 public:
139 static PassOwnPtr<MockLayerTreeHost> create(TestHooks* testHooks, WebCore::CCLayerTreeHostClient* client, PassRefPtr<WebCore::LayerChromium> rootLayer, const WebCore::CCLayerTreeSettings& settings)
141 OwnPtr<MockLayerTreeHost> layerTreeHost(adoptPtr(new MockLayerTreeHost(testHooks, client, settings)));
142 bool success = layerTreeHost->initialize();
143 EXPECT_TRUE(success);
144 layerTreeHost->setRootLayer(rootLayer);
146 // LayerTreeHostImpl won't draw if it has 1x1 viewport.
147 layerTreeHost->setViewportSize(IntSize(1, 1), IntSize(1, 1));
149 layerTreeHost->rootLayer()->setLayerAnimationDelegate(testHooks);
151 return layerTreeHost.release();
154 virtual PassOwnPtr<WebCore::CCLayerTreeHostImpl> createLayerTreeHostImpl(WebCore::CCLayerTreeHostImplClient* client)
156 return MockLayerTreeHostImpl::create(m_testHooks, settings(), client);
159 virtual void didAddAnimation() OVERRIDE
161 CCLayerTreeHost::didAddAnimation();
162 m_testHooks->didAddAnimation();
165 private:
166 MockLayerTreeHost(TestHooks* testHooks, WebCore::CCLayerTreeHostClient* client, const WebCore::CCLayerTreeSettings& settings)
167 : CCLayerTreeHost(client, settings)
168 , m_testHooks(testHooks)
172 TestHooks* m_testHooks;
175 // Implementation of CCLayerTreeHost callback interface.
176 class MockLayerTreeHostClient : public MockCCLayerTreeHostClient {
177 public:
178 static PassOwnPtr<MockLayerTreeHostClient> create(TestHooks* testHooks)
180 return adoptPtr(new MockLayerTreeHostClient(testHooks));
183 virtual void willBeginFrame() OVERRIDE
187 virtual void didBeginFrame() OVERRIDE
191 virtual void animate(double monotonicTime) OVERRIDE
193 m_testHooks->animate(monotonicTime);
196 virtual void layout() OVERRIDE
198 m_testHooks->layout();
201 virtual void applyScrollAndScale(const IntSize& scrollDelta, float scale) OVERRIDE
203 m_testHooks->applyScrollAndScale(scrollDelta, scale);
206 virtual PassOwnPtr<WebCompositorOutputSurface> createOutputSurface() OVERRIDE
208 return m_testHooks->createOutputSurface();
211 virtual void didRecreateOutputSurface(bool succeeded) OVERRIDE
213 m_testHooks->didRecreateOutputSurface(succeeded);
216 virtual PassOwnPtr<CCInputHandler> createInputHandler() OVERRIDE
218 return nullptr;
221 virtual void willCommit() OVERRIDE
225 virtual void didCommit() OVERRIDE
227 m_testHooks->didCommit();
230 virtual void didCommitAndDrawFrame() OVERRIDE
232 m_testHooks->didCommitAndDrawFrame();
235 virtual void didCompleteSwapBuffers() OVERRIDE
239 virtual void scheduleComposite() OVERRIDE
241 m_testHooks->scheduleComposite();
244 private:
245 explicit MockLayerTreeHostClient(TestHooks* testHooks) : m_testHooks(testHooks) { }
247 TestHooks* m_testHooks;
250 class TimeoutTask : public WebThread::Task {
251 public:
252 explicit TimeoutTask(CCThreadedTest* test)
253 : m_test(test)
257 void clearTest()
259 m_test = 0;
262 virtual ~TimeoutTask()
264 if (m_test)
265 m_test->clearTimeout();
268 virtual void run()
270 if (m_test)
271 m_test->timeout();
274 private:
275 CCThreadedTest* m_test;
278 class BeginTask : public WebThread::Task {
279 public:
280 explicit BeginTask(CCThreadedTest* test)
281 : m_test(test)
285 virtual ~BeginTask() { }
286 virtual void run()
288 m_test->doBeginTest();
290 private:
291 CCThreadedTest* m_test;
294 class EndTestTask : public WebThread::Task {
295 public:
296 explicit EndTestTask(CCThreadedTest* test)
297 : m_test(test)
301 virtual ~EndTestTask()
303 if (m_test)
304 m_test->clearEndTestTask();
307 void clearTest()
309 m_test = 0;
312 virtual void run()
314 if (m_test)
315 m_test->endTest();
318 private:
319 CCThreadedTest* m_test;
322 CCThreadedTest::CCThreadedTest()
323 : m_beginning(false)
324 , m_endWhenBeginReturns(false)
325 , m_timedOut(false)
326 , m_finished(false)
327 , m_scheduled(false)
328 , m_started(false)
329 , m_endTestTask(0)
332 void CCThreadedTest::endTest()
334 m_finished = true;
336 // If we are called from the CCThread, re-call endTest on the main thread.
337 if (!isMainThread())
338 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadedTest::endTest));
339 else {
340 // For the case where we endTest during beginTest(), set a flag to indicate that
341 // the test should end the second beginTest regains control.
342 if (m_beginning)
343 m_endWhenBeginReturns = true;
344 else
345 onEndTest(static_cast<void*>(this));
349 void CCThreadedTest::endTestAfterDelay(int delayMilliseconds)
351 // If we are called from the CCThread, re-call endTest on the main thread.
352 if (!isMainThread())
353 m_mainThreadProxy->postTask(createCCThreadTask(this, &CCThreadedTest::endTestAfterDelay, delayMilliseconds));
354 else {
355 m_endTestTask = new EndTestTask(this);
356 WebKit::Platform::current()->currentThread()->postDelayedTask(m_endTestTask, delayMilliseconds);
360 void CCThreadedTest::postSetNeedsAnimateToMainThread()
362 callOnMainThread(CCThreadedTest::dispatchSetNeedsAnimate, this);
365 void CCThreadedTest::postAddAnimationToMainThread()
367 callOnMainThread(CCThreadedTest::dispatchAddAnimation, this);
370 void CCThreadedTest::postAddInstantAnimationToMainThread()
372 callOnMainThread(CCThreadedTest::dispatchAddInstantAnimation, this);
375 void CCThreadedTest::postSetNeedsCommitToMainThread()
377 callOnMainThread(CCThreadedTest::dispatchSetNeedsCommit, this);
380 void CCThreadedTest::postAcquireLayerTextures()
382 callOnMainThread(CCThreadedTest::dispatchAcquireLayerTextures, this);
385 void CCThreadedTest::postSetNeedsRedrawToMainThread()
387 callOnMainThread(CCThreadedTest::dispatchSetNeedsRedraw, this);
390 void CCThreadedTest::postSetNeedsAnimateAndCommitToMainThread()
392 callOnMainThread(CCThreadedTest::dispatchSetNeedsAnimateAndCommit, this);
395 void CCThreadedTest::postSetVisibleToMainThread(bool visible)
397 callOnMainThread(visible ? CCThreadedTest::dispatchSetVisible : CCThreadedTest::dispatchSetInvisible, this);
400 void CCThreadedTest::postDidAddAnimationToMainThread()
402 callOnMainThread(CCThreadedTest::dispatchDidAddAnimation, this);
405 void CCThreadedTest::doBeginTest()
407 ASSERT(isMainThread());
408 m_client = MockLayerTreeHostClient::create(this);
410 RefPtr<LayerChromium> rootLayer = LayerChromium::create();
411 m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, m_settings);
412 ASSERT_TRUE(m_layerTreeHost);
413 rootLayer->setLayerTreeHost(m_layerTreeHost.get());
414 m_layerTreeHost->setSurfaceReady();
416 m_started = true;
417 m_beginning = true;
418 beginTest();
419 m_beginning = false;
420 if (m_endWhenBeginReturns)
421 onEndTest(static_cast<void*>(this));
424 void CCThreadedTest::timeout()
426 m_timedOut = true;
427 endTest();
430 void CCThreadedTest::scheduleComposite()
432 if (!m_started || m_scheduled || m_finished)
433 return;
434 m_scheduled = true;
435 callOnMainThread(&CCThreadedTest::dispatchComposite, this);
438 void CCThreadedTest::onEndTest(void* self)
440 ASSERT(isMainThread());
441 WebKit::Platform::current()->currentThread()->exitRunLoop();
444 void CCThreadedTest::dispatchSetNeedsAnimate(void* self)
446 ASSERT(isMainThread());
448 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
449 ASSERT(test);
450 if (test->m_finished)
451 return;
453 if (test->m_layerTreeHost)
454 test->m_layerTreeHost->setNeedsAnimate();
457 void CCThreadedTest::dispatchAddInstantAnimation(void* self)
459 ASSERT(isMainThread());
461 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
462 ASSERT(test);
463 if (test->m_finished)
464 return;
466 if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
467 addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 0, 0, 0.5, false);
470 void CCThreadedTest::dispatchAddAnimation(void* self)
472 ASSERT(isMainThread());
474 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
475 ASSERT(test);
476 if (test->m_finished)
477 return;
479 if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
480 addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 10, 0, 0.5, true);
483 void CCThreadedTest::dispatchSetNeedsAnimateAndCommit(void* self)
485 ASSERT(isMainThread());
487 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
488 ASSERT(test);
489 if (test->m_finished)
490 return;
492 if (test->m_layerTreeHost) {
493 test->m_layerTreeHost->setNeedsAnimate();
494 test->m_layerTreeHost->setNeedsCommit();
498 void CCThreadedTest::dispatchSetNeedsCommit(void* self)
500 ASSERT(isMainThread());
502 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
503 ASSERT_TRUE(test);
504 if (test->m_finished)
505 return;
507 if (test->m_layerTreeHost)
508 test->m_layerTreeHost->setNeedsCommit();
511 void CCThreadedTest::dispatchAcquireLayerTextures(void* self)
513 ASSERT(isMainThread());
515 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
516 ASSERT_TRUE(test);
517 if (test->m_finished)
518 return;
520 if (test->m_layerTreeHost)
521 test->m_layerTreeHost->acquireLayerTextures();
524 void CCThreadedTest::dispatchSetNeedsRedraw(void* self)
526 ASSERT(isMainThread());
528 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
529 ASSERT_TRUE(test);
530 if (test->m_finished)
531 return;
533 if (test->m_layerTreeHost)
534 test->m_layerTreeHost->setNeedsRedraw();
537 void CCThreadedTest::dispatchSetVisible(void* self)
539 ASSERT(isMainThread());
541 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
542 ASSERT(test);
543 if (test->m_finished)
544 return;
546 if (test->m_layerTreeHost)
547 test->m_layerTreeHost->setVisible(true);
550 void CCThreadedTest::dispatchSetInvisible(void* self)
552 ASSERT(isMainThread());
554 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
555 ASSERT(test);
556 if (test->m_finished)
557 return;
559 if (test->m_layerTreeHost)
560 test->m_layerTreeHost->setVisible(false);
563 void CCThreadedTest::dispatchComposite(void* self)
565 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
566 ASSERT(isMainThread());
567 ASSERT(test);
568 test->m_scheduled = false;
569 if (test->m_layerTreeHost && !test->m_finished)
570 test->m_layerTreeHost->composite();
573 void CCThreadedTest::dispatchDidAddAnimation(void* self)
575 ASSERT(isMainThread());
577 CCThreadedTest* test = static_cast<CCThreadedTest*>(self);
578 ASSERT(test);
579 if (test->m_finished)
580 return;
582 if (test->m_layerTreeHost)
583 test->m_layerTreeHost->didAddAnimation();
586 void CCThreadedTest::runTest(bool threaded)
588 // For these tests, we will enable threaded animations.
589 Platform::current()->compositorSupport()->setAcceleratedAnimationEnabled(true);
591 if (threaded) {
592 m_webThread = adoptPtr(WebKit::Platform::current()->createThread("CCThreadedTest"));
593 Platform::current()->compositorSupport()->initialize(m_webThread.get());
594 } else
595 Platform::current()->compositorSupport()->initialize(0);
597 ASSERT(CCProxy::isMainThread());
598 m_mainThreadProxy = CCScopedThreadProxy::create(CCProxy::mainThread());
600 initializeSettings(m_settings);
602 m_beginTask = new BeginTask(this);
603 WebKit::Platform::current()->currentThread()->postDelayedTask(m_beginTask, 0); // postDelayedTask takes ownership of the task
604 m_timeoutTask = new TimeoutTask(this);
605 WebKit::Platform::current()->currentThread()->postDelayedTask(m_timeoutTask, 5000);
606 WebKit::Platform::current()->currentThread()->enterRunLoop();
608 if (m_layerTreeHost && m_layerTreeHost->rootLayer())
609 m_layerTreeHost->rootLayer()->setLayerTreeHost(0);
610 m_layerTreeHost.clear();
612 if (m_timeoutTask)
613 m_timeoutTask->clearTest();
615 if (m_endTestTask)
616 m_endTestTask->clearTest();
618 ASSERT_FALSE(m_layerTreeHost.get());
619 m_client.clear();
620 if (m_timedOut) {
621 FAIL() << "Test timed out";
622 Platform::current()->compositorSupport()->shutdown();
623 return;
625 afterTest();
626 Platform::current()->compositorSupport()->shutdown();
629 } // namespace WebKitTests