Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / renderer / gpu / queue_message_swap_promise_unittest.cc
blob069cd2cdde9f231f80b80240cdf521ff6af7a406
1 // 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.
5 #include "content/renderer/gpu/queue_message_swap_promise.h"
7 #include <vector>
9 #include "base/memory/scoped_vector.h"
10 #include "cc/output/swap_promise.h"
11 #include "content/renderer/gpu/frame_swap_message_queue.h"
12 #include "content/renderer/gpu/render_widget_compositor.h"
13 #include "content/renderer/render_widget.h"
14 #include "content/test/mock_render_process.h"
15 #include "ipc/ipc_message.h"
16 #include "ipc/ipc_sync_message_filter.h"
17 #include "ipc/ipc_test_sink.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace content {
22 class TestRenderWidget : public RenderWidget {
23 public:
24 using RenderWidget::QueueMessageImpl;
26 private:
27 ~TestRenderWidget() override {}
29 DISALLOW_COPY_AND_ASSIGN(TestRenderWidget);
32 class TestSyncMessageFilter : public IPC::SyncMessageFilter {
33 public:
34 TestSyncMessageFilter() : IPC::SyncMessageFilter(NULL) {}
36 bool Send(IPC::Message* message) override {
37 messages_.push_back(message);
38 return true;
41 ScopedVector<IPC::Message>& messages() { return messages_; }
43 private:
44 ~TestSyncMessageFilter() override {}
46 ScopedVector<IPC::Message> messages_;
48 DISALLOW_COPY_AND_ASSIGN(TestSyncMessageFilter);
51 struct QueueMessageData {
52 MessageDeliveryPolicy policy;
53 int source_frame_number;
56 class QueueMessageSwapPromiseTest : public testing::Test {
57 public:
58 QueueMessageSwapPromiseTest()
59 : frame_swap_message_queue_(new FrameSwapMessageQueue()),
60 sync_message_filter_(new TestSyncMessageFilter()) {}
62 ~QueueMessageSwapPromiseTest() override {}
64 scoped_ptr<cc::SwapPromise> QueueMessageImpl(IPC::Message* msg,
65 MessageDeliveryPolicy policy,
66 int source_frame_number) {
67 return TestRenderWidget::QueueMessageImpl(msg,
68 policy,
69 frame_swap_message_queue_.get(),
70 sync_message_filter_,
71 source_frame_number).Pass();
74 ScopedVector<IPC::Message>& DirectSendMessages() {
75 return sync_message_filter_->messages();
78 ScopedVector<IPC::Message>& NextSwapMessages() {
79 next_swap_messages_.clear();
80 scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope =
81 frame_swap_message_queue_->AcquireSendMessageScope();
82 frame_swap_message_queue_->DrainMessages(&next_swap_messages_);
83 return next_swap_messages_;
86 bool ContainsMessage(const ScopedVector<IPC::Message>& messages,
87 const IPC::Message& message) {
88 if (messages.empty())
89 return false;
90 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
91 i != messages.end();
92 ++i) {
93 if ((*i)->type() == message.type())
94 return true;
96 return false;
99 bool NextSwapHasMessage(const IPC::Message& message) {
100 return ContainsMessage(NextSwapMessages(), message);
103 void QueueMessages(QueueMessageData data[], size_t count) {
104 for (size_t i = 0; i < count; ++i) {
105 messages_.push_back(
106 IPC::Message(0, i + 1, IPC::Message::PRIORITY_NORMAL));
107 promises_.push_back(
108 QueueMessageImpl(new IPC::Message(messages_[i]),
109 data[i].policy,
110 data[i].source_frame_number).release());
114 void CleanupPromises() {
115 for (ScopedVector<cc::SwapPromise>::iterator i = promises_.begin();
116 i != promises_.end();
117 ++i) {
118 if (*i)
119 (*i)->DidSwap(NULL);
123 protected:
124 void VisualStateSwapPromiseDidNotSwap(
125 cc::SwapPromise::DidNotSwapReason reason);
127 scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_;
128 scoped_refptr<TestSyncMessageFilter> sync_message_filter_;
129 std::vector<IPC::Message> messages_;
130 ScopedVector<cc::SwapPromise> promises_;
132 private:
133 ScopedVector<IPC::Message> next_swap_messages_;
135 DISALLOW_COPY_AND_ASSIGN(QueueMessageSwapPromiseTest);
138 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySchedulesMessageForNextSwap) {
139 QueueMessageData data[] = {
140 /* { policy, source_frame_number } */
141 {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 1},
143 QueueMessages(data, arraysize(data));
145 ASSERT_TRUE(promises_[0]);
146 EXPECT_TRUE(DirectSendMessages().empty());
147 EXPECT_FALSE(frame_swap_message_queue_->Empty());
148 EXPECT_TRUE(NextSwapHasMessage(messages_[0]));
150 CleanupPromises();
153 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicyNeedsAtMostOnePromise) {
154 QueueMessageData data[] = {
155 /* { policy, source_frame_number } */
156 {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 1},
157 {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 1},
159 QueueMessages(data, arraysize(data));
161 ASSERT_TRUE(promises_[0]);
162 ASSERT_FALSE(promises_[1]);
164 CleanupPromises();
167 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnNoUpdate) {
168 QueueMessageData data[] = {
169 /* { policy, source_frame_number } */
170 {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 1},
172 QueueMessages(data, arraysize(data));
174 promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
175 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
176 EXPECT_TRUE(NextSwapMessages().empty());
177 EXPECT_TRUE(frame_swap_message_queue_->Empty());
180 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnSwapFails) {
181 QueueMessageData data[] = {
182 /* { policy, source_frame_number } */
183 {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 1},
185 QueueMessages(data, arraysize(data));
187 promises_[0]->DidNotSwap(cc::SwapPromise::SWAP_FAILS);
188 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
189 EXPECT_TRUE(NextSwapMessages().empty());
190 EXPECT_TRUE(frame_swap_message_queue_->Empty());
193 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicyRetainsMessageOnCommitFails) {
194 QueueMessageData data[] = {
195 /* { policy, source_frame_number } */
196 {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 1},
198 QueueMessages(data, arraysize(data));
200 promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_FAILS);
201 EXPECT_TRUE(DirectSendMessages().empty());
202 EXPECT_FALSE(frame_swap_message_queue_->Empty());
203 EXPECT_TRUE(NextSwapHasMessage(messages_[0]));
206 TEST_F(QueueMessageSwapPromiseTest,
207 VisualStateQueuesMessageWhenCommitRequested) {
208 QueueMessageData data[] = {
209 /* { policy, source_frame_number } */
210 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
212 QueueMessages(data, arraysize(data));
214 ASSERT_TRUE(promises_[0]);
215 EXPECT_TRUE(DirectSendMessages().empty());
216 EXPECT_FALSE(frame_swap_message_queue_->Empty());
217 EXPECT_TRUE(NextSwapMessages().empty());
219 CleanupPromises();
222 TEST_F(QueueMessageSwapPromiseTest,
223 VisualStateQueuesMessageWhenOtherMessageAlreadyQueued) {
224 QueueMessageData data[] = {
225 /* { policy, source_frame_number } */
226 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
227 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
229 QueueMessages(data, arraysize(data));
231 EXPECT_TRUE(DirectSendMessages().empty());
232 EXPECT_FALSE(frame_swap_message_queue_->Empty());
233 EXPECT_FALSE(NextSwapHasMessage(messages_[1]));
235 CleanupPromises();
238 TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidSwap) {
239 QueueMessageData data[] = {
240 /* { policy, source_frame_number } */
241 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
242 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
243 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 2},
245 QueueMessages(data, arraysize(data));
247 promises_[0]->DidSwap(NULL);
248 ASSERT_FALSE(promises_[1]);
249 ScopedVector<IPC::Message> messages;
250 messages.swap(NextSwapMessages());
251 EXPECT_EQ(2u, messages.size());
252 EXPECT_TRUE(ContainsMessage(messages, messages_[0]));
253 EXPECT_TRUE(ContainsMessage(messages, messages_[1]));
254 EXPECT_FALSE(ContainsMessage(messages, messages_[2]));
256 promises_[2]->DidSwap(NULL);
257 messages.swap(NextSwapMessages());
258 EXPECT_EQ(1u, messages.size());
259 EXPECT_TRUE(ContainsMessage(messages, messages_[2]));
261 EXPECT_TRUE(DirectSendMessages().empty());
262 EXPECT_TRUE(NextSwapMessages().empty());
263 EXPECT_TRUE(frame_swap_message_queue_->Empty());
266 void QueueMessageSwapPromiseTest::VisualStateSwapPromiseDidNotSwap(
267 cc::SwapPromise::DidNotSwapReason reason) {
268 QueueMessageData data[] = {
269 /* { policy, source_frame_number } */
270 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
271 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
272 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 2},
274 QueueMessages(data, arraysize(data));
276 promises_[0]->DidNotSwap(reason);
277 ASSERT_FALSE(promises_[1]);
278 EXPECT_TRUE(NextSwapMessages().empty());
279 EXPECT_EQ(2u, DirectSendMessages().size());
280 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
281 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[1]));
282 EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[2]));
284 promises_[2]->DidNotSwap(reason);
285 EXPECT_TRUE(NextSwapMessages().empty());
286 EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[2]));
288 EXPECT_TRUE(NextSwapMessages().empty());
289 EXPECT_TRUE(frame_swap_message_queue_->Empty());
292 TEST_F(QueueMessageSwapPromiseTest, VisalStateSwapPromiseDidNotSwapNoUpdate) {
293 VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
296 TEST_F(QueueMessageSwapPromiseTest,
297 VisualStateSwapPromiseDidNotSwapCommitFails) {
298 // COMMIT_FAILS is treated differently:
299 // If we fail to swap with COMMIT_FAILS, then the renderer is
300 // shutting down, which implies that the RenderFrameHostImpl
301 // destructor will eventually be called, firing the remaining
302 // response callbacks (with swap_success = false) itself.
303 QueueMessageData data[] = {
304 /* { policy, source_frame_number } */
305 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
306 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 1},
307 {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, 2},
309 QueueMessages(data, arraysize(data));
311 promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_FAILS);
312 ASSERT_FALSE(promises_[1]);
313 EXPECT_TRUE(NextSwapMessages().empty());
314 EXPECT_EQ(0u, DirectSendMessages().size());
315 EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[0]));
316 EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[1]));
317 EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[2]));
319 promises_[2]->DidNotSwap(cc::SwapPromise::COMMIT_FAILS);
320 EXPECT_TRUE(NextSwapMessages().empty());
321 EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[2]));
323 EXPECT_TRUE(NextSwapMessages().empty());
324 EXPECT_FALSE(frame_swap_message_queue_->Empty());
327 TEST_F(QueueMessageSwapPromiseTest, VisalStateSwapPromiseDidNotSwapSwapFails) {
328 VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::SWAP_FAILS);
331 } // namespace content