| // 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ANIMATION_WORKLET_MUTATOR_DISPATCHER_IMPL_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ANIMATION_WORKLET_MUTATOR_DISPATCHER_IMPL_H_ |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/time/tick_clock.h" |
| #include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator.h" |
| #include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher.h" |
| #include "third_party/blink/renderer/platform/graphics/mutator_client.h" |
| #include "third_party/blink/renderer/platform/heap/handle.h" |
| #include "third_party/blink/renderer/platform/heap/persistent.h" |
| #include "third_party/blink/renderer/platform/heap/visitor.h" |
| #include "third_party/blink/renderer/platform/wtf/functional.h" |
| #include "third_party/blink/renderer/platform/wtf/hash_set.h" |
| #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" |
| |
| namespace blink { |
| |
| class CompositorMutatorClient; |
| class MainThreadMutatorClient; |
| |
| // Fans out requests to all of the registered AnimationWorkletMutators which can |
| // then run worklet animations to produce mutation updates. Requests for |
| // animation frames are received from AnimationWorkletMutators and generate a |
| // new frame. |
| class PLATFORM_EXPORT AnimationWorkletMutatorDispatcherImpl final |
| : public AnimationWorkletMutatorDispatcher { |
| public: |
| // There are two outputs for the two interface surfaces of the created |
| // class blob. The returned owning pointer to the Client, which |
| // also owns the rest of the structure. |mutatee| form a |
| // pair for referencing the AnimationWorkletMutatorDispatcherImpl. i.e. Put |
| // tasks on the TaskRunner using the WeakPtr to get to the methods. |
| static std::unique_ptr<CompositorMutatorClient> CreateCompositorThreadClient( |
| base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>& mutatee, |
| scoped_refptr<base::SingleThreadTaskRunner> mutatee_runner); |
| static std::unique_ptr<MainThreadMutatorClient> CreateMainThreadClient( |
| base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>& mutatee, |
| scoped_refptr<base::SingleThreadTaskRunner> mutatee_runner); |
| |
| explicit AnimationWorkletMutatorDispatcherImpl( |
| scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| ~AnimationWorkletMutatorDispatcherImpl() override; |
| |
| // AnimationWorkletMutatorDispatcher implementation. |
| void MutateSynchronously( |
| std::unique_ptr<AnimationWorkletDispatcherInput>) override; |
| |
| bool MutateAsynchronously(std::unique_ptr<AnimationWorkletDispatcherInput>, |
| MutateQueuingStrategy, |
| AsyncMutationCompleteCallback) override; |
| |
| // TODO(majidvp): Remove when timeline inputs are known. |
| bool HasMutators() override; |
| |
| // Interface for use by the AnimationWorklet Thread(s) to request calls. |
| // (To the given Mutator on the given TaskRunner.) |
| void RegisterAnimationWorkletMutator( |
| CrossThreadPersistent<AnimationWorkletMutator>, |
| scoped_refptr<base::SingleThreadTaskRunner> mutator_runner); |
| |
| void UnregisterAnimationWorkletMutator( |
| CrossThreadPersistent<AnimationWorkletMutator>); |
| |
| void SetClient(MutatorClient* client) { client_ = client; } |
| |
| void SynchronizeAnimatorName(const String& animator_name); |
| |
| MutatorClient* client() { return client_; } |
| |
| base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> GetWeakPtr() { |
| return weak_factory_.GetWeakPtr(); |
| } |
| |
| void SetClockForTesting(std::unique_ptr<base::TickClock> tick_clock) { |
| tick_clock_ = std::move(tick_clock); |
| } |
| |
| private: |
| class OutputVectorRef; |
| struct AsyncMutationRequest; |
| |
| using InputMap = HashMap<int, std::unique_ptr<AnimationWorkletInput>>; |
| |
| using AnimationWorkletMutatorToTaskRunnerMap = |
| HashMap<CrossThreadPersistent<AnimationWorkletMutator>, |
| scoped_refptr<base::SingleThreadTaskRunner>>; |
| |
| InputMap CreateInputMap(AnimationWorkletDispatcherInput& mutator_input) const; |
| |
| // Dispatches mutation update requests. The callback is triggered once all |
| // mutation updates have been computed and it runs on the animation worklet |
| // thread associated with the last mutation to complete. |
| void RequestMutations(CrossThreadOnceClosure done_callback); |
| |
| // Dispatches mutation update requests. The request time includes time |
| // in the queue. In the event that a queued request is replaced, the |
| // replacement uses the original request time. |
| // |done_callback| is called on the impl thread on completion of the mutation |
| // cycle. |
| void MutateAsynchronouslyInternal( |
| base::TimeTicks request_time, |
| AsyncMutationCompleteCallback done_callback); |
| |
| // Called when the asynchronous mutation cycle is complete. The mutation id |
| // is used for asynchronous task monitoring and request time is used for |
| // collecting UMA stats of the total time between mutation request and |
| // completion. |
| void AsyncMutationsDone(int async_mutation_id, base::TimeTicks request_time); |
| |
| // Returns true if any updates were applied. |
| bool ApplyMutationsOnHostThread(); |
| |
| // Timing function used for UMA metrics. Uses a tick clock that may be |
| // overridden for testing purposes. |
| base::TimeTicks NowTicks() const; |
| |
| // The AnimationWorkletProxyClients are also owned by the WorkerClients |
| // dictionary. |
| AnimationWorkletMutatorToTaskRunnerMap mutator_map_; |
| |
| // |weak_interface| argument will be modified (initialized) by this function. |
| template <typename ClientType> |
| static std::unique_ptr<ClientType> CreateClient( |
| base::WeakPtr<AnimationWorkletMutatorDispatcherImpl>& weak_interface, |
| scoped_refptr<base::SingleThreadTaskRunner> queue); |
| |
| scoped_refptr<base::SingleThreadTaskRunner> host_queue_; |
| |
| // The MutatorClient owns (std::unique_ptr) us, so this pointer is |
| // valid as long as this class exists. |
| MutatorClient* client_; |
| |
| // Map of mutator scope IDs to mutator input. The Mutate methods safeguards |
| // against concurrent calls (important once async mutations are introduced) by |
| // checking that the map has been reset on entry. For this reason, it is |
| // important to reset the map at the end of the mutation cycle. |
| InputMap mutator_input_map_; |
| |
| // Reference to a vector for collecting mutation output. The vector is |
| // accessed across threads, thus it must be guaranteed to persist until the |
| // last mutation update is complete, and updates must be done in a thread-safe |
| // manner. The Mutate method guards against concurrent calls (important once |
| // async mutations are introduced) by checking that the output vector is |
| // empty. For this reason, it is important to clear the output at the end of |
| // the mutation cycle. |
| scoped_refptr<OutputVectorRef> outputs_; |
| |
| // Active callback for the completion of an async mutation cycle. |
| AsyncMutationCompleteCallback on_async_mutation_complete_; |
| |
| // Queues for pending mutation requests. Each queue can hold a single request. |
| // On completion of a mutation cycle, a fresh mutation cycle is started if |
| // either queue contains a request. The priority queue takes precedence if |
| // both queues contain a request. The request stored in the replaceable queue |
| // can be updated in a later async mutation call, whereas the priority queue |
| // entry cannot, as each priority request is required to run. |
| std::unique_ptr<AsyncMutationRequest> queued_priority_request; |
| std::unique_ptr<AsyncMutationRequest> queued_replaceable_request; |
| |
| std::unique_ptr<base::TickClock> tick_clock_; |
| |
| base::WeakPtrFactory<AnimationWorkletMutatorDispatcherImpl> weak_factory_{ |
| this}; |
| |
| DISALLOW_COPY_AND_ASSIGN(AnimationWorkletMutatorDispatcherImpl); |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ANIMATION_WORKLET_MUTATOR_DISPATCHER_IMPL_H_ |