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 | |
7 #include <limits> | |
8 | |
9 #include "base/containers/hash_tables.h" | |
10 #include "base/logging.h" | |
11 #include "base/stl_util.h" | |
12 #include "ipc/ipc_message.h" | |
13 | |
14 using std::vector; | |
15 | |
16 namespace content { | |
17 | |
18 class FrameSwapMessageSubQueue { | |
19 public: | |
20 FrameSwapMessageSubQueue() {} | |
21 virtual ~FrameSwapMessageSubQueue() {} | |
22 virtual bool Empty() const = 0; | |
23 virtual void QueueMessage(int source_frame_number, | |
24 scoped_ptr<IPC::Message> msg, | |
25 bool* is_first) = 0; | |
26 virtual void DrainMessages(int source_frame_number, | |
27 ScopedVector<IPC::Message>* messages) = 0; | |
28 | |
29 private: | |
30 DISALLOW_COPY_AND_ASSIGN(FrameSwapMessageSubQueue); | |
31 }; | |
32 | |
33 namespace { | |
34 | |
35 // Queue specific to MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE. | |
36 class SendMessageScopeImpl : public FrameSwapMessageQueue::SendMessageScope { | |
37 public: | |
38 SendMessageScopeImpl(base::Lock* lock) : auto_lock_(*lock) {} | |
39 ~SendMessageScopeImpl() override {} | |
40 | |
41 private: | |
42 base::AutoLock auto_lock_; | |
43 }; | |
44 | |
45 class VisualStateQueue : public FrameSwapMessageSubQueue { | |
46 public: | |
47 VisualStateQueue() {} | |
48 | |
49 ~VisualStateQueue() override { | |
50 for (VisualStateQueueMap::iterator i = queue_.begin(); i != queue_.end(); | |
51 i++) { | |
52 STLDeleteElements(&i->second); | |
53 } | |
54 } | |
55 | |
56 bool Empty() const override { return queue_.empty(); } | |
57 | |
58 void QueueMessage(int source_frame_number, | |
59 scoped_ptr<IPC::Message> msg, | |
60 bool* is_first) override { | |
61 if (is_first) | |
62 *is_first = (queue_.count(source_frame_number) == 0); | |
63 | |
64 queue_[source_frame_number].push_back(msg.release()); | |
65 } | |
66 | |
67 void DrainMessages(int source_frame_number, | |
68 ScopedVector<IPC::Message>* messages) override { | |
69 VisualStateQueueMap::iterator end = queue_.upper_bound(source_frame_number); | |
70 for (VisualStateQueueMap::iterator i = queue_.begin(); i != end; i++) { | |
71 DCHECK(i->first <= source_frame_number); | |
72 messages->insert(messages->end(), i->second.begin(), i->second.end()); | |
73 i->second.clear(); | |
74 } | |
75 queue_.erase(queue_.begin(), end); | |
76 } | |
77 | |
78 private: | |
79 typedef std::map<int, std::vector<IPC::Message*> > VisualStateQueueMap; | |
80 VisualStateQueueMap queue_; | |
81 | |
82 DISALLOW_COPY_AND_ASSIGN(VisualStateQueue); | |
83 }; | |
84 | |
85 // Queue specific to MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP. | |
86 class SwapQueue : public FrameSwapMessageSubQueue { | |
87 public: | |
88 SwapQueue() {} | |
89 bool Empty() const override { return queue_.empty(); } | |
90 | |
91 void QueueMessage(int source_frame_number, | |
92 scoped_ptr<IPC::Message> msg, | |
93 bool* is_first) override { | |
94 if (is_first) | |
95 *is_first = Empty(); | |
96 queue_.push_back(msg.release()); | |
97 } | |
98 | |
99 void DrainMessages(int source_frame_number, | |
100 ScopedVector<IPC::Message>* messages) override { | |
101 messages->insert(messages->end(), queue_.begin(), queue_.end()); | |
102 queue_.weak_clear(); | |
103 } | |
104 | |
105 private: | |
106 ScopedVector<IPC::Message> queue_; | |
107 | |
108 DISALLOW_COPY_AND_ASSIGN(SwapQueue); | |
109 }; | |
110 | |
111 } // namespace | |
112 | |
113 FrameSwapMessageQueue::FrameSwapMessageQueue() | |
114 : visual_state_queue_(new VisualStateQueue()), | |
115 swap_queue_(new SwapQueue()) { | |
116 } | |
117 | |
118 FrameSwapMessageQueue::~FrameSwapMessageQueue() { | |
119 } | |
120 | |
121 bool FrameSwapMessageQueue::Empty() const { | |
122 base::AutoLock lock(lock_); | |
123 return next_drain_messages_.empty() && visual_state_queue_->Empty() && | |
124 swap_queue_->Empty(); | |
125 } | |
126 | |
127 FrameSwapMessageSubQueue* FrameSwapMessageQueue::GetSubQueue( | |
128 MessageDeliveryPolicy policy) { | |
129 switch (policy) { | |
130 case MESSAGE_DELIVERY_POLICY_WITH_NEXT_SWAP: | |
131 return swap_queue_.get(); | |
132 break; | |
133 case MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE: | |
134 return visual_state_queue_.get(); | |
135 break; | |
136 } | |
137 NOTREACHED(); | |
138 return NULL; | |
139 } | |
140 | |
141 void FrameSwapMessageQueue::QueueMessageForFrame(MessageDeliveryPolicy policy, | |
142 int source_frame_number, | |
143 scoped_ptr<IPC::Message> msg, | |
144 bool* is_first) { | |
145 base::AutoLock lock(lock_); | |
146 GetSubQueue(policy)->QueueMessage(source_frame_number, msg.Pass(), is_first); | |
147 } | |
148 | |
149 void FrameSwapMessageQueue::DidSwap(int source_frame_number) { | |
150 base::AutoLock lock(lock_); | |
151 | |
152 visual_state_queue_->DrainMessages(source_frame_number, | |
153 &next_drain_messages_); | |
154 } | |
155 | |
156 void FrameSwapMessageQueue::DidNotSwap(int source_frame_number, | |
157 cc::SwapPromise::DidNotSwapReason reason, | |
158 ScopedVector<IPC::Message>* messages) { | |
159 base::AutoLock lock(lock_); | |
160 switch (reason) { | |
161 case cc::SwapPromise::SWAP_FAILS: | |
162 case cc::SwapPromise::COMMIT_NO_UPDATE: | |
163 swap_queue_->DrainMessages(source_frame_number, messages); | |
164 visual_state_queue_->DrainMessages(source_frame_number, messages); | |
165 break; | |
166 case cc::SwapPromise::COMMIT_FAILS: | |
167 // Do not queue any responses here. | |
168 // If COMMIT_FAILS the renderer is shutting down, which will | |
169 // result in the RenderFrameHostImpl destructor firing the | |
170 // remaining response callbacks itself. | |
171 break; | |
172 default: | |
173 NOTREACHED(); | |
174 } | |
175 } | |
176 | |
177 void FrameSwapMessageQueue::DrainMessages( | |
178 ScopedVector<IPC::Message>* messages) { | |
179 lock_.AssertAcquired(); | |
180 | |
181 swap_queue_->DrainMessages(0, messages); | |
182 messages->insert(messages->end(), | |
183 next_drain_messages_.begin(), | |
184 next_drain_messages_.end()); | |
185 next_drain_messages_.weak_clear(); | |
186 } | |
187 | |
188 scoped_ptr<FrameSwapMessageQueue::SendMessageScope> | |
189 FrameSwapMessageQueue::AcquireSendMessageScope() { | |
190 return make_scoped_ptr(new SendMessageScopeImpl(&lock_)); | |
191 } | |
192 | |
193 // static | |
194 void FrameSwapMessageQueue::TransferMessages(ScopedVector<IPC::Message>& source, | |
195 vector<IPC::Message>* dest) { | |
196 for (vector<IPC::Message*>::iterator i = source.begin(); i != source.end(); | |
197 ++i) { | |
198 IPC::Message* m(*i); | |
199 dest->push_back(*m); | |
200 delete m; | |
201 } | |
202 source.weak_clear(); | |
203 } | |
204 | |
205 } // namespace content | |
OLD | NEW |