Turn on NaClBrowserTest.SuccessfulUMA under linux asan.
[chromium-blink-merge.git] / cc / layers / painted_scrollbar_layer.cc
blob6bb76368c485f7fecaccf6630c22661738b1540f
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(
37 scoped_ptr<Scrollbar> scrollbar,
38 int scroll_layer_id)
39 : scrollbar_(scrollbar.Pass()),
40 scroll_layer_id_(scroll_layer_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::SetScrollLayerId(int id) {
56 if (id == scroll_layer_id_)
57 return;
59 scroll_layer_id_ = id;
60 SetNeedsFullTreeSync();
63 bool PaintedScrollbarLayer::OpacityCanAnimateOnImplThread() const {
64 return scrollbar_->IsOverlay();
67 ScrollbarOrientation PaintedScrollbarLayer::orientation() const {
68 return scrollbar_->Orientation();
71 int PaintedScrollbarLayer::MaxTextureSize() {
72 DCHECK(layer_tree_host());
73 return layer_tree_host()->GetRendererCapabilities().max_texture_size;
76 float PaintedScrollbarLayer::ClampScaleToMaxTextureSize(float scale) {
77 // If the scaled content_bounds() is bigger than the max texture size of the
78 // device, we need to clamp it by rescaling, since content_bounds() is used
79 // below to set the texture size.
80 gfx::Size scaled_bounds = ComputeContentBoundsForScale(scale, scale);
81 if (scaled_bounds.width() > MaxTextureSize() ||
82 scaled_bounds.height() > MaxTextureSize()) {
83 if (scaled_bounds.width() > scaled_bounds.height())
84 return (MaxTextureSize() - 1) / static_cast<float>(bounds().width());
85 else
86 return (MaxTextureSize() - 1) / static_cast<float>(bounds().height());
88 return scale;
91 void PaintedScrollbarLayer::CalculateContentsScale(
92 float ideal_contents_scale,
93 float device_scale_factor,
94 float page_scale_factor,
95 bool animating_transform_to_screen,
96 float* contents_scale_x,
97 float* contents_scale_y,
98 gfx::Size* content_bounds) {
99 ContentsScalingLayer::CalculateContentsScale(
100 ClampScaleToMaxTextureSize(ideal_contents_scale),
101 device_scale_factor,
102 page_scale_factor,
103 animating_transform_to_screen,
104 contents_scale_x,
105 contents_scale_y,
106 content_bounds);
109 void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
110 ContentsScalingLayer::PushPropertiesTo(layer);
112 PaintedScrollbarLayerImpl* scrollbar_layer =
113 static_cast<PaintedScrollbarLayerImpl*>(layer);
115 scrollbar_layer->SetThumbThickness(thumb_thickness_);
116 scrollbar_layer->SetThumbLength(thumb_length_);
117 if (orientation() == HORIZONTAL) {
118 scrollbar_layer->SetTrackStart(
119 track_rect_.x() - location_.x());
120 scrollbar_layer->SetTrackLength(track_rect_.width());
121 } else {
122 scrollbar_layer->SetTrackStart(
123 track_rect_.y() - location_.y());
124 scrollbar_layer->SetTrackLength(track_rect_.height());
127 if (track_resource_.get())
128 scrollbar_layer->set_track_ui_resource_id(track_resource_->id());
129 if (thumb_resource_.get())
130 scrollbar_layer->set_thumb_ui_resource_id(thumb_resource_->id());
132 scrollbar_layer->set_is_overlay_scrollbar(is_overlay_);
135 ScrollbarLayerInterface* PaintedScrollbarLayer::ToScrollbarLayer() {
136 return this;
139 void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
140 // When the LTH is set to null or has changed, then this layer should remove
141 // all of its associated resources.
142 if (!host || host != layer_tree_host()) {
143 track_resource_.reset();
144 thumb_resource_.reset();
147 ContentsScalingLayer::SetLayerTreeHost(host);
150 gfx::Rect PaintedScrollbarLayer::ScrollbarLayerRectToContentRect(
151 gfx::Rect layer_rect) const {
152 // Don't intersect with the bounds as in LayerRectToContentRect() because
153 // layer_rect here might be in coordinates of the containing layer.
154 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect(
155 layer_rect, contents_scale_y(), contents_scale_y());
156 // We should never return a rect bigger than the content_bounds().
157 gfx::Size clamped_size = expanded_rect.size();
158 clamped_size.SetToMin(content_bounds());
159 expanded_rect.set_size(clamped_size);
160 return expanded_rect;
163 gfx::Rect PaintedScrollbarLayer::OriginThumbRect() const {
164 gfx::Size thumb_size;
165 if (orientation() == HORIZONTAL) {
166 thumb_size =
167 gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness());
168 } else {
169 thumb_size =
170 gfx::Size(scrollbar_->ThumbThickness(), scrollbar_->ThumbLength());
172 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size));
175 void PaintedScrollbarLayer::UpdateThumbAndTrackGeometry() {
176 UpdateProperty(scrollbar_->TrackRect(), &track_rect_);
177 UpdateProperty(scrollbar_->Location(), &location_);
178 UpdateProperty(scrollbar_->IsOverlay(), &is_overlay_);
179 UpdateProperty(scrollbar_->HasThumb(), &has_thumb_);
180 if (has_thumb_) {
181 UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_);
182 UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_);
186 bool PaintedScrollbarLayer::Update(ResourceUpdateQueue* queue,
187 const OcclusionTracker* occlusion) {
188 UpdateThumbAndTrackGeometry();
190 gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect(
191 gfx::Rect(location_, bounds()));
193 if (track_rect_.IsEmpty() || scaled_track_rect.IsEmpty())
194 return false;
197 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
198 true);
199 ContentsScalingLayer::Update(queue, occlusion);
202 if (update_rect_.IsEmpty() && track_resource_)
203 return false;
205 track_resource_ = ScopedUIResource::Create(
206 layer_tree_host(), RasterizeScrollbarPart(scaled_track_rect, TRACK));
208 gfx::Rect thumb_rect = OriginThumbRect();
209 if (has_thumb_ && !thumb_rect.IsEmpty()) {
210 thumb_resource_ = ScopedUIResource::Create(
211 layer_tree_host(), RasterizeScrollbarPart(thumb_rect, THUMB));
214 // UI resources changed so push properties is needed.
215 SetNeedsPushProperties();
216 return true;
219 UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart(
220 gfx::Rect rect,
221 ScrollbarPart part) {
222 DCHECK(!rect.size().IsEmpty());
224 SkBitmap skbitmap;
225 skbitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
226 skbitmap.allocPixels();
228 SkCanvas skcanvas(skbitmap);
229 skcanvas.translate(SkFloatToScalar(-rect.x()), SkFloatToScalar(-rect.y()));
230 skcanvas.scale(SkFloatToScalar(contents_scale_x()),
231 SkFloatToScalar(contents_scale_y()));
233 gfx::Rect layer_rect = gfx::ScaleToEnclosingRect(
234 rect, 1.f / contents_scale_x(), 1.f / contents_scale_y());
235 SkRect layer_skrect = RectToSkRect(layer_rect);
236 SkPaint paint;
237 paint.setAntiAlias(false);
238 paint.setXfermodeMode(SkXfermode::kClear_Mode);
239 skcanvas.drawRect(layer_skrect, paint);
240 skcanvas.clipRect(layer_skrect);
242 scrollbar_->PaintPart(&skcanvas, part, layer_rect);
243 // Make sure that the pixels are no longer mutable to unavoid unnecessary
244 // allocation and copying.
245 skbitmap.setImmutable();
247 return UIResourceBitmap(skbitmap);
250 } // namespace cc