blob: ff18628f88a1cfdcc13aef1fcbeabafd68dae2b1 [file] [log] [blame]
// 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 "web/CompositorMutatorImpl.h"
#include "core/animation/CustomCompositorAnimationManager.h"
#include "core/dom/CompositorProxy.h"
#include "platform/CrossThreadFunctional.h"
#include "platform/WaitableEvent.h"
#include "platform/graphics/CompositorMutationsTarget.h"
#include "platform/graphics/CompositorMutatorClient.h"
#include "platform/heap/Handle.h"
#include "platform/instrumentation/tracing/TraceEvent.h"
#include "platform/wtf/PtrUtil.h"
#include "public/platform/Platform.h"
#include "web/CompositorAnimator.h"
namespace blink {
namespace {
void CreateCompositorMutatorClient(
std::unique_ptr<CompositorMutatorClient>* ptr,
WaitableEvent* done_event) {
CompositorMutatorImpl* mutator = CompositorMutatorImpl::Create();
ptr->reset(new CompositorMutatorClient(mutator, mutator->AnimationManager()));
mutator->SetClient(ptr->get());
done_event->Signal();
}
} // namespace
CompositorMutatorImpl::CompositorMutatorImpl()
: animation_manager_(WTF::WrapUnique(new CustomCompositorAnimationManager)),
client_(nullptr) {}
std::unique_ptr<CompositorMutatorClient> CompositorMutatorImpl::CreateClient() {
std::unique_ptr<CompositorMutatorClient> mutator_client;
WaitableEvent done_event;
if (WebThread* compositor_thread = Platform::Current()->CompositorThread()) {
compositor_thread->GetWebTaskRunner()->PostTask(
BLINK_FROM_HERE, CrossThreadBind(&CreateCompositorMutatorClient,
CrossThreadUnretained(&mutator_client),
CrossThreadUnretained(&done_event)));
} else {
CreateCompositorMutatorClient(&mutator_client, &done_event);
}
// TODO(flackr): Instead of waiting for this event, we may be able to just set
// the mutator on the CompositorWorkerProxyClient directly from the compositor
// thread before it gets used there. We still need to make sure we only
// create one mutator though.
done_event.Wait();
return mutator_client;
}
CompositorMutatorImpl* CompositorMutatorImpl::Create() {
return new CompositorMutatorImpl();
}
bool CompositorMutatorImpl::Mutate(
double monotonic_time_now,
CompositorMutableStateProvider* state_provider) {
TRACE_EVENT0("compositor-worker", "CompositorMutatorImpl::mutate");
bool need_to_reinvoke = false;
// TODO(vollick): we should avoid executing the animation frame
// callbacks if none of the proxies in the global scope are affected by
// m_mutations.
for (CompositorAnimator* animator : animators_) {
if (animator->Mutate(monotonic_time_now, state_provider))
need_to_reinvoke = true;
}
return need_to_reinvoke;
}
void CompositorMutatorImpl::RegisterCompositorAnimator(
CompositorAnimator* animator) {
DCHECK(!IsMainThread());
TRACE_EVENT0("compositor-worker",
"CompositorMutatorImpl::registerCompositorAnimator");
DCHECK(!animators_.Contains(animator));
animators_.insert(animator);
SetNeedsMutate();
}
void CompositorMutatorImpl::UnregisterCompositorAnimator(
CompositorAnimator* animator) {
DCHECK(animators_.Contains(animator));
animators_.erase(animator);
}
void CompositorMutatorImpl::SetNeedsMutate() {
DCHECK(!IsMainThread());
TRACE_EVENT0("compositor-worker", "CompositorMutatorImpl::setNeedsMutate");
client_->SetNeedsMutate();
}
} // namespace blink