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>
<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
</head>
<body>
<script>
// Runs a series of tests related to importing scripts on a worklet.
//
// Usage:
// runImportTests(workletType);
function runImportTests(worklet) {
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.');
}).catch(function(error) {
assert_unreached('unexpected rejection: ' + error);
......@@ -18,7 +15,7 @@
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.');
}).catch(function(error) {
assert_unreached('unexpected rejection: ' + error);
......@@ -28,7 +25,7 @@
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.');
}).catch(function(error) {
assert_equals(error.name, 'NetworkError', 'error should be a NetworkError.');
......@@ -38,14 +35,11 @@
promise_test(function() {
return paintWorklet.import('http://invalid:123$').then(function() {
return worklet.import('http://invalid:123$').then(function() {
assert_unreached('import should fail.');
}).catch(function(error) {
assert_equals(error.name, 'SyntaxError', 'error should be 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") {
"ThreadedWorkletGlobalScope.cpp",
"ThreadedWorkletGlobalScope.h",
"ThreadedWorkletGlobalScopeProxy.h",
"ThreadedWorkletMessagingProxy.cpp",
"ThreadedWorkletMessagingProxy.h",
"ThreadedWorkletObjectProxy.cpp",
"ThreadedWorkletObjectProxy.h",
"Worker.cpp",
"Worker.h",
"WorkerBackingThread.cpp",
......
......@@ -7,19 +7,15 @@
#include "core/workers/WorkletGlobalScopeProxy.h"
// TODO(ikilpatrick): remove this file once AudioWorklet is no longer using it.
namespace blink {
class ThreadedWorkletGlobalScopeProxy : public WorkletGlobalScopeProxy {
public:
void evaluateScript(const ScriptSourceCode&) final
{
// TODO(ikilpatrick): implement.
}
void terminateWorkletGlobalScope() final
{
// TODO(ikilpatrick): implement.
}
void evaluateScript(const ScriptSourceCode&) final {}
void terminateWorkletGlobalScope() final {}
};
} // 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 @@
#include "modules/compositorworker/AnimationWorklet.h"
#include "bindings/core/v8/V8Binding.h"
#include "core/dom/Document.h"
#include "core/frame/LocalFrame.h"
#include "core/workers/ThreadedWorkletGlobalScopeProxy.h"
#include "modules/compositorworker/AnimationWorkletMessagingProxy.h"
#include "modules/compositorworker/AnimationWorkletThread.h"
namespace blink {
// static
AnimationWorklet* AnimationWorklet::create(LocalFrame* frame)
{
AnimationWorkletThread::ensureSharedBackingThread();
AnimationWorklet* worklet = new AnimationWorklet(frame);
worklet->suspendIfNeeded();
return worklet;
......@@ -20,17 +23,19 @@ AnimationWorklet* AnimationWorklet::create(LocalFrame* frame)
AnimationWorklet::AnimationWorklet(LocalFrame* frame)
: Worklet(frame)
, m_workletGlobalScopeProxy(new ThreadedWorkletGlobalScopeProxy())
, m_workletMessagingProxy(new AnimationWorkletMessagingProxy(frame->document()))
{
m_workletMessagingProxy->initialize();
}
AnimationWorklet::~AnimationWorklet()
{
m_workletMessagingProxy->parentObjectDestroyed();
}
WorkletGlobalScopeProxy* AnimationWorklet::workletGlobalScopeProxy() const
{
return m_workletGlobalScopeProxy.get();
return m_workletMessagingProxy;
}
DEFINE_TRACE(AnimationWorklet)
......
......@@ -12,7 +12,7 @@
namespace blink {
class LocalFrame;
class ThreadedWorkletGlobalScopeProxy;
class ThreadedWorkletMessagingProxy;
class WorkletGlobalScopeProxy;
class MODULES_EXPORT AnimationWorklet final : public Worklet {
......@@ -28,8 +28,9 @@ public:
private:
explicit AnimationWorklet(LocalFrame*);
// TODO(ikilpatrick): this will change to a raw ptr once we have a thread.
std::unique_ptr<ThreadedWorkletGlobalScopeProxy> m_workletGlobalScopeProxy;
// The proxy outlives the worklet as it is used to perform thread shutdown,
// it deletes itself once this has occured.
ThreadedWorkletMessagingProxy* const m_workletMessagingProxy;
};
} // 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") {
"AnimationWorklet.h",
"AnimationWorkletGlobalScope.cpp",
"AnimationWorkletGlobalScope.h",
"AnimationWorkletMessagingProxy.cpp",
"AnimationWorkletMessagingProxy.h",
"AnimationWorkletThread.cpp",
"AnimationWorkletThread.h",
"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