| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "modules/compositorworker/CompositorWorkerThread.h" | 5 #include "modules/compositorworker/CompositorWorkerThread.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptSourceCode.h" | 7 #include "bindings/core/v8/ScriptSourceCode.h" |
| 8 #include "bindings/core/v8/SourceLocation.h" | 8 #include "bindings/core/v8/SourceLocation.h" |
| 9 #include "bindings/core/v8/V8GCController.h" | 9 #include "bindings/core/v8/V8GCController.h" |
| 10 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" | 10 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" |
| 11 #include "core/dom/CompositorProxyClient.h" | 11 #include "core/dom/CompositorProxyClient.h" |
| 12 #include "core/inspector/ConsoleMessage.h" | 12 #include "core/inspector/ConsoleMessage.h" |
| 13 #include "core/testing/DummyPageHolder.h" | 13 #include "core/testing/DummyPageHolder.h" |
| 14 #include "core/workers/InProcessWorkerObjectProxy.h" | 14 #include "core/workers/InProcessWorkerObjectProxy.h" |
| 15 #include "core/workers/WorkerBackingThread.h" | 15 #include "core/workers/WorkerBackingThread.h" |
| 16 #include "core/workers/WorkerLoaderProxy.h" | 16 #include "core/workers/WorkerLoaderProxy.h" |
| 17 #include "core/workers/WorkerOrWorkletGlobalScope.h" | 17 #include "core/workers/WorkerOrWorkletGlobalScope.h" |
| 18 #include "core/workers/WorkerThreadStartupData.h" | 18 #include "core/workers/WorkerThreadStartupData.h" |
| 19 #include "modules/compositorworker/CompositorWorkerGlobalScope.h" |
| 19 #include "platform/CrossThreadFunctional.h" | 20 #include "platform/CrossThreadFunctional.h" |
| 20 #include "platform/WaitableEvent.h" | 21 #include "platform/WaitableEvent.h" |
| 21 #include "platform/WebThreadSupportingGC.h" | 22 #include "platform/WebThreadSupportingGC.h" |
| 22 #include "platform/heap/Handle.h" | 23 #include "platform/heap/Handle.h" |
| 23 #include "platform/testing/TestingPlatformSupport.h" | 24 #include "platform/testing/TestingPlatformSupport.h" |
| 24 #include "platform/testing/UnitTestHelpers.h" | 25 #include "platform/testing/UnitTestHelpers.h" |
| 25 #include "public/platform/Platform.h" | 26 #include "public/platform/Platform.h" |
| 26 #include "public/platform/WebAddressSpace.h" | 27 #include "public/platform/WebAddressSpace.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 28 #include "wtf/PtrUtil.h" | 29 #include "wtf/PtrUtil.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 62 |
| 62 Persistent<ExecutionContext> m_executionContext; | 63 Persistent<ExecutionContext> m_executionContext; |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 class TestCompositorProxyClient | 66 class TestCompositorProxyClient |
| 66 : public GarbageCollected<TestCompositorProxyClient> | 67 : public GarbageCollected<TestCompositorProxyClient> |
| 67 , public CompositorProxyClient { | 68 , public CompositorProxyClient { |
| 68 USING_GARBAGE_COLLECTED_MIXIN(TestCompositorProxyClient); | 69 USING_GARBAGE_COLLECTED_MIXIN(TestCompositorProxyClient); |
| 69 public: | 70 public: |
| 70 TestCompositorProxyClient() {} | 71 TestCompositorProxyClient() {} |
| 72 DEFINE_INLINE_VIRTUAL_TRACE() |
| 73 { |
| 74 CompositorProxyClient::trace(visitor); |
| 75 visitor->trace(m_globalScope); |
| 76 } |
| 71 | 77 |
| 72 void setGlobalScope(WorkerGlobalScope*) override {} | 78 void setGlobalScope(WorkerGlobalScope* scope) override |
| 79 { |
| 80 m_globalScope = static_cast<CompositorWorkerGlobalScope*>(scope); |
| 81 } |
| 82 CompositorWorkerGlobalScope* globalScope() { return m_globalScope; } |
| 73 void requestAnimationFrame() override {} | 83 void requestAnimationFrame() override {} |
| 74 void registerCompositorProxy(CompositorProxy*) override {} | 84 void registerCompositorProxy(CompositorProxy*) override {} |
| 75 void unregisterCompositorProxy(CompositorProxy*) override {} | 85 void unregisterCompositorProxy(CompositorProxy*) override {} |
| 86 |
| 87 private: |
| 88 Member<CompositorWorkerGlobalScope> m_globalScope; |
| 76 }; | 89 }; |
| 77 | 90 |
| 78 class CompositorWorkerTestPlatform : public TestingPlatformSupport { | 91 class CompositorWorkerTestPlatform : public TestingPlatformSupport { |
| 79 public: | 92 public: |
| 80 CompositorWorkerTestPlatform() | 93 CompositorWorkerTestPlatform() |
| 81 : m_thread(wrapUnique(m_oldPlatform->createThread("Compositor"))) | 94 : m_thread(wrapUnique(m_oldPlatform->createThread("Compositor"))) |
| 82 { | 95 { |
| 83 } | 96 } |
| 84 | 97 |
| 85 WebThread* compositorThread() const override | 98 WebThread* compositorThread() const override |
| (...skipping 19 matching lines...) Expand all Loading... |
| 105 m_objectProxy = TestCompositorWorkerObjectProxy::create(&m_page->documen
t()); | 118 m_objectProxy = TestCompositorWorkerObjectProxy::create(&m_page->documen
t()); |
| 106 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http://
fake.url/")); | 119 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http://
fake.url/")); |
| 107 } | 120 } |
| 108 | 121 |
| 109 void TearDown() override | 122 void TearDown() override |
| 110 { | 123 { |
| 111 m_page.reset(); | 124 m_page.reset(); |
| 112 CompositorWorkerThread::clearSharedBackingThread(); | 125 CompositorWorkerThread::clearSharedBackingThread(); |
| 113 } | 126 } |
| 114 | 127 |
| 115 std::unique_ptr<CompositorWorkerThread> createCompositorWorker() | 128 std::unique_ptr<CompositorWorkerThread> createCompositorWorker(CompositorPro
xyClient* client = nullptr) |
| 116 { | 129 { |
| 117 std::unique_ptr<CompositorWorkerThread> workerThread = CompositorWorkerT
hread::create(nullptr, *m_objectProxy, 0); | 130 std::unique_ptr<CompositorWorkerThread> workerThread = CompositorWorkerT
hread::create(nullptr, *m_objectProxy, 0); |
| 118 WorkerClients* clients = WorkerClients::create(); | 131 WorkerClients* clients = WorkerClients::create(); |
| 119 provideCompositorProxyClientTo(clients, new TestCompositorProxyClient); | 132 if (!client) |
| 133 client = new TestCompositorProxyClient(); |
| 134 provideCompositorProxyClientTo(clients, client); |
| 120 workerThread->start(WorkerThreadStartupData::create( | 135 workerThread->start(WorkerThreadStartupData::create( |
| 121 KURL(ParsedURLString, "http://fake.url/"), | 136 KURL(ParsedURLString, "http://fake.url/"), |
| 122 "fake user agent", | 137 "fake user agent", |
| 123 "//fake source code", | 138 "//fake source code", |
| 124 nullptr, | 139 nullptr, |
| 125 DontPauseWorkerGlobalScopeOnStart, | 140 DontPauseWorkerGlobalScopeOnStart, |
| 126 nullptr, | 141 nullptr, |
| 127 "", | 142 "", |
| 128 m_securityOrigin.get(), | 143 m_securityOrigin.get(), |
| 129 clients, | 144 clients, |
| 130 WebAddressSpaceLocal, | 145 WebAddressSpaceLocal, |
| 131 nullptr, | 146 nullptr, |
| 132 nullptr, | 147 nullptr, |
| 133 V8CacheOptionsDefault)); | 148 V8CacheOptionsDefault)); |
| 134 return workerThread; | 149 return workerThread; |
| 135 } | 150 } |
| 136 | 151 |
| 137 // Attempts to run some simple script for |worker|. | 152 // Attempts to run some simple script for |worker|. |
| 138 void checkWorkerCanExecuteScript(WorkerThread* worker) | 153 void checkWorkerCanExecuteScript(WorkerThread* worker) |
| 139 { | 154 { |
| 140 std::unique_ptr<WaitableEvent> waitEvent = wrapUnique(new WaitableEvent(
)); | 155 std::unique_ptr<WaitableEvent> waitEvent = wrapUnique(new WaitableEvent(
)); |
| 141 worker->workerBackingThread().backingThread().postTask(BLINK_FROM_HERE,
crossThreadBind(&CompositorWorkerThreadTest::executeScriptInWorker, crossThreadU
nretained(this), | 156 worker->workerBackingThread().backingThread().postTask(BLINK_FROM_HERE,
crossThreadBind(&CompositorWorkerThreadTest::executeScriptInWorker, crossThreadU
nretained(this), |
| 142 crossThreadUnretained(worker), crossThreadUnretained(waitEvent.get()
))); | 157 crossThreadUnretained(worker), crossThreadUnretained(waitEvent.get()
))); |
| 143 waitEvent->wait(); | 158 waitEvent->wait(); |
| 144 } | 159 } |
| 145 | 160 |
| 161 void waitForWorker(WorkerThread* worker) |
| 162 { |
| 163 std::unique_ptr<WaitableEvent> waitEvent = wrapUnique(new WaitableEvent(
)); |
| 164 worker->workerBackingThread().backingThread().postTask(BLINK_FROM_HERE,
crossThreadBind(&CompositorWorkerThreadTest::signalFromWorker, crossThreadUnreta
ined(this), |
| 165 crossThreadUnretained(worker), crossThreadUnretained(waitEvent.get()
))); |
| 166 waitEvent->wait(); |
| 167 } |
| 168 |
| 146 private: | 169 private: |
| 147 void executeScriptInWorker(WorkerThread* worker, WaitableEvent* waitEvent) | 170 void executeScriptInWorker(WorkerThread* worker, WaitableEvent* waitEvent) |
| 148 { | 171 { |
| 149 WorkerOrWorkletScriptController* scriptController = worker->globalScope(
)->scriptController(); | 172 WorkerOrWorkletScriptController* scriptController = worker->globalScope(
)->scriptController(); |
| 150 bool evaluateResult = scriptController->evaluate(ScriptSourceCode("var c
ounter = 0; ++counter;")); | 173 bool evaluateResult = scriptController->evaluate(ScriptSourceCode("var c
ounter = 0; ++counter;")); |
| 151 ASSERT_UNUSED(evaluateResult, evaluateResult); | 174 ASSERT_UNUSED(evaluateResult, evaluateResult); |
| 152 waitEvent->signal(); | 175 waitEvent->signal(); |
| 153 } | 176 } |
| 154 | 177 |
| 178 void signalFromWorker(WorkerThread* worker, WaitableEvent* waitEvent) |
| 179 { |
| 180 waitEvent->signal(); |
| 181 } |
| 182 |
| 155 std::unique_ptr<DummyPageHolder> m_page; | 183 std::unique_ptr<DummyPageHolder> m_page; |
| 156 RefPtr<SecurityOrigin> m_securityOrigin; | 184 RefPtr<SecurityOrigin> m_securityOrigin; |
| 157 std::unique_ptr<InProcessWorkerObjectProxy> m_objectProxy; | 185 std::unique_ptr<InProcessWorkerObjectProxy> m_objectProxy; |
| 158 CompositorWorkerTestPlatform m_testPlatform; | 186 CompositorWorkerTestPlatform m_testPlatform; |
| 159 }; | 187 }; |
| 160 | 188 |
| 161 TEST_F(CompositorWorkerThreadTest, Basic) | 189 TEST_F(CompositorWorkerThreadTest, Basic) |
| 162 { | 190 { |
| 163 std::unique_ptr<CompositorWorkerThread> compositorWorker = createCompositorW
orker(); | 191 std::unique_ptr<CompositorWorkerThread> compositorWorker = createCompositorW
orker(); |
| 164 checkWorkerCanExecuteScript(compositorWorker.get()); | 192 checkWorkerCanExecuteScript(compositorWorker.get()); |
| 165 compositorWorker->terminateAndWait(); | 193 compositorWorker->terminateAndWait(); |
| 166 } | 194 } |
| 167 | 195 |
| 196 TEST_F(CompositorWorkerThreadTest, Shutdown) |
| 197 { |
| 198 TestCompositorProxyClient* testClient = new TestCompositorProxyClient; |
| 199 std::unique_ptr<CompositorWorkerThread> compositorWorker = createCompositorW
orker(testClient); |
| 200 waitForWorker(compositorWorker.get()); |
| 201 // Once the worker has started, we should have a valid global scope. |
| 202 EXPECT_NE(nullptr, testClient->globalScope()); |
| 203 |
| 204 // After terminating the worker, we should no longer have a reference to the
global scope |
| 205 // in the client so that we don't try to execute animation frame callbacks o
n a terminated |
| 206 // worker. |
| 207 compositorWorker->terminateAndWait(); |
| 208 EXPECT_EQ(nullptr, testClient->globalScope()); |
| 209 } |
| 210 |
| 168 // Tests that the same WebThread is used for new workers if the WebThread is sti
ll alive. | 211 // Tests that the same WebThread is used for new workers if the WebThread is sti
ll alive. |
| 169 TEST_F(CompositorWorkerThreadTest, CreateSecondAndTerminateFirst) | 212 TEST_F(CompositorWorkerThreadTest, CreateSecondAndTerminateFirst) |
| 170 { | 213 { |
| 171 // Create the first worker and wait until it is initialized. | 214 // Create the first worker and wait until it is initialized. |
| 172 std::unique_ptr<CompositorWorkerThread> firstWorker = createCompositorWorker
(); | 215 std::unique_ptr<CompositorWorkerThread> firstWorker = createCompositorWorker
(); |
| 173 WebThreadSupportingGC* firstThread = &firstWorker->workerBackingThread().bac
kingThread(); | 216 WebThreadSupportingGC* firstThread = &firstWorker->workerBackingThread().bac
kingThread(); |
| 174 checkWorkerCanExecuteScript(firstWorker.get()); | 217 checkWorkerCanExecuteScript(firstWorker.get()); |
| 175 v8::Isolate* firstIsolate = firstWorker->isolate(); | 218 v8::Isolate* firstIsolate = firstWorker->isolate(); |
| 176 ASSERT_TRUE(firstIsolate); | 219 ASSERT_TRUE(firstIsolate); |
| 177 | 220 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 v8::Isolate* secondIsolate = secondWorker->isolate(); | 280 v8::Isolate* secondIsolate = secondWorker->isolate(); |
| 238 ASSERT_TRUE(secondIsolate); | 281 ASSERT_TRUE(secondIsolate); |
| 239 EXPECT_EQ(firstIsolate, secondIsolate); | 282 EXPECT_EQ(firstIsolate, secondIsolate); |
| 240 | 283 |
| 241 // Verify that the isolate can run some scripts correctly in the second work
er. | 284 // Verify that the isolate can run some scripts correctly in the second work
er. |
| 242 checkWorkerCanExecuteScript(secondWorker.get()); | 285 checkWorkerCanExecuteScript(secondWorker.get()); |
| 243 secondWorker->terminateAndWait(); | 286 secondWorker->terminateAndWait(); |
| 244 } | 287 } |
| 245 | 288 |
| 246 } // namespace blink | 289 } // namespace blink |
| OLD | NEW |