OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/renderer/gpu/frame_swap_message_queue.h" | |
6 #include "ipc/ipc_message.h" | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 | |
9 namespace content { | |
10 | |
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()) {} | |
18 | |
19 protected: | |
20 void QueueNextSwapMessage(scoped_ptr<IPC::Message> msg) { | |
21 queue_->QueueMessageForFrame( | |
22 MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 0, msg.Pass(), NULL); | |
23 } | |
24 | |
25 void QueueNextSwapMessage(scoped_ptr<IPC::Message> msg, bool* first) { | |
26 queue_->QueueMessageForFrame( | |
27 MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, 0, msg.Pass(), first); | |
28 } | |
29 | |
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); | |
36 } | |
37 | |
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); | |
45 } | |
46 | |
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); | |
54 } | |
55 | |
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; | |
63 } | |
64 return false; | |
65 } | |
66 | |
67 scoped_ptr<IPC::Message> CloneMessage(const IPC::Message& other) { | |
68 return make_scoped_ptr(new IPC::Message(other)).Pass(); | |
69 } | |
70 | |
71 void TestDidNotSwap(cc::SwapPromise::DidNotSwapReason reason); | |
72 | |
73 IPC::Message first_message_; | |
74 IPC::Message second_message_; | |
75 IPC::Message third_message_; | |
76 scoped_refptr<FrameSwapMessageQueue> queue_; | |
77 }; | |
78 | |
79 TEST_F(FrameSwapMessageQueueTest, TestEmptyQueueDrain) { | |
80 ScopedVector<IPC::Message> messages; | |
81 | |
82 DrainMessages(0, &messages); | |
83 ASSERT_TRUE(messages.empty()); | |
84 } | |
85 | |
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()); | |
97 } | |
98 | |
99 TEST_F(FrameSwapMessageQueueTest, TestQueueMessageFirst) { | |
100 ScopedVector<IPC::Message> messages; | |
101 bool visual_state_first = false; | |
102 bool next_swap_first = false; | |
103 | |
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); | |
114 | |
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); | |
121 | |
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); | |
126 } | |
127 | |
128 TEST_F(FrameSwapMessageQueueTest, TestNextSwapMessageSentWithNextFrame) { | |
129 ScopedVector<IPC::Message> messages; | |
130 | |
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(); | |
137 | |
138 DrainMessages(2, &messages); | |
139 ASSERT_TRUE(messages.empty()); | |
140 } | |
141 | |
142 TEST_F(FrameSwapMessageQueueTest, TestNextSwapMessageSentWithCurrentFrame) { | |
143 ScopedVector<IPC::Message> messages; | |
144 | |
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(); | |
151 | |
152 DrainMessages(1, &messages); | |
153 ASSERT_TRUE(messages.empty()); | |
154 } | |
155 | |
156 TEST_F(FrameSwapMessageQueueTest, | |
157 TestDrainsVisualStateMessagesForCorrespondingFrames) { | |
158 ScopedVector<IPC::Message> messages; | |
159 | |
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()); | |
165 | |
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(); | |
171 | |
172 DrainMessages(2, &messages); | |
173 ASSERT_TRUE(messages.empty()); | |
174 | |
175 DrainMessages(5, &messages); | |
176 ASSERT_EQ(1u, messages.size()); | |
177 ASSERT_EQ(third_message_.routing_id(), messages.front()->routing_id()); | |
178 } | |
179 | |
180 TEST_F(FrameSwapMessageQueueTest, | |
181 TestQueueNextSwapMessagePreservesFifoOrdering) { | |
182 ScopedVector<IPC::Message> messages; | |
183 | |
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()); | |
190 } | |
191 | |
192 TEST_F(FrameSwapMessageQueueTest, | |
193 TestQueueVisualStateMessagePreservesFifoOrdering) { | |
194 ScopedVector<IPC::Message> messages; | |
195 | |
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()); | |
202 } | |
203 | |
204 void FrameSwapMessageQueueTest::TestDidNotSwap( | |
205 cc::SwapPromise::DidNotSwapReason reason) { | |
206 ScopedVector<IPC::Message> messages; | |
207 | |
208 QueueNextSwapMessage(CloneMessage(first_message_)); | |
209 QueueVisualStateMessage(2, CloneMessage(second_message_)); | |
210 QueueVisualStateMessage(3, CloneMessage(third_message_)); | |
211 | |
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(); | |
217 | |
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(); | |
222 } | |
223 | |
224 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapNoUpdate) { | |
225 TestDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE); | |
226 } | |
227 | |
228 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapSwapFails) { | |
229 TestDidNotSwap(cc::SwapPromise::SWAP_FAILS); | |
230 } | |
231 | |
232 TEST_F(FrameSwapMessageQueueTest, TestDidNotSwapCommitFails) { | |
233 ScopedVector<IPC::Message> messages; | |
234 | |
235 QueueNextSwapMessage(CloneMessage(first_message_)); | |
236 QueueVisualStateMessage(2, CloneMessage(second_message_)); | |
237 QueueVisualStateMessage(3, CloneMessage(third_message_)); | |
238 | |
239 queue_->DidNotSwap(2, cc::SwapPromise::COMMIT_FAILS, &messages); | |
240 ASSERT_EQ(0u, messages.size()); | |
241 messages.clear(); | |
242 | |
243 queue_->DidNotSwap(3, cc::SwapPromise::COMMIT_FAILS, &messages); | |
244 ASSERT_EQ(0u, messages.size()); | |
245 messages.clear(); | |
246 | |
247 DrainMessages(1, &messages); | |
248 ASSERT_EQ(1u, messages.size()); | |
249 ASSERT_TRUE(HasMessageForId(messages, first_message_.routing_id())); | |
250 } | |
251 | |
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; } | |
257 | |
258 private: | |
259 bool* deleted_; | |
260 }; | |
261 | |
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); | |
268 } | |
269 | |
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); | |
277 } | |
278 | |
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); | |
287 } | |
288 | |
289 } // namespace content | |
OLD | NEW |