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 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ANIMATION_WORKLET_MUTATOR_DISPATCHER_IMPL_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ANIMATION_WORKLET_MUTATOR_DISPATCHER_IMPL_H_ 7 8 #include <memory> 9 10 #include "base/macros.h" 11 #include "base/memory/weak_ptr.h" 12 #include "base/single_thread_task_runner.h" 13 #include "base/time/tick_clock.h" 14 #include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h" 15 #include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher.h" 16 #include "third_party/blink/renderer/platform/graphics/mutator_client.h" 17 #include "third_party/blink/renderer/platform/heap/handle.h" 18 #include "third_party/blink/renderer/platform/heap/persistent.h" 19 #include "third_party/blink/renderer/platform/heap/visitor.h" 20 #include "third_party/blink/renderer/platform/wtf/functional.h" 21 #include "third_party/blink/renderer/platform/wtf/hash_set.h" 22 #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" 23 24 namespace blink { 25 26 class CompositorMutatorClient; 27 class MainThreadMutatorClient; 28 29 // Fans out requests to all of the registered AnimationWorkletMutators which can 30 // then run worklet animations to produce mutation updates. Requests for 31 // animation frames are received from AnimationWorkletMutators and generate a 32 // new frame. 33 class PLATFORM_EXPORT AnimationWorkletMutatorDispatcherImpl final 34 : public AnimationWorkletMutatorDispatcher { 35 public: 36 // There are three outputs for the two interface surfaces of the created 37 // class blob. The returned owning pointer to the Client, which 38 // also owns the rest of the structure. |mutatee| and |mutatee_runner| form a 39 // pair for referencing the AnimationWorkletMutatorDispatcherImpl. i.e. Put 40 // tasks on the TaskRunner using the WeakPtr to get to the methods. 41 static std::unique_ptr<CompositorMutatorClient> CreateCompositorThreadClient( 42 base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>* mutatee, 43 scoped_refptr<base::SingleThreadTaskRunner>* mutatee_runner); 44 static std::unique_ptr<MainThreadMutatorClient> CreateMainThreadClient( 45 base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>* mutatee, 46 scoped_refptr<base::SingleThreadTaskRunner>* mutatee_runner); 47 48 explicit AnimationWorkletMutatorDispatcherImpl(bool main_thread_task_runner); 49 ~AnimationWorkletMutatorDispatcherImpl() override; 50 51 // AnimationWorkletMutatorDispatcher implementation. 52 void MutateSynchronously( 53 std::unique_ptr<AnimationWorkletDispatcherInput>) override; 54 55 bool MutateAsynchronously(std::unique_ptr<AnimationWorkletDispatcherInput>, 56 MutateQueuingStrategy, 57 AsyncMutationCompleteCallback) override; 58 59 // TODO(majidvp): Remove when timeline inputs are known. 60 bool HasMutators() override; 61 62 // Interface for use by the AnimationWorklet Thread(s) to request calls. 63 // (To the given Mutator on the given TaskRunner.) 64 void RegisterAnimationWorkletMutator( 65 CrossThreadPersistent<AnimationWorkletMutator>, 66 scoped_refptr<base::SingleThreadTaskRunner> mutator_runner); 67 68 void UnregisterAnimationWorkletMutator( 69 CrossThreadPersistent<AnimationWorkletMutator>); 70 SetClient(MutatorClient * client)71 void SetClient(MutatorClient* client) { client_ = client; } 72 73 void SynchronizeAnimatorName(const String& animator_name); 74 client()75 MutatorClient* client() { return client_; } 76 GetTaskRunner()77 scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() { 78 return host_queue_; 79 } 80 GetWeakPtr()81 base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> GetWeakPtr() { 82 return weak_factory_.GetWeakPtr(); 83 } 84 SetClockForTesting(std::unique_ptr<base::TickClock> tick_clock)85 void SetClockForTesting(std::unique_ptr<base::TickClock> tick_clock) { 86 tick_clock_.reset(tick_clock.release()); 87 } 88 89 private: 90 class OutputVectorRef; 91 struct AsyncMutationRequest; 92 93 using InputMap = HashMap<int, std::unique_ptr<AnimationWorkletInput>>; 94 95 using AnimationWorkletMutatorToTaskRunnerMap = 96 HashMap<CrossThreadPersistent<AnimationWorkletMutator>, 97 scoped_refptr<base::SingleThreadTaskRunner>>; 98 99 InputMap CreateInputMap(AnimationWorkletDispatcherInput& mutator_input) const; 100 101 // Dispatches mutation update requests. The callback is triggered once all 102 // mutation updates have been computed and it runs on the animation worklet 103 // thread associated with the last mutation to complete. 104 void RequestMutations(CrossThreadOnceClosure done_callback); 105 106 // Dispatches mutation update requests. The request time includes time 107 // in the queue. In the event that a queued request is replaced, the 108 // replacement uses the original request time. 109 // |done_callback| is called on the impl thread on completion of the mutation 110 // cycle. 111 void MutateAsynchronouslyInternal( 112 base::TimeTicks request_time, 113 AsyncMutationCompleteCallback done_callback); 114 115 // Called when the asynchronous mutation cycle is complete. The mutation id 116 // is used for asynchronous task monitoring and request time is used for 117 // collecting UMA stats of the total time between mutation request and 118 // completion. 119 void AsyncMutationsDone(int async_mutation_id, base::TimeTicks request_time); 120 121 // Returns true if any updates were applied. 122 bool ApplyMutationsOnHostThread(); 123 124 // Timing function used for UMA metrics. Uses a tick clock that may be 125 // overridden for testing purposes. 126 base::TimeTicks NowTicks() const; 127 128 // The AnimationWorkletProxyClients are also owned by the WorkerClients 129 // dictionary. 130 AnimationWorkletMutatorToTaskRunnerMap mutator_map_; 131 132 template <typename ClientType> 133 static std::unique_ptr<ClientType> CreateClient( 134 base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>* weak_interface, 135 scoped_refptr<base::SingleThreadTaskRunner>* queue, 136 bool create_main_thread_client); 137 138 scoped_refptr<base::SingleThreadTaskRunner> host_queue_; 139 140 // The MutatorClient owns (std::unique_ptr) us, so this pointer is 141 // valid as long as this class exists. 142 MutatorClient* client_; 143 144 // Map of mutator scope IDs to mutator input. The Mutate methods safeguards 145 // against concurrent calls (important once async mutations are introduced) by 146 // checking that the map has been reset on entry. For this reason, it is 147 // important to reset the map at the end of the mutation cycle. 148 InputMap mutator_input_map_; 149 150 // Reference to a vector for collecting mutation output. The vector is 151 // accessed across threads, thus it must be guaranteed to persist until the 152 // last mutation update is complete, and updates must be done in a thread-safe 153 // manner. The Mutate method guards against concurrent calls (important once 154 // async mutations are introduced) by checking that the output vector is 155 // empty. For this reason, it is important to clear the output at the end of 156 // the mutation cycle. 157 scoped_refptr<OutputVectorRef> outputs_; 158 159 // Active callback for the completion of an async mutation cycle. 160 AsyncMutationCompleteCallback on_async_mutation_complete_; 161 162 // Queues for pending mutation requests. Each queue can hold a single request. 163 // On completion of a mutation cycle, a fresh mutation cycle is started if 164 // either queue contains a request. The priority queue takes precedence if 165 // both queues contain a request. The request stored in the replaceable queue 166 // can be updated in a later async mutation call, whereas the priority queue 167 // entry cannot, as each priority request is required to run. 168 std::unique_ptr<AsyncMutationRequest> queued_priority_request; 169 std::unique_ptr<AsyncMutationRequest> queued_replaceable_request; 170 171 std::unique_ptr<base::TickClock> tick_clock_; 172 173 base::WeakPtrFactory<AnimationWorkletMutatorDispatcherImpl> weak_factory_{ 174 this}; 175 176 DISALLOW_COPY_AND_ASSIGN(AnimationWorkletMutatorDispatcherImpl); 177 }; 178 179 } // namespace blink 180 181 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ANIMATION_WORKLET_MUTATOR_DISPATCHER_IMPL_H_ 182