OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/renderer/render_widget.h" | 5 #include "chrome/renderer/render_widget.h" |
6 | 6 |
7 #include "base/gfx/point.h" | 7 #include "base/gfx/point.h" |
8 #include "base/gfx/size.h" | 8 #include "base/gfx/size.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
11 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
| 12 #include "build/build_config.h" |
12 #include "chrome/renderer/render_process.h" | 13 #include "chrome/renderer/render_process.h" |
13 #include "skia/ext/platform_canvas_win.h" | 14 #include "skia/ext/platform_canvas.h" |
| 15 |
| 16 #if defined(OS_POSIX) |
| 17 #include "skia/include/SkPixelRef.h" |
| 18 #include "skia/include/SkMallocPixelRef.h" |
| 19 #endif // defined(OS_POSIX) |
14 | 20 |
15 #include "webkit/glue/webinputevent.h" | 21 #include "webkit/glue/webinputevent.h" |
16 #include "webkit/glue/webwidget.h" | 22 #include "webkit/glue/webwidget.h" |
17 | 23 |
18 /////////////////////////////////////////////////////////////////////////////// | 24 /////////////////////////////////////////////////////////////////////////////// |
19 | 25 |
20 namespace { | 26 namespace { |
21 | 27 |
22 // This class is used to defer calling RenderWidget::Close() while the current | 28 // This class is used to defer calling RenderWidget::Close() while the current |
23 // thread is inside RenderThread::Send(), which in some cases can result in a | 29 // thread is inside RenderThread::Send(), which in some cases can result in a |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable) | 76 RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable) |
71 : routing_id_(MSG_ROUTING_NONE), | 77 : routing_id_(MSG_ROUTING_NONE), |
72 opener_id_(MSG_ROUTING_NONE), | 78 opener_id_(MSG_ROUTING_NONE), |
73 render_thread_(render_thread), | 79 render_thread_(render_thread), |
74 host_window_(NULL), | 80 host_window_(NULL), |
75 current_paint_buf_(NULL), | 81 current_paint_buf_(NULL), |
76 current_scroll_buf_(NULL), | 82 current_scroll_buf_(NULL), |
77 next_paint_flags_(0), | 83 next_paint_flags_(0), |
78 paint_reply_pending_(false), | 84 paint_reply_pending_(false), |
79 did_show_(false), | 85 did_show_(false), |
80 closing_(false), | |
81 is_hidden_(false), | 86 is_hidden_(false), |
82 needs_repainting_on_restore_(false), | 87 needs_repainting_on_restore_(false), |
83 has_focus_(false), | 88 has_focus_(false), |
| 89 closing_(false), |
84 ime_is_active_(false), | 90 ime_is_active_(false), |
85 ime_control_enable_ime_(true), | 91 ime_control_enable_ime_(true), |
86 ime_control_x_(-1), | 92 ime_control_x_(-1), |
87 ime_control_y_(-1), | 93 ime_control_y_(-1), |
88 ime_control_new_state_(false), | 94 ime_control_new_state_(false), |
89 ime_control_updated_(false), | 95 ime_control_updated_(false), |
90 ime_control_busy_(false), | 96 ime_control_busy_(false), |
91 activatable_(activatable) { | 97 activatable_(activatable) { |
92 RenderProcess::AddRefProcess(); | 98 RenderProcess::AddRefProcess(); |
93 DCHECK(render_thread_); | 99 DCHECK(render_thread_); |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 } | 351 } |
346 | 352 |
347 void RenderWidget::ClearFocus() { | 353 void RenderWidget::ClearFocus() { |
348 // We may have got the focus from the browser before this gets processed, in | 354 // We may have got the focus from the browser before this gets processed, in |
349 // which case we do not want to unfocus ourself. | 355 // which case we do not want to unfocus ourself. |
350 if (!has_focus_ && webwidget_) | 356 if (!has_focus_ && webwidget_) |
351 webwidget_->SetFocus(false); | 357 webwidget_->SetFocus(false); |
352 } | 358 } |
353 | 359 |
354 void RenderWidget::PaintRect(const gfx::Rect& rect, | 360 void RenderWidget::PaintRect(const gfx::Rect& rect, |
355 base::SharedMemory* paint_buf) { | 361 skia::PlatformCanvas* canvas) { |
356 skia::PlatformCanvasWin canvas(rect.width(), rect.height(), true, | |
357 paint_buf->handle()); | |
358 // Bring the canvas into the coordinate system of the paint rect | 362 // Bring the canvas into the coordinate system of the paint rect |
359 canvas.translate(static_cast<SkScalar>(-rect.x()), | 363 canvas->translate(static_cast<SkScalar>(-rect.x()), |
360 static_cast<SkScalar>(-rect.y())); | 364 static_cast<SkScalar>(-rect.y())); |
361 | 365 |
362 webwidget_->Paint(&canvas, rect); | 366 webwidget_->Paint(canvas, rect); |
363 | 367 |
364 // Flush to underlying bitmap. TODO(darin): is this needed? | 368 // Flush to underlying bitmap. TODO(darin): is this needed? |
365 canvas.getTopPlatformDevice().accessBitmap(false); | 369 canvas->getTopPlatformDevice().accessBitmap(false); |
366 | 370 |
367 // Let the subclass observe this paint operations. | 371 // Let the subclass observe this paint operations. |
368 DidPaint(); | 372 DidPaint(); |
369 } | 373 } |
370 | 374 |
| 375 // static |
371 size_t RenderWidget::GetPaintBufSize(const gfx::Rect& rect) { | 376 size_t RenderWidget::GetPaintBufSize(const gfx::Rect& rect) { |
372 // TODO(darin): protect against overflow | 377 // TODO(darin): protect against overflow |
373 return 4 * rect.width() * rect.height(); | 378 const size_t stride = skia::PlatformCanvas::StrideForWidth(rect.width()); |
| 379 return stride * rect.height(); |
374 } | 380 } |
375 | 381 |
376 void RenderWidget::DoDeferredPaint() { | 382 void RenderWidget::DoDeferredPaint() { |
377 if (!webwidget_ || paint_reply_pending() || paint_rect_.IsEmpty()) | 383 if (!webwidget_ || paint_reply_pending() || paint_rect_.IsEmpty()) |
378 return; | 384 return; |
379 | 385 |
380 // When we are hidden, we want to suppress painting, but we still need to | 386 // When we are hidden, we want to suppress painting, but we still need to |
381 // mark this DoDeferredPaint as complete. | 387 // mark this DoDeferredPaint as complete. |
382 if (is_hidden_ || size_.IsEmpty()) { | 388 if (is_hidden_ || size_.IsEmpty()) { |
383 paint_rect_ = gfx::Rect(); | 389 paint_rect_ = gfx::Rect(); |
384 needs_repainting_on_restore_ = true; | 390 needs_repainting_on_restore_ = true; |
385 return; | 391 return; |
386 } | 392 } |
387 | 393 |
388 // Layout may generate more invalidation... | 394 // Layout may generate more invalidation... |
389 webwidget_->Layout(); | 395 webwidget_->Layout(); |
390 | 396 |
391 // OK, save the current paint_rect to a local since painting may cause more | 397 // OK, save the current paint_rect to a local since painting may cause more |
392 // invalidation. Some WebCore rendering objects only layout when painted. | 398 // invalidation. Some WebCore rendering objects only layout when painted. |
393 gfx::Rect damaged_rect = paint_rect_; | 399 gfx::Rect damaged_rect = paint_rect_; |
394 paint_rect_ = gfx::Rect(); | 400 paint_rect_ = gfx::Rect(); |
395 | 401 |
396 // Compute a buffer for painting and cache it. | 402 // Compute a buffer for painting and cache it. |
| 403 #if defined(OS_WIN) |
397 current_paint_buf_ = | 404 current_paint_buf_ = |
398 RenderProcess::AllocSharedMemory(GetPaintBufSize(damaged_rect)); | 405 RenderProcess::AllocSharedMemory(GetPaintBufSize(damaged_rect)); |
399 if (!current_paint_buf_) { | 406 if (!current_paint_buf_) { |
400 NOTREACHED(); | 407 NOTREACHED(); |
401 return; | 408 return; |
402 } | 409 } |
| 410 skia::PlatformCanvasWin canvas(damaged_rect.width(), damaged_rect.height(), |
| 411 true, current_paint_buf_->handle()); |
| 412 #elif defined(OS_POSIX) |
| 413 // Currently, on POSIX, we are serialising the bitmap data over the IPC |
| 414 // channel. |
| 415 skia::PlatformCanvas canvas(damaged_rect.width(), damaged_rect.height(), |
| 416 true); |
| 417 #endif // defined(OS_POSIX) |
403 | 418 |
404 PaintRect(damaged_rect, current_paint_buf_); | 419 PaintRect(damaged_rect, &canvas); |
405 | 420 |
406 ViewHostMsg_PaintRect_Params params; | 421 ViewHostMsg_PaintRect_Params params; |
407 params.bitmap = current_paint_buf_->handle(); | |
408 params.bitmap_rect = damaged_rect; | 422 params.bitmap_rect = damaged_rect; |
409 params.view_size = size_; | 423 params.view_size = size_; |
410 params.plugin_window_moves = plugin_window_moves_; | 424 params.plugin_window_moves = plugin_window_moves_; |
411 params.flags = next_paint_flags_; | 425 params.flags = next_paint_flags_; |
412 | 426 |
| 427 #if defined(OS_WIN) |
| 428 // Windows passes a HANDLE to the shared memory over IPC |
| 429 params.bitmap = current_paint_buf_->handle(); |
| 430 #elif defined(OS_POSIX) |
| 431 // POSIX currently passes the data itself. |
| 432 params.bitmap = canvas.getDevice()->accessBitmap(false); |
| 433 #endif // defined(OS_WIN) |
| 434 |
413 plugin_window_moves_.clear(); | 435 plugin_window_moves_.clear(); |
414 | 436 |
415 paint_reply_pending_ = true; | 437 paint_reply_pending_ = true; |
416 Send(new ViewHostMsg_PaintRect(routing_id_, params)); | 438 Send(new ViewHostMsg_PaintRect(routing_id_, params)); |
417 next_paint_flags_ = 0; | 439 next_paint_flags_ = 0; |
418 | 440 |
419 UpdateIME(); | 441 UpdateIME(); |
420 } | 442 } |
421 | 443 |
422 void RenderWidget::DoDeferredScroll() { | 444 void RenderWidget::DoDeferredScroll() { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 damaged_rect.set_height(dy); | 484 damaged_rect.set_height(dy); |
463 } else { | 485 } else { |
464 damaged_rect.set_y(scroll_rect_.bottom() + dy); | 486 damaged_rect.set_y(scroll_rect_.bottom() + dy); |
465 damaged_rect.set_height(-dy); | 487 damaged_rect.set_height(-dy); |
466 } | 488 } |
467 } | 489 } |
468 | 490 |
469 // In case the scroll offset exceeds the width/height of the scroll rect | 491 // In case the scroll offset exceeds the width/height of the scroll rect |
470 damaged_rect = scroll_rect_.Intersect(damaged_rect); | 492 damaged_rect = scroll_rect_.Intersect(damaged_rect); |
471 | 493 |
| 494 #if defined(OS_WIN) |
472 current_scroll_buf_ = | 495 current_scroll_buf_ = |
473 RenderProcess::AllocSharedMemory(GetPaintBufSize(damaged_rect)); | 496 RenderProcess::AllocSharedMemory(GetPaintBufSize(damaged_rect)); |
474 if (!current_scroll_buf_) { | 497 if (!current_scroll_buf_) { |
475 NOTREACHED(); | 498 NOTREACHED(); |
476 return; | 499 return; |
477 } | 500 } |
| 501 skia::PlatformCanvasWin canvas(damaged_rect.width(), damaged_rect.height(), |
| 502 true, current_scroll_buf_->handle()); |
| 503 #elif defined(OS_POSIX) |
| 504 // Currently, on POSIX, we are serialising the bitmap data over the IPC |
| 505 // channel. |
| 506 skia::PlatformCanvas canvas(damaged_rect.width(), damaged_rect.height(), |
| 507 true); |
| 508 #endif // defined(OS_POSIX) |
478 | 509 |
479 // Set these parameters before calling Paint, since that could result in | 510 // Set these parameters before calling Paint, since that could result in |
480 // further invalidates (uncommon). | 511 // further invalidates (uncommon). |
481 ViewHostMsg_ScrollRect_Params params; | 512 ViewHostMsg_ScrollRect_Params params; |
482 params.bitmap = current_scroll_buf_->handle(); | |
483 params.bitmap_rect = damaged_rect; | 513 params.bitmap_rect = damaged_rect; |
484 params.dx = scroll_delta_.x(); | 514 params.dx = scroll_delta_.x(); |
485 params.dy = scroll_delta_.y(); | 515 params.dy = scroll_delta_.y(); |
486 params.clip_rect = scroll_rect_; | 516 params.clip_rect = scroll_rect_; |
487 params.view_size = size_; | 517 params.view_size = size_; |
488 params.plugin_window_moves = plugin_window_moves_; | 518 params.plugin_window_moves = plugin_window_moves_; |
489 | 519 |
| 520 #if defined(OS_WIN) |
| 521 // Windows passes a HANDLE to the shared memory over IPC |
| 522 params.bitmap = current_scroll_buf_->handle(); |
| 523 #elif defined(OS_POSIX) |
| 524 // POSIX currently passes the data itself. |
| 525 params.bitmap = canvas.getDevice()->accessBitmap(false); |
| 526 #endif // defined(OS_WIN) |
| 527 |
490 plugin_window_moves_.clear(); | 528 plugin_window_moves_.clear(); |
491 | 529 |
492 // Mark the scroll operation as no longer pending. | 530 // Mark the scroll operation as no longer pending. |
493 scroll_rect_ = gfx::Rect(); | 531 scroll_rect_ = gfx::Rect(); |
494 | 532 |
495 PaintRect(damaged_rect, current_scroll_buf_); | 533 PaintRect(damaged_rect, &canvas); |
496 Send(new ViewHostMsg_ScrollRect(routing_id_, params)); | 534 Send(new ViewHostMsg_ScrollRect(routing_id_, params)); |
497 UpdateIME(); | 535 UpdateIME(); |
498 } | 536 } |
499 | 537 |
500 /////////////////////////////////////////////////////////////////////////////// | 538 /////////////////////////////////////////////////////////////////////////////// |
501 // WebWidgetDelegate | 539 // WebWidgetDelegate |
502 | 540 |
503 gfx::NativeViewId RenderWidget::GetContainingView(WebWidget* webwidget) { | 541 gfx::NativeViewId RenderWidget::GetContainingView(WebWidget* webwidget) { |
504 return host_window_; | 542 return host_window_; |
505 } | 543 } |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 for (; i < plugin_window_moves_.size(); ++i) { | 805 for (; i < plugin_window_moves_.size(); ++i) { |
768 if (plugin_window_moves_[i].window == move.window) { | 806 if (plugin_window_moves_[i].window == move.window) { |
769 plugin_window_moves_[i] = move; | 807 plugin_window_moves_[i] = move; |
770 break; | 808 break; |
771 } | 809 } |
772 } | 810 } |
773 | 811 |
774 if (i == plugin_window_moves_.size()) | 812 if (i == plugin_window_moves_.size()) |
775 plugin_window_moves_.push_back(move); | 813 plugin_window_moves_.push_back(move); |
776 } | 814 } |
OLD | NEW |