| Index: third_party/WebKit/Source/modules/worklet/CompositorWorkletThread.cpp
|
| diff --git a/third_party/WebKit/Source/modules/worklet/CompositorWorkletThread.cpp b/third_party/WebKit/Source/modules/worklet/CompositorWorkletThread.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8f07292431f18f7f3bcfb673150d9b02bcdc4b98
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/modules/worklet/CompositorWorkletThread.cpp
|
| @@ -0,0 +1,165 @@
|
| +// Copyright 2015 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 "config.h"
|
| +#include "modules/worklet/CompositorWorkletThread.h"
|
| +
|
| +#include "bindings/core/v8/GlobalScopeScriptController.h"
|
| +#include "bindings/core/v8/V8Binding.h"
|
| +#include "bindings/core/v8/V8GCController.h"
|
| +#include "bindings/core/v8/V8Initializer.h"
|
| +#include "bindings/core/v8/V8PerIsolateData.h"
|
| +#include "bindings/core/v8/V8RecursionScope.h"
|
| +#include "core/dom/Microtask.h"
|
| +#include "modules/worklet/WorkletGlobalScope.h"
|
| +#include "platform/Logging.h"
|
| +#include "platform/Task.h"
|
| +#include "platform/ThreadSafeFunctional.h"
|
| +#include "platform/WebThreadSupportingGC.h"
|
| +#include "public/platform/Platform.h"
|
| +#include "public/platform/WebThread.h"
|
| +
|
| +namespace blink {
|
| +
|
| +class WorkletMicrotaskRunner : public WebThread::TaskObserver {
|
| +public:
|
| + explicit WorkletMicrotaskRunner(CompositorWorkletThread* compositorWorkletThread)
|
| + : m_compositorWorkletThread(compositorWorkletThread)
|
| + {
|
| + }
|
| +
|
| + void willProcessTask() final {}
|
| +
|
| + void didProcessTask() final
|
| + {
|
| + Microtask::performCheckpoint(m_compositorWorkletThread->isolate());
|
| + }
|
| +
|
| +private:
|
| + // Thread owns the microtask runner; reference remains
|
| + // valid for the lifetime of this object.
|
| + CompositorWorkletThread* m_compositorWorkletThread;
|
| +};
|
| +
|
| +class CompositorWorkletSharedState {
|
| +public:
|
| + static CompositorWorkletSharedState& instance()
|
| + {
|
| + DEFINE_STATIC_LOCAL_THREAD_SAFE(CompositorWorkletSharedState, compositorWorkletSharedState, (new CompositorWorkletSharedState()));
|
| + return compositorWorkletSharedState;
|
| + }
|
| +
|
| + WebThreadSupportingGC* compositorWorkletThread()
|
| + {
|
| + MutexLocker lock(m_mutex);
|
| + if (!m_thread && isMainThread()) {
|
| + WebThread* platformThread = Platform::current()->compositorThread();
|
| + m_thread = WebThreadSupportingGC::createForThread(platformThread);
|
| + }
|
| + return m_thread.get();
|
| + }
|
| +
|
| + void initializeBackingThread()
|
| + {
|
| + MutexLocker lock(m_mutex);
|
| + ASSERT(m_thread->isCurrentThread());
|
| +
|
| + m_thread->initialize();
|
| +
|
| + // Initialize the isolate at the same time.
|
| + ASSERT(!m_isolate);
|
| + m_isolate = V8PerIsolateData::initialize();
|
| + V8Initializer::initializeWorker(m_isolate);
|
| +
|
| + OwnPtr<V8IsolateInterruptor> interruptor = adoptPtr(new V8IsolateInterruptor(m_isolate));
|
| + ThreadState::current()->addInterruptor(interruptor.release());
|
| + ThreadState::current()->registerTraceDOMWrappers(m_isolate, V8GCController::traceDOMWrappers);
|
| + }
|
| +
|
| + v8::Isolate* isolate()
|
| + {
|
| + MutexLocker lock(m_mutex);
|
| + ASSERT(m_thread->isCurrentThread());
|
| + ASSERT(m_isolate);
|
| + // It is safe to use the existing isolate even if TerminateExecution() has been
|
| + // called on it, without calling CancelTerminateExecution().
|
| + return m_isolate;
|
| + }
|
| +
|
| +private:
|
| + CompositorWorkletSharedState() {}
|
| + ~CompositorWorkletSharedState() {}
|
| +
|
| + Mutex m_mutex;
|
| + OwnPtr<WebThreadSupportingGC> m_thread;
|
| + v8::Isolate* m_isolate = nullptr;
|
| +};
|
| +
|
| +PassRefPtr<CompositorWorkletThread> CompositorWorkletThread::create()
|
| +{
|
| + ASSERT(isMainThread());
|
| + return adoptRef(new CompositorWorkletThread());
|
| +}
|
| +
|
| +CompositorWorkletThread::CompositorWorkletThread()
|
| +{
|
| +}
|
| +
|
| +CompositorWorkletThread::~CompositorWorkletThread()
|
| +{
|
| +}
|
| +
|
| +void CompositorWorkletThread::initialize()
|
| +{
|
| + ASSERT(isMainThread());
|
| +
|
| + if (m_initialized)
|
| + return;
|
| +
|
| + m_initialized = true;
|
| + backingThread().postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&CompositorWorkletThread::initializeInternal, AllowCrossThreadAccess(this))));
|
| +}
|
| +
|
| +void CompositorWorkletThread::initializeInternal()
|
| +{
|
| + ASSERT(backingThread().isCurrentThread());
|
| +
|
| + {
|
| + MutexLocker lock(m_threadStateMutex);
|
| +
|
| + m_microtaskRunner = adoptPtr(new WorkletMicrotaskRunner(this));
|
| + CompositorWorkletSharedState::instance().initializeBackingThread();
|
| + backingThread().addTaskObserver(m_microtaskRunner.get());
|
| +
|
| + m_isolate = CompositorWorkletSharedState::instance().isolate();
|
| + m_workletGlobalScope = WorkletGlobalScope::create(m_isolate);
|
| + }
|
| +}
|
| +
|
| +void CompositorWorkletThread::loadScript(const String& sourceCode)
|
| +{
|
| + ASSERT(isMainThread());
|
| + backingThread().postTask(BLINK_FROM_HERE, new Task(threadSafeBind(&CompositorWorkletThread::loadScriptInternal, AllowCrossThreadAccess(this), sourceCode.isolatedCopy())));
|
| +}
|
| +
|
| +void CompositorWorkletThread::loadScriptInternal(const String& sourceCode)
|
| +{
|
| + ASSERT(backingThread().isCurrentThread());
|
| +
|
| + ScriptState::Scope scope(m_workletGlobalScope->script()->scriptState());
|
| + V8RecursionScope recursionScope(m_workletGlobalScope->isolate());
|
| +
|
| + v8::Local<v8::String> source = v8::String::NewFromUtf8(m_workletGlobalScope->isolate(), sourceCode.ascii().data(), v8::NewStringType::kNormal).ToLocalChecked();
|
| + v8::Local<v8::Script> script = v8::Script::Compile(m_workletGlobalScope->script()->context(), source).ToLocalChecked();
|
| + v8::Local<v8::Value> result = script->Run(m_workletGlobalScope->script()->context()).ToLocalChecked();
|
| +
|
| + WTF_LOG(NotYetImplemented, "loadScriptInternal: %lf\n", v8::Number::Cast(*result)->Value());
|
| +}
|
| +
|
| +WebThreadSupportingGC& CompositorWorkletThread::backingThread()
|
| +{
|
| + return *CompositorWorkletSharedState::instance().compositorWorkletThread();
|
| +}
|
| +
|
| +} // namespace blink
|
|
|