101055e8b045829c0213f69afb4f688a97ae2b1b
[platform/framework/web/crosswalk.git] / src / content / renderer / gpu / queue_message_swap_promise_unittest.cc
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/queue_message_swap_promise.h"
6
7 #include <vector>
8
9 #include "base/memory/scoped_vector.h"
10 #include "cc/base/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"
19
20 namespace content {
21
22 class TestRenderWidget : public RenderWidget {
23  public:
24   using RenderWidget::QueueMessageImpl;
25
26  private:
27   ~TestRenderWidget() override {}
28
29   DISALLOW_COPY_AND_ASSIGN(TestRenderWidget);
30 };
31
32 class TestSyncMessageFilter : public IPC::SyncMessageFilter {
33  public:
34   TestSyncMessageFilter() : IPC::SyncMessageFilter(NULL) {}
35
36   bool Send(IPC::Message* message) override {
37     messages_.push_back(message);
38     return true;
39   }
40
41   ScopedVector<IPC::Message>& messages() { return messages_; }
42
43  private:
44   ~TestSyncMessageFilter() override {}
45
46   ScopedVector<IPC::Message> messages_;
47
48   DISALLOW_COPY_AND_ASSIGN(TestSyncMessageFilter);
49 };
50
51 struct QueueMessageData {
52   MessageDeliveryPolicy policy;
53   bool commit_requested;
54   int source_frame_number;
55 };
56
57 class QueueMessageSwapPromiseTest : public testing::Test {
58  public:
59   QueueMessageSwapPromiseTest()
60       : frame_swap_message_queue_(new FrameSwapMessageQueue()),
61         sync_message_filter_(new TestSyncMessageFilter()) {}
62
63   ~QueueMessageSwapPromiseTest() override {}
64
65   scoped_ptr<cc::SwapPromise> QueueMessageImpl(IPC::Message* msg,
66                                                MessageDeliveryPolicy policy,
67                                                bool commit_requested,
68                                                int source_frame_number) {
69     return TestRenderWidget::QueueMessageImpl(msg,
70                                               policy,
71                                               frame_swap_message_queue_.get(),
72                                               sync_message_filter_,
73                                               commit_requested,
74                                               source_frame_number).Pass();
75   }
76
77   ScopedVector<IPC::Message>& DirectSendMessages() {
78     return sync_message_filter_->messages();
79   }
80
81   ScopedVector<IPC::Message>& NextSwapMessages() {
82     next_swap_messages_.clear();
83     scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope =
84         frame_swap_message_queue_->AcquireSendMessageScope();
85     frame_swap_message_queue_->DrainMessages(&next_swap_messages_);
86     return next_swap_messages_;
87   }
88
89   bool ContainsMessage(const ScopedVector<IPC::Message>& messages,
90                        const IPC::Message& message) {
91     if (messages.empty())
92       return false;
93     for (ScopedVector<IPC::Message>::const_iterator i = messages.begin();
94          i != messages.end();
95          ++i) {
96       if ((*i)->type() == message.type())
97         return true;
98     }
99     return false;
100   }
101
102   bool NextSwapHasMessage(const IPC::Message& message) {
103     return ContainsMessage(NextSwapMessages(), message);
104   }
105
106   void QueueMessages(QueueMessageData data[], size_t count) {
107     for (size_t i = 0; i < count; ++i) {
108       messages_.push_back(
109           IPC::Message(0, i + 1, IPC::Message::PRIORITY_NORMAL));
110       promises_.push_back(
111           QueueMessageImpl(new IPC::Message(messages_[i]),
112                            data[i].policy,
113                            data[i].commit_requested,
114                            data[i].source_frame_number).release());
115     }
116   }
117
118   void CleanupPromises() {
119     for (ScopedVector<cc::SwapPromise>::iterator i = promises_.begin();
120          i != promises_.end();
121          ++i) {
122       if (*i)
123         (*i)->DidSwap(NULL);
124     }
125   }
126
127  protected:
128   void VisualStateSwapPromiseDidNotSwap(
129       cc::SwapPromise::DidNotSwapReason reason);
130
131   scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue_;
132   scoped_refptr<TestSyncMessageFilter> sync_message_filter_;
133   std::vector<IPC::Message> messages_;
134   ScopedVector<cc::SwapPromise> promises_;
135
136  private:
137   ScopedVector<IPC::Message> next_swap_messages_;
138
139   DISALLOW_COPY_AND_ASSIGN(QueueMessageSwapPromiseTest);
140 };
141
142 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySchedulesMessageForNextSwap) {
143   QueueMessageData data[] = {
144     /* { policy, commit_requested, source_frame_number } */
145     {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, false, 1},
146   };
147   QueueMessages(data, arraysize(data));
148
149   ASSERT_TRUE(promises_[0]);
150   EXPECT_TRUE(DirectSendMessages().empty());
151   EXPECT_FALSE(frame_swap_message_queue_->Empty());
152   EXPECT_TRUE(NextSwapHasMessage(messages_[0]));
153
154   CleanupPromises();
155 }
156
157 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicyNeedsAtMostOnePromise) {
158   QueueMessageData data[] = {
159     /* { policy, commit_requested, source_frame_number } */
160     {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, false, 1},
161     {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, false, 1},
162   };
163   QueueMessages(data, arraysize(data));
164
165   ASSERT_TRUE(promises_[0]);
166   ASSERT_FALSE(promises_[1]);
167
168   CleanupPromises();
169 }
170
171 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnNoUpdate) {
172   QueueMessageData data[] = {
173     /* { policy, commit_requested, source_frame_number } */
174     {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, false, 1},
175   };
176   QueueMessages(data, arraysize(data));
177
178   promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
179   EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
180   EXPECT_TRUE(NextSwapMessages().empty());
181   EXPECT_TRUE(frame_swap_message_queue_->Empty());
182 }
183
184 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySendsMessageOnSwapFails) {
185   QueueMessageData data[] = {
186     /* { policy, commit_requested, source_frame_number } */
187     {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, false, 1},
188   };
189   QueueMessages(data, arraysize(data));
190
191   promises_[0]->DidNotSwap(cc::SwapPromise::SWAP_FAILS);
192   EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
193   EXPECT_TRUE(NextSwapMessages().empty());
194   EXPECT_TRUE(frame_swap_message_queue_->Empty());
195 }
196
197 TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicyRetainsMessageOnCommitFails) {
198   QueueMessageData data[] = {
199     /* { policy, commit_requested, source_frame_number } */
200     {MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP, false, 1},
201   };
202   QueueMessages(data, arraysize(data));
203
204   promises_[0]->DidNotSwap(cc::SwapPromise::COMMIT_FAILS);
205   EXPECT_TRUE(DirectSendMessages().empty());
206   EXPECT_FALSE(frame_swap_message_queue_->Empty());
207   EXPECT_TRUE(NextSwapHasMessage(messages_[0]));
208 }
209
210 TEST_F(QueueMessageSwapPromiseTest, VisualStateDirectSend) {
211   QueueMessageData data[] = {
212     /* { policy, commit_requested, source_frame_number } */
213     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, false, 1},
214   };
215   QueueMessages(data, arraysize(data));
216
217   ASSERT_FALSE(promises_[0]);
218   EXPECT_FALSE(DirectSendMessages().empty());
219   EXPECT_TRUE(frame_swap_message_queue_->Empty());
220   EXPECT_TRUE(NextSwapMessages().empty());
221 }
222
223 TEST_F(QueueMessageSwapPromiseTest,
224        VisualStateQueuesMessageWhenCommitRequested) {
225   QueueMessageData data[] = {
226     /* { policy, commit_requested, source_frame_number } */
227     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, true, 1},
228   };
229   QueueMessages(data, arraysize(data));
230
231   ASSERT_TRUE(promises_[0]);
232   EXPECT_TRUE(DirectSendMessages().empty());
233   EXPECT_FALSE(frame_swap_message_queue_->Empty());
234   EXPECT_TRUE(NextSwapMessages().empty());
235
236   CleanupPromises();
237 }
238
239 TEST_F(QueueMessageSwapPromiseTest,
240        VisualStateQueuesMessageWhenOtherMessageAlreadyQueued) {
241   QueueMessageData data[] = {
242     /* { policy, commit_requested, source_frame_number } */
243     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, true, 1},
244     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, true, 1},
245   };
246   QueueMessages(data, arraysize(data));
247
248   EXPECT_TRUE(DirectSendMessages().empty());
249   EXPECT_FALSE(frame_swap_message_queue_->Empty());
250   EXPECT_FALSE(NextSwapHasMessage(messages_[1]));
251
252   CleanupPromises();
253 }
254
255 TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidSwap) {
256   QueueMessageData data[] = {
257     /* { policy, commit_requested, source_frame_number } */
258     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, true, 1},
259     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, false, 1},
260     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, false, 2},
261   };
262   QueueMessages(data, arraysize(data));
263
264   promises_[0]->DidSwap(NULL);
265   ASSERT_FALSE(promises_[1]);
266   ScopedVector<IPC::Message> messages;
267   messages.swap(NextSwapMessages());
268   EXPECT_EQ(2u, messages.size());
269   EXPECT_TRUE(ContainsMessage(messages, messages_[0]));
270   EXPECT_TRUE(ContainsMessage(messages, messages_[1]));
271   EXPECT_FALSE(ContainsMessage(messages, messages_[2]));
272
273   promises_[2]->DidSwap(NULL);
274   messages.swap(NextSwapMessages());
275   EXPECT_EQ(1u, messages.size());
276   EXPECT_TRUE(ContainsMessage(messages, messages_[2]));
277
278   EXPECT_TRUE(DirectSendMessages().empty());
279   EXPECT_TRUE(NextSwapMessages().empty());
280   EXPECT_TRUE(frame_swap_message_queue_->Empty());
281 }
282
283 void QueueMessageSwapPromiseTest::VisualStateSwapPromiseDidNotSwap(
284     cc::SwapPromise::DidNotSwapReason reason) {
285   QueueMessageData data[] = {
286     /* { policy, commit_requested, source_frame_number } */
287     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, true, 1},
288     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, false, 1},
289     {MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE, false, 2},
290   };
291   QueueMessages(data, arraysize(data));
292
293   promises_[0]->DidNotSwap(reason);
294   ASSERT_FALSE(promises_[1]);
295   EXPECT_TRUE(NextSwapMessages().empty());
296   EXPECT_EQ(2u, DirectSendMessages().size());
297   EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[0]));
298   EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[1]));
299   EXPECT_FALSE(ContainsMessage(DirectSendMessages(), messages_[2]));
300
301   promises_[2]->DidNotSwap(reason);
302   EXPECT_TRUE(NextSwapMessages().empty());
303   EXPECT_TRUE(ContainsMessage(DirectSendMessages(), messages_[2]));
304
305   EXPECT_TRUE(NextSwapMessages().empty());
306   EXPECT_TRUE(frame_swap_message_queue_->Empty());
307 }
308
309 TEST_F(QueueMessageSwapPromiseTest, VisalStateSwapPromiseDidNotSwapNoUpdate) {
310   VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_NO_UPDATE);
311 }
312
313 TEST_F(QueueMessageSwapPromiseTest,
314        VisalStateSwapPromiseDidNotSwapCommitFails) {
315   VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::COMMIT_FAILS);
316 }
317
318 TEST_F(QueueMessageSwapPromiseTest, VisalStateSwapPromiseDidNotSwapSwapFails) {
319   VisualStateSwapPromiseDidNotSwap(cc::SwapPromise::SWAP_FAILS);
320 }
321
322 }  // namespace content