Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/plugin/pepper_view.h" | 5 #include "remoting/client/plugin/pepper_view.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "ppapi/cpp/graphics_2d.h" | 9 #include "ppapi/cpp/graphics_2d.h" |
| 10 #include "ppapi/cpp/image_data.h" | 10 #include "ppapi/cpp/image_data.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 backing_store_->stride() * r.y() + kBytesPerPixel * r.x(); | 123 backing_store_->stride() * r.y() + kBytesPerPixel * r.x(); |
| 124 | 124 |
| 125 // TODO(hclam): We really should eliminate this memory copy. | 125 // TODO(hclam): We really should eliminate this memory copy. |
| 126 for (int j = 0; j < r.height(); ++j) { | 126 for (int j = 0; j < r.height(); ++j) { |
| 127 memcpy(out, in, r.width() * kBytesPerPixel); | 127 memcpy(out, in, r.width() * kBytesPerPixel); |
| 128 in += kFrameStride; | 128 in += kFrameStride; |
| 129 out += backing_store_->stride(); | 129 out += backing_store_->stride(); |
| 130 } | 130 } |
| 131 | 131 |
| 132 if (DoScaling()) { | 132 if (DoScaling()) { |
| 133 gfx::Rect r_scaled = UpdateScaledBackingStore(r); | 133 pp::Rect r_scaled = UpdateScaledBackingStore( |
|
dmac
2011/07/20 00:34:31
is there really no gfx::Rect to pp:Rect conversion
garykac
2011/07/20 18:55:28
Nope. The old code did a conversion like this as w
| |
| 134 pp::Rect(r.x(), r.y(), r.width(), r.height())); | |
| 134 graphics2d_.PaintImageData(*scaled_backing_store_.get(), pp::Point(0, 0), | 135 graphics2d_.PaintImageData(*scaled_backing_store_.get(), pp::Point(0, 0), |
| 135 pp::Rect(r_scaled.x(), r_scaled.y(), | 136 r_scaled); |
| 136 r_scaled.width(), r_scaled.height())); | |
| 137 } else { | 137 } else { |
| 138 // Pepper Graphics 2D has a strange and badly documented API that the | 138 // Pepper Graphics 2D has a strange and badly documented API that the |
| 139 // point here is the offset from the source rect. Why? | 139 // point here is the offset from the source rect. Why? |
| 140 graphics2d_.PaintImageData(*backing_store_.get(), pp::Point(0, 0), | 140 graphics2d_.PaintImageData(*backing_store_.get(), pp::Point(0, 0), |
| 141 pp::Rect(r.x(), r.y(), r.width(), r.height())); | 141 pp::Rect(r.x(), r.y(), r.width(), r.height())); |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 | 144 |
| 145 graphics2d_.Flush(TaskToCompletionCallback( | 145 graphics2d_.Flush(TaskToCompletionCallback( |
| 146 task_factory_.NewRunnableMethod(&PepperView::OnPaintDone, | 146 task_factory_.NewRunnableMethod(&PepperView::OnPaintDone, |
| 147 base::Time::Now()))); | 147 base::Time::Now()))); |
| 148 | 148 |
| 149 TraceContext::tracer()->PrintString("End Paint Frame."); | 149 TraceContext::tracer()->PrintString("End Paint Frame."); |
| 150 } | 150 } |
| 151 | 151 |
| 152 gfx::Rect PepperView::UpdateScaledBackingStore(const gfx::Rect& r) { | 152 pp::Rect PepperView::UpdateScaledBackingStore(const pp::Rect& r) { |
| 153 const int kBytesPerPixel = GetBytesPerPixel(media::VideoFrame::RGB32); | 153 const int kBytesPerPixel = GetBytesPerPixel(media::VideoFrame::RGB32); |
| 154 // Find the updated rectangle in the scaled backing store. | 154 // Find the updated rectangle in the scaled backing store. |
| 155 gfx::Point top_left = ConvertHostToScreen(r.origin()); | 155 pp::Point top_left = ConvertHostToScreen(r.point()); |
| 156 gfx::Point bottom_right = ConvertHostToScreen(gfx::Point(r.right(), | 156 pp::Point bottom_right = ConvertHostToScreen(pp::Point(r.right(), |
| 157 r.bottom())); | 157 r.bottom())); |
| 158 int r_scaled_left = top_left.x(); | 158 int r_scaled_left = top_left.x(); |
| 159 int r_scaled_right = bottom_right.x(); | 159 int r_scaled_right = bottom_right.x(); |
| 160 int r_scaled_top = top_left.y(); | 160 int r_scaled_top = top_left.y(); |
| 161 int r_scaled_bottom = bottom_right.y(); | 161 int r_scaled_bottom = bottom_right.y(); |
| 162 if (r_scaled_right <= r_scaled_left || r_scaled_bottom <= r_scaled_top) | 162 if (r_scaled_right <= r_scaled_left || r_scaled_bottom <= r_scaled_top) |
| 163 return gfx::Rect(r_scaled_left, r_scaled_top, 0, 0); | 163 return pp::Rect(r_scaled_left, r_scaled_top, 0, 0); |
| 164 | 164 |
| 165 // Allow for the fact that ConvertHostToScreen and ConvertScreenToHost aren't | 165 // Allow for the fact that ConvertHostToScreen and ConvertScreenToHost aren't |
| 166 // exact inverses. | 166 // exact inverses. |
| 167 r_scaled_right++; | 167 r_scaled_right++; |
| 168 r_scaled_bottom++; | 168 r_scaled_bottom++; |
| 169 | 169 |
| 170 // Clip the scaled rectangle. | 170 // Clip the scaled rectangle. |
| 171 r_scaled_left = std::max(r_scaled_left, 0); | 171 r_scaled_left = std::max(r_scaled_left, 0); |
| 172 r_scaled_left = std::min(r_scaled_left, client_width_); | 172 r_scaled_left = std::min(r_scaled_left, client_width_); |
| 173 r_scaled_right = std::max(r_scaled_right, 0); | 173 r_scaled_right = std::max(r_scaled_right, 0); |
| 174 r_scaled_right = std::min(r_scaled_right, client_width_); | 174 r_scaled_right = std::min(r_scaled_right, client_width_); |
| 175 r_scaled_top = std::max(r_scaled_top, 0); | 175 r_scaled_top = std::max(r_scaled_top, 0); |
| 176 r_scaled_top = std::min(r_scaled_top, client_height_); | 176 r_scaled_top = std::min(r_scaled_top, client_height_); |
| 177 r_scaled_bottom = std::max(r_scaled_bottom, 0); | 177 r_scaled_bottom = std::max(r_scaled_bottom, 0); |
| 178 r_scaled_bottom = std::min(r_scaled_bottom, client_height_); | 178 r_scaled_bottom = std::min(r_scaled_bottom, client_height_); |
| 179 | 179 |
| 180 // Blit from the backing store to the scaled backing store. | 180 // Blit from the backing store to the scaled backing store. |
| 181 for (int y_scaled = r_scaled_top; y_scaled < r_scaled_bottom; y_scaled++) { | 181 for (int y_scaled = r_scaled_top; y_scaled < r_scaled_bottom; y_scaled++) { |
| 182 int y = ConvertScreenToHost(gfx::Point(0, y_scaled)).y(); | 182 int y = ConvertScreenToHost(pp::Point(0, y_scaled)).y(); |
| 183 // Special case where each pixel is a word. | 183 // Special case where each pixel is a word. |
| 184 if ((kBytesPerPixel == 4) && (backing_store_->stride() % 4 == 0) && | 184 if ((kBytesPerPixel == 4) && (backing_store_->stride() % 4 == 0) && |
| 185 (scaled_backing_store_->stride() % 4 == 0)) { | 185 (scaled_backing_store_->stride() % 4 == 0)) { |
| 186 uint32* from = reinterpret_cast<uint32*>(backing_store_->data()) + | 186 uint32* from = reinterpret_cast<uint32*>(backing_store_->data()) + |
| 187 (y * backing_store_->stride() / 4); | 187 (y * backing_store_->stride() / 4); |
| 188 uint32* to = reinterpret_cast<uint32*>(scaled_backing_store_->data()) + | 188 uint32* to = reinterpret_cast<uint32*>(scaled_backing_store_->data()) + |
| 189 (y_scaled * scaled_backing_store_->stride() / 4) + r_scaled_left; | 189 (y_scaled * scaled_backing_store_->stride() / 4) + r_scaled_left; |
| 190 uint32* to_max = to + (r_scaled_right - r_scaled_left); | 190 uint32* to_max = to + (r_scaled_right - r_scaled_left); |
| 191 const int* offset = &screen_x_to_host_x_[r_scaled_left]; | 191 const int* offset = &screen_x_to_host_x_[r_scaled_left]; |
| 192 while (to < to_max) | 192 while (to < to_max) |
| 193 *to++ = from[*offset++]; | 193 *to++ = from[*offset++]; |
| 194 } else { | 194 } else { |
| 195 // Currently that special case is the only case that's ever encountered. | 195 // Currently that special case is the only case that's ever encountered. |
| 196 NOTREACHED(); | 196 NOTREACHED(); |
| 197 uint8* from = reinterpret_cast<uint8*>(backing_store_->data()) + | 197 uint8* from = reinterpret_cast<uint8*>(backing_store_->data()) + |
| 198 (y * backing_store_->stride()); | 198 (y * backing_store_->stride()); |
| 199 uint8* to = reinterpret_cast<uint8*>(scaled_backing_store_->data()) + | 199 uint8* to = reinterpret_cast<uint8*>(scaled_backing_store_->data()) + |
| 200 (y_scaled * scaled_backing_store_->stride()) + | 200 (y_scaled * scaled_backing_store_->stride()) + |
| 201 (r_scaled_left * kBytesPerPixel); | 201 (r_scaled_left * kBytesPerPixel); |
| 202 for (int x_sc = r_scaled_left; x_sc < r_scaled_right; x_sc++) { | 202 for (int x_sc = r_scaled_left; x_sc < r_scaled_right; x_sc++) { |
| 203 int x = screen_x_to_host_x_[x_sc]; | 203 int x = screen_x_to_host_x_[x_sc]; |
| 204 memcpy(to, from + (x * kBytesPerPixel), kBytesPerPixel); | 204 memcpy(to, from + (x * kBytesPerPixel), kBytesPerPixel); |
| 205 to += kBytesPerPixel; | 205 to += kBytesPerPixel; |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 return gfx::Rect(r_scaled_left, r_scaled_top, r_scaled_right - r_scaled_left, | 209 return pp::Rect(r_scaled_left, r_scaled_top, r_scaled_right - r_scaled_left, |
| 210 r_scaled_bottom - r_scaled_top); | 210 r_scaled_bottom - r_scaled_top); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void PepperView::BlankRect(pp::ImageData& image_data, const gfx::Rect& rect) { | 213 void PepperView::BlankRect(pp::ImageData& image_data, const pp::Rect& rect) { |
| 214 const int kBytesPerPixel = GetBytesPerPixel(media::VideoFrame::RGB32); | 214 const int kBytesPerPixel = GetBytesPerPixel(media::VideoFrame::RGB32); |
| 215 for (int y = rect.y(); y < rect.bottom(); y++) { | 215 for (int y = rect.y(); y < rect.bottom(); y++) { |
| 216 uint8* to = reinterpret_cast<uint8*>(image_data.data()) + | 216 uint8* to = reinterpret_cast<uint8*>(image_data.data()) + |
| 217 (y * image_data.stride()) + (rect.x() * kBytesPerPixel); | 217 (y * image_data.stride()) + (rect.x() * kBytesPerPixel); |
| 218 memset(to, 0xff, rect.width() * kBytesPerPixel); | 218 memset(to, 0xff, rect.width() * kBytesPerPixel); |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 | 221 |
| 222 void PepperView::SetSolidFill(uint32 color) { | 222 void PepperView::SetSolidFill(uint32 color) { |
| 223 DCHECK(CurrentlyOnPluginThread()); | 223 DCHECK(CurrentlyOnPluginThread()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 return; | 278 return; |
| 279 | 279 |
| 280 host_width_ = width; | 280 host_width_ = width; |
| 281 host_height_ = height; | 281 host_height_ = height; |
| 282 | 282 |
| 283 ResizeInternals(); | 283 ResizeInternals(); |
| 284 | 284 |
| 285 instance_->GetScriptableObject()->SetDesktopSize(host_width_, host_height_); | 285 instance_->GetScriptableObject()->SetDesktopSize(host_width_, host_height_); |
| 286 } | 286 } |
| 287 | 287 |
| 288 gfx::Point PepperView::ConvertScreenToHost(const gfx::Point& p) const { | 288 pp::Point PepperView::ConvertScreenToHost(const pp::Point& p) const { |
| 289 DCHECK(CurrentlyOnPluginThread()); | 289 DCHECK(CurrentlyOnPluginThread()); |
| 290 | 290 |
| 291 int x = static_cast<int>(p.x() / screen_scale_); | 291 int x = static_cast<int>(p.x() / screen_scale_); |
| 292 x = std::min(x, host_width_ - 1); | 292 x = std::min(x, host_width_ - 1); |
| 293 x = std::max(x, 0); | 293 x = std::max(x, 0); |
| 294 int y = static_cast<int>(p.y() / screen_scale_); | 294 int y = static_cast<int>(p.y() / screen_scale_); |
| 295 y = std::min(y, host_height_ - 1); | 295 y = std::min(y, host_height_ - 1); |
| 296 y = std::max(y, 0); | 296 y = std::max(y, 0); |
| 297 return gfx::Point(x, y); | 297 return pp::Point(x, y); |
| 298 } | 298 } |
| 299 | 299 |
| 300 gfx::Point PepperView::ConvertHostToScreen(const gfx::Point& p) const { | 300 pp::Point PepperView::ConvertHostToScreen(const pp::Point& p) const { |
| 301 return gfx::Point(static_cast<int>(p.x() * screen_scale_), | 301 return pp::Point(static_cast<int>(p.x() * screen_scale_), |
| 302 static_cast<int>(p.y() * screen_scale_)); | 302 static_cast<int>(p.y() * screen_scale_)); |
| 303 } | 303 } |
| 304 | 304 |
| 305 void PepperView::SetScreenScale(double screen_scale) { | 305 void PepperView::SetScreenScale(double screen_scale) { |
| 306 if (screen_scale == screen_scale_) | 306 if (screen_scale == screen_scale_) |
| 307 return; | 307 return; |
| 308 screen_scale_ = screen_scale; | 308 screen_scale_ = screen_scale; |
| 309 ResizeInternals(); | 309 ResizeInternals(); |
| 310 RefreshPaint(); | 310 RefreshPaint(); |
| 311 } | 311 } |
| 312 | 312 |
| 313 void PepperView::RefreshPaint() { | 313 void PepperView::RefreshPaint() { |
| 314 if (DoScaling()) { | 314 if (DoScaling()) { |
| 315 // Render from the whole backing store, to the scaled backing store, at the | 315 // Render from the whole backing store, to the scaled backing store, at the |
| 316 // current scale. | 316 // current scale. |
| 317 gfx::Rect updated_rect = UpdateScaledBackingStore(gfx::Rect( | 317 pp::Rect updated_rect = UpdateScaledBackingStore(pp::Rect( |
| 318 host_width_, host_height_)); | 318 host_width_, host_height_)); |
| 319 // If the scale has just decreased, then there is stale raster data | 319 // If the scale has just decreased, then there is stale raster data |
| 320 // to the right of, and below, the scaled copy of the host screen that's | 320 // to the right of, and below, the scaled copy of the host screen that's |
| 321 // just been rendered into the scaled backing store. | 321 // just been rendered into the scaled backing store. |
| 322 // So blank out everything to the east of that copy... | 322 // So blank out everything to the east of that copy... |
| 323 BlankRect(*scaled_backing_store_, gfx::Rect( | 323 BlankRect(*scaled_backing_store_, pp::Rect( |
| 324 updated_rect.right(), 0, | 324 updated_rect.right(), 0, |
| 325 scaled_backing_store_->size().width() - updated_rect.right(), | 325 scaled_backing_store_->size().width() - updated_rect.right(), |
| 326 updated_rect.bottom())); | 326 updated_rect.bottom())); |
| 327 // ...and everything to the south and south-east. | 327 // ...and everything to the south and south-east. |
| 328 BlankRect(*scaled_backing_store_, gfx::Rect( | 328 BlankRect(*scaled_backing_store_, pp::Rect( |
| 329 0, updated_rect.bottom(), scaled_backing_store_->size().width(), | 329 0, updated_rect.bottom(), scaled_backing_store_->size().width(), |
| 330 scaled_backing_store_->size().height() - updated_rect.bottom())); | 330 scaled_backing_store_->size().height() - updated_rect.bottom())); |
| 331 graphics2d_.PaintImageData(*scaled_backing_store_.get(), pp::Point(0, 0), | 331 graphics2d_.PaintImageData(*scaled_backing_store_.get(), pp::Point(0, 0), |
| 332 pp::Rect(scaled_backing_store_->size())); | 332 pp::Rect(scaled_backing_store_->size())); |
| 333 graphics2d_.Flush(TaskToCompletionCallback( | 333 graphics2d_.Flush(TaskToCompletionCallback( |
| 334 task_factory_.NewRunnableMethod(&PepperView::OnRefreshPaintDone))); | 334 task_factory_.NewRunnableMethod(&PepperView::OnRefreshPaintDone))); |
| 335 } else { | 335 } else { |
| 336 graphics2d_.PaintImageData(*backing_store_.get(), pp::Point(0, 0), | 336 graphics2d_.PaintImageData(*backing_store_.get(), pp::Point(0, 0), |
| 337 pp::Rect(backing_store_->size())); | 337 pp::Rect(backing_store_->size())); |
| 338 graphics2d_.Flush(TaskToCompletionCallback( | 338 graphics2d_.Flush(TaskToCompletionCallback( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 << "Not enough memory for scaled backing store."; | 377 << "Not enough memory for scaled backing store."; |
| 378 } | 378 } |
| 379 } else { | 379 } else { |
| 380 scaled_backing_store_.reset(); | 380 scaled_backing_store_.reset(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 // Cache the horizontal component of the map from client screen co-ordinates | 383 // Cache the horizontal component of the map from client screen co-ordinates |
| 384 // to host screen co-ordinates. | 384 // to host screen co-ordinates. |
| 385 screen_x_to_host_x_.reset(new int[client_width_]); | 385 screen_x_to_host_x_.reset(new int[client_width_]); |
| 386 for (int x = 0; x < client_width_; x++) | 386 for (int x = 0; x < client_width_; x++) |
| 387 screen_x_to_host_x_[x] = ConvertScreenToHost(gfx::Point(x, 0)).x(); | 387 screen_x_to_host_x_[x] = ConvertScreenToHost(pp::Point(x, 0)).x(); |
| 388 } | 388 } |
| 389 | 389 |
| 390 bool PepperView::DoScaling() const { | 390 bool PepperView::DoScaling() const { |
| 391 return (screen_scale_ != 1.0); | 391 return (screen_scale_ != 1.0); |
| 392 } | 392 } |
| 393 | 393 |
| 394 void PepperView::SetScreenSize(int width, int height) { | 394 void PepperView::SetScreenSize(int width, int height) { |
| 395 DCHECK(CurrentlyOnPluginThread()); | 395 DCHECK(CurrentlyOnPluginThread()); |
| 396 | 396 |
| 397 client_width_ = width; | 397 client_width_ = width; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 instance_->GetStats()->video_paint_ms()->Record( | 467 instance_->GetStats()->video_paint_ms()->Record( |
| 468 (base::Time::Now() - paint_start).InMilliseconds()); | 468 (base::Time::Now() - paint_start).InMilliseconds()); |
| 469 return; | 469 return; |
| 470 } | 470 } |
| 471 | 471 |
| 472 void PepperView::OnRefreshPaintDone() { | 472 void PepperView::OnRefreshPaintDone() { |
| 473 DCHECK(CurrentlyOnPluginThread()); | 473 DCHECK(CurrentlyOnPluginThread()); |
| 474 } | 474 } |
| 475 | 475 |
| 476 } // namespace remoting | 476 } // namespace remoting |
| OLD | NEW |