| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/AbstractAnimationWorkletThread.h" | 5 #include "modules/compositorworker/AbstractAnimationWorkletThread.h" |
| 6 | 6 |
| 7 #include "core/workers/WorkerBackingThread.h" | 7 #include "core/workers/WorkerBackingThread.h" |
| 8 #include "core/workers/WorkletBackingThreadHolder.h" |
| 8 #include "platform/CrossThreadFunctional.h" | 9 #include "platform/CrossThreadFunctional.h" |
| 9 #include "platform/WaitableEvent.h" | |
| 10 #include "platform/WebThreadSupportingGC.h" | 10 #include "platform/WebThreadSupportingGC.h" |
| 11 #include "public/platform/Platform.h" | 11 #include "public/platform/Platform.h" |
| 12 #include "wtf/Assertions.h" | 12 #include "wtf/Assertions.h" |
| 13 #include "wtf/PtrUtil.h" | 13 #include "wtf/PtrUtil.h" |
| 14 #include <memory> | 14 #include <memory> |
| 15 | 15 |
| 16 namespace blink { | 16 namespace blink { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 // This is a singleton class holding the animation worklet thread in this | 20 // This is a singleton class holding the animation worklet thread in this |
| 21 // renderer process. BackingThreadHolder::m_thread is cleared by | 21 // renderer process. WorkletBackingThreadHolder::m_thread is cleared by |
| 22 // ModulesInitializer::shutdown. | 22 // ModulesInitializer::shutdown. |
| 23 // |
| 23 // See WorkerThread::terminateAndWaitForAllWorkers for the process shutdown | 24 // See WorkerThread::terminateAndWaitForAllWorkers for the process shutdown |
| 24 // case. | 25 // case. |
| 25 class BackingThreadHolder { | 26 // |
| 27 // TODO(hongchan): consider refactoring static methods in this class into |
| 28 // a template class. |
| 29 class AnimationWorkletBackingThreadHolder final |
| 30 : public WorkletBackingThreadHolder { |
| 26 public: | 31 public: |
| 27 static BackingThreadHolder* instance() { | 32 static AnimationWorkletBackingThreadHolder* instance() { |
| 28 MutexLocker locker(holderInstanceMutex()); | 33 MutexLocker locker(holderInstanceMutex()); |
| 29 return s_instance; | 34 return s_instance; |
| 30 } | 35 } |
| 31 | 36 |
| 32 static void ensureInstance() { | 37 static void ensureInstance() { |
| 33 if (!s_instance) | 38 if (!s_instance) |
| 34 s_instance = new BackingThreadHolder; | 39 s_instance = new AnimationWorkletBackingThreadHolder; |
| 35 } | 40 } |
| 36 | 41 |
| 37 static void clear() { | 42 static void clear() { |
| 38 MutexLocker locker(holderInstanceMutex()); | 43 MutexLocker locker(holderInstanceMutex()); |
| 39 if (s_instance) { | 44 if (s_instance) { |
| 40 s_instance->shutdownAndWait(); | 45 s_instance->shutdownAndWait(); |
| 41 delete s_instance; | 46 delete s_instance; |
| 42 s_instance = nullptr; | 47 s_instance = nullptr; |
| 43 } | 48 } |
| 44 } | 49 } |
| 45 | 50 |
| 46 static void createForTest() { | 51 static void createForTest() { |
| 47 MutexLocker locker(holderInstanceMutex()); | 52 MutexLocker locker(holderInstanceMutex()); |
| 48 DCHECK_EQ(nullptr, s_instance); | 53 DCHECK_EQ(nullptr, s_instance); |
| 49 s_instance = new BackingThreadHolder(WorkerBackingThread::createForTest( | 54 s_instance = new AnimationWorkletBackingThreadHolder( |
| 50 Platform::current()->compositorThread())); | 55 WorkerBackingThread::createForTest( |
| 56 Platform::current()->compositorThread())); |
| 51 } | 57 } |
| 52 | 58 |
| 53 WorkerBackingThread* thread() { return m_thread.get(); } | |
| 54 | |
| 55 private: | 59 private: |
| 56 BackingThreadHolder( | 60 AnimationWorkletBackingThreadHolder( |
| 57 std::unique_ptr<WorkerBackingThread> useBackingThread = nullptr) | 61 std::unique_ptr<WorkerBackingThread> backingThread = nullptr) |
| 58 : m_thread(useBackingThread | 62 : WorkletBackingThreadHolder( |
| 59 ? std::move(useBackingThread) | 63 backingThread ? std::move(backingThread) |
| 60 : WorkerBackingThread::create( | 64 : WorkerBackingThread::create( |
| 61 Platform::current()->compositorThread())) { | 65 Platform::current()->compositorThread())) {} |
| 62 DCHECK(isMainThread()); | |
| 63 m_thread->backingThread().postTask( | |
| 64 BLINK_FROM_HERE, | |
| 65 crossThreadBind(&BackingThreadHolder::initializeOnThread, | |
| 66 crossThreadUnretained(this))); | |
| 67 } | |
| 68 | 66 |
| 69 static Mutex& holderInstanceMutex() { | 67 static Mutex& holderInstanceMutex() { |
| 70 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, holderMutex, new Mutex); | 68 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, holderMutex, new Mutex); |
| 71 return holderMutex; | 69 return holderMutex; |
| 72 } | 70 } |
| 73 | 71 |
| 74 void initializeOnThread() { | 72 void initializeOnThread() final { |
| 75 MutexLocker locker(holderInstanceMutex()); | 73 MutexLocker locker(holderInstanceMutex()); |
| 76 DCHECK(!m_initialized); | 74 DCHECK(!m_initialized); |
| 77 m_thread->initialize(); | 75 m_thread->initialize(); |
| 78 m_initialized = true; | 76 m_initialized = true; |
| 79 } | 77 } |
| 80 | 78 |
| 81 void shutdownAndWait() { | 79 static AnimationWorkletBackingThreadHolder* s_instance; |
| 82 DCHECK(isMainThread()); | |
| 83 WaitableEvent doneEvent; | |
| 84 m_thread->backingThread().postTask( | |
| 85 BLINK_FROM_HERE, crossThreadBind(&BackingThreadHolder::shutdownOnThread, | |
| 86 crossThreadUnretained(this), | |
| 87 crossThreadUnretained(&doneEvent))); | |
| 88 doneEvent.wait(); | |
| 89 } | |
| 90 | |
| 91 void shutdownOnThread(WaitableEvent* doneEvent) { | |
| 92 m_thread->shutdown(); | |
| 93 doneEvent->signal(); | |
| 94 } | |
| 95 | |
| 96 std::unique_ptr<WorkerBackingThread> m_thread; | |
| 97 bool m_initialized = false; | |
| 98 | |
| 99 static BackingThreadHolder* s_instance; | |
| 100 }; | 80 }; |
| 101 | 81 |
| 102 BackingThreadHolder* BackingThreadHolder::s_instance = nullptr; | 82 AnimationWorkletBackingThreadHolder* |
| 83 AnimationWorkletBackingThreadHolder::s_instance = nullptr; |
| 103 | 84 |
| 104 } // namespace | 85 } // namespace |
| 105 | 86 |
| 106 AbstractAnimationWorkletThread::AbstractAnimationWorkletThread( | 87 AbstractAnimationWorkletThread::AbstractAnimationWorkletThread( |
| 107 PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, | 88 PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, |
| 108 WorkerReportingProxy& workerReportingProxy) | 89 WorkerReportingProxy& workerReportingProxy) |
| 109 : WorkerThread(std::move(workerLoaderProxy), workerReportingProxy) {} | 90 : WorkerThread(std::move(workerLoaderProxy), workerReportingProxy) {} |
| 110 | 91 |
| 111 AbstractAnimationWorkletThread::~AbstractAnimationWorkletThread() {} | 92 AbstractAnimationWorkletThread::~AbstractAnimationWorkletThread() {} |
| 112 | 93 |
| 113 WorkerBackingThread& AbstractAnimationWorkletThread::workerBackingThread() { | 94 WorkerBackingThread& AbstractAnimationWorkletThread::workerBackingThread() { |
| 114 return *BackingThreadHolder::instance()->thread(); | 95 return *AnimationWorkletBackingThreadHolder::instance()->thread(); |
| 115 } | 96 } |
| 116 | 97 |
| 117 void collectAllGarbageOnThread(WaitableEvent* doneEvent) { | 98 void collectAllGarbageOnThread(WaitableEvent* doneEvent) { |
| 118 blink::ThreadState::current()->collectAllGarbage(); | 99 blink::ThreadState::current()->collectAllGarbage(); |
| 119 doneEvent->signal(); | 100 doneEvent->signal(); |
| 120 } | 101 } |
| 121 | 102 |
| 122 void AbstractAnimationWorkletThread::collectAllGarbage() { | 103 void AbstractAnimationWorkletThread::collectAllGarbage() { |
| 123 DCHECK(isMainThread()); | 104 DCHECK(isMainThread()); |
| 124 WaitableEvent doneEvent; | 105 WaitableEvent doneEvent; |
| 125 BackingThreadHolder* instance = BackingThreadHolder::instance(); | 106 AnimationWorkletBackingThreadHolder* instance = |
| 107 AnimationWorkletBackingThreadHolder::instance(); |
| 126 if (!instance) | 108 if (!instance) |
| 127 return; | 109 return; |
| 128 instance->thread()->backingThread().postTask( | 110 instance->thread()->backingThread().postTask( |
| 129 BLINK_FROM_HERE, crossThreadBind(&collectAllGarbageOnThread, | 111 BLINK_FROM_HERE, crossThreadBind(&collectAllGarbageOnThread, |
| 130 crossThreadUnretained(&doneEvent))); | 112 crossThreadUnretained(&doneEvent))); |
| 131 doneEvent.wait(); | 113 doneEvent.wait(); |
| 132 } | 114 } |
| 133 | 115 |
| 134 void AbstractAnimationWorkletThread::ensureSharedBackingThread() { | 116 void AbstractAnimationWorkletThread::ensureSharedBackingThread() { |
| 135 DCHECK(isMainThread()); | 117 DCHECK(isMainThread()); |
| 136 BackingThreadHolder::ensureInstance(); | 118 AnimationWorkletBackingThreadHolder::ensureInstance(); |
| 137 } | 119 } |
| 138 | 120 |
| 139 void AbstractAnimationWorkletThread::clearSharedBackingThread() { | 121 void AbstractAnimationWorkletThread::clearSharedBackingThread() { |
| 140 DCHECK(isMainThread()); | 122 DCHECK(isMainThread()); |
| 141 BackingThreadHolder::clear(); | 123 AnimationWorkletBackingThreadHolder::clear(); |
| 142 } | 124 } |
| 143 | 125 |
| 144 void AbstractAnimationWorkletThread::createSharedBackingThreadForTest() { | 126 void AbstractAnimationWorkletThread::createSharedBackingThreadForTest() { |
| 145 BackingThreadHolder::createForTest(); | 127 AnimationWorkletBackingThreadHolder::createForTest(); |
| 146 } | 128 } |
| 147 | 129 |
| 148 } // namespace blink | 130 } // namespace blink |
| OLD | NEW |