blob: 878d37e1db9c38c0fd199556a8fdf4c237ca6e05 [file] [log] [blame]
[email protected]586871b2014-07-22 17:05:111// Copyright 2014 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
Sadrul Habib Chowdhury31c98712018-12-11 04:15:135#include "content/renderer/queue_message_swap_promise.h"
[email protected]586871b2014-07-22 17:05:116
avi1023d012015-12-25 02:39:147#include <stddef.h>
8
leon.han21e0e482017-02-23 04:13:329#include <memory>
[email protected]586871b2014-07-22 17:05:1110#include <vector>
11
avi1023d012015-12-25 02:39:1412#include "base/macros.h"
dchengcedca5612016-04-09 01:40:1513#include "base/memory/ptr_util.h"
fdoray86573e42017-04-06 17:26:3614#include "base/test/scoped_task_environment.h"
danakjba65a0912017-09-21 16:38:4215#include "cc/trees/swap_promise.h"
danakj4b347212018-07-04 17:55:1716#include "content/common/render_frame_metadata.mojom.h"
Albert J. Wong3c93c182018-09-27 17:29:4317#include "content/common/widget_messages.h"
Sadrul Habib Chowdhury31c98712018-12-11 04:15:1318#include "content/renderer/compositor/layer_tree_view.h"
19#include "content/renderer/frame_swap_message_queue.h"
[email protected]586871b2014-07-22 17:05:1120#include "content/renderer/render_widget.h"
21#include "content/test/mock_render_process.h"
22#include "ipc/ipc_message.h"
23#include "ipc/ipc_sync_message_filter.h"
24#include "ipc/ipc_test_sink.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27namespace content {
28
[email protected]586871b2014-07-22 17:05:1129class TestSyncMessageFilter : public IPC::SyncMessageFilter {
30 public:
rockotb97e3d32016-09-16 17:39:0331 TestSyncMessageFilter() : IPC::SyncMessageFilter(nullptr) {}
[email protected]586871b2014-07-22 17:05:1132
dcheng6d18e402014-10-21 12:32:5233 bool Send(IPC::Message* message) override {
Albert J. Wong3c93c182018-09-27 17:29:4334 if (message->type() == WidgetHostMsg_FrameSwapMessages::ID) {
35 WidgetHostMsg_FrameSwapMessages::Param param;
36 WidgetHostMsg_FrameSwapMessages::Read(message, &param);
samans26510e442017-06-01 22:29:1237 std::vector<IPC::Message> messages = std::get<1>(param);
38 last_swap_messages_.clear();
39 for (const IPC::Message& message : messages) {
Jeremy Roman04f27c372017-10-27 15:20:5540 last_swap_messages_.push_back(std::make_unique<IPC::Message>(message));
samans26510e442017-06-01 22:29:1241 }
42 delete message;
43 } else {
44 direct_send_messages_.push_back(base::WrapUnique(message));
45 }
[email protected]586871b2014-07-22 17:05:1146 return true;
47 }
48
samans26510e442017-06-01 22:29:1249 std::vector<std::unique_ptr<IPC::Message>>& last_swap_messages() {
50 return last_swap_messages_;
51 }
52
53 const std::vector<std::unique_ptr<IPC::Message>>& direct_send_messages() {
54 return direct_send_messages_;
55 }
[email protected]586871b2014-07-22 17:05:1156
57 private:
dcheng6d18e402014-10-21 12:32:5258 ~TestSyncMessageFilter() override {}
[email protected]586871b2014-07-22 17:05:1159
samans26510e442017-06-01 22:29:1260 std::vector<std::unique_ptr<IPC::Message>> direct_send_messages_;
61 std::vector<std::unique_ptr<IPC::Message>> last_swap_messages_;
[email protected]586871b2014-07-22 17:05:1162
63 DISALLOW_COPY_AND_ASSIGN(TestSyncMessageFilter);
64};
65
[email protected]586871b2014-07-22 17:05:1166class QueueMessageSwapPromiseTest : public testing::Test {
67 public:
68 QueueMessageSwapPromiseTest()
samans26510e442017-06-01 22:29:1269 : frame_swap_message_queue_(new FrameSwapMessageQueue(0)),
[email protected]586871b2014-07-22 17:05:1170 sync_message_filter_(new TestSyncMessageFilter()) {}
71
dchengf5762152014-10-29 02:12:0672 ~QueueMessageSwapPromiseTest() override {}
[email protected]586871b2014-07-22 17:05:1173
Sadrul Habib Chowdhury31c98712018-12-11 04:15:1374 std::unique_ptr<cc::SwapPromise> QueueMessageImpl(IPC::Message* msg,
75 int source_frame_number) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:4976 return RenderWidget::QueueMessageImpl(msg, frame_swap_message_queue_.get(),
77 sync_message_filter_,
78 source_frame_number);
[email protected]586871b2014-07-22 17:05:1179 }
80
dchengcedca5612016-04-09 01:40:1581 const std::vector<std::unique_ptr<IPC::Message>>& DirectSendMessages() {
samans26510e442017-06-01 22:29:1282 return sync_message_filter_->direct_send_messages();
83 }
84
85 std::vector<std::unique_ptr<IPC::Message>>& LastSwapMessages() {
86 return sync_message_filter_->last_swap_messages();
[email protected]586871b2014-07-22 17:05:1187 }
88
dchengcedca5612016-04-09 01:40:1589 std::vector<std::unique_ptr<IPC::Message>>& NextSwapMessages() {
[email protected]586871b2014-07-22 17:05:1190 next_swap_messages_.clear();
dchengcedca5612016-04-09 01:40:1591 std::unique_ptr<FrameSwapMessageQueue::SendMessageScope>
92 send_message_scope =
93 frame_swap_message_queue_->AcquireSendMessageScope();
[email protected]586871b2014-07-22 17:05:1194 frame_swap_message_queue_->DrainMessages(&next_swap_messages_);
95 return next_swap_messages_;
96 }
97
dchengcedca5612016-04-09 01:40:1598 bool ContainsMessage(
99 const std::vector<std::unique_ptr<IPC::Message>>& messages,
100 const IPC::Message& message) {
[email protected]586871b2014-07-22 17:05:11101 if (messages.empty())
102 return false;
martina.kollarova9dc9caa2015-12-09 16:10:49103 for (const auto& msg : messages) {
104 if (msg->type() == message.type())
[email protected]586871b2014-07-22 17:05:11105 return true;
106 }
107 return false;
108 }
109
samans26510e442017-06-01 22:29:12110 bool LastSwapHasMessage(const IPC::Message& message) {
111 return ContainsMessage(LastSwapMessages(), message);
112 }
113
[email protected]586871b2014-07-22 17:05:11114 bool NextSwapHasMessage(const IPC::Message& message) {
115 return ContainsMessage(NextSwapMessages(), message);
116 }
117
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49118 void QueueMessages(int source_frame_numbers[], size_t count) {
[email protected]586871b2014-07-22 17:05:11119 for (size_t i = 0; i < count; ++i) {
120 messages_.push_back(
121 IPC::Message(0, i + 1, IPC::Message::PRIORITY_NORMAL));
leon.han21e0e482017-02-23 04:13:32122 promises_.push_back(QueueMessageImpl(new IPC::Message(messages_[i]),
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49123 source_frame_numbers[i]));
[email protected]586871b2014-07-22 17:05:11124 }
125 }
126
127 void CleanupPromises() {
leon.han21e0e482017-02-23 04:13:32128 for (const auto& promise : promises_) {
129 if (promise.get()) {
130 promise->DidActivate();
Sadrul Habib Chowdhury24856212018-05-25 21:38:43131 promise->WillSwap(&dummy_metadata_);
leon.han21e0e482017-02-23 04:13:32132 promise->DidSwap();
tobiasjs93d464842015-05-15 17:52:44133 }
[email protected]586871b2014-07-22 17:05:11134 }
135 }
136
137 protected:
138 void VisualStateSwapPromiseDidNotSwap(
139 cc::SwapPromise::DidNotSwapReason reason);
140
fdoray86573e42017-04-06 17:26:36141 base::test::ScopedTaskEnvironment scoped_task_environment_;
[email protected]586871b2014-07-22 17:05:11142 scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_;
143 scoped_refptr<TestSyncMessageFilter> sync_message_filter_;
144 std::vector<IPC::Message> messages_;
leon.han21e0e482017-02-23 04:13:32145 std::vector<std::unique_ptr<cc::SwapPromise>> promises_;
jonross7c62fcb2018-02-21 16:35:46146 viz::CompositorFrameMetadata dummy_metadata_;
Jonathan89a3da22018-01-12 16:41:20147 cc::RenderFrameMetadata dummy_render_frame_metadata_;
[email protected]586871b2014-07-22 17:05:11148
149 private:
dchengcedca5612016-04-09 01:40:15150 std::vector<std::unique_ptr<IPC::Message>> next_swap_messages_;
[email protected]586871b2014-07-22 17:05:11151
152 DISALLOW_COPY_AND_ASSIGN(QueueMessageSwapPromiseTest);
153};
154
155TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySchedulesMessageForNextSwap) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49156 int source_frame_numbers[] = {1};
157 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11158
leon.han21e0e482017-02-23 04:13:32159 ASSERT_TRUE(promises_[0].get());
tobiasjs93d464842015-05-15 17:52:44160 promises_[0]->DidActivate();
Sadrul Habib Chowdhury24856212018-05-25 21:38:43161 promises_[0]->WillSwap(&dummy_metadata_);
samanse7345c82016-12-16 02:51:16162 promises_[0]->DidSwap();
tobiasjs93d464842015-05-15 17:52:44163
[email protected]586871b2014-07-22 17:05:11164 EXPECT_TRUE(DirectSendMessages().empty());
samans26510e442017-06-01 22:29:12165 EXPECT_TRUE(frame_swap_message_queue_->Empty());
166 EXPECT_TRUE(LastSwapHasMessage(messages_[0]));
[email protected]586871b2014-07-22 17:05:11167}
168
169TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicyNeedsAtMostOnePromise) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49170 int source_frame_numbers[] = {1, 1};
171 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11172
leon.han21e0e482017-02-23 04:13:32173 ASSERT_TRUE(promises_[0].get());
174 ASSERT_FALSE(promises_[1].get());
[email protected]586871b2014-07-22 17:05:11175
176 CleanupPromises();
177}
178
179TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnNoUpdate) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49180 int source_frame_numbers[] = {1};
181 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11182
183 promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
184 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
samans26510e442017-06-01 22:29:12185 EXPECT_TRUE(LastSwapMessages().empty());
[email protected]586871b2014-07-22 17:05:11186 EXPECT_TRUE(frame_swap_message_queue_->Empty());
187}
188
189TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnSwapFails) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49190 int source_frame_numbers[] = {1};
191 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11192
193 promises_[0]->DidNotSwap(cc::SwapPromise::SWAP_FAILS);
194 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
samans26510e442017-06-01 22:29:12195 EXPECT_TRUE(LastSwapMessages().empty());
[email protected]586871b2014-07-22 17:05:11196 EXPECT_TRUE(frame_swap_message_queue_->Empty());
197}
198
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49199TEST_F(QueueMessageSwapPromiseTest,
200 NextActivatePolicyRetainsMessageOnCommitFails) {
201 int source_frame_numbers[] = {1};
202 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11203
204 promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_FAILS);
205 EXPECT_TRUE(DirectSendMessages().empty());
samans26510e442017-06-01 22:29:12206 EXPECT_TRUE(LastSwapMessages().empty());
[email protected]586871b2014-07-22 17:05:11207 EXPECT_FALSE(frame_swap_message_queue_->Empty());
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49208 frame_swap_message_queue_->DidActivate(2);
[email protected]586871b2014-07-22 17:05:11209 EXPECT_TRUE(NextSwapHasMessage(messages_[0]));
210}
211
[email protected]586871b2014-07-22 17:05:11212TEST_F(QueueMessageSwapPromiseTest,
213 VisualStateQueuesMessageWhenCommitRequested) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49214 int source_frame_numbers[] = {1};
215 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11216
leon.han21e0e482017-02-23 04:13:32217 ASSERT_TRUE(promises_[0].get());
[email protected]586871b2014-07-22 17:05:11218 EXPECT_TRUE(DirectSendMessages().empty());
219 EXPECT_FALSE(frame_swap_message_queue_->Empty());
220 EXPECT_TRUE(NextSwapMessages().empty());
221
222 CleanupPromises();
223}
224
225TEST_F(QueueMessageSwapPromiseTest,
226 VisualStateQueuesMessageWhenOtherMessageAlreadyQueued) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49227 int source_frame_numbers[] = {1, 1};
228 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11229
230 EXPECT_TRUE(DirectSendMessages().empty());
231 EXPECT_FALSE(frame_swap_message_queue_->Empty());
232 EXPECT_FALSE(NextSwapHasMessage(messages_[1]));
233
234 CleanupPromises();
235}
236
tobiasjs93d464842015-05-15 17:52:44237TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidActivate) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49238 int source_frame_numbers[] = {1, 1, 2};
239 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11240
tobiasjs93d464842015-05-15 17:52:44241 promises_[0]->DidActivate();
Sadrul Habib Chowdhury24856212018-05-25 21:38:43242 promises_[0]->WillSwap(&dummy_metadata_);
samanse7345c82016-12-16 02:51:16243 promises_[0]->DidSwap();
leon.han21e0e482017-02-23 04:13:32244 ASSERT_FALSE(promises_[1].get());
dchengcedca5612016-04-09 01:40:15245 std::vector<std::unique_ptr<IPC::Message>> messages;
samans26510e442017-06-01 22:29:12246 messages.swap(LastSwapMessages());
jonross7c62fcb2018-02-21 16:35:46247 EXPECT_EQ(2u, messages.size());
[email protected]586871b2014-07-22 17:05:11248 EXPECT_TRUE(ContainsMessage(messages, messages_[0]));
249 EXPECT_TRUE(ContainsMessage(messages, messages_[1]));
250 EXPECT_FALSE(ContainsMessage(messages, messages_[2]));
251
tobiasjs93d464842015-05-15 17:52:44252 promises_[2]->DidActivate();
253 promises_[2]->DidNotSwap(cc::SwapPromise::SWAP_FAILS);
[email protected]586871b2014-07-22 17:05:11254 messages.swap(NextSwapMessages());
loyso260a8f72016-09-08 02:07:17255 EXPECT_TRUE(messages.empty());
[email protected]586871b2014-07-22 17:05:11256
loyso260a8f72016-09-08 02:07:17257 EXPECT_EQ(1u, DirectSendMessages().size());
258 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[2]));
259
[email protected]586871b2014-07-22 17:05:11260 EXPECT_TRUE(NextSwapMessages().empty());
261 EXPECT_TRUE(frame_swap_message_queue_->Empty());
262}
263
264void QueueMessageSwapPromiseTest::VisualStateSwapPromiseDidNotSwap(
265 cc::SwapPromise::DidNotSwapReason reason) {
Sadrul Habib Chowdhury4e0335cf2018-07-31 20:08:49266 int source_frame_numbers[] = {1, 1, 2};
267 QueueMessages(source_frame_numbers, base::size(source_frame_numbers));
[email protected]586871b2014-07-22 17:05:11268
tobiasjs93d464842015-05-15 17:52:44269 // If we fail to swap with COMMIT_FAILS or ACTIVATE_FAILS, then
270 // messages are delivered by the RenderFrameHostImpl destructor,
271 // rather than directly by the swap promise.
272 bool msg_delivered = reason != cc::SwapPromise::COMMIT_FAILS &&
273 reason != cc::SwapPromise::ACTIVATION_FAILS;
274
[email protected]586871b2014-07-22 17:05:11275 promises_[0]->DidNotSwap(reason);
leon.han21e0e482017-02-23 04:13:32276 ASSERT_FALSE(promises_[1].get());
[email protected]586871b2014-07-22 17:05:11277 EXPECT_TRUE(NextSwapMessages().empty());
tobiasjs93d464842015-05-15 17:52:44278 EXPECT_EQ(msg_delivered, ContainsMessage(DirectSendMessages(), messages_[0]));
279 EXPECT_EQ(msg_delivered, ContainsMessage(DirectSendMessages(), messages_[1]));
[email protected]586871b2014-07-22 17:05:11280 EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[2]));
281
282 promises_[2]->DidNotSwap(reason);
283 EXPECT_TRUE(NextSwapMessages().empty());
tobiasjs93d464842015-05-15 17:52:44284 EXPECT_EQ(msg_delivered, ContainsMessage(DirectSendMessages(), messages_[2]));
[email protected]586871b2014-07-22 17:05:11285
286 EXPECT_TRUE(NextSwapMessages().empty());
tobiasjs93d464842015-05-15 17:52:44287 EXPECT_EQ(msg_delivered, frame_swap_message_queue_->Empty());
[email protected]586871b2014-07-22 17:05:11288}
289
tobiasjs93d464842015-05-15 17:52:44290TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidNotSwapNoUpdate) {
[email protected]586871b2014-07-22 17:05:11291 VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
292}
293
294TEST_F(QueueMessageSwapPromiseTest,
tobiasjs8d503c0a2015-03-04 14:41:21295 VisualStateSwapPromiseDidNotSwapCommitFails) {
tobiasjs93d464842015-05-15 17:52:44296 VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_FAILS);
[email protected]586871b2014-07-22 17:05:11297}
298
tobiasjs93d464842015-05-15 17:52:44299TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidNotSwapSwapFails) {
[email protected]586871b2014-07-22 17:05:11300 VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::SWAP_FAILS);
301}
302
tobiasjs93d464842015-05-15 17:52:44303TEST_F(QueueMessageSwapPromiseTest,
304 VisualStateSwapPromiseDidNotSwapActivationFails) {
305 VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::ACTIVATION_FAILS);
306}
307
[email protected]586871b2014-07-22 17:05:11308} // namespace content