OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "image_pipe_endpoint.h" | |
6 | |
7 namespace image_pipe { | |
8 | |
9 void ImagePipeEndpoint::ImagePipeLogError(const char* entity, | |
10 const char* message, | |
11 uint32_t id) { | |
12 MOJO_LOG(ERROR) << "ImagePipe " << entity << " Error on Image ID " << id | |
13 << ": " << message; | |
14 } | |
15 | |
16 void ImagePipeEndpoint::ProducerFatalError(const char* message, uint32_t id) { | |
17 if (is_checked_) { | |
18 ImagePipeLogError("Producer", message, id); | |
19 if (is_producer_) { | |
20 MOJO_CHECK(false); | |
21 } else { | |
22 fatal_error_handler_(); | |
23 } | |
24 } | |
25 } | |
26 | |
27 void ImagePipeEndpoint::ConsumerFatalError(const char* message, uint32_t id) { | |
28 ImagePipeLogError("Consumer", message, id); | |
29 if (is_producer_) { | |
30 fatal_error_handler_(); | |
31 } else { | |
32 if (is_checked_) { | |
33 MOJO_CHECK(false); | |
34 } else { | |
35 fatal_error_handler_(); | |
36 } | |
37 } | |
38 } | |
39 | |
40 ImagePipeEndpoint::ImagePipeEndpoint(bool is_producer, | |
41 std::function<void()> fatal_error_handler) | |
42 : is_producer_(is_producer), | |
43 is_checked_(true), | |
44 fatal_error_handler_(fatal_error_handler) {} | |
45 | |
46 ImagePipeEndpoint::~ImagePipeEndpoint() {} | |
47 | |
48 void ImagePipeEndpoint::ProducerAdd(uint32_t id) { | |
49 if (IsInPool(id)) { | |
50 ProducerFatalError("Attempting to add an image that is already in the pool", | |
51 id); | |
52 } else { | |
53 image_pool_ids_.push_back(id); | |
54 if (is_producer_) { | |
55 producer_acquirable_ids_.push_back(id); | |
56 } else { | |
57 producer_owned_ids_.push_back(id); | |
58 } | |
59 } | |
60 } | |
61 | |
62 bool ImagePipeEndpoint::AcquireNextImage(uint32_t& id_out) { | |
63 auto acquirable_ids_ = | |
64 is_producer_ ? &producer_acquirable_ids_ : &consumer_acquirable_ids_; | |
65 auto owned_ids_ = is_producer_ ? &producer_owned_ids_ : &consumer_owned_ids_; | |
66 | |
67 if (acquirable_ids_->empty()) { | |
68 return false; | |
69 } | |
70 | |
71 int id = acquirable_ids_->front(); | |
72 acquirable_ids_->pop_front(); | |
73 owned_ids_->push_back(id); | |
74 id_out = id; | |
75 return true; | |
76 } | |
77 | |
78 void ImagePipeEndpoint::ProducerRemove(uint32_t id) { | |
79 if (IsInPool(id)) { | |
80 if ((IsConsumerOwned(id) || IsConsumerAcquirable(id))) { | |
81 ProducerFatalError( | |
82 "Attempting to remove an image that has been presented " | |
83 "but has not been released by the consumer", | |
84 id); | |
85 } else { | |
86 auto image_pool_ids_iter = | |
87 std::find(image_pool_ids_.begin(), image_pool_ids_.end(), id); | |
88 image_pool_ids_.erase(image_pool_ids_iter); | |
jamesr
2016/02/18 20:40:59
you should check that |image_pool_ids_iter| is not
Forrest Reiling
2016/02/25 00:35:14
Thats enforced by IsInPool(id) in the outer if sta
| |
89 MOJO_DCHECK(!is_checked_ || IsProducerOwned(id) || | |
90 IsProducerAcquirable(id)); | |
91 if (IsProducerOwned(id)) { | |
92 MOJO_DCHECK(!is_checked_ || !IsProducerAcquirable(id)); | |
93 auto producer_owned_ids_iter = std::find(producer_owned_ids_.begin(), | |
94 producer_owned_ids_.end(), id); | |
95 producer_owned_ids_.erase(producer_owned_ids_iter); | |
96 MOJO_DCHECK(!is_checked_ || !IsProducerOwned(id)); | |
97 } else { | |
98 MOJO_DCHECK(!is_checked_ || IsProducerAcquirable(id)); | |
99 auto producer_acquirable_ids_iter = | |
100 std::find(producer_acquirable_ids_.begin(), | |
101 producer_acquirable_ids_.end(), id); | |
102 producer_acquirable_ids_.erase(producer_acquirable_ids_iter); | |
103 MOJO_DCHECK(!is_checked_ || !IsProducerAcquirable(id)); | |
104 } | |
105 } | |
106 } else { | |
107 ProducerFatalError( | |
108 "Attempting to remove an image that is not in the image pool", id); | |
109 } | |
110 } | |
111 | |
112 // private method to ensure that produce/release logic is symmetric between | |
jamesr
2016/02/18 20:40:58
start all comments with uppercase letters and end
Forrest Reiling
2016/02/25 00:35:14
Done.
| |
113 // producer and consumer since they represent the same action from a state | |
114 // tracking perspective | |
115 void ImagePipeEndpoint::ReleaseInternal(uint32_t id, | |
116 bool released_by_producer) { | |
117 auto releaser_owned_ids = | |
jamesr
2016/02/18 20:40:59
i can't figure out what type |releaser_owned_ids|
Forrest Reiling
2016/02/25 00:35:14
I like the reference syntax, Im definitely on boar
| |
118 released_by_producer ? &producer_owned_ids_ : &consumer_owned_ids_; | |
119 auto releasee_owned_ids = | |
120 !released_by_producer ? &producer_owned_ids_ : &consumer_owned_ids_; | |
121 | |
122 auto releasee_acquirable_ids = !released_by_producer | |
123 ? &producer_acquirable_ids_ | |
124 : &consumer_acquirable_ids_; | |
125 | |
126 auto IsReleaserOwned = released_by_producer | |
127 ? &ImagePipeEndpoint::IsProducerOwned | |
128 : &ImagePipeEndpoint::IsConsumerOwned; | |
129 | |
130 MOJO_DCHECK(!is_checked_ || (this->*IsReleaserOwned)(id)); | |
131 auto releaser_owned_ids_iter = | |
132 std::find(releaser_owned_ids->begin(), releaser_owned_ids->end(), id); | |
133 releaser_owned_ids->erase(releaser_owned_ids_iter); | |
134 MOJO_DCHECK(!is_checked_ || !(this->*IsReleaserOwned)(id)); | |
135 | |
136 // if the release action is coming from our side of the pipe, we wont see the | |
137 // acquire events, so we just pretend the other side immediately aquires | |
138 // everything to simplify state tracking | |
139 if (released_by_producer == is_producer_) { | |
140 releasee_owned_ids->push_back(id); | |
141 } else { | |
142 releasee_acquirable_ids->push_back(id); | |
143 } | |
144 } | |
145 | |
146 void ImagePipeEndpoint::ProducerPresent( | |
147 uint32_t id, | |
148 mojo::gfx::ImagePipe::PresentImageCallback callback) { | |
149 if (IsProducerOwned(id)) { | |
150 MOJO_DCHECK(!is_checked_ || (IsInPool(id) && !IsConsumerOwned(id) && | |
151 !IsConsumerAcquirable(id))); | |
152 ReleaseInternal(id, true); | |
153 present_callback_map_[id] = callback; | |
154 } else if (!IsInPool(id)) { | |
155 ProducerFatalError( | |
156 "Attempting to present an image that is not in the image pool", id); | |
157 } else if (IsProducerAcquirable(id)) { | |
158 ProducerFatalError( | |
159 "Attempting to present an image that has not been acquired", id); | |
160 } else if (IsConsumerOwned(id) || IsConsumerAcquirable(id)) { | |
161 ProducerFatalError( | |
162 "Attempting to present an image that has already been presented", id); | |
163 } | |
164 } | |
165 | |
166 void ImagePipeEndpoint::ConsumerRelease(uint32_t id, | |
167 mojo::gfx::PresentationStatus status) { | |
168 if (IsConsumerOwned(id)) { | |
169 MOJO_DCHECK(!is_checked_ || (IsInPool(id) && !IsProducerOwned(id) && | |
170 !IsProducerAcquirable(id))); | |
171 ReleaseInternal(id, false); | |
172 CallPresentCallback(id, status); | |
173 } else if (!IsInPool(id)) { | |
174 ConsumerFatalError( | |
175 "Attempting to release an image that is not in the image pool", id); | |
176 } else if (IsConsumerAcquirable(id)) { | |
177 ConsumerFatalError( | |
178 "Attempting to release an image that has not been acquired", id); | |
179 } else if (IsProducerOwned(id) || IsProducerAcquirable(id)) { | |
180 ConsumerFatalError( | |
181 "Attempting to release an image that has not been presented", id); | |
182 } | |
183 } | |
184 | |
185 void ImagePipeEndpoint::ProducerFlush() { | |
186 if (!is_producer_) { | |
187 for (auto id : consumer_acquirable_ids_) { | |
188 MOJO_DCHECK(!is_checked_ || (IsInPool(id) && !IsConsumerOwned(id) && | |
189 !IsProducerOwned(id))); | |
190 CallPresentCallback(id, | |
191 mojo::gfx::PresentationStatus::NOT_PRESENTED_FLUSHED); | |
192 } | |
193 consumer_acquirable_ids_.clear(); | |
194 } | |
195 } | |
196 | |
197 void ImagePipeEndpoint::CallPresentCallback( | |
198 uint32_t id, | |
199 mojo::gfx::PresentationStatus status) { | |
200 auto present_callback_iter = present_callback_map_.find(id); | |
201 MOJO_DCHECK(present_callback_iter != present_callback_map_.end()); | |
202 auto present_callback = present_callback_iter->second; | |
203 present_callback_map_.erase(present_callback_iter); | |
204 present_callback.Run(id, status); | |
205 } | |
206 | |
207 bool ImagePipeEndpoint::IsInPool(uint32_t id) const { | |
208 auto container = image_pool_ids_; | |
jamesr
2016/02/18 20:40:58
did you mean to make a copy of the entire vector h
Forrest Reiling
2016/02/25 00:35:14
No this is just me C++'ing myself in the foot. So
| |
209 return std::find(container.begin(), container.end(), id) != container.end(); | |
210 } | |
211 | |
212 bool ImagePipeEndpoint::IsConsumerOwned(uint32_t id) const { | |
213 auto container = consumer_owned_ids_; | |
214 return std::find(container.begin(), container.end(), id) != container.end(); | |
215 } | |
216 | |
217 bool ImagePipeEndpoint::IsConsumerAcquirable(uint32_t id) const { | |
218 auto container = consumer_acquirable_ids_; | |
219 return std::find(container.begin(), container.end(), id) != container.end(); | |
220 } | |
221 | |
222 bool ImagePipeEndpoint::IsProducerOwned(uint32_t id) const { | |
223 auto container = producer_owned_ids_; | |
224 return std::find(container.begin(), container.end(), id) != container.end(); | |
225 } | |
226 | |
227 bool ImagePipeEndpoint::IsProducerAcquirable(uint32_t id) const { | |
228 auto container = producer_acquirable_ids_; | |
229 return std::find(container.begin(), container.end(), id) != container.end(); | |
230 } | |
231 | |
232 void ImagePipeEndpoint::DisableFatalErrors() { | |
233 is_checked_ = false; | |
234 } | |
235 } | |
jamesr
2016/02/18 20:40:58
newline before bracket, add a comment indicating w
Forrest Reiling
2016/02/25 00:35:14
Done.
| |
OLD | NEW |