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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 is_swapped_out_(false), | 91 is_swapped_out_(false), |
91 input_method_is_active_(false), | 92 input_method_is_active_(false), |
92 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 93 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
93 can_compose_inline_(true), | 94 can_compose_inline_(true), |
94 popup_type_(popup_type), | 95 popup_type_(popup_type), |
95 pending_window_rect_count_(0), | 96 pending_window_rect_count_(0), |
96 suppress_next_char_events_(false), | 97 suppress_next_char_events_(false), |
97 is_accelerated_compositing_active_(false), | 98 is_accelerated_compositing_active_(false), |
98 animation_update_pending_(false), | 99 animation_update_pending_(false), |
99 animation_task_posted_(false), | 100 animation_task_posted_(false), |
100 invalidation_task_posted_(false) { | 101 invalidation_task_posted_(false), |
102 invert_(false) { | |
101 RenderProcess::current()->AddRefProcess(); | 103 RenderProcess::current()->AddRefProcess(); |
102 DCHECK(RenderThread::Get()); | 104 DCHECK(RenderThread::Get()); |
103 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( | 105 has_disable_gpu_vsync_switch_ = CommandLine::ForCurrentProcess()->HasSwitch( |
104 switches::kDisableGpuVsync); | 106 switches::kDisableGpuVsync); |
105 } | 107 } |
106 | 108 |
107 RenderWidget::~RenderWidget() { | 109 RenderWidget::~RenderWidget() { |
108 DCHECK(!webwidget_) << "Leaking our WebWidget!"; | 110 DCHECK(!webwidget_) << "Leaking our WebWidget!"; |
109 STLDeleteElements(&updates_pending_swap_); | 111 STLDeleteElements(&updates_pending_swap_); |
110 if (current_paint_buf_) { | 112 if (current_paint_buf_) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) | 207 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) |
206 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) | 208 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) |
207 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) | 209 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus) |
208 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) | 210 IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive) |
209 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) | 211 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) |
210 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) | 212 IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) |
211 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) | 213 IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnMsgPaintAtSize) |
212 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) | 214 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint) |
213 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) | 215 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) |
214 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) | 216 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) |
217 IPC_MESSAGE_HANDLER(ViewMsg_InvertWebContent, OnInvertWebContent) | |
215 IPC_MESSAGE_UNHANDLED(handled = false) | 218 IPC_MESSAGE_UNHANDLED(handled = false) |
216 IPC_END_MESSAGE_MAP() | 219 IPC_END_MESSAGE_MAP() |
217 return handled; | 220 return handled; |
218 } | 221 } |
219 | 222 |
220 bool RenderWidget::Send(IPC::Message* message) { | 223 bool RenderWidget::Send(IPC::Message* message) { |
221 // Don't send any messages after the browser has told us to close, and filter | 224 // Don't send any messages after the browser has told us to close, and filter |
222 // most outgoing messages while swapped out. | 225 // most outgoing messages while swapped out. |
223 if ((is_swapped_out_ && | 226 if ((is_swapped_out_ && |
224 !content::SwappedOutMessages::CanSendWhileSwappedOut(message)) || | 227 !content::SwappedOutMessages::CanSendWhileSwappedOut(message)) || |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
556 const gfx::Point& canvas_origin, | 559 const gfx::Point& canvas_origin, |
557 skia::PlatformCanvas* canvas) { | 560 skia::PlatformCanvas* canvas) { |
558 TRACE_EVENT2("renderer", "PaintRect", | 561 TRACE_EVENT2("renderer", "PaintRect", |
559 "width", rect.width(), "height", rect.height()); | 562 "width", rect.width(), "height", rect.height()); |
560 canvas->save(); | 563 canvas->save(); |
561 | 564 |
562 // Bring the canvas into the coordinate system of the paint rect. | 565 // Bring the canvas into the coordinate system of the paint rect. |
563 canvas->translate(static_cast<SkScalar>(-canvas_origin.x()), | 566 canvas->translate(static_cast<SkScalar>(-canvas_origin.x()), |
564 static_cast<SkScalar>(-canvas_origin.y())); | 567 static_cast<SkScalar>(-canvas_origin.y())); |
565 | 568 |
569 if (invert_) { | |
570 // Draw everything to a temporary bitmap and then apply an | |
571 // inverting color map to the result. This is balanced by an extra | |
572 // call to canvas->restore(), below. | |
573 DCHECK(invert_paint_.get()); | |
574 SkRect bounds; | |
575 bounds.set(rect.x(), rect.y(), rect.right(), rect.bottom()); | |
576 canvas->saveLayer(&bounds, invert_paint_.get()); | |
vandebo (ex-Chrome)
2012/02/07 17:57:11
It's a shame that we have to do this in a layer.
| |
577 } | |
578 | |
566 // If there is a custom background, tile it. | 579 // If there is a custom background, tile it. |
567 if (!background_.empty()) { | 580 if (!background_.empty()) { |
568 SkPaint paint; | 581 SkPaint paint; |
569 SkShader* shader = SkShader::CreateBitmapShader(background_, | 582 SkShader* shader = SkShader::CreateBitmapShader(background_, |
570 SkShader::kRepeat_TileMode, | 583 SkShader::kRepeat_TileMode, |
571 SkShader::kRepeat_TileMode); | 584 SkShader::kRepeat_TileMode); |
572 paint.setShader(shader)->unref(); | 585 paint.setShader(shader)->unref(); |
573 | 586 |
574 // Use kSrc_Mode to handle background_ transparency properly. | 587 // Use kSrc_Mode to handle background_ transparency properly. |
575 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 588 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 optimized_instance->Paint(webkit_glue::ToWebCanvas(canvas), | 629 optimized_instance->Paint(webkit_glue::ToWebCanvas(canvas), |
617 optimized_copy_location, rect); | 630 optimized_copy_location, rect); |
618 } else { | 631 } else { |
619 // Normal painting case. | 632 // Normal painting case. |
620 webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect); | 633 webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect); |
621 | 634 |
622 // Flush to underlying bitmap. TODO(darin): is this needed? | 635 // Flush to underlying bitmap. TODO(darin): is this needed? |
623 skia::GetTopDevice(*canvas)->accessBitmap(false); | 636 skia::GetTopDevice(*canvas)->accessBitmap(false); |
624 } | 637 } |
625 | 638 |
639 if (invert_) | |
640 canvas->restore(); | |
641 | |
626 PaintDebugBorder(rect, canvas); | 642 PaintDebugBorder(rect, canvas); |
627 canvas->restore(); | 643 canvas->restore(); |
628 } | 644 } |
629 | 645 |
630 void RenderWidget::PaintDebugBorder(const gfx::Rect& rect, | 646 void RenderWidget::PaintDebugBorder(const gfx::Rect& rect, |
631 skia::PlatformCanvas* canvas) { | 647 skia::PlatformCanvas* canvas) { |
632 static bool kPaintBorder = | 648 static bool kPaintBorder = |
633 CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowPaintRects); | 649 CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowPaintRects); |
634 if (!kPaintBorder) | 650 if (!kPaintBorder) |
635 return; | 651 return; |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1353 didInvalidateRect(repaint_rect); | 1369 didInvalidateRect(repaint_rect); |
1354 } | 1370 } |
1355 } | 1371 } |
1356 | 1372 |
1357 void RenderWidget::OnSetTextDirection(WebTextDirection direction) { | 1373 void RenderWidget::OnSetTextDirection(WebTextDirection direction) { |
1358 if (!webwidget_) | 1374 if (!webwidget_) |
1359 return; | 1375 return; |
1360 webwidget_->setTextDirection(direction); | 1376 webwidget_->setTextDirection(direction); |
1361 } | 1377 } |
1362 | 1378 |
1379 void RenderWidget::OnInvertWebContent(bool invert) { | |
1380 invert_ = invert; | |
1381 if (!invert_paint_.get()) { | |
vandebo (ex-Chrome)
2012/02/07 17:57:11
nit: && invert
| |
1382 // Gamma-aware color inversion: each source pixel value x is normally | |
1383 // displayed on a computer monitor with a gamma correction x^gamma, | |
1384 // where gamma is typically in the range 1.8...2.2. By approximating | |
vandebo (ex-Chrome)
2012/02/07 17:57:11
I guess there isn't a way to look up the active ga
| |
1385 // gamma as exactly 2, the formula to invert one value is sqrt(1 - x^2). | |
1386 uint8_t table[256]; | |
1387 for (unsigned int i = 0; i < 256; i++) { | |
1388 double value = i / 255.0; | |
1389 value = sqrt(1 - (value * value)); | |
1390 table[i] = static_cast<uint8_t>(255 * value); | |
1391 } | |
1392 | |
1393 // Create a Skia Paint with this inverting color map. | |
1394 invert_paint_.reset(new SkPaint()); | |
1395 invert_paint_->setStyle(SkPaint::kFill_Style); | |
1396 invert_paint_->setColor(SK_ColorBLACK); | |
1397 SkColorFilter* filter = SkTableColorFilter::CreateARGB( | |
1398 NULL, table, table, table); | |
1399 invert_paint_->setColorFilter(filter); | |
1400 filter->unref(); | |
1401 } | |
1402 | |
1403 OnMsgRepaint(size_); | |
vandebo (ex-Chrome)
2012/02/07 17:57:11
nit: should we only repaint if invert changed?
| |
1404 } | |
1405 | |
1363 webkit::ppapi::PluginInstance* RenderWidget::GetBitmapForOptimizedPluginPaint( | 1406 webkit::ppapi::PluginInstance* RenderWidget::GetBitmapForOptimizedPluginPaint( |
1364 const gfx::Rect& paint_bounds, | 1407 const gfx::Rect& paint_bounds, |
1365 TransportDIB** dib, | 1408 TransportDIB** dib, |
1366 gfx::Rect* location, | 1409 gfx::Rect* location, |
1367 gfx::Rect* clip) { | 1410 gfx::Rect* clip) { |
1368 // Bare RenderWidgets don't support optimized plugin painting. | 1411 // Bare RenderWidgets don't support optimized plugin painting. |
1369 return NULL; | 1412 return NULL; |
1370 } | 1413 } |
1371 | 1414 |
1372 gfx::Point RenderWidget::GetScrollOffset() { | 1415 gfx::Point RenderWidget::GetScrollOffset() { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1576 } | 1619 } |
1577 } | 1620 } |
1578 | 1621 |
1579 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { | 1622 bool RenderWidget::WillHandleMouseEvent(const WebKit::WebMouseEvent& event) { |
1580 return false; | 1623 return false; |
1581 } | 1624 } |
1582 | 1625 |
1583 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { | 1626 bool RenderWidget::WebWidgetHandlesCompositorScheduling() const { |
1584 return false; | 1627 return false; |
1585 } | 1628 } |
OLD | NEW |