Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / renderer / gpu / frame_swap_message_queue_unittest.cc
blob80405988717b26f278e2ec4a17a018602bcf16b6
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/frame_swap_message_queue.h"
6 #include "ipc/ipc_message.h"
7 #include "testing/gtest/include/gtest/gtest.h"
9 namespace content {
11 class FrameSwapMessageQueueTest : public testing::Test {
12 public:
13 FrameSwapMessageQueueTest()
14 : first_message_(41, 1, IPC::Message::PRIORITY_NORMAL),
15 second_message_(42, 2, IPC::Message::PRIORITY_NORMAL),
16 third_message_(43, 3, IPC::Message::PRIORITY_NORMAL),
17 queue_(new FrameSwapMessageQueue()) {}
19 protected:
20 void QueueNextSwapMessage(scoped_ptr<IPC::Message> msg) {
21 queue_->QueueMessageForFrame(
22 MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 0, msg.Pass(), NULL);
25 void QueueNextSwapMessage(scoped_ptr<IPC::Message> msg, bool* first) {
26 queue_->QueueMessageForFrame(
27 MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 0, msg.Pass(), first);
30 void QueueVisualStateMessage(int source_frame_number,
31 scoped_ptr<IPC::Message> msg) {
32 queue_->QueueMessageForFrame(MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE,
33 source_frame_number,
34 msg.Pass(),
35 NULL);
38 void QueueVisualStateMessage(int source_frame_number,
39 scoped_ptr<IPC::Message> msg,
40 bool* first) {
41 queue_->QueueMessageForFrame(MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE,
42 source_frame_number,
43 msg.Pass(),
44 first);
47 void DrainMessages(int source_frame_number,
48 ScopedVector<IPC::Message>* messages) {
49 messages->clear();
50 queue_->DidActivate(source_frame_number);
51 queue_->DidSwap(source_frame_number);
52 scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope =
53 queue_->AcquireSendMessageScope();
54 queue_->DrainMessages(messages);
57 bool HasMessageForId(const ScopedVector<IPC::Message>& messages,
58 int routing_id) {
59 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
60 i != messages.end();
61 ++i) {
62 if ((*i)->routing_id() == routing_id)
63 return true;
65 return false;
68 scoped_ptr<IPC::Message> CloneMessage(const IPC::Message& other) {
69 return make_scoped_ptr(new IPC::Message(other)).Pass();
72 void TestDidNotSwap(cc::SwapPromise::DidNotSwapReason reason);
74 IPC::Message first_message_;
75 IPC::Message second_message_;
76 IPC::Message third_message_;
77 scoped_refptr<FrameSwapMessageQueue> queue_;
80 TEST_F(FrameSwapMessageQueueTest, TestEmptyQueueDrain) {
81 ScopedVector<IPC::Message> messages;
83 DrainMessages(0, &messages);
84 ASSERT_TRUE(messages.empty());
87 TEST_F(FrameSwapMessageQueueTest, TestEmpty) {
88 ScopedVector<IPC::Message> messages;
89 ASSERT_TRUE(queue_->Empty());
90 QueueNextSwapMessage(CloneMessage(first_message_));
91 ASSERT_FALSE(queue_->Empty());
92 DrainMessages(0, &messages);
93 ASSERT_TRUE(queue_->Empty());
94 QueueVisualStateMessage(1, CloneMessage(first_message_));
95 ASSERT_FALSE(queue_->Empty());
96 queue_->DidActivate(1);
97 queue_->DidSwap(1);
98 ASSERT_FALSE(queue_->Empty());
101 TEST_F(FrameSwapMessageQueueTest, TestQueueMessageFirst) {
102 ScopedVector<IPC::Message> messages;
103 bool visual_state_first = false;
104 bool next_swap_first = false;
106 // Queuing the first time should result in true.
107 QueueVisualStateMessage(1, CloneMessage(first_message_), &visual_state_first);
108 ASSERT_TRUE(visual_state_first);
109 // Queuing the second time should result in true.
110 QueueVisualStateMessage(
111 1, CloneMessage(second_message_), &visual_state_first);
112 ASSERT_FALSE(visual_state_first);
113 // Queuing for a different frame should result in true.
114 QueueVisualStateMessage(2, CloneMessage(first_message_), &visual_state_first);
115 ASSERT_TRUE(visual_state_first);
117 // Queuing for a different policy should result in true.
118 QueueNextSwapMessage(CloneMessage(first_message_), &next_swap_first);
119 ASSERT_TRUE(next_swap_first);
120 // Second time for the same policy is still false.
121 QueueNextSwapMessage(CloneMessage(first_message_), &next_swap_first);
122 ASSERT_FALSE(next_swap_first);
124 DrainMessages(4, &messages);
125 // Queuing after all messages are drained is a true again.
126 QueueVisualStateMessage(4, CloneMessage(first_message_), &visual_state_first);
127 ASSERT_TRUE(visual_state_first);
130 TEST_F(FrameSwapMessageQueueTest, TestNextSwapMessageSentWithNextFrame) {
131 ScopedVector<IPC::Message> messages;
133 DrainMessages(1, &messages);
134 QueueNextSwapMessage(CloneMessage(first_message_));
135 DrainMessages(2, &messages);
136 ASSERT_EQ(1u, messages.size());
137 ASSERT_EQ(first_message_.routing_id(), messages.front()->routing_id());
138 messages.clear();
140 DrainMessages(2, &messages);
141 ASSERT_TRUE(messages.empty());
144 TEST_F(FrameSwapMessageQueueTest, TestNextSwapMessageSentWithCurrentFrame) {
145 ScopedVector<IPC::Message> messages;
147 DrainMessages(1, &messages);
148 QueueNextSwapMessage(CloneMessage(first_message_));
149 DrainMessages(1, &messages);
150 ASSERT_EQ(1u, messages.size());
151 ASSERT_EQ(first_message_.routing_id(), messages.front()->routing_id());
152 messages.clear();
154 DrainMessages(1, &messages);
155 ASSERT_TRUE(messages.empty());
158 TEST_F(FrameSwapMessageQueueTest,
159 TestDrainsVisualStateMessagesForCorrespondingFrames) {
160 ScopedVector<IPC::Message> messages;
162 QueueVisualStateMessage(1, CloneMessage(first_message_));
163 QueueVisualStateMessage(2, CloneMessage(second_message_));
164 QueueVisualStateMessage(3, CloneMessage(third_message_));
165 DrainMessages(0, &messages);
166 ASSERT_TRUE(messages.empty());
168 DrainMessages(2, &messages);
169 ASSERT_EQ(2u, messages.size());
170 ASSERT_TRUE(HasMessageForId(messages, first_message_.routing_id()));
171 ASSERT_TRUE(HasMessageForId(messages, second_message_.routing_id()));
172 messages.clear();
174 DrainMessages(2, &messages);
175 ASSERT_TRUE(messages.empty());
177 DrainMessages(5, &messages);
178 ASSERT_EQ(1u, messages.size());
179 ASSERT_EQ(third_message_.routing_id(), messages.front()->routing_id());
182 TEST_F(FrameSwapMessageQueueTest,
183 TestQueueNextSwapMessagePreservesFifoOrdering) {
184 ScopedVector<IPC::Message> messages;
186 QueueNextSwapMessage(CloneMessage(first_message_));
187 QueueNextSwapMessage(CloneMessage(second_message_));
188 DrainMessages(1, &messages);
189 ASSERT_EQ(2u, messages.size());
190 ASSERT_EQ(first_message_.routing_id(), messages[0]->routing_id());
191 ASSERT_EQ(second_message_.routing_id(), messages[1]->routing_id());
194 TEST_F(FrameSwapMessageQueueTest,
195 TestQueueVisualStateMessagePreservesFifoOrdering) {
196 ScopedVector<IPC::Message> messages;
198 QueueVisualStateMessage(1, CloneMessage(first_message_));
199 QueueVisualStateMessage(1, CloneMessage(second_message_));
200 DrainMessages(1, &messages);
201 ASSERT_EQ(2u, messages.size());
202 ASSERT_EQ(first_message_.routing_id(), messages[0]->routing_id());
203 ASSERT_EQ(second_message_.routing_id(), messages[1]->routing_id());
206 void FrameSwapMessageQueueTest::TestDidNotSwap(
207 cc::SwapPromise::DidNotSwapReason reason) {
208 ScopedVector<IPC::Message> messages;
210 QueueNextSwapMessage(CloneMessage(first_message_));
211 QueueVisualStateMessage(2, CloneMessage(second_message_));
212 QueueVisualStateMessage(3, CloneMessage(third_message_));
213 const int rid[] = {first_message_.routing_id(),
214 second_message_.routing_id(),
215 third_message_.routing_id()};
217 bool msg_delivered = reason != cc::SwapPromise::COMMIT_FAILS &&
218 reason != cc::SwapPromise::ACTIVATION_FAILS;
220 queue_->DidNotSwap(2, reason, &messages);
221 ASSERT_TRUE(msg_delivered == HasMessageForId(messages, rid[0]));
222 ASSERT_TRUE(msg_delivered == HasMessageForId(messages, rid[1]));
223 ASSERT_FALSE(HasMessageForId(messages, rid[2]));
224 messages.clear();
226 queue_->DidNotSwap(3, reason, &messages);
227 ASSERT_FALSE(HasMessageForId(messages, rid[0]));
228 ASSERT_FALSE(HasMessageForId(messages, rid[1]));
229 ASSERT_TRUE(msg_delivered == HasMessageForId(messages, rid[2]));
230 messages.clear();
232 // all undelivered messages should still be available for RenderFrameHostImpl
233 // to deliver.
234 DrainMessages(3, &messages);
235 ASSERT_TRUE(msg_delivered != HasMessageForId(messages, rid[0]));
236 ASSERT_TRUE(msg_delivered != HasMessageForId(messages, rid[1]));
237 ASSERT_TRUE(msg_delivered != HasMessageForId(messages, rid[2]));
240 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapNoUpdate) {
241 TestDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
244 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapSwapFails) {
245 TestDidNotSwap(cc::SwapPromise::SWAP_FAILS);
248 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapCommitFails) {
249 TestDidNotSwap(cc::SwapPromise::COMMIT_FAILS);
252 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapActivationFails) {
253 TestDidNotSwap(cc::SwapPromise::ACTIVATION_FAILS);
256 class NotifiesDeletionMessage : public IPC::Message {
257 public:
258 NotifiesDeletionMessage(bool* deleted, const IPC::Message& other)
259 : IPC::Message(other), deleted_(deleted) {}
260 ~NotifiesDeletionMessage() override { *deleted_ = true; }
262 private:
263 bool* deleted_;
266 TEST_F(FrameSwapMessageQueueTest, TestDeletesNextSwapMessage) {
267 bool message_deleted = false;
268 QueueNextSwapMessage(make_scoped_ptr(
269 new NotifiesDeletionMessage(&message_deleted, first_message_)));
270 queue_ = NULL;
271 ASSERT_TRUE(message_deleted);
274 TEST_F(FrameSwapMessageQueueTest, TestDeletesVisualStateMessage) {
275 bool message_deleted = false;
276 QueueVisualStateMessage(1,
277 make_scoped_ptr(new NotifiesDeletionMessage(
278 &message_deleted, first_message_)));
279 queue_ = NULL;
280 ASSERT_TRUE(message_deleted);
283 TEST_F(FrameSwapMessageQueueTest, TestDeletesQueuedVisualStateMessage) {
284 bool message_deleted = false;
285 QueueVisualStateMessage(1,
286 make_scoped_ptr(new NotifiesDeletionMessage(
287 &message_deleted, first_message_)));
288 queue_->DidActivate(1);
289 queue_->DidSwap(1);
290 queue_ = NULL;
291 ASSERT_TRUE(message_deleted);
294 } // namespace content