Commit 927da55e authored by Vladimir Levin's avatar Vladimir Levin Committed by Chromium LUCI CQ

cc: Add cc::DocumentTransitionRequest for requesting document transitions.

This patch adds an intermediate class to help with the document
transitions. The idea is that Blink would create this request, and
transfer it to the compositor on commit. When the compositor decides
to submit a frame to viz, it would then construct viz directives from
this request and send it over to viz.

This patch also adds an include and a type usage in Blink to ensure
presubmit is happy.

R=khushalsagar@chromium.org

Bug: 1150461
Change-Id: I8e2bcc18b8bd9f1de0d057a8bf608365ac5aa10b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2574600Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Commit-Queue: vmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#835340}
parent 0f5fc650
......@@ -33,6 +33,8 @@ cc_component("cc") {
"benchmarks/unittest_only_benchmark.h",
"benchmarks/unittest_only_benchmark_impl.cc",
"benchmarks/unittest_only_benchmark_impl.h",
"document_transition/document_transition_request.cc",
"document_transition/document_transition_request.h",
"input/actively_scrolling_type.h",
"input/browser_controls_offset_manager.cc",
"input/browser_controls_offset_manager.h",
......@@ -655,6 +657,7 @@ cc_test("cc_unittests") {
"base/unique_notifier_unittest.cc",
"benchmarks/micro_benchmark_controller_unittest.cc",
"debug/rendering_stats_unittest.cc",
"document_transition/document_transition_request_unittest.cc",
"input/browser_controls_offset_manager_unittest.cc",
"input/main_thread_scrolling_reason_unittest.cc",
"input/scroll_snap_data_unittest.cc",
......
# cc/document\_transition
The document transition direction supports the Document Transition and Shared
Element Transition projects in Blink. Please see
//third\_party/blink/renderer/core/document\_transition/README.md for more details.
// Copyright 2020 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 "cc/document_transition/document_transition_request.h"
#include <memory>
#include <utility>
#include "base/callback.h"
#include "base/memory/ptr_util.h"
#include "components/viz/common/quads/compositor_frame_transition_directive.h"
namespace cc {
uint32_t DocumentTransitionRequest::s_next_sequence_id_ = 1;
// static
std::unique_ptr<DocumentTransitionRequest>
DocumentTransitionRequest::CreatePrepare(Effect effect,
base::TimeDelta duration,
base::OnceClosure commit_callback) {
return base::WrapUnique(new DocumentTransitionRequest(
effect, duration, std::move(commit_callback)));
}
// static
std::unique_ptr<DocumentTransitionRequest>
DocumentTransitionRequest::CreateStart(base::OnceClosure commit_callback) {
return base::WrapUnique(
new DocumentTransitionRequest(std::move(commit_callback)));
}
DocumentTransitionRequest::DocumentTransitionRequest(
Effect effect,
base::TimeDelta duration,
base::OnceClosure commit_callback)
: type_(Type::kSave),
effect_(effect),
duration_(duration),
commit_callback_(std::move(commit_callback)) {}
DocumentTransitionRequest::DocumentTransitionRequest(
base::OnceClosure commit_callback)
: type_(Type::kAnimate), commit_callback_(std::move(commit_callback)) {}
DocumentTransitionRequest::~DocumentTransitionRequest() = default;
viz::CompositorFrameTransitionDirective
DocumentTransitionRequest::ConstructDirective() const {
// Note that the clamped_duration is also verified at
// CompositorFrameTransitionDirective deserialization time.
auto clamped_duration =
duration_ < viz::CompositorFrameTransitionDirective::kMaxDuration
? duration_
: viz::CompositorFrameTransitionDirective::kMaxDuration;
return viz::CompositorFrameTransitionDirective(s_next_sequence_id_++, type_,
effect_, clamped_duration);
}
} // namespace cc
// Copyright 2020 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 CC_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_REQUEST_H_
#define CC_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_REQUEST_H_
#include <memory>
#include <utility>
#include "base/callback.h"
#include "cc/cc_export.h"
#include "components/viz/common/quads/compositor_frame_transition_directive.h"
namespace cc {
// This class represents a document transition request. It is constructed in
// Blink with an intent of translating this request into a viz directive for the
// transition to occur.
class CC_EXPORT DocumentTransitionRequest {
public:
using Effect = viz::CompositorFrameTransitionDirective::Effect;
// Creates a Type::kPrepare type of request.
static std::unique_ptr<DocumentTransitionRequest> CreatePrepare(
Effect effect,
base::TimeDelta duration,
base::OnceClosure commit_callback);
// Creates a Type::kSave type of request.
static std::unique_ptr<DocumentTransitionRequest> CreateStart(
base::OnceClosure commit_callback);
DocumentTransitionRequest(DocumentTransitionRequest&) = delete;
~DocumentTransitionRequest();
DocumentTransitionRequest& operator=(DocumentTransitionRequest&) = delete;
// The callback is run when the request is committed from the main thread onto
// the compositor thread. This is used to indicate that the request has been
// submitted for processing and that script may now change the page in some
// way. In other words, this callback would resolve the prepare promise that
// script may be waiting for.
base::OnceClosure TakeCommitCallback() { return std::move(commit_callback_); }
// This constructs a viz directive. Note that repeated calls to this function
// would create a new sequence id for the directive, which means it would be
// processed again by viz.
viz::CompositorFrameTransitionDirective ConstructDirective() const;
private:
using Type = viz::CompositorFrameTransitionDirective::Type;
DocumentTransitionRequest(Effect effect,
base::TimeDelta duration,
base::OnceClosure commit_callback);
explicit DocumentTransitionRequest(base::OnceClosure commit_callback);
const Type type_;
const Effect effect_ = Effect::kNone;
const base::TimeDelta duration_;
base::OnceClosure commit_callback_;
static uint32_t s_next_sequence_id_;
};
} // namespace cc
#endif // CC_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_REQUEST_H_
// Copyright 2020 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 "cc/document_transition/document_transition_request.h"
#include <utility>
#include "base/test/bind.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
TEST(DocumentTransitionRequestTest, PrepareRequest) {
bool called = false;
auto callback = base::BindLambdaForTesting([&called]() { called = true; });
auto request = DocumentTransitionRequest::CreatePrepare(
DocumentTransitionRequest::Effect::kRevealLeft,
base::TimeDelta::FromMilliseconds(123), std::move(callback));
EXPECT_FALSE(called);
request->TakeCommitCallback().Run();
EXPECT_TRUE(called);
EXPECT_TRUE(request->TakeCommitCallback().is_null());
auto directive = request->ConstructDirective();
EXPECT_GT(directive.sequence_id(), 0u);
EXPECT_EQ(DocumentTransitionRequest::Effect::kRevealLeft, directive.effect());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(123), directive.duration());
EXPECT_EQ(viz::CompositorFrameTransitionDirective::Type::kSave,
directive.type());
auto duplicate = request->ConstructDirective();
EXPECT_GT(duplicate.sequence_id(), directive.sequence_id());
EXPECT_EQ(duplicate.effect(), directive.effect());
EXPECT_EQ(duplicate.duration(), directive.duration());
EXPECT_EQ(duplicate.type(), directive.type());
}
TEST(DocumentTransitionRequestTest, PrepareRequestLongDurationIsCapped) {
auto long_duration = base::TimeDelta::FromSeconds(1);
ASSERT_GT(long_duration,
viz::CompositorFrameTransitionDirective::kMaxDuration);
auto request = DocumentTransitionRequest::CreatePrepare(
DocumentTransitionRequest::Effect::kRevealLeft, long_duration,
base::OnceCallback<void()>());
auto directive = request->ConstructDirective();
EXPECT_EQ(viz::CompositorFrameTransitionDirective::kMaxDuration,
directive.duration());
}
TEST(DocumentTransitionRequestTest, StartRequest) {
bool called = false;
auto callback = base::BindLambdaForTesting([&called]() { called = true; });
auto request = DocumentTransitionRequest::CreateStart(std::move(callback));
EXPECT_FALSE(called);
request->TakeCommitCallback().Run();
EXPECT_TRUE(called);
EXPECT_TRUE(request->TakeCommitCallback().is_null());
auto directive = request->ConstructDirective();
EXPECT_GT(directive.sequence_id(), 0u);
EXPECT_EQ(viz::CompositorFrameTransitionDirective::Type::kAnimate,
directive.type());
}
} // namespace cc
include_rules = [
"+cc/document_transition/document_transition_request.h"
]
......@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOCUMENT_TRANSITION_DOCUMENT_TRANSITION_H_
#include "cc/document_transition/document_transition_request.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
......@@ -29,6 +30,8 @@ class CORE_EXPORT DocumentTransition final : public ScriptWrappable {
void start();
private:
using Effect = cc::DocumentTransitionRequest::Effect;
Member<Document> document_;
};
......
......@@ -354,6 +354,9 @@ _CONFIG = [
'gfx::ScrollOffset',
'ui::ScrollGranularity',
# Document transitions
'cc::DocumentTransitionRequest',
# base/types/strong_alias.h
'base::StrongAlias',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment