OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/client/rectangle_update_decoder.h" | 5 #include "remoting/client/rectangle_update_decoder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 if (!message_loop_->BelongsToCurrentThread()) { | 133 if (!message_loop_->BelongsToCurrentThread()) { |
134 message_loop_->PostTask( | 134 message_loop_->PostTask( |
135 FROM_HERE, base::Bind(&RectangleUpdateDecoder::SetOutputSize, | 135 FROM_HERE, base::Bind(&RectangleUpdateDecoder::SetOutputSize, |
136 this, size)); | 136 this, size)); |
137 return; | 137 return; |
138 } | 138 } |
139 | 139 |
140 // TODO(wez): Refresh the frame only if the ratio has changed. | 140 // TODO(wez): Refresh the frame only if the ratio has changed. |
141 if (frame_) { | 141 if (frame_) { |
142 SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height()); | 142 SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height()); |
143 refresh_region_.op(frame_rect, SkRegion::kUnion_Op); | 143 refresh_rects_.push_back(frame_rect); |
144 } | 144 } |
145 | 145 |
146 // TODO(hclam): If the scale ratio has changed we should reallocate a | 146 // TODO(hclam): If the scale ratio has changed we should reallocate a |
147 // VideoFrame of different size. However if the scale ratio is always | 147 // VideoFrame of different size. However if the scale ratio is always |
148 // smaller than 1.0 we can use the same video frame. | 148 // smaller than 1.0 we can use the same video frame. |
149 if (decoder_.get()) { | 149 if (decoder_.get()) { |
150 decoder_->SetOutputSize(size); | 150 decoder_->SetOutputSize(size); |
151 RefreshFullFrame(); | 151 RefreshFullFrame(); |
152 } | 152 } |
153 } | 153 } |
154 | 154 |
155 void RectangleUpdateDecoder::UpdateClipRect(const SkIRect& new_clip_rect) { | 155 void RectangleUpdateDecoder::UpdateClipRect(const SkIRect& new_clip_rect) { |
156 if (!message_loop_->BelongsToCurrentThread()) { | 156 if (!message_loop_->BelongsToCurrentThread()) { |
157 message_loop_->PostTask( | 157 message_loop_->PostTask( |
158 FROM_HERE, base::Bind(&RectangleUpdateDecoder::UpdateClipRect, | 158 FROM_HERE, base::Bind(&RectangleUpdateDecoder::UpdateClipRect, |
159 this, new_clip_rect)); | 159 this, new_clip_rect)); |
160 return; | 160 return; |
161 } | 161 } |
162 | 162 |
163 if (new_clip_rect == clip_rect_ || !decoder_.get()) | 163 if (new_clip_rect == clip_rect_ || !decoder_.get()) |
164 return; | 164 return; |
165 | 165 |
166 // TODO(wez): Only refresh newly-exposed portions of the frame. | 166 // TODO(wez): Only refresh newly-exposed portions of the frame. |
167 if (frame_) { | 167 if (frame_) { |
168 SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height()); | 168 SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height()); |
169 refresh_region_.op(frame_rect, SkRegion::kUnion_Op); | 169 refresh_rects_.push_back(frame_rect); |
170 } | 170 } |
171 | 171 |
172 clip_rect_ = new_clip_rect; | 172 clip_rect_ = new_clip_rect; |
173 decoder_->SetClipRect(new_clip_rect); | 173 decoder_->SetClipRect(new_clip_rect); |
174 | 174 |
175 // TODO(wez): Defer refresh so that multiple events can be batched. | 175 // TODO(wez): Defer refresh so that multiple events can be batched. |
176 DoRefresh(); | 176 DoRefresh(); |
177 } | 177 } |
178 | 178 |
179 void RectangleUpdateDecoder::RefreshFullFrame() { | 179 void RectangleUpdateDecoder::RefreshFullFrame() { |
180 if (!message_loop_->BelongsToCurrentThread()) { | 180 if (!message_loop_->BelongsToCurrentThread()) { |
181 message_loop_->PostTask( | 181 message_loop_->PostTask( |
182 FROM_HERE, base::Bind(&RectangleUpdateDecoder::RefreshFullFrame, this)); | 182 FROM_HERE, base::Bind(&RectangleUpdateDecoder::RefreshFullFrame, this)); |
183 return; | 183 return; |
184 } | 184 } |
185 | 185 |
186 // If a video frame or the decoder is not allocated yet then don't | 186 // If a video frame or the decoder is not allocated yet then don't |
187 // save the refresh rectangle to avoid wasted computation. | 187 // save the refresh rectangle to avoid wasted computation. |
188 if (!frame_ || !decoder_.get()) | 188 if (!frame_ || !decoder_.get()) |
189 return; | 189 return; |
190 | 190 |
191 SkIRect frame_rect = SkIRect::MakeWH(frame_->width(), frame_->height()); | 191 refresh_rects_.push_back( |
192 refresh_region_.op(frame_rect, SkRegion::kUnion_Op); | 192 SkIRect::MakeWH(static_cast<int>(frame_->width()), |
193 | 193 static_cast<int>(frame_->height()))); |
194 DoRefresh(); | 194 DoRefresh(); |
195 } | 195 } |
196 | 196 |
197 void RectangleUpdateDecoder::SubmitToConsumer() { | 197 void RectangleUpdateDecoder::SubmitToConsumer() { |
198 // A frame is not allocated yet, we can reach here because of a refresh | 198 // A frame is not allocated yet, we can reach here because of a refresh |
199 // request. | 199 // request. |
200 if (!frame_) | 200 if (!frame_) |
201 return; | 201 return; |
202 | 202 |
203 SkRegion* dirty_region = new SkRegion; | 203 RectVector* dirty_rects = new RectVector(); |
204 decoder_->GetUpdatedRegion(dirty_region); | 204 decoder_->GetUpdatedRects(dirty_rects); |
205 | 205 |
206 consumer_->OnPartialFrameOutput(frame_, dirty_region, base::Bind( | 206 consumer_->OnPartialFrameOutput(frame_, dirty_rects, base::Bind( |
207 &RectangleUpdateDecoder::OnFrameConsumed, this, dirty_region)); | 207 &RectangleUpdateDecoder::OnFrameConsumed, this, dirty_rects)); |
208 } | 208 } |
209 | 209 |
210 void RectangleUpdateDecoder::DoRefresh() { | 210 void RectangleUpdateDecoder::DoRefresh() { |
211 DCHECK(message_loop_->BelongsToCurrentThread()); | 211 DCHECK(message_loop_->BelongsToCurrentThread()); |
212 | 212 |
213 if (refresh_region_.isEmpty()) | 213 if (refresh_rects_.empty()) |
214 return; | 214 return; |
215 | 215 |
216 decoder_->RefreshRegion(refresh_region_); | 216 decoder_->RefreshRects(refresh_rects_); |
217 refresh_region_.setEmpty(); | 217 refresh_rects_.clear(); |
218 SubmitToConsumer(); | 218 SubmitToConsumer(); |
219 } | 219 } |
220 | 220 |
221 void RectangleUpdateDecoder::OnFrameConsumed(SkRegion* region) { | 221 void RectangleUpdateDecoder::OnFrameConsumed(RectVector* rects) { |
222 if (!message_loop_->BelongsToCurrentThread()) { | 222 if (!message_loop_->BelongsToCurrentThread()) { |
223 message_loop_->PostTask( | 223 message_loop_->PostTask( |
224 FROM_HERE, base::Bind(&RectangleUpdateDecoder::OnFrameConsumed, | 224 FROM_HERE, base::Bind(&RectangleUpdateDecoder::OnFrameConsumed, |
225 this, region)); | 225 this, rects)); |
226 return; | 226 return; |
227 } | 227 } |
228 | 228 |
229 delete region; | 229 delete rects; |
230 | 230 |
231 DoRefresh(); | 231 DoRefresh(); |
232 } | 232 } |
233 | 233 |
234 } // namespace remoting | 234 } // namespace remoting |
OLD | NEW |