[safe browsing] Push missing download BINHASH histograms.
[chromium-blink-merge.git] / cc / layers / painted_scrollbar_layer.cc
blob9060994ea81bcd440e83244548b864e1c03b3428
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.
5 #include "cc/layers/painted_scrollbar_layer.h"
7 #include "base/auto_reset.h"
8 #include "base/basictypes.h"
9 #include "base/debug/trace_event.h"
10 #include "cc/layers/painted_scrollbar_layer_impl.h"
11 #include "cc/resources/ui_resource_bitmap.h"
12 #include "cc/trees/layer_tree_host.h"
13 #include "cc/trees/layer_tree_impl.h"
14 #include "skia/ext/platform_canvas.h"
15 #include "skia/ext/refptr.h"
16 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "third_party/skia/include/core/SkSize.h"
19 #include "ui/gfx/skia_util.h"
21 namespace cc {
23 scoped_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl(
24 LayerTreeImpl* tree_impl) {
25 return PaintedScrollbarLayerImpl::Create(
26 tree_impl, id(), scrollbar_->Orientation()).PassAs<LayerImpl>();
29 scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create(
30 scoped_ptr<Scrollbar> scrollbar,
31 int scroll_layer_id) {
32 return make_scoped_refptr(
33 new PaintedScrollbarLayer(scrollbar.Pass(), scroll_layer_id));
36 PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_ptr<Scrollbar> scrollbar,
37 int scroll_layer_id)
38 : scrollbar_(scrollbar.Pass()),
39 scroll_layer_id_(scroll_layer_id),
40 clip_layer_id_(Layer::INVALID_ID),
41 thumb_thickness_(scrollbar_->ThumbThickness()),
42 thumb_length_(scrollbar_->ThumbLength()),
43 is_overlay_(scrollbar_->IsOverlay()),
44 has_thumb_(scrollbar_->HasThumb()) {
45 if (!scrollbar_->IsOverlay())
46 SetShouldScrollOnMainThread(true);
49 PaintedScrollbarLayer::~PaintedScrollbarLayer() {}
51 int PaintedScrollbarLayer::ScrollLayerId() const {
52 return scroll_layer_id_;
55 void PaintedScrollbarLayer::SetScrollLayer(int layer_id) {
56 if (layer_id == scroll_layer_id_)
57 return;
59 scroll_layer_id_ = layer_id;
60 SetNeedsFullTreeSync();
63 void PaintedScrollbarLayer::SetClipLayer(int layer_id) {
64 if (layer_id == clip_layer_id_)
65 return;
67 clip_layer_id_ = layer_id;
68 SetNeedsFullTreeSync();
71 bool PaintedScrollbarLayer::OpacityCanAnimateOnImplThread() const {
72 return scrollbar_->IsOverlay();
75 ScrollbarOrientation PaintedScrollbarLayer::orientation() const {
76 return scrollbar_->Orientation();
79 int PaintedScrollbarLayer::MaxTextureSize() {
80 DCHECK(layer_tree_host());
81 return layer_tree_host()->GetRendererCapabilities().max_texture_size;
84 float PaintedScrollbarLayer::ClampScaleToMaxTextureSize(float scale) {
85 // If the scaled content_bounds() is bigger than the max texture size of the
86 // device, we need to clamp it by rescaling, since content_bounds() is used
87 // below to set the texture size.
88 gfx::Size scaled_bounds = ComputeContentBoundsForScale(scale, scale);
89 if (scaled_bounds.width() > MaxTextureSize() ||
90 scaled_bounds.height() > MaxTextureSize()) {
91 if (scaled_bounds.width() > scaled_bounds.height())
92 return (MaxTextureSize() - 1) / static_cast<float>(bounds().width());
93 else
94 return (MaxTextureSize() - 1) / static_cast<float>(bounds().height());
96 return scale;
99 void PaintedScrollbarLayer::CalculateContentsScale(
100 float ideal_contents_scale,
101 float device_scale_factor,
102 float page_scale_factor,
103 bool animating_transform_to_screen,
104 float* contents_scale_x,
105 float* contents_scale_y,
106 gfx::Size* content_bounds) {
107 ContentsScalingLayer::CalculateContentsScale(
108 ClampScaleToMaxTextureSize(ideal_contents_scale),
109 device_scale_factor,
110 page_scale_factor,
111 animating_transform_to_screen,
112 contents_scale_x,
113 contents_scale_y,
114 content_bounds);
117 void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
118 ContentsScalingLayer::PushPropertiesTo(layer);
120 PushScrollClipPropertiesTo(layer);
122 PaintedScrollbarLayerImpl* scrollbar_layer =
123 static_cast<PaintedScrollbarLayerImpl*>(layer);
125 scrollbar_layer->SetThumbThickness(thumb_thickness_);
126 scrollbar_layer->SetThumbLength(thumb_length_);
127 if (orientation() == HORIZONTAL) {
128 scrollbar_layer->SetTrackStart(
129 track_rect_.x() - location_.x());
130 scrollbar_layer->SetTrackLength(track_rect_.width());
131 } else {
132 scrollbar_layer->SetTrackStart(
133 track_rect_.y() - location_.y());
134 scrollbar_layer->SetTrackLength(track_rect_.height());
137 if (track_resource_.get())
138 scrollbar_layer->set_track_ui_resource_id(track_resource_->id());
139 if (thumb_resource_.get())
140 scrollbar_layer->set_thumb_ui_resource_id(thumb_resource_->id());
142 scrollbar_layer->set_is_overlay_scrollbar(is_overlay_);
145 ScrollbarLayerInterface* PaintedScrollbarLayer::ToScrollbarLayer() {
146 return this;
149 void PaintedScrollbarLayer::PushScrollClipPropertiesTo(LayerImpl* layer) {
150 PaintedScrollbarLayerImpl* scrollbar_layer =
151 static_cast<PaintedScrollbarLayerImpl*>(layer);
153 scrollbar_layer->SetScrollLayerById(scroll_layer_id_);
154 scrollbar_layer->SetClipLayerById(clip_layer_id_);
157 void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
158 // When the LTH is set to null or has changed, then this layer should remove
159 // all of its associated resources.
160 if (!host || host != layer_tree_host()) {
161 track_resource_.reset();
162 thumb_resource_.reset();
165 ContentsScalingLayer::SetLayerTreeHost(host);
168 gfx::Rect PaintedScrollbarLayer::ScrollbarLayerRectToContentRect(
169 const gfx::Rect& layer_rect) const {
170 // Don't intersect with the bounds as in LayerRectToContentRect() because
171 // layer_rect here might be in coordinates of the containing layer.
172 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect(
173 layer_rect, contents_scale_x(), contents_scale_y());
174 // We should never return a rect bigger than the content_bounds().
175 gfx::Size clamped_size = expanded_rect.size();
176 clamped_size.SetToMin(content_bounds());
177 expanded_rect.set_size(clamped_size);
178 return expanded_rect;
181 gfx::Rect PaintedScrollbarLayer::OriginThumbRect() const {
182 gfx::Size thumb_size;
183 if (orientation() == HORIZONTAL) {
184 thumb_size =
185 gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness());
186 } else {
187 thumb_size =
188 gfx::Size(scrollbar_->ThumbThickness(), scrollbar_->ThumbLength());
190 return gfx::Rect(thumb_size);
193 void PaintedScrollbarLayer::UpdateThumbAndTrackGeometry() {
194 UpdateProperty(scrollbar_->TrackRect(), &track_rect_);
195 UpdateProperty(scrollbar_->Location(), &location_);
196 UpdateProperty(scrollbar_->IsOverlay(), &is_overlay_);
197 UpdateProperty(scrollbar_->HasThumb(), &has_thumb_);
198 if (has_thumb_) {
199 UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_);
200 UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_);
204 bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue,
205 const OcclusionTracker* occlusion) {
206 UpdateThumbAndTrackGeometry();
208 gfx::Rect track_layer_rect = gfx::Rect(location_, bounds());
209 gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect(
210 track_layer_rect);
212 if (track_rect_.IsEmpty() || scaled_track_rect.IsEmpty())
213 return false;
216 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
217 true);
218 ContentsScalingLayer::Update(queue, occlusion);
221 if (update_rect_.IsEmpty() && track_resource_)
222 return false;
224 track_resource_ = ScopedUIResource::Create(
225 layer_tree_host(),
226 RasterizeScrollbarPart(track_layer_rect, scaled_track_rect, TRACK));
228 gfx::Rect thumb_layer_rect = OriginThumbRect();
229 gfx::Rect scaled_thumb_rect =
230 ScrollbarLayerRectToContentRect(thumb_layer_rect);
231 if (has_thumb_ && !scaled_thumb_rect.IsEmpty()) {
232 thumb_resource_ = ScopedUIResource::Create(
233 layer_tree_host(),
234 RasterizeScrollbarPart(thumb_layer_rect, scaled_thumb_rect, THUMB));
237 // UI resources changed so push properties is needed.
238 SetNeedsPushProperties();
239 return true;
242 UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart(
243 const gfx::Rect& layer_rect,
244 const gfx::Rect& content_rect,
245 ScrollbarPart part) {
246 DCHECK(!content_rect.size().IsEmpty());
247 DCHECK(!layer_rect.size().IsEmpty());
249 SkBitmap skbitmap;
250 skbitmap.setConfig(SkBitmap::kARGB_8888_Config,
251 content_rect.width(),
252 content_rect.height());
253 skbitmap.allocPixels();
255 SkCanvas skcanvas(skbitmap);
257 float scale_x =
258 content_rect.width() / static_cast<float>(layer_rect.width());
259 float scale_y =
260 content_rect.height() / static_cast<float>(layer_rect.height());
262 skcanvas.scale(SkFloatToScalar(scale_x),
263 SkFloatToScalar(scale_y));
264 skcanvas.translate(SkFloatToScalar(-layer_rect.x()),
265 SkFloatToScalar(-layer_rect.y()));
267 SkRect layer_skrect = RectToSkRect(layer_rect);
268 SkPaint paint;
269 paint.setAntiAlias(false);
270 paint.setXfermodeMode(SkXfermode::kClear_Mode);
271 skcanvas.drawRect(layer_skrect, paint);
272 skcanvas.clipRect(layer_skrect);
274 scrollbar_->PaintPart(&skcanvas, part, layer_rect);
275 // Make sure that the pixels are no longer mutable to unavoid unnecessary
276 // allocation and copying.
277 skbitmap.setImmutable();
279 return UIResourceBitmap(skbitmap);
282 } // namespace cc