Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / display / overscan_calibrator.cc
blobcd679d93d8f50e05a0ea1a50fd9d7368675ad508
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
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/display/overscan_calibrator.h"
7 #include "ash/display/display_info.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/display/window_tree_host_manager.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "base/callback.h"
13 #include "third_party/skia/include/core/SkColor.h"
14 #include "third_party/skia/include/core/SkPaint.h"
15 #include "third_party/skia/include/core/SkPath.h"
16 #include "ui/aura/window.h"
17 #include "ui/compositor/layer.h"
18 #include "ui/compositor/paint_recorder.h"
19 #include "ui/gfx/canvas.h"
21 namespace chromeos {
22 namespace {
24 // The opacity for the arrows of the overscan calibration.
25 const float kArrowOpacity = 0.8;
27 // The height in pixel for the arrows to show the overscan calibration.
28 const int kCalibrationArrowHeight = 50;
30 // The gap between the boundary and calibration arrows.
31 const int kArrowGapWidth = 20;
33 // Draw the arrow for the overscan calibration to |canvas|.
34 void DrawTriangle(int x_offset,
35 int y_offset,
36 double rotation_degree,
37 gfx::Canvas* canvas) {
38 // Draw triangular arrows.
39 SkPaint content_paint;
40 content_paint.setStyle(SkPaint::kFill_Style);
41 content_paint.setColor(SkColorSetA(SK_ColorBLACK, kuint8max * kArrowOpacity));
42 SkPaint border_paint;
43 border_paint.setStyle(SkPaint::kStroke_Style);
44 border_paint.setColor(SkColorSetA(SK_ColorWHITE, kuint8max * kArrowOpacity));
46 SkPath base_path;
47 base_path.moveTo(0, SkIntToScalar(-kCalibrationArrowHeight));
48 base_path.lineTo(SkIntToScalar(-kCalibrationArrowHeight), 0);
49 base_path.lineTo(SkIntToScalar(kCalibrationArrowHeight), 0);
50 base_path.close();
52 SkPath path;
53 gfx::Transform rotate_transform;
54 rotate_transform.Rotate(rotation_degree);
55 gfx::Transform move_transform;
56 move_transform.Translate(x_offset, y_offset);
57 rotate_transform.ConcatTransform(move_transform);
58 base_path.transform(rotate_transform.matrix(), &path);
60 canvas->DrawPath(path, content_paint);
61 canvas->DrawPath(path, border_paint);
64 } // namespace
66 OverscanCalibrator::OverscanCalibrator(
67 const gfx::Display& target_display, const gfx::Insets& initial_insets)
68 : display_(target_display),
69 insets_(initial_insets),
70 initial_insets_(initial_insets),
71 committed_(false) {
72 // Undo the overscan calibration temporarily so that the user can see
73 // dark boundary and current overscan region.
74 ash::Shell::GetInstance()->window_tree_host_manager()->SetOverscanInsets(
75 display_.id(), gfx::Insets());
77 ash::DisplayInfo info =
78 ash::Shell::GetInstance()->display_manager()->GetDisplayInfo(
79 display_.id());
81 aura::Window* root = ash::Shell::GetInstance()
82 ->window_tree_host_manager()
83 ->GetRootWindowForDisplayId(display_.id());
84 ui::Layer* parent_layer =
85 ash::Shell::GetContainer(root, ash::kShellWindowId_OverlayContainer)
86 ->layer();
88 calibration_layer_.reset(new ui::Layer());
89 calibration_layer_->SetOpacity(0.5f);
90 calibration_layer_->SetBounds(parent_layer->bounds());
91 calibration_layer_->set_delegate(this);
92 parent_layer->Add(calibration_layer_.get());
95 OverscanCalibrator::~OverscanCalibrator() {
96 // Overscan calibration has finished without commit, so the display has to
97 // be the original offset.
98 if (!committed_) {
99 ash::Shell::GetInstance()->window_tree_host_manager()->SetOverscanInsets(
100 display_.id(), initial_insets_);
104 void OverscanCalibrator::Commit() {
105 ash::Shell::GetInstance()->window_tree_host_manager()->SetOverscanInsets(
106 display_.id(), insets_);
107 committed_ = true;
110 void OverscanCalibrator::Reset() {
111 insets_ = initial_insets_;
112 calibration_layer_->SchedulePaint(calibration_layer_->bounds());
115 void OverscanCalibrator::UpdateInsets(const gfx::Insets& insets) {
116 insets_.Set(std::max(insets.top(), 0),
117 std::max(insets.left(), 0),
118 std::max(insets.bottom(), 0),
119 std::max(insets.right(), 0));
120 calibration_layer_->SchedulePaint(calibration_layer_->bounds());
123 void OverscanCalibrator::OnPaintLayer(const ui::PaintContext& context) {
124 ui::PaintRecorder recorder(context, calibration_layer_->size());
125 static const SkColor kTransparent = SkColorSetARGB(0, 0, 0, 0);
126 gfx::Rect full_bounds = calibration_layer_->bounds();
127 gfx::Rect inner_bounds = full_bounds;
128 inner_bounds.Inset(insets_);
129 recorder.canvas()->FillRect(full_bounds, SK_ColorBLACK);
130 recorder.canvas()->FillRect(inner_bounds, kTransparent,
131 SkXfermode::kClear_Mode);
133 gfx::Point center = inner_bounds.CenterPoint();
134 int vertical_offset = inner_bounds.height() / 2 - kArrowGapWidth;
135 int horizontal_offset = inner_bounds.width() / 2 - kArrowGapWidth;
137 gfx::Canvas* canvas = recorder.canvas();
138 DrawTriangle(center.x(), center.y() + vertical_offset, 0, canvas);
139 DrawTriangle(center.x(), center.y() - vertical_offset, 180, canvas);
140 DrawTriangle(center.x() - horizontal_offset, center.y(), 90, canvas);
141 DrawTriangle(center.x() + horizontal_offset, center.y(), -90, canvas);
144 void OverscanCalibrator::OnDelegatedFrameDamage(
145 const gfx::Rect& damage_rect_in_dip) {
148 void OverscanCalibrator::OnDeviceScaleFactorChanged(
149 float device_scale_factor) {
150 // TODO(mukai): Cancel the overscan calibration when the device
151 // configuration has changed.
154 base::Closure OverscanCalibrator::PrepareForLayerBoundsChange() {
155 return base::Closure();
158 } // namespace chromeos