Commit 4bd1a1b4 authored by ikilpatrick's avatar ikilpatrick Committed by Commit bot

[worklets] Introduce ThreadedWorkletMessagingProxy and AnimationWorkletMessagaingProxy.

This patch does the plumbing from the animationworklet to the globalscope to import scripts etc.

BUG=567358

Review-Url: https://codereview.chromium.org/2312493002
Cr-Commit-Position: refs/heads/master@{#418765}
parent ddef9a3a
<!DOCTYPE html>
<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/import-tests.js"></script>
</head>
<body>
<script>
runImportTests(window.animationWorklet);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/import-tests.js"></script>
</head>
<body>
<script>
runImportTests(window.paintWorklet);
</script>
</body>
</html>
<!DOCTYPE html> // Runs a series of tests related to importing scripts on a worklet.
<html> //
<head> // Usage:
<script src="../resources/testharness.js"></script> // runImportTests(workletType);
<script src="../resources/testharnessreport.js"></script> function runImportTests(worklet) {
</head>
<body>
<script>
promise_test(function() { promise_test(function() {
return paintWorklet.import('resources/empty-worklet-script.js').then(function(undefined_arg) { return worklet.import('resources/empty-worklet-script.js').then(function(undefined_arg) {
assert_equals(undefined_arg, undefined, 'Promise should resolve with no arguments.'); assert_equals(undefined_arg, undefined, 'Promise should resolve with no arguments.');
}).catch(function(error) { }).catch(function(error) {
assert_unreached('unexpected rejection: ' + error); assert_unreached('unexpected rejection: ' + error);
...@@ -18,7 +15,7 @@ ...@@ -18,7 +15,7 @@
promise_test(function() { promise_test(function() {
return paintWorklet.import('resources/throwing-worklet-script.js').then(function(undefined_arg) { return worklet.import('resources/throwing-worklet-script.js').then(function(undefined_arg) {
assert_equals(undefined_arg, undefined, 'Promise should resolve with no arguments.'); assert_equals(undefined_arg, undefined, 'Promise should resolve with no arguments.');
}).catch(function(error) { }).catch(function(error) {
assert_unreached('unexpected rejection: ' + error); assert_unreached('unexpected rejection: ' + error);
...@@ -28,7 +25,7 @@ ...@@ -28,7 +25,7 @@
promise_test(function() { promise_test(function() {
return paintWorklet.import('non-existant-worklet-script.js').then(function() { return worklet.import('non-existant-worklet-script.js').then(function() {
assert_unreached('import should fail.'); assert_unreached('import should fail.');
}).catch(function(error) { }).catch(function(error) {
assert_equals(error.name, 'NetworkError', 'error should be a NetworkError.'); assert_equals(error.name, 'NetworkError', 'error should be a NetworkError.');
...@@ -38,14 +35,11 @@ ...@@ -38,14 +35,11 @@
promise_test(function() { promise_test(function() {
return paintWorklet.import('http://invalid:123$').then(function() { return worklet.import('http://invalid:123$').then(function() {
assert_unreached('import should fail.'); assert_unreached('import should fail.');
}).catch(function(error) { }).catch(function(error) {
assert_equals(error.name, 'SyntaxError', 'error should be a SyntaxError.'); assert_equals(error.name, 'SyntaxError', 'error should be a SyntaxError.');
}); });
}, 'Attempting to resolve an invalid URL should reject the given promise with a SyntaxError.'); }, 'Attempting to resolve an invalid URL should reject the given promise with a SyntaxError.');
}
</script>
</body>
</html>
...@@ -38,6 +38,10 @@ blink_core_sources("workers") { ...@@ -38,6 +38,10 @@ blink_core_sources("workers") {
"ThreadedWorkletGlobalScope.cpp", "ThreadedWorkletGlobalScope.cpp",
"ThreadedWorkletGlobalScope.h", "ThreadedWorkletGlobalScope.h",
"ThreadedWorkletGlobalScopeProxy.h", "ThreadedWorkletGlobalScopeProxy.h",
"ThreadedWorkletMessagingProxy.cpp",
"ThreadedWorkletMessagingProxy.h",
"ThreadedWorkletObjectProxy.cpp",
"ThreadedWorkletObjectProxy.h",
"Worker.cpp", "Worker.cpp",
"Worker.h", "Worker.h",
"WorkerBackingThread.cpp", "WorkerBackingThread.cpp",
......
...@@ -7,19 +7,15 @@ ...@@ -7,19 +7,15 @@
#include "core/workers/WorkletGlobalScopeProxy.h" #include "core/workers/WorkletGlobalScopeProxy.h"
// TODO(ikilpatrick): remove this file once AudioWorklet is no longer using it.
namespace blink { namespace blink {
class ThreadedWorkletGlobalScopeProxy : public WorkletGlobalScopeProxy { class ThreadedWorkletGlobalScopeProxy : public WorkletGlobalScopeProxy {
public: public:
void evaluateScript(const ScriptSourceCode&) final void evaluateScript(const ScriptSourceCode&) final {}
{
// TODO(ikilpatrick): implement. void terminateWorkletGlobalScope() final {}
}
void terminateWorkletGlobalScope() final
{
// TODO(ikilpatrick): implement.
}
}; };
} // namespace blink } // namespace blink
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/workers/ThreadedWorkletMessagingProxy.h"
#include "bindings/core/v8/ScriptSourceCode.h"
#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/dom/SecurityContext.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/origin_trials/OriginTrialContext.h"
#include "core/workers/ThreadedWorkletObjectProxy.h"
#include "core/workers/WorkerInspectorProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
#include "core/workers/WorkletGlobalScope.h"
#include "public/platform/WebTaskRunner.h"
namespace blink {
namespace {
void evaluateScriptOnWorkletGlobalScope(const String& source, const KURL& scriptURL, ExecutionContext* executionContext)
{
WorkletGlobalScope* globalScope = toWorkletGlobalScope(executionContext);
globalScope->scriptController()->evaluate(ScriptSourceCode(source, scriptURL));
}
} // namespace
ThreadedWorkletMessagingProxy::ThreadedWorkletMessagingProxy(ExecutionContext* executionContext)
: ThreadedMessagingProxyBase(executionContext)
, m_workletObjectProxy(ThreadedWorkletObjectProxy::create(this))
{
}
void ThreadedWorkletMessagingProxy::initialize()
{
DCHECK(isParentContextThread());
if (askedToTerminate())
return;
Document* document = toDocument(getExecutionContext());
SecurityOrigin* starterOrigin = document->getSecurityOrigin();
KURL scriptURL = document->url();
ContentSecurityPolicy* csp = document->contentSecurityPolicy();
DCHECK(csp);
WorkerThreadStartMode startMode = workerInspectorProxy()->workerStartMode(document);
std::unique_ptr<WorkerSettings> workerSettings = wrapUnique(new WorkerSettings(document->settings()));
// TODO(ikilpatrick): Decide on sensible a value for referrerPolicy.
std::unique_ptr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(scriptURL, document->userAgent(), String(), nullptr, startMode, csp->headers().get(), /* referrerPolicy */ String(), starterOrigin, nullptr, document->addressSpace(), OriginTrialContext::getTokens(document).get(), std::move(workerSettings));
initializeWorkerThread(std::move(startupData));
workerInspectorProxy()->workerThreadCreated(document, workerThread(), scriptURL);
}
void ThreadedWorkletMessagingProxy::evaluateScript(const ScriptSourceCode& scriptSourceCode)
{
postTaskToWorkerGlobalScope(BLINK_FROM_HERE, createCrossThreadTask(&evaluateScriptOnWorkletGlobalScope, scriptSourceCode.source(), scriptSourceCode.url()));
}
void ThreadedWorkletMessagingProxy::terminateWorkletGlobalScope()
{
terminateGlobalScope();
}
} // namespace blink
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ThreadedWorkletMessagingProxy_h
#define ThreadedWorkletMessagingProxy_h
#include "core/CoreExport.h"
#include "core/workers/ThreadedMessagingProxyBase.h"
#include "core/workers/WorkletGlobalScopeProxy.h"
namespace blink {
class ThreadedWorkletObjectProxy;
class CORE_EXPORT ThreadedWorkletMessagingProxy
: public ThreadedMessagingProxyBase
, public WorkletGlobalScopeProxy {
public:
// WorkletGlobalScopeProxy implementation.
void evaluateScript(const ScriptSourceCode&) final;
void terminateWorkletGlobalScope() final;
void initialize();
protected:
explicit ThreadedWorkletMessagingProxy(ExecutionContext*);
ThreadedWorkletObjectProxy& workletObjectProxy() { return *m_workletObjectProxy; }
private:
std::unique_ptr<ThreadedWorkletObjectProxy> m_workletObjectProxy;
};
} // namespace blink
#endif // ThreadedWorkletMessagingProxy_h
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/workers/ThreadedWorkletObjectProxy.h"
#include "bindings/core/v8/SerializedScriptValue.h"
#include "bindings/core/v8/SourceLocation.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/inspector/ConsoleMessage.h"
#include "core/workers/ThreadedWorkletMessagingProxy.h"
#include "wtf/Functional.h"
#include "wtf/PtrUtil.h"
#include <memory>
namespace blink {
std::unique_ptr<ThreadedWorkletObjectProxy> ThreadedWorkletObjectProxy::create(ThreadedWorkletMessagingProxy* messagingProxy)
{
DCHECK(messagingProxy);
return wrapUnique(new ThreadedWorkletObjectProxy(messagingProxy));
}
void ThreadedWorkletObjectProxy::postTaskToMainExecutionContext(std::unique_ptr<ExecutionContextTask> task)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, std::move(task));
}
void ThreadedWorkletObjectProxy::reportConsoleMessage(MessageSource source, MessageLevel level, const String& message, SourceLocation* location)
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&::blink::ThreadedWorkletMessagingProxy::reportConsoleMessage, crossThreadUnretained(m_messagingProxy), source, level, message, passed(location->clone())));
}
void ThreadedWorkletObjectProxy::postMessageToPageInspector(const String& message)
{
DCHECK(getExecutionContext()->isDocument());
toDocument(getExecutionContext())->postInspectorTask(BLINK_FROM_HERE, createCrossThreadTask(&::blink::ThreadedWorkletMessagingProxy::postMessageToPageInspector, crossThreadUnretained(m_messagingProxy), message));
}
void ThreadedWorkletObjectProxy::didCloseWorkerGlobalScope()
{
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&::blink::ThreadedWorkletMessagingProxy::terminateGlobalScope, crossThreadUnretained(m_messagingProxy)));
}
void ThreadedWorkletObjectProxy::didTerminateWorkerThread()
{
// This will terminate the MessagingProxy.
getExecutionContext()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadedWorkletMessagingProxy::workerThreadTerminated, crossThreadUnretained(m_messagingProxy)));
}
ThreadedWorkletObjectProxy::ThreadedWorkletObjectProxy(ThreadedWorkletMessagingProxy* messagingProxy)
: m_messagingProxy(messagingProxy)
{
}
ExecutionContext* ThreadedWorkletObjectProxy::getExecutionContext() const
{
DCHECK(m_messagingProxy);
return m_messagingProxy->getExecutionContext();
}
} // namespace blink
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ThreadedWorkletObjectProxy_h
#define ThreadedWorkletObjectProxy_h
#include "bindings/core/v8/SourceLocation.h"
#include "core/CoreExport.h"
#include "core/dom/MessagePort.h"
#include "core/workers/WorkerReportingProxy.h"
namespace blink {
class ConsoleMessage;
class ExecutionContext;
class ExecutionContextTask;
class ThreadedWorkletMessagingProxy;
// A proxy to talk to the parent worklet object. This object is created on the
// main thread, passed on to the worklet thread, and used just to proxy
// messages to the ThreadedWorkletMessagingProxy on the main thread.
class CORE_EXPORT ThreadedWorkletObjectProxy : public WorkerReportingProxy {
USING_FAST_MALLOC(ThreadedWorkletObjectProxy);
WTF_MAKE_NONCOPYABLE(ThreadedWorkletObjectProxy);
public:
static std::unique_ptr<ThreadedWorkletObjectProxy> create(ThreadedWorkletMessagingProxy*);
~ThreadedWorkletObjectProxy() override {}
void postTaskToMainExecutionContext(std::unique_ptr<ExecutionContextTask>);
void reportPendingActivity(bool hasPendingActivity);
// WorkerReportingProxy overrides.
void reportException(const String& errorMessage, std::unique_ptr<SourceLocation>, int exceptionId) override {}
void reportConsoleMessage(MessageSource, MessageLevel, const String& message, SourceLocation*) override;
void postMessageToPageInspector(const String&) override;
void didEvaluateWorkerScript(bool success) override {}
void didCloseWorkerGlobalScope() override;
void willDestroyWorkerGlobalScope() override {}
void didTerminateWorkerThread() override;
protected:
ThreadedWorkletObjectProxy(ThreadedWorkletMessagingProxy*);
private:
ExecutionContext* getExecutionContext() const;
// This object always outlives this proxy.
ThreadedWorkletMessagingProxy* m_messagingProxy;
};
} // namespace blink
#endif // ThreadedWorkletObjectProxy_h
...@@ -5,14 +5,17 @@ ...@@ -5,14 +5,17 @@
#include "modules/compositorworker/AnimationWorklet.h" #include "modules/compositorworker/AnimationWorklet.h"
#include "bindings/core/v8/V8Binding.h" #include "bindings/core/v8/V8Binding.h"
#include "core/dom/Document.h"
#include "core/frame/LocalFrame.h" #include "core/frame/LocalFrame.h"
#include "core/workers/ThreadedWorkletGlobalScopeProxy.h" #include "modules/compositorworker/AnimationWorkletMessagingProxy.h"
#include "modules/compositorworker/AnimationWorkletThread.h"
namespace blink { namespace blink {
// static // static
AnimationWorklet* AnimationWorklet::create(LocalFrame* frame) AnimationWorklet* AnimationWorklet::create(LocalFrame* frame)
{ {
AnimationWorkletThread::ensureSharedBackingThread();
AnimationWorklet* worklet = new AnimationWorklet(frame); AnimationWorklet* worklet = new AnimationWorklet(frame);
worklet->suspendIfNeeded(); worklet->suspendIfNeeded();
return worklet; return worklet;
...@@ -20,17 +23,19 @@ AnimationWorklet* AnimationWorklet::create(LocalFrame* frame) ...@@ -20,17 +23,19 @@ AnimationWorklet* AnimationWorklet::create(LocalFrame* frame)
AnimationWorklet::AnimationWorklet(LocalFrame* frame) AnimationWorklet::AnimationWorklet(LocalFrame* frame)
: Worklet(frame) : Worklet(frame)
, m_workletGlobalScopeProxy(new ThreadedWorkletGlobalScopeProxy()) , m_workletMessagingProxy(new AnimationWorkletMessagingProxy(frame->document()))
{ {
m_workletMessagingProxy->initialize();
} }
AnimationWorklet::~AnimationWorklet() AnimationWorklet::~AnimationWorklet()
{ {
m_workletMessagingProxy->parentObjectDestroyed();
} }
WorkletGlobalScopeProxy* AnimationWorklet::workletGlobalScopeProxy() const WorkletGlobalScopeProxy* AnimationWorklet::workletGlobalScopeProxy() const
{ {
return m_workletGlobalScopeProxy.get(); return m_workletMessagingProxy;
} }
DEFINE_TRACE(AnimationWorklet) DEFINE_TRACE(AnimationWorklet)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
namespace blink { namespace blink {
class LocalFrame; class LocalFrame;
class ThreadedWorkletGlobalScopeProxy; class ThreadedWorkletMessagingProxy;
class WorkletGlobalScopeProxy; class WorkletGlobalScopeProxy;
class MODULES_EXPORT AnimationWorklet final : public Worklet { class MODULES_EXPORT AnimationWorklet final : public Worklet {
...@@ -28,8 +28,9 @@ public: ...@@ -28,8 +28,9 @@ public:
private: private:
explicit AnimationWorklet(LocalFrame*); explicit AnimationWorklet(LocalFrame*);
// TODO(ikilpatrick): this will change to a raw ptr once we have a thread. // The proxy outlives the worklet as it is used to perform thread shutdown,
std::unique_ptr<ThreadedWorkletGlobalScopeProxy> m_workletGlobalScopeProxy; // it deletes itself once this has occured.
ThreadedWorkletMessagingProxy* const m_workletMessagingProxy;
}; };
} // namespace blink } // namespace blink
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "modules/compositorworker/AnimationWorkletMessagingProxy.h"
#include "core/workers/ThreadedWorkletObjectProxy.h"
#include "modules/compositorworker/AnimationWorkletThread.h"
namespace blink {
AnimationWorkletMessagingProxy::AnimationWorkletMessagingProxy(ExecutionContext* executionContext)
: ThreadedWorkletMessagingProxy(executionContext)
{
}
AnimationWorkletMessagingProxy::~AnimationWorkletMessagingProxy()
{
}
std::unique_ptr<WorkerThread> AnimationWorkletMessagingProxy::createWorkerThread(double originTime)
{
return AnimationWorkletThread::create(loaderProxy(), workletObjectProxy());
}
} // namespace blink
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef AnimationWorkletMessagingProxy_h
#define AnimationWorkletMessagingProxy_h
#include "core/workers/ThreadedWorkletMessagingProxy.h"
#include "wtf/Allocator.h"
#include <memory>
namespace blink {
class ExecutionContext;
class WorkerThread;
class AnimationWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy {
USING_FAST_MALLOC(AnimationWorkletMessagingProxy);
public:
explicit AnimationWorkletMessagingProxy(ExecutionContext*);
protected:
~AnimationWorkletMessagingProxy() override;
std::unique_ptr<WorkerThread> createWorkerThread(double originTime) override;
};
} // namespace blink
#endif // AnimationWorkletMessagingProxy_h
...@@ -12,6 +12,8 @@ blink_modules_sources("compositorworker") { ...@@ -12,6 +12,8 @@ blink_modules_sources("compositorworker") {
"AnimationWorklet.h", "AnimationWorklet.h",
"AnimationWorkletGlobalScope.cpp", "AnimationWorkletGlobalScope.cpp",
"AnimationWorkletGlobalScope.h", "AnimationWorkletGlobalScope.h",
"AnimationWorkletMessagingProxy.cpp",
"AnimationWorkletMessagingProxy.h",
"AnimationWorkletThread.cpp", "AnimationWorkletThread.cpp",
"AnimationWorkletThread.h", "AnimationWorkletThread.h",
"CompositorWorker.cpp", "CompositorWorker.cpp",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment