Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / renderer / gpu / frame_swap_message_queue_unittest.cc
blobdc802c0e33c7748c278b6caf80d5969b2c3273e8
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_->DidSwap(source_frame_number);
51 scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope =
52 queue_->AcquireSendMessageScope();
53 queue_->DrainMessages(messages);
56 bool HasMessageForId(const ScopedVector<IPC::Message>& messages,
57 int routing_id) {
58 for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
59 i != messages.end();
60 ++i) {
61 if ((*i)->routing_id() == routing_id)
62 return true;
64 return false;
67 scoped_ptr<IPC::Message> CloneMessage(const IPC::Message& other) {
68 return make_scoped_ptr(new IPC::Message(other)).Pass();
71 void TestDidNotSwap(cc::SwapPromise::DidNotSwapReason reason);
73 IPC::Message first_message_;
74 IPC::Message second_message_;
75 IPC::Message third_message_;
76 scoped_refptr<FrameSwapMessageQueue> queue_;
79 TEST_F(FrameSwapMessageQueueTest, TestEmptyQueueDrain) {
80 ScopedVector<IPC::Message> messages;
82 DrainMessages(0, &messages);
83 ASSERT_TRUE(messages.empty());
86 TEST_F(FrameSwapMessageQueueTest, TestEmpty) {
87 ScopedVector<IPC::Message> messages;
88 ASSERT_TRUE(queue_->Empty());
89 QueueNextSwapMessage(CloneMessage(first_message_));
90 ASSERT_FALSE(queue_->Empty());
91 DrainMessages(0, &messages);
92 ASSERT_TRUE(queue_->Empty());
93 QueueVisualStateMessage(1, CloneMessage(first_message_));
94 ASSERT_FALSE(queue_->Empty());
95 queue_->DidSwap(1);
96 ASSERT_FALSE(queue_->Empty());
99 TEST_F(FrameSwapMessageQueueTest, TestQueueMessageFirst) {
100 ScopedVector<IPC::Message> messages;
101 bool visual_state_first = false;
102 bool next_swap_first = false;
104 // Queuing the first time should result in true.
105 QueueVisualStateMessage(1, CloneMessage(first_message_), &visual_state_first);
106 ASSERT_TRUE(visual_state_first);
107 // Queuing the second time should result in true.
108 QueueVisualStateMessage(
109 1, CloneMessage(second_message_), &visual_state_first);
110 ASSERT_FALSE(visual_state_first);
111 // Queuing for a different frame should result in true.
112 QueueVisualStateMessage(2, CloneMessage(first_message_), &visual_state_first);
113 ASSERT_TRUE(visual_state_first);
115 // Queuing for a different policy should result in true.
116 QueueNextSwapMessage(CloneMessage(first_message_), &next_swap_first);
117 ASSERT_TRUE(next_swap_first);
118 // Second time for the same policy is still false.
119 QueueNextSwapMessage(CloneMessage(first_message_), &next_swap_first);
120 ASSERT_FALSE(next_swap_first);
122 DrainMessages(4, &messages);
123 // Queuing after all messages are drained is a true again.
124 QueueVisualStateMessage(4, CloneMessage(first_message_), &visual_state_first);
125 ASSERT_TRUE(visual_state_first);
128 TEST_F(FrameSwapMessageQueueTest, TestNextSwapMessageSentWithNextFrame) {
129 ScopedVector<IPC::Message> messages;
131 DrainMessages(1, &messages);
132 QueueNextSwapMessage(CloneMessage(first_message_));
133 DrainMessages(2, &messages);
134 ASSERT_EQ(1u, messages.size());
135 ASSERT_EQ(first_message_.routing_id(), messages.front()->routing_id());
136 messages.clear();
138 DrainMessages(2, &messages);
139 ASSERT_TRUE(messages.empty());
142 TEST_F(FrameSwapMessageQueueTest, TestNextSwapMessageSentWithCurrentFrame) {
143 ScopedVector<IPC::Message> messages;
145 DrainMessages(1, &messages);
146 QueueNextSwapMessage(CloneMessage(first_message_));
147 DrainMessages(1, &messages);
148 ASSERT_EQ(1u, messages.size());
149 ASSERT_EQ(first_message_.routing_id(), messages.front()->routing_id());
150 messages.clear();
152 DrainMessages(1, &messages);
153 ASSERT_TRUE(messages.empty());
156 TEST_F(FrameSwapMessageQueueTest,
157 TestDrainsVisualStateMessagesForCorrespondingFrames) {
158 ScopedVector<IPC::Message> messages;
160 QueueVisualStateMessage(1, CloneMessage(first_message_));
161 QueueVisualStateMessage(2, CloneMessage(second_message_));
162 QueueVisualStateMessage(3, CloneMessage(third_message_));
163 DrainMessages(0, &messages);
164 ASSERT_TRUE(messages.empty());
166 DrainMessages(2, &messages);
167 ASSERT_EQ(2u, messages.size());
168 ASSERT_TRUE(HasMessageForId(messages, first_message_.routing_id()));
169 ASSERT_TRUE(HasMessageForId(messages, second_message_.routing_id()));
170 messages.clear();
172 DrainMessages(2, &messages);
173 ASSERT_TRUE(messages.empty());
175 DrainMessages(5, &messages);
176 ASSERT_EQ(1u, messages.size());
177 ASSERT_EQ(third_message_.routing_id(), messages.front()->routing_id());
180 TEST_F(FrameSwapMessageQueueTest,
181 TestQueueNextSwapMessagePreservesFifoOrdering) {
182 ScopedVector<IPC::Message> messages;
184 QueueNextSwapMessage(CloneMessage(first_message_));
185 QueueNextSwapMessage(CloneMessage(second_message_));
186 DrainMessages(1, &messages);
187 ASSERT_EQ(2u, messages.size());
188 ASSERT_EQ(first_message_.routing_id(), messages[0]->routing_id());
189 ASSERT_EQ(second_message_.routing_id(), messages[1]->routing_id());
192 TEST_F(FrameSwapMessageQueueTest,
193 TestQueueVisualStateMessagePreservesFifoOrdering) {
194 ScopedVector<IPC::Message> messages;
196 QueueVisualStateMessage(1, CloneMessage(first_message_));
197 QueueVisualStateMessage(1, CloneMessage(second_message_));
198 DrainMessages(1, &messages);
199 ASSERT_EQ(2u, messages.size());
200 ASSERT_EQ(first_message_.routing_id(), messages[0]->routing_id());
201 ASSERT_EQ(second_message_.routing_id(), messages[1]->routing_id());
204 void FrameSwapMessageQueueTest::TestDidNotSwap(
205 cc::SwapPromise::DidNotSwapReason reason) {
206 ScopedVector<IPC::Message> messages;
208 QueueNextSwapMessage(CloneMessage(first_message_));
209 QueueVisualStateMessage(2, CloneMessage(second_message_));
210 QueueVisualStateMessage(3, CloneMessage(third_message_));
212 queue_->DidNotSwap(2, cc::SwapPromise::COMMIT_NO_UPDATE, &messages);
213 ASSERT_EQ(2u, messages.size());
214 ASSERT_TRUE(HasMessageForId(messages, first_message_.routing_id()));
215 ASSERT_TRUE(HasMessageForId(messages, second_message_.routing_id()));
216 messages.clear();
218 queue_->DidNotSwap(3, cc::SwapPromise::COMMIT_NO_UPDATE, &messages);
219 ASSERT_EQ(1u, messages.size());
220 ASSERT_TRUE(HasMessageForId(messages, third_message_.routing_id()));
221 messages.clear();
224 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapNoUpdate) {
225 TestDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
228 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapSwapFails) {
229 TestDidNotSwap(cc::SwapPromise::SWAP_FAILS);
232 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapCommitFails) {
233 ScopedVector<IPC::Message> messages;
235 QueueNextSwapMessage(CloneMessage(first_message_));
236 QueueVisualStateMessage(2, CloneMessage(second_message_));
237 QueueVisualStateMessage(3, CloneMessage(third_message_));
239 queue_->DidNotSwap(2, cc::SwapPromise::COMMIT_FAILS, &messages);
240 ASSERT_EQ(0u, messages.size());
241 messages.clear();
243 queue_->DidNotSwap(3, cc::SwapPromise::COMMIT_FAILS, &messages);
244 ASSERT_EQ(0u, messages.size());
245 messages.clear();
247 DrainMessages(1, &messages);
248 ASSERT_EQ(1u, messages.size());
249 ASSERT_TRUE(HasMessageForId(messages, first_message_.routing_id()));
252 class NotifiesDeletionMessage : public IPC::Message {
253 public:
254 NotifiesDeletionMessage(bool* deleted, const IPC::Message& other)
255 : IPC::Message(other), deleted_(deleted) {}
256 ~NotifiesDeletionMessage() override { *deleted_ = true; }
258 private:
259 bool* deleted_;
262 TEST_F(FrameSwapMessageQueueTest, TestDeletesNextSwapMessage) {
263 bool message_deleted = false;
264 QueueNextSwapMessage(make_scoped_ptr(
265 new NotifiesDeletionMessage(&message_deleted, first_message_)));
266 queue_ = NULL;
267 ASSERT_TRUE(message_deleted);
270 TEST_F(FrameSwapMessageQueueTest, TestDeletesVisualStateMessage) {
271 bool message_deleted = false;
272 QueueVisualStateMessage(1,
273 make_scoped_ptr(new NotifiesDeletionMessage(
274 &message_deleted, first_message_)));
275 queue_ = NULL;
276 ASSERT_TRUE(message_deleted);
279 TEST_F(FrameSwapMessageQueueTest, TestDeletesQueuedVisualStateMessage) {
280 bool message_deleted = false;
281 QueueVisualStateMessage(1,
282 make_scoped_ptr(new NotifiesDeletionMessage(
283 &message_deleted, first_message_)));
284 queue_->DidSwap(1);
285 queue_ = NULL;
286 ASSERT_TRUE(message_deleted);
289 } // namespace content