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. 4 5 #include "ui/compositor/dip_util.h" 6 7 #include "base/command_line.h" 8 #include "cc/layers/layer.h" 9 #include "ui/compositor/compositor.h" 10 #include "ui/compositor/compositor_switches.h" 11 #include "ui/compositor/layer.h" 12 #include "ui/gfx/display.h" 13 #include "ui/gfx/geometry/safe_integer_conversions.h" 14 #include "ui/gfx/point.h" 15 #include "ui/gfx/point_conversions.h" 16 #include "ui/gfx/rect.h" 17 #include "ui/gfx/rect_conversions.h" 18 #include "ui/gfx/size.h" 19 #include "ui/gfx/size_conversions.h" 20 21 #if DCHECK_IS_ON 22 #include "ui/compositor/layer_animator.h" 23 #endif 24 25 namespace ui { 26 27 float GetDeviceScaleFactor(const Layer* layer) { 28 return layer->device_scale_factor(); 29 } 30 31 gfx::Point ConvertPointToDIP(const Layer* layer, 32 const gfx::Point& point_in_pixel) { 33 return gfx::ToFlooredPoint( 34 gfx::ScalePoint(point_in_pixel, 1.0f / GetDeviceScaleFactor(layer))); 35 } 36 37 gfx::PointF ConvertPointToDIP(const Layer* layer, 38 const gfx::PointF& point_in_pixel) { 39 return gfx::ScalePoint(point_in_pixel, 1.0f / GetDeviceScaleFactor(layer)); 40 } 41 42 gfx::Size ConvertSizeToDIP(const Layer* layer, 43 const gfx::Size& size_in_pixel) { 44 return gfx::ToFlooredSize( 45 gfx::ScaleSize(size_in_pixel, 1.0f / GetDeviceScaleFactor(layer))); 46 } 47 48 gfx::Rect ConvertRectToDIP(const Layer* layer, 49 const gfx::Rect& rect_in_pixel) { 50 float scale = 1.0f / GetDeviceScaleFactor(layer); 51 return gfx::ToFlooredRectDeprecated(gfx::ScaleRect(rect_in_pixel, scale)); 52 } 53 54 gfx::Point ConvertPointToPixel(const Layer* layer, 55 const gfx::Point& point_in_dip) { 56 return gfx::ToFlooredPoint( 57 gfx::ScalePoint(point_in_dip, GetDeviceScaleFactor(layer))); 58 } 59 60 gfx::Size ConvertSizeToPixel(const Layer* layer, 61 const gfx::Size& size_in_dip) { 62 return gfx::ToFlooredSize( 63 gfx::ScaleSize(size_in_dip, GetDeviceScaleFactor(layer))); 64 } 65 66 gfx::Rect ConvertRectToPixel(const Layer* layer, 67 const gfx::Rect& rect_in_dip) { 68 float scale = GetDeviceScaleFactor(layer); 69 // Use ToEnclosingRect() to ensure we paint all the possible pixels 70 // touched. ToEnclosingRect() floors the origin, and ceils the max 71 // coordinate. To do otherwise (such as flooring the size) potentially 72 // results in rounding down and not drawing all the pixels that are 73 // touched. 74 return gfx::ToEnclosingRect( 75 gfx::RectF(gfx::ScalePoint(rect_in_dip.origin(), scale), 76 gfx::ScaleSize(rect_in_dip.size(), scale))); 77 } 78 79 #if DCHECK_IS_ON 80 namespace { 81 82 void CheckSnapped(float snapped_position) { 83 const float kEplison = 0.0001f; 84 float diff = std::abs(snapped_position - gfx::ToRoundedInt(snapped_position)); 85 DCHECK_LT(diff, kEplison); 86 } 87 88 } // namespace 89 #endif 90 91 void SnapLayerToPhysicalPixelBoundary(ui::Layer* snapped_layer, 92 ui::Layer* layer_to_snap) { 93 DCHECK_NE(snapped_layer, layer_to_snap); 94 DCHECK(snapped_layer); 95 DCHECK(snapped_layer->Contains(layer_to_snap)); 96 97 gfx::Point view_offset_dips = layer_to_snap->GetTargetBounds().origin(); 98 ui::Layer::ConvertPointToLayer( 99 layer_to_snap->parent(), snapped_layer, &view_offset_dips); 100 gfx::PointF view_offset = view_offset_dips; 101 102 float scale_factor = GetDeviceScaleFactor(layer_to_snap); 103 view_offset.Scale(scale_factor); 104 gfx::PointF view_offset_snapped(gfx::ToRoundedInt(view_offset.x()), 105 gfx::ToRoundedInt(view_offset.y())); 106 107 gfx::Vector2dF fudge = view_offset_snapped - view_offset; 108 fudge.Scale(1.0 / scale_factor); 109 layer_to_snap->SetSubpixelPositionOffset(fudge); 110 #if DCHECK_IS_ON 111 gfx::Point layer_offset; 112 gfx::PointF origin; 113 Layer::ConvertPointToLayer( 114 layer_to_snap->parent(), snapped_layer, &layer_offset); 115 if (layer_to_snap->GetAnimator()->is_animating()) { 116 origin = layer_to_snap->GetTargetBounds().origin() + 117 layer_to_snap->subpixel_position_offset(); 118 } else { 119 cc::Layer* cc_layer = layer_to_snap->cc_layer(); 120 origin = cc_layer->position(); 121 } 122 CheckSnapped((layer_offset.x() + origin.x()) * scale_factor); 123 CheckSnapped((layer_offset.y() + origin.y()) * scale_factor); 124 #endif 125 } 126 127 } // namespace ui 128