1 // Copyright 2013 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 "webkit/renderer/compositor_bindings/web_layer_impl_fixed_bounds.h" 6 7 #include "cc/layers/layer.h" 8 #include "third_party/WebKit/public/platform/WebFloatPoint.h" 9 #include "third_party/WebKit/public/platform/WebSize.h" 10 #include "third_party/skia/include/utils/SkMatrix44.h" 11 12 using cc::Layer; 13 14 namespace webkit { 15 WebLayerImplFixedBounds()16WebLayerImplFixedBounds::WebLayerImplFixedBounds() { 17 } 18 WebLayerImplFixedBounds(scoped_refptr<Layer> layer)19WebLayerImplFixedBounds::WebLayerImplFixedBounds(scoped_refptr<Layer> layer) 20 : WebLayerImpl(layer) { 21 } 22 23 ~WebLayerImplFixedBounds()24WebLayerImplFixedBounds::~WebLayerImplFixedBounds() { 25 } 26 invalidateRect(const blink::WebFloatRect & rect)27void WebLayerImplFixedBounds::invalidateRect(const blink::WebFloatRect& rect) { 28 // Partial invalidations seldom occur for such layers. 29 // Simply invalidate the whole layer to avoid transformation of coordinates. 30 invalidate(); 31 } 32 setAnchorPoint(const blink::WebFloatPoint & anchor_point)33void WebLayerImplFixedBounds::setAnchorPoint( 34 const blink::WebFloatPoint& anchor_point) { 35 if (anchor_point != this->anchorPoint()) { 36 layer_->SetAnchorPoint(anchor_point); 37 UpdateLayerBoundsAndTransform(); 38 } 39 } 40 setBounds(const blink::WebSize & bounds)41void WebLayerImplFixedBounds::setBounds(const blink::WebSize& bounds) { 42 if (original_bounds_ != gfx::Size(bounds)) { 43 original_bounds_ = bounds; 44 UpdateLayerBoundsAndTransform(); 45 } 46 } 47 bounds() const48blink::WebSize WebLayerImplFixedBounds::bounds() const { 49 return original_bounds_; 50 } 51 setSublayerTransform(const SkMatrix44 & matrix)52void WebLayerImplFixedBounds::setSublayerTransform(const SkMatrix44& matrix) { 53 gfx::Transform transform; 54 transform.matrix() = matrix; 55 SetSublayerTransformInternal(transform); 56 } 57 sublayerTransform() const58SkMatrix44 WebLayerImplFixedBounds::sublayerTransform() const { 59 return original_sublayer_transform_.matrix(); 60 } 61 setTransform(const SkMatrix44 & matrix)62void WebLayerImplFixedBounds::setTransform(const SkMatrix44& matrix) { 63 gfx::Transform transform; 64 transform.matrix() = matrix; 65 SetTransformInternal(transform); 66 } 67 transform() const68SkMatrix44 WebLayerImplFixedBounds::transform() const { 69 return original_transform_.matrix(); 70 } 71 SetFixedBounds(gfx::Size fixed_bounds)72void WebLayerImplFixedBounds::SetFixedBounds(gfx::Size fixed_bounds) { 73 if (fixed_bounds_ != fixed_bounds) { 74 fixed_bounds_ = fixed_bounds; 75 UpdateLayerBoundsAndTransform(); 76 } 77 } 78 SetSublayerTransformInternal(const gfx::Transform & transform)79void WebLayerImplFixedBounds::SetSublayerTransformInternal( 80 const gfx::Transform& transform) { 81 if (original_sublayer_transform_ != transform) { 82 original_sublayer_transform_ = transform; 83 UpdateLayerBoundsAndTransform(); 84 } 85 } 86 SetTransformInternal(const gfx::Transform & transform)87void WebLayerImplFixedBounds::SetTransformInternal( 88 const gfx::Transform& transform) { 89 if (original_transform_ != transform) { 90 original_transform_ = transform; 91 UpdateLayerBoundsAndTransform(); 92 } 93 } 94 UpdateLayerBoundsAndTransform()95void WebLayerImplFixedBounds::UpdateLayerBoundsAndTransform() { 96 if (fixed_bounds_.IsEmpty() || original_bounds_.IsEmpty() || 97 fixed_bounds_ == original_bounds_ || 98 // For now fall back to non-fixed bounds for non-zero anchor point. 99 // TODO(wangxianzhu): Support non-zero anchor point for fixed bounds. 100 anchorPoint().x || anchorPoint().y) { 101 layer_->SetBounds(original_bounds_); 102 layer_->SetTransform(original_transform_); 103 layer_->SetSublayerTransform(original_sublayer_transform_); 104 return; 105 } 106 107 layer_->SetBounds(fixed_bounds_); 108 109 // Apply bounds scale (bounds/fixed_bounds) over original transform. 110 gfx::Transform transform_with_bounds_scale(original_transform_); 111 float bounds_scale_x = 112 static_cast<float>(original_bounds_.width()) / fixed_bounds_.width(); 113 float bounds_scale_y = 114 static_cast<float>(original_bounds_.height()) / fixed_bounds_.height(); 115 transform_with_bounds_scale.Scale(bounds_scale_x, bounds_scale_y); 116 layer_->SetTransform(transform_with_bounds_scale); 117 118 // As we apply extra scale transform on this layer which will propagate to the 119 // sublayers, here undo the scale on sublayers. 120 gfx::Transform sublayer_transform_with_inverse_bounds_scale; 121 sublayer_transform_with_inverse_bounds_scale.Scale(1.f / bounds_scale_x, 122 1.f / bounds_scale_y); 123 sublayer_transform_with_inverse_bounds_scale.PreconcatTransform( 124 original_sublayer_transform_); 125 layer_->SetSublayerTransform(sublayer_transform_with_inverse_bounds_scale); 126 } 127 128 } // namespace webkit 129