OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "cc/layers/painted_scrollbar_layer.h" | 5 #include "cc/layers/painted_scrollbar_layer.h" |
6 | 6 |
7 #include <algorithm> | |
8 | |
9 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
10 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
11 #include "base/trace_event/trace_event.h" | 9 #include "base/trace_event/trace_event.h" |
12 #include "cc/base/math_util.h" | |
13 #include "cc/layers/painted_scrollbar_layer_impl.h" | 10 #include "cc/layers/painted_scrollbar_layer_impl.h" |
14 #include "cc/resources/ui_resource_bitmap.h" | 11 #include "cc/resources/ui_resource_bitmap.h" |
15 #include "cc/trees/layer_tree_host.h" | 12 #include "cc/trees/layer_tree_host.h" |
16 #include "cc/trees/layer_tree_impl.h" | 13 #include "cc/trees/layer_tree_impl.h" |
17 #include "skia/ext/platform_canvas.h" | 14 #include "skia/ext/platform_canvas.h" |
18 #include "skia/ext/refptr.h" | 15 #include "skia/ext/refptr.h" |
19 #include "third_party/skia/include/core/SkBitmap.h" | 16 #include "third_party/skia/include/core/SkBitmap.h" |
20 #include "third_party/skia/include/core/SkCanvas.h" | 17 #include "third_party/skia/include/core/SkCanvas.h" |
21 #include "third_party/skia/include/core/SkSize.h" | 18 #include "third_party/skia/include/core/SkSize.h" |
22 #include "ui/gfx/geometry/size_conversions.h" | |
23 #include "ui/gfx/skia_util.h" | 19 #include "ui/gfx/skia_util.h" |
24 | 20 |
25 namespace cc { | 21 namespace cc { |
26 | 22 |
27 scoped_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( | 23 scoped_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( |
28 LayerTreeImpl* tree_impl) { | 24 LayerTreeImpl* tree_impl) { |
29 return PaintedScrollbarLayerImpl::Create( | 25 return PaintedScrollbarLayerImpl::Create( |
30 tree_impl, id(), scrollbar_->Orientation()); | 26 tree_impl, id(), scrollbar_->Orientation()); |
31 } | 27 } |
32 | 28 |
33 scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create( | 29 scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create( |
34 scoped_ptr<Scrollbar> scrollbar, | 30 scoped_ptr<Scrollbar> scrollbar, |
35 int scroll_layer_id) { | 31 int scroll_layer_id) { |
36 return make_scoped_refptr( | 32 return make_scoped_refptr( |
37 new PaintedScrollbarLayer(scrollbar.Pass(), scroll_layer_id)); | 33 new PaintedScrollbarLayer(scrollbar.Pass(), scroll_layer_id)); |
38 } | 34 } |
39 | 35 |
40 PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, | 36 PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, |
41 int scroll_layer_id) | 37 int scroll_layer_id) |
42 : scrollbar_(scrollbar.Pass()), | 38 : scrollbar_(scrollbar.Pass()), |
43 scroll_layer_id_(scroll_layer_id), | 39 scroll_layer_id_(scroll_layer_id), |
44 clip_layer_id_(Layer::INVALID_ID), | 40 clip_layer_id_(Layer::INVALID_ID), |
45 internal_contents_scale_(0.f), | |
46 thumb_thickness_(scrollbar_->ThumbThickness()), | 41 thumb_thickness_(scrollbar_->ThumbThickness()), |
47 thumb_length_(scrollbar_->ThumbLength()), | 42 thumb_length_(scrollbar_->ThumbLength()), |
48 is_overlay_(scrollbar_->IsOverlay()), | 43 is_overlay_(scrollbar_->IsOverlay()), |
49 has_thumb_(scrollbar_->HasThumb()) { | 44 has_thumb_(scrollbar_->HasThumb()) { |
50 if (!scrollbar_->IsOverlay()) | 45 if (!scrollbar_->IsOverlay()) |
51 SetShouldScrollOnMainThread(true); | 46 SetShouldScrollOnMainThread(true); |
52 } | 47 } |
53 | 48 |
54 PaintedScrollbarLayer::~PaintedScrollbarLayer() {} | 49 PaintedScrollbarLayer::~PaintedScrollbarLayer() {} |
55 | 50 |
(...skipping 24 matching lines...) Expand all Loading... |
80 ScrollbarOrientation PaintedScrollbarLayer::orientation() const { | 75 ScrollbarOrientation PaintedScrollbarLayer::orientation() const { |
81 return scrollbar_->Orientation(); | 76 return scrollbar_->Orientation(); |
82 } | 77 } |
83 | 78 |
84 int PaintedScrollbarLayer::MaxTextureSize() { | 79 int PaintedScrollbarLayer::MaxTextureSize() { |
85 DCHECK(layer_tree_host()); | 80 DCHECK(layer_tree_host()); |
86 return layer_tree_host()->GetRendererCapabilities().max_texture_size; | 81 return layer_tree_host()->GetRendererCapabilities().max_texture_size; |
87 } | 82 } |
88 | 83 |
89 float PaintedScrollbarLayer::ClampScaleToMaxTextureSize(float scale) { | 84 float PaintedScrollbarLayer::ClampScaleToMaxTextureSize(float scale) { |
90 // If the scaled bounds() is bigger than the max texture size of the | 85 // If the scaled content_bounds() is bigger than the max texture size of the |
91 // device, we need to clamp it by rescaling, since this is used | 86 // device, we need to clamp it by rescaling, since content_bounds() is used |
92 // below to set the texture size. | 87 // below to set the texture size. |
93 gfx::Size scaled_bounds = gfx::ToCeiledSize(gfx::ScaleSize(bounds(), scale)); | 88 gfx::Size scaled_bounds = ComputeContentBoundsForScale(scale, scale); |
94 if (scaled_bounds.width() > MaxTextureSize() || | 89 if (scaled_bounds.width() > MaxTextureSize() || |
95 scaled_bounds.height() > MaxTextureSize()) { | 90 scaled_bounds.height() > MaxTextureSize()) { |
96 if (scaled_bounds.width() > scaled_bounds.height()) | 91 if (scaled_bounds.width() > scaled_bounds.height()) |
97 return (MaxTextureSize() - 1) / static_cast<float>(bounds().width()); | 92 return (MaxTextureSize() - 1) / static_cast<float>(bounds().width()); |
98 else | 93 else |
99 return (MaxTextureSize() - 1) / static_cast<float>(bounds().height()); | 94 return (MaxTextureSize() - 1) / static_cast<float>(bounds().height()); |
100 } | 95 } |
101 return scale; | 96 return scale; |
102 } | 97 } |
103 | 98 |
| 99 void PaintedScrollbarLayer::CalculateContentsScale( |
| 100 float ideal_contents_scale, |
| 101 float* contents_scale_x, |
| 102 float* contents_scale_y, |
| 103 gfx::Size* content_bounds) { |
| 104 ContentsScalingLayer::CalculateContentsScale( |
| 105 ClampScaleToMaxTextureSize(ideal_contents_scale), |
| 106 contents_scale_x, |
| 107 contents_scale_y, |
| 108 content_bounds); |
| 109 } |
| 110 |
104 void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { | 111 void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { |
105 Layer::PushPropertiesTo(layer); | 112 ContentsScalingLayer::PushPropertiesTo(layer); |
106 | 113 |
107 PushScrollClipPropertiesTo(layer); | 114 PushScrollClipPropertiesTo(layer); |
108 | 115 |
109 PaintedScrollbarLayerImpl* scrollbar_layer = | 116 PaintedScrollbarLayerImpl* scrollbar_layer = |
110 static_cast<PaintedScrollbarLayerImpl*>(layer); | 117 static_cast<PaintedScrollbarLayerImpl*>(layer); |
111 | 118 |
112 scrollbar_layer->set_internal_contents_scale_and_bounds( | |
113 internal_contents_scale_, internal_content_bounds_); | |
114 | |
115 scrollbar_layer->SetThumbThickness(thumb_thickness_); | 119 scrollbar_layer->SetThumbThickness(thumb_thickness_); |
116 scrollbar_layer->SetThumbLength(thumb_length_); | 120 scrollbar_layer->SetThumbLength(thumb_length_); |
117 if (orientation() == HORIZONTAL) { | 121 if (orientation() == HORIZONTAL) { |
118 scrollbar_layer->SetTrackStart( | 122 scrollbar_layer->SetTrackStart( |
119 track_rect_.x() - location_.x()); | 123 track_rect_.x() - location_.x()); |
120 scrollbar_layer->SetTrackLength(track_rect_.width()); | 124 scrollbar_layer->SetTrackLength(track_rect_.width()); |
121 } else { | 125 } else { |
122 scrollbar_layer->SetTrackStart( | 126 scrollbar_layer->SetTrackStart( |
123 track_rect_.y() - location_.y()); | 127 track_rect_.y() - location_.y()); |
124 scrollbar_layer->SetTrackLength(track_rect_.height()); | 128 scrollbar_layer->SetTrackLength(track_rect_.height()); |
(...skipping 24 matching lines...) Expand all Loading... |
149 } | 153 } |
150 | 154 |
151 void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { | 155 void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { |
152 // When the LTH is set to null or has changed, then this layer should remove | 156 // When the LTH is set to null or has changed, then this layer should remove |
153 // all of its associated resources. | 157 // all of its associated resources. |
154 if (!host || host != layer_tree_host()) { | 158 if (!host || host != layer_tree_host()) { |
155 track_resource_ = nullptr; | 159 track_resource_ = nullptr; |
156 thumb_resource_ = nullptr; | 160 thumb_resource_ = nullptr; |
157 } | 161 } |
158 | 162 |
159 Layer::SetLayerTreeHost(host); | 163 ContentsScalingLayer::SetLayerTreeHost(host); |
160 } | 164 } |
161 | 165 |
162 gfx::Rect PaintedScrollbarLayer::ScrollbarLayerRectToContentRect( | 166 gfx::Rect PaintedScrollbarLayer::ScrollbarLayerRectToContentRect( |
163 const gfx::Rect& layer_rect) const { | 167 const gfx::Rect& layer_rect) const { |
164 // Don't intersect with the bounds as in LayerRectToContentRect() because | 168 // Don't intersect with the bounds as in LayerRectToContentRect() because |
165 // layer_rect here might be in coordinates of the containing layer. | 169 // layer_rect here might be in coordinates of the containing layer. |
166 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect( | 170 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect( |
167 layer_rect, internal_contents_scale_, internal_contents_scale_); | 171 layer_rect, contents_scale_x(), contents_scale_y()); |
168 // We should never return a rect bigger than the content bounds. | 172 // We should never return a rect bigger than the content_bounds(). |
169 gfx::Size clamped_size = expanded_rect.size(); | 173 gfx::Size clamped_size = expanded_rect.size(); |
170 clamped_size.SetToMin(internal_content_bounds_); | 174 clamped_size.SetToMin(content_bounds()); |
171 expanded_rect.set_size(clamped_size); | 175 expanded_rect.set_size(clamped_size); |
172 return expanded_rect; | 176 return expanded_rect; |
173 } | 177 } |
174 | 178 |
175 gfx::Rect PaintedScrollbarLayer::OriginThumbRect() const { | 179 gfx::Rect PaintedScrollbarLayer::OriginThumbRect() const { |
176 gfx::Size thumb_size; | 180 gfx::Size thumb_size; |
177 if (orientation() == HORIZONTAL) { | 181 if (orientation() == HORIZONTAL) { |
178 thumb_size = | 182 thumb_size = |
179 gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness()); | 183 gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness()); |
180 } else { | 184 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
191 UpdateProperty(scrollbar_->HasThumb(), &has_thumb_); | 195 UpdateProperty(scrollbar_->HasThumb(), &has_thumb_); |
192 if (has_thumb_) { | 196 if (has_thumb_) { |
193 UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_); | 197 UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_); |
194 UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_); | 198 UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_); |
195 } else { | 199 } else { |
196 UpdateProperty(0, &thumb_thickness_); | 200 UpdateProperty(0, &thumb_thickness_); |
197 UpdateProperty(0, &thumb_length_); | 201 UpdateProperty(0, &thumb_length_); |
198 } | 202 } |
199 } | 203 } |
200 | 204 |
201 void PaintedScrollbarLayer::UpdateInternalContentScale() { | |
202 float scale = layer_tree_host()->device_scale_factor(); | |
203 if (layer_tree_host() | |
204 ->settings() | |
205 .layer_transforms_should_scale_layer_contents) { | |
206 gfx::Vector2dF transform_scales = | |
207 MathUtil::ComputeTransform2dScaleComponents(draw_transform(), scale); | |
208 scale = std::max(transform_scales.x(), transform_scales.y()); | |
209 } | |
210 bool changed = false; | |
211 changed |= UpdateProperty(ClampScaleToMaxTextureSize(scale), | |
212 &internal_contents_scale_); | |
213 changed |= UpdateProperty( | |
214 gfx::ToCeiledSize(gfx::ScaleSize(bounds(), internal_contents_scale_)), | |
215 &internal_content_bounds_); | |
216 if (changed) { | |
217 // If the content scale or bounds change, repaint. | |
218 SetNeedsDisplay(); | |
219 } | |
220 } | |
221 | |
222 bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue, | 205 bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue, |
223 const OcclusionTracker<Layer>* occlusion) { | 206 const OcclusionTracker<Layer>* occlusion) { |
224 { | |
225 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, | |
226 true); | |
227 Layer::Update(queue, occlusion); | |
228 UpdateInternalContentScale(); | |
229 } | |
230 | |
231 UpdateThumbAndTrackGeometry(); | 207 UpdateThumbAndTrackGeometry(); |
232 | 208 |
233 gfx::Rect track_layer_rect = gfx::Rect(location_, bounds()); | 209 gfx::Rect track_layer_rect = gfx::Rect(location_, bounds()); |
234 gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect( | 210 gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect( |
235 track_layer_rect); | 211 track_layer_rect); |
236 | 212 |
237 bool updated = false; | 213 bool updated = false; |
238 | 214 |
239 if (track_rect_.IsEmpty() || scaled_track_rect.IsEmpty()) { | 215 if (track_rect_.IsEmpty() || scaled_track_rect.IsEmpty()) { |
240 if (track_resource_) { | 216 if (track_resource_) { |
241 track_resource_ = nullptr; | 217 track_resource_ = nullptr; |
242 thumb_resource_ = nullptr; | 218 thumb_resource_ = nullptr; |
243 SetNeedsPushProperties(); | 219 SetNeedsPushProperties(); |
244 updated = true; | 220 updated = true; |
245 } | 221 } |
246 return updated; | 222 return updated; |
247 } | 223 } |
248 | 224 |
249 if (!has_thumb_ && thumb_resource_) { | 225 if (!has_thumb_ && thumb_resource_) { |
250 thumb_resource_ = nullptr; | 226 thumb_resource_ = nullptr; |
251 SetNeedsPushProperties(); | 227 SetNeedsPushProperties(); |
252 updated = true; | 228 } |
| 229 |
| 230 { |
| 231 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, |
| 232 true); |
| 233 ContentsScalingLayer::Update(queue, occlusion); |
253 } | 234 } |
254 | 235 |
255 if (update_rect_.IsEmpty() && track_resource_) | 236 if (update_rect_.IsEmpty() && track_resource_) |
256 return updated; | 237 return updated; |
257 | 238 |
258 track_resource_ = ScopedUIResource::Create( | 239 track_resource_ = ScopedUIResource::Create( |
259 layer_tree_host(), | 240 layer_tree_host(), |
260 RasterizeScrollbarPart(track_layer_rect, scaled_track_rect, TRACK)); | 241 RasterizeScrollbarPart(track_layer_rect, scaled_track_rect, TRACK)); |
261 | 242 |
262 gfx::Rect thumb_layer_rect = OriginThumbRect(); | 243 gfx::Rect thumb_layer_rect = OriginThumbRect(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 | 285 |
305 scrollbar_->PaintPart(&skcanvas, part, layer_rect); | 286 scrollbar_->PaintPart(&skcanvas, part, layer_rect); |
306 // Make sure that the pixels are no longer mutable to unavoid unnecessary | 287 // Make sure that the pixels are no longer mutable to unavoid unnecessary |
307 // allocation and copying. | 288 // allocation and copying. |
308 skbitmap.setImmutable(); | 289 skbitmap.setImmutable(); |
309 | 290 |
310 return UIResourceBitmap(skbitmap); | 291 return UIResourceBitmap(skbitmap); |
311 } | 292 } |
312 | 293 |
313 } // namespace cc | 294 } // namespace cc |
OLD | NEW |