| 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 |