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 "content/renderer/render_widget.h" | 5 #include "content/renderer/render_widget.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
17 #include "content/common/swapped_out_messages.h" | 17 #include "content/common/swapped_out_messages.h" |
18 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
19 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
20 #include "content/renderer/gpu/compositor_thread.h" | 20 #include "content/renderer/gpu/compositor_thread.h" |
21 #include "content/renderer/render_process.h" | 21 #include "content/renderer/render_process.h" |
22 #include "content/renderer/render_thread_impl.h" | 22 #include "content/renderer/render_thread_impl.h" |
23 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | 23 #include "content/renderer/renderer_webkitplatformsupport_impl.h" |
24 #include "ipc/ipc_sync_message.h" | 24 #include "ipc/ipc_sync_message.h" |
25 #include "skia/ext/platform_canvas.h" | 25 #include "skia/ext/platform_canvas.h" |
26 #include "third_party/skia/include/core/SkShader.h" | 26 #include "third_party/skia/include/core/SkShader.h" |
| 27 #include "third_party/skia/include/effects/SkTableColorFilter.h" |
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" |
28 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPoint.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebPoint.h" |
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" | 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" |
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" | 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" |
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h" | 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h" |
32 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" | 33 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" |
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" |
34 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | 35 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" |
35 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" | 36 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" |
36 #include "ui/gfx/point.h" | 37 #include "ui/gfx/point.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 is_swapped_out_(false), | 92 is_swapped_out_(false), |
92 input_method_is_active_(false), | 93 input_method_is_active_(false), |
93 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 94 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
94 can_compose_inline_(true), | 95 can_compose_inline_(true), |
95 popup_type_(popup_type), | 96 popup_type_(popup_type), |
96 pending_window_rect_count_(0), | 97 pending_window_rect_count_(0), |
97 suppress_next_char_events_(false), | 98 suppress_next_char_events_(false), |
98 is_accelerated_compositing_active_(false), | 99 is_accelerated_compositing_active_(false), |
99 animation_update_pending_(false), | 100 animation_update_pending_(false), |
100 animation_task_posted_(false), | 101 animation_task_posted_(false), |
101 invalidation_task_posted_(false) { | 102 invalidation_task_posted_(false), |
| 103 invert_(false) { |
102 RenderProcess::current()->AddRefProcess(); | 104 RenderProcess::current()->AddRefProcess(); |
103 DCHECK(RenderThread::Get()); | 105 DCHECK(RenderThread::Get()); |
104 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( | 106 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( |
105 switches::kDisableGpuVsync); | 107 switches::kDisableGpuVsync); |
106 } | 108 } |
107 | 109 |
108 RenderWidget::~RenderWidget() { | 110 RenderWidget::~RenderWidget() { |
109 DCHECK(!webwidget_) << "Leaking our WebWidget!"; | 111 DCHECK(!webwidget_) << "Leaking our WebWidget!"; |
110 STLDeleteElements(&updates_pending_swap_); | 112 STLDeleteElements(&updates_pending_swap_); |
111 if (current_paint_buf_) { | 113 if (current_paint_buf_) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) | 212 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) |
211 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) | 213 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) |
212 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) | 214 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) |
213 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) | 215 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) |
214 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) | 216 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) |
215 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) | 217 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) |
216 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) | 218 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) |
217 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) | 219 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) |
218 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) | 220 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) |
219 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) | 221 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) |
| 222 IPC_MESSAGE_HANDLER(ViewMsg_InvertWebContent, OnInvertWebContent) |
220 IPC_MESSAGE_UNHANDLED(handled = false) | 223 IPC_MESSAGE_UNHANDLED(handled = false) |
221 IPC_END_MESSAGE_MAP() | 224 IPC_END_MESSAGE_MAP() |
222 return handled; | 225 return handled; |
223 } | 226 } |
224 | 227 |
225 bool RenderWidget::Send(IPC::Message* message) { | 228 bool RenderWidget::Send(IPC::Message* message) { |
226 // Don't send any messages after the browser has told us to close, and filter | 229 // Don't send any messages after the browser has told us to close, and filter |
227 // most outgoing messages while swapped out. | 230 // most outgoing messages while swapped out. |
228 if ((is_swapped_out_ && | 231 if ((is_swapped_out_ && |
229 !content::SwappedOutMessages::CanSendWhileSwappedOut(message)) || | 232 !content::SwappedOutMessages::CanSendWhileSwappedOut(message)) || |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 const gfx::Point& canvas_origin, | 583 const gfx::Point& canvas_origin, |
581 skia::PlatformCanvas* canvas) { | 584 skia::PlatformCanvas* canvas) { |
582 TRACE_EVENT2("renderer", "PaintRect", | 585 TRACE_EVENT2("renderer", "PaintRect", |
583 "width", rect.width(), "height", rect.height()); | 586 "width", rect.width(), "height", rect.height()); |
584 canvas->save(); | 587 canvas->save(); |
585 | 588 |
586 // Bring the canvas into the coordinate system of the paint rect. | 589 // Bring the canvas into the coordinate system of the paint rect. |
587 canvas->translate(static_cast<SkScalar>(-canvas_origin.x()), | 590 canvas->translate(static_cast<SkScalar>(-canvas_origin.x()), |
588 static_cast<SkScalar>(-canvas_origin.y())); | 591 static_cast<SkScalar>(-canvas_origin.y())); |
589 | 592 |
| 593 if (invert_) { |
| 594 // Draw everything to a temporary bitmap and then apply an |
| 595 // inverting color map to the result. This is balanced by an extra |
| 596 // call to canvas->restore(), below. |
| 597 DCHECK(invert_paint_.get()); |
| 598 SkRect bounds; |
| 599 bounds.set(rect.x(), rect.y(), rect.right(), rect.bottom()); |
| 600 canvas->saveLayer(&bounds, invert_paint_.get()); |
| 601 } |
| 602 |
590 // If there is a custom background, tile it. | 603 // If there is a custom background, tile it. |
591 if (!background_.empty()) { | 604 if (!background_.empty()) { |
592 SkPaint paint; | 605 SkPaint paint; |
593 SkShader* shader = SkShader::CreateBitmapShader(background_, | 606 SkShader* shader = SkShader::CreateBitmapShader(background_, |
594 SkShader::kRepeat_TileMode, | 607 SkShader::kRepeat_TileMode, |
595 SkShader::kRepeat_TileMode); | 608 SkShader::kRepeat_TileMode); |
596 paint.setShader(shader)->unref(); | 609 paint.setShader(shader)->unref(); |
597 | 610 |
598 // Use kSrc_Mode to handle background_ transparency properly. | 611 // Use kSrc_Mode to handle background_ transparency properly. |
599 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 612 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 optimized_instance->Paint(webkit_glue::ToWebCanvas(canvas), | 653 optimized_instance->Paint(webkit_glue::ToWebCanvas(canvas), |
641 optimized_copy_location, rect); | 654 optimized_copy_location, rect); |
642 } else { | 655 } else { |
643 // Normal painting case. | 656 // Normal painting case. |
644 webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect); | 657 webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect); |
645 | 658 |
646 // Flush to underlying bitmap. TODO(darin): is this needed? | 659 // Flush to underlying bitmap. TODO(darin): is this needed? |
647 skia::GetTopDevice(*canvas)->accessBitmap(false); | 660 skia::GetTopDevice(*canvas)->accessBitmap(false); |
648 } | 661 } |
649 | 662 |
| 663 if (invert_) |
| 664 canvas->restore(); |
| 665 |
650 PaintDebugBorder(rect, canvas); | 666 PaintDebugBorder(rect, canvas); |
651 canvas->restore(); | 667 canvas->restore(); |
652 } | 668 } |
653 | 669 |
654 void RenderWidget::PaintDebugBorder(const gfx::Rect& rect, | 670 void RenderWidget::PaintDebugBorder(const gfx::Rect& rect, |
655 skia::PlatformCanvas* canvas) { | 671 skia::PlatformCanvas* canvas) { |
656 static bool kPaintBorder = | 672 static bool kPaintBorder = |
657 CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowPaintRects); | 673 CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowPaintRects); |
658 if (!kPaintBorder) | 674 if (!kPaintBorder) |
659 return; | 675 return; |
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 didInvalidateRect(repaint_rect); | 1398 didInvalidateRect(repaint_rect); |
1383 } | 1399 } |
1384 } | 1400 } |
1385 | 1401 |
1386 void RenderWidget::OnSetTextDirection(WebTextDirection direction) { | 1402 void RenderWidget::OnSetTextDirection(WebTextDirection direction) { |
1387 if (!webwidget_) | 1403 if (!webwidget_) |
1388 return; | 1404 return; |
1389 webwidget_->setTextDirection(direction); | 1405 webwidget_->setTextDirection(direction); |
1390 } | 1406 } |
1391 | 1407 |
| 1408 void RenderWidget::OnInvertWebContent(bool invert) { |
| 1409 if (invert_ == invert) |
| 1410 return; |
| 1411 |
| 1412 invert_ = invert; |
| 1413 |
| 1414 if (invert_ && !invert_paint_.get()) { |
| 1415 // Gamma-aware color inversion: each source pixel value x is normally |
| 1416 // displayed on a computer monitor with a gamma correction x^gamma, |
| 1417 // where gamma is typically in the range 1.8...2.2. By approximating |
| 1418 // gamma as exactly 2, the formula to invert one value is sqrt(1 - x^2). |
| 1419 uint8_t table[256]; |
| 1420 for (unsigned int i = 0; i < 256; i++) { |
| 1421 double value = i / 255.0; |
| 1422 value = sqrt(1 - (value * value)); |
| 1423 table[i] = static_cast<uint8_t>(255 * value); |
| 1424 } |
| 1425 |
| 1426 // Create a Skia Paint with this inverting color map. |
| 1427 invert_paint_.reset(new SkPaint()); |
| 1428 invert_paint_->setStyle(SkPaint::kFill_Style); |
| 1429 invert_paint_->setColor(SK_ColorBLACK); |
| 1430 SkColorFilter* filter = SkTableColorFilter::CreateARGB( |
| 1431 NULL, table, table, table); |
| 1432 invert_paint_->setColorFilter(filter); |
| 1433 filter->unref(); |
| 1434 } |
| 1435 |
| 1436 OnMsgRepaint(size_); |
| 1437 } |
| 1438 |
1392 webkit::ppapi::PluginInstance* RenderWidget::GetBitmapForOptimizedPluginPaint( | 1439 webkit::ppapi::PluginInstance* RenderWidget::GetBitmapForOptimizedPluginPaint( |
1393 const gfx::Rect& paint_bounds, | 1440 const gfx::Rect& paint_bounds, |
1394 TransportDIB** dib, | 1441 TransportDIB** dib, |
1395 gfx::Rect* location, | 1442 gfx::Rect* location, |
1396 gfx::Rect* clip) { | 1443 gfx::Rect* clip) { |
1397 // Bare RenderWidgets don't support optimized plugin painting. | 1444 // Bare RenderWidgets don't support optimized plugin painting. |
1398 return NULL; | 1445 return NULL; |
1399 } | 1446 } |
1400 | 1447 |
1401 gfx::Point RenderWidget::GetScrollOffset() { | 1448 gfx::Point RenderWidget::GetScrollOffset() { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 } | 1652 } |
1606 } | 1653 } |
1607 | 1654 |
1608 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { | 1655 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { |
1609 return false; | 1656 return false; |
1610 } | 1657 } |
1611 | 1658 |
1612 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { | 1659 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { |
1613 return false; | 1660 return false; |
1614 } | 1661 } |
OLD | NEW |