Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: chrome/renderer/render_widget.cc

Issue 21485: Bitmap transport (Closed)
Patch Set: Fix some mac crashes Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "build/build_config.h"
13 #include "chrome/common/render_messages.h" 13 #include "chrome/common/render_messages.h"
14 #include "chrome/common/transport_dib.h"
14 #include "chrome/renderer/render_process.h" 15 #include "chrome/renderer/render_process.h"
15 #include "skia/ext/platform_canvas.h" 16 #include "skia/ext/platform_canvas.h"
16 17
17 #if defined(OS_POSIX) 18 #if defined(OS_POSIX)
18 #include "skia/include/SkPixelRef.h" 19 #include "skia/include/SkPixelRef.h"
19 #include "skia/include/SkMallocPixelRef.h" 20 #include "skia/include/SkMallocPixelRef.h"
20 #endif // defined(OS_POSIX) 21 #endif // defined(OS_POSIX)
21 22
22 #include "webkit/glue/webinputevent.h" 23 #include "webkit/glue/webinputevent.h"
23 #include "webkit/glue/webwidget.h" 24 #include "webkit/glue/webwidget.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 ime_control_updated_(false), 98 ime_control_updated_(false),
98 ime_control_busy_(false), 99 ime_control_busy_(false),
99 activatable_(activatable) { 100 activatable_(activatable) {
100 RenderProcess::AddRefProcess(); 101 RenderProcess::AddRefProcess();
101 DCHECK(render_thread_); 102 DCHECK(render_thread_);
102 } 103 }
103 104
104 RenderWidget::~RenderWidget() { 105 RenderWidget::~RenderWidget() {
105 DCHECK(!webwidget_) << "Leaking our WebWidget!"; 106 DCHECK(!webwidget_) << "Leaking our WebWidget!";
106 if (current_paint_buf_) { 107 if (current_paint_buf_) {
107 RenderProcess::FreeSharedMemory(current_paint_buf_); 108 RenderProcess::ReleaseTransportDIB(current_paint_buf_);
108 current_paint_buf_ = NULL; 109 current_paint_buf_ = NULL;
109 } 110 }
110 if (current_scroll_buf_) { 111 if (current_scroll_buf_) {
111 RenderProcess::FreeSharedMemory(current_scroll_buf_); 112 RenderProcess::ReleaseTransportDIB(current_scroll_buf_);
112 current_scroll_buf_ = NULL; 113 current_scroll_buf_ = NULL;
113 } 114 }
114 RenderProcess::ReleaseProcess(); 115 RenderProcess::ReleaseProcess();
115 } 116 }
116 117
117 /*static*/ 118 /*static*/
118 RenderWidget* RenderWidget::Create(int32 opener_id, 119 RenderWidget* RenderWidget::Create(int32 opener_id,
119 RenderThreadBase* render_thread, 120 RenderThreadBase* render_thread,
120 bool activatable) { 121 bool activatable) {
121 DCHECK(opener_id != MSG_ROUTING_NONE); 122 DCHECK(opener_id != MSG_ROUTING_NONE);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 // Generate a full repaint. 291 // Generate a full repaint.
291 DidInvalidateRect(webwidget_, gfx::Rect(size_.width(), size_.height())); 292 DidInvalidateRect(webwidget_, gfx::Rect(size_.width(), size_.height()));
292 } 293 }
293 294
294 void RenderWidget::OnPaintRectAck() { 295 void RenderWidget::OnPaintRectAck() {
295 DCHECK(paint_reply_pending()); 296 DCHECK(paint_reply_pending());
296 paint_reply_pending_ = false; 297 paint_reply_pending_ = false;
297 // If we sent a PaintRect message with a zero-sized bitmap, then 298 // If we sent a PaintRect message with a zero-sized bitmap, then
298 // we should have no current paint buf. 299 // we should have no current paint buf.
299 if (current_paint_buf_) { 300 if (current_paint_buf_) {
300 RenderProcess::FreeSharedMemory(current_paint_buf_); 301 RenderProcess::ReleaseTransportDIB(current_paint_buf_);
301 current_paint_buf_ = NULL; 302 current_paint_buf_ = NULL;
302 } 303 }
304
303 // Continue painting if necessary... 305 // Continue painting if necessary...
304 DoDeferredPaint(); 306 DoDeferredPaint();
305 } 307 }
306 308
307 void RenderWidget::OnScrollRectAck() { 309 void RenderWidget::OnScrollRectAck() {
308 #if defined(OS_WIN)
309 DCHECK(scroll_reply_pending()); 310 DCHECK(scroll_reply_pending());
310 311
311 RenderProcess::FreeSharedMemory(current_scroll_buf_); 312 if (current_scroll_buf_) {
312 current_scroll_buf_ = NULL; 313 RenderProcess::ReleaseTransportDIB(current_scroll_buf_);
313 #endif 314 current_scroll_buf_ = NULL;
315 }
314 316
315 // Continue scrolling if necessary... 317 // Continue scrolling if necessary...
316 DoDeferredScroll(); 318 DoDeferredScroll();
317 } 319 }
318 320
319 void RenderWidget::OnHandleInputEvent(const IPC::Message& message) { 321 void RenderWidget::OnHandleInputEvent(const IPC::Message& message) {
320 void* iter = NULL; 322 void* iter = NULL;
321 323
322 const char* data; 324 const char* data;
323 int data_length; 325 int data_length;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 374
373 webwidget_->Paint(canvas, rect); 375 webwidget_->Paint(canvas, rect);
374 376
375 // Flush to underlying bitmap. TODO(darin): is this needed? 377 // Flush to underlying bitmap. TODO(darin): is this needed?
376 canvas->getTopPlatformDevice().accessBitmap(false); 378 canvas->getTopPlatformDevice().accessBitmap(false);
377 379
378 // Let the subclass observe this paint operations. 380 // Let the subclass observe this paint operations.
379 DidPaint(); 381 DidPaint();
380 } 382 }
381 383
382 // static
383 size_t RenderWidget::GetPaintBufSize(const gfx::Rect& rect) {
384 // TODO(darin): protect against overflow
385 const size_t stride = skia::PlatformCanvas::StrideForWidth(rect.width());
386 return stride * rect.height();
387 }
388
389 void RenderWidget::DoDeferredPaint() { 384 void RenderWidget::DoDeferredPaint() {
390 if (!webwidget_ || paint_reply_pending() || paint_rect_.IsEmpty()) 385 if (!webwidget_ || paint_reply_pending() || paint_rect_.IsEmpty())
391 return; 386 return;
392 387
393 // When we are hidden, we want to suppress painting, but we still need to 388 // When we are hidden, we want to suppress painting, but we still need to
394 // mark this DoDeferredPaint as complete. 389 // mark this DoDeferredPaint as complete.
395 if (is_hidden_ || size_.IsEmpty()) { 390 if (is_hidden_ || size_.IsEmpty()) {
396 paint_rect_ = gfx::Rect(); 391 paint_rect_ = gfx::Rect();
397 needs_repainting_on_restore_ = true; 392 needs_repainting_on_restore_ = true;
398 return; 393 return;
399 } 394 }
400 395
401 // Layout may generate more invalidation... 396 // Layout may generate more invalidation...
402 webwidget_->Layout(); 397 webwidget_->Layout();
403 398
404 // OK, save the current paint_rect to a local since painting may cause more 399 // OK, save the current paint_rect to a local since painting may cause more
405 // invalidation. Some WebCore rendering objects only layout when painted. 400 // invalidation. Some WebCore rendering objects only layout when painted.
406 gfx::Rect damaged_rect = paint_rect_; 401 gfx::Rect damaged_rect = paint_rect_;
407 paint_rect_ = gfx::Rect(); 402 paint_rect_ = gfx::Rect();
408 403
409 // Compute a buffer for painting and cache it. 404 // Compute a buffer for painting and cache it.
410 #if defined(OS_WIN) 405 skia::PlatformCanvas* canvas =
411 current_paint_buf_ = 406 RenderProcess::GetDrawingCanvas(&current_paint_buf_, damaged_rect);
412 RenderProcess::AllocSharedMemory(GetPaintBufSize(damaged_rect)); 407 if (!canvas) {
413 if (!current_paint_buf_) {
414 NOTREACHED(); 408 NOTREACHED();
415 return; 409 return;
416 } 410 }
417 skia::PlatformCanvasWin canvas(damaged_rect.width(), damaged_rect.height(),
418 true, current_paint_buf_->handle());
419 #elif defined(OS_POSIX)
420 // Currently, on POSIX, we are serialising the bitmap data over the IPC
421 // channel.
422 skia::PlatformCanvas canvas(damaged_rect.width(), damaged_rect.height(),
423 true);
424 #endif // defined(OS_POSIX)
425 411
426 PaintRect(damaged_rect, &canvas); 412 PaintRect(damaged_rect, canvas);
427 413
428 ViewHostMsg_PaintRect_Params params; 414 ViewHostMsg_PaintRect_Params params;
429 params.bitmap_rect = damaged_rect; 415 params.bitmap_rect = damaged_rect;
430 params.view_size = size_; 416 params.view_size = size_;
431 params.plugin_window_moves = plugin_window_moves_; 417 params.plugin_window_moves = plugin_window_moves_;
432 params.flags = next_paint_flags_; 418 params.flags = next_paint_flags_;
419 params.bitmap = current_paint_buf_->id();
433 420
434 #if defined(OS_WIN) 421 delete canvas;
435 // Windows passes a HANDLE to the shared memory over IPC
436 params.bitmap = current_paint_buf_->handle();
437 #elif defined(OS_POSIX)
438 // POSIX currently passes the data itself.
439 params.bitmap = canvas.getDevice()->accessBitmap(false);
440 #endif // defined(OS_WIN)
441 422
442 plugin_window_moves_.clear(); 423 plugin_window_moves_.clear();
443 424
444 paint_reply_pending_ = true; 425 paint_reply_pending_ = true;
445 Send(new ViewHostMsg_PaintRect(routing_id_, params)); 426 Send(new ViewHostMsg_PaintRect(routing_id_, params));
446 next_paint_flags_ = 0; 427 next_paint_flags_ = 0;
447 428
448 UpdateIME(); 429 UpdateIME();
449 } 430 }
450 431
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 damaged_rect.set_height(dy); 472 damaged_rect.set_height(dy);
492 } else { 473 } else {
493 damaged_rect.set_y(scroll_rect_.bottom() + dy); 474 damaged_rect.set_y(scroll_rect_.bottom() + dy);
494 damaged_rect.set_height(-dy); 475 damaged_rect.set_height(-dy);
495 } 476 }
496 } 477 }
497 478
498 // In case the scroll offset exceeds the width/height of the scroll rect 479 // In case the scroll offset exceeds the width/height of the scroll rect
499 damaged_rect = scroll_rect_.Intersect(damaged_rect); 480 damaged_rect = scroll_rect_.Intersect(damaged_rect);
500 481
501 #if defined(OS_WIN) 482 skia::PlatformCanvas* canvas =
502 current_scroll_buf_ = 483 RenderProcess::GetDrawingCanvas(&current_scroll_buf_, damaged_rect);
503 RenderProcess::AllocSharedMemory(GetPaintBufSize(damaged_rect)); 484 if (!canvas) {
504 if (!current_scroll_buf_) {
505 NOTREACHED(); 485 NOTREACHED();
506 return; 486 return;
507 } 487 }
508 skia::PlatformCanvasWin canvas(damaged_rect.width(), damaged_rect.height(),
509 true, current_scroll_buf_->handle());
510 #elif defined(OS_POSIX)
511 // Currently, on POSIX, we are serialising the bitmap data over the IPC
512 // channel.
513 skia::PlatformCanvas canvas(damaged_rect.width(), damaged_rect.height(),
514 true);
515 #endif // defined(OS_POSIX)
516 488
517 // Set these parameters before calling Paint, since that could result in 489 // Set these parameters before calling Paint, since that could result in
518 // further invalidates (uncommon). 490 // further invalidates (uncommon).
519 ViewHostMsg_ScrollRect_Params params; 491 ViewHostMsg_ScrollRect_Params params;
520 params.bitmap_rect = damaged_rect; 492 params.bitmap_rect = damaged_rect;
521 params.dx = scroll_delta_.x(); 493 params.dx = scroll_delta_.x();
522 params.dy = scroll_delta_.y(); 494 params.dy = scroll_delta_.y();
523 params.clip_rect = scroll_rect_; 495 params.clip_rect = scroll_rect_;
524 params.view_size = size_; 496 params.view_size = size_;
525 params.plugin_window_moves = plugin_window_moves_; 497 params.plugin_window_moves = plugin_window_moves_;
526 498 params.bitmap = current_scroll_buf_->id();
527 #if defined(OS_WIN)
528 // Windows passes a HANDLE to the shared memory over IPC
529 params.bitmap = current_scroll_buf_->handle();
530 #elif defined(OS_POSIX)
531 // POSIX currently passes the data itself.
532 params.bitmap = canvas.getDevice()->accessBitmap(false);
533 #endif // defined(OS_WIN)
534 499
535 plugin_window_moves_.clear(); 500 plugin_window_moves_.clear();
536 501
537 // Mark the scroll operation as no longer pending. 502 // Mark the scroll operation as no longer pending.
538 scroll_rect_ = gfx::Rect(); 503 scroll_rect_ = gfx::Rect();
539 504
540 PaintRect(damaged_rect, &canvas); 505 PaintRect(damaged_rect, canvas);
541 Send(new ViewHostMsg_ScrollRect(routing_id_, params)); 506 Send(new ViewHostMsg_ScrollRect(routing_id_, params));
507 delete canvas;
542 UpdateIME(); 508 UpdateIME();
543 } 509 }
544 510
545 /////////////////////////////////////////////////////////////////////////////// 511 ///////////////////////////////////////////////////////////////////////////////
546 // WebWidgetDelegate 512 // WebWidgetDelegate
547 513
548 gfx::NativeViewId RenderWidget::GetContainingView(WebWidget* webwidget) { 514 gfx::NativeViewId RenderWidget::GetContainingView(WebWidget* webwidget) {
549 return host_window_; 515 return host_window_;
550 } 516 }
551 517
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 for (; i < plugin_window_moves_.size(); ++i) { 800 for (; i < plugin_window_moves_.size(); ++i) {
835 if (plugin_window_moves_[i].window == move.window) { 801 if (plugin_window_moves_[i].window == move.window) {
836 plugin_window_moves_[i] = move; 802 plugin_window_moves_[i] = move;
837 break; 803 break;
838 } 804 }
839 } 805 }
840 806
841 if (i == plugin_window_moves_.size()) 807 if (i == plugin_window_moves_.size())
842 plugin_window_moves_.push_back(move); 808 plugin_window_moves_.push_back(move);
843 } 809 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698