Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Side by Side Diff: cc/scrollbar_layer.cc

Issue 12603013: Part 10 of cc/ directory shuffles: layers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/scrollbar_layer.h ('k') | cc/scrollbar_layer_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 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 "cc/scrollbar_layer.h"
6
7 #include "base/basictypes.h"
8 #include "base/debug/trace_event.h"
9 #include "cc/resources/caching_bitmap_content_layer_updater.h"
10 #include "cc/resources/layer_painter.h"
11 #include "cc/resources/prioritized_resource.h"
12 #include "cc/resources/resource_update_queue.h"
13 #include "cc/scrollbar_layer_impl.h"
14 #include "cc/trees/layer_tree_host.h"
15 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
16 #include "ui/gfx/rect_conversions.h"
17
18 namespace cc {
19
20 scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl(
21 LayerTreeImpl* tree_impl) {
22 return ScrollbarLayerImpl::Create(
23 tree_impl,
24 id(),
25 ScrollbarGeometryFixedThumb::create(make_scoped_ptr(geometry_->clone())))
26 .PassAs<LayerImpl>();
27 }
28
29 scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create(
30 scoped_ptr<WebKit::WebScrollbar> scrollbar,
31 scoped_ptr<ScrollbarThemePainter> painter,
32 scoped_ptr<WebKit::WebScrollbarThemeGeometry> geometry,
33 int scrollLayerId) {
34 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(),
35 painter.Pass(),
36 geometry.Pass(),
37 scrollLayerId));
38 }
39
40 ScrollbarLayer::ScrollbarLayer(
41 scoped_ptr<WebKit::WebScrollbar> scrollbar,
42 scoped_ptr<ScrollbarThemePainter> painter,
43 scoped_ptr<WebKit::WebScrollbarThemeGeometry> geometry,
44 int scrollLayerId)
45 : scrollbar_(scrollbar.Pass()),
46 painter_(painter.Pass()),
47 geometry_(geometry.Pass()),
48 scroll_layer_id_(scrollLayerId),
49 texture_format_(GL_INVALID_ENUM) {
50 if (!scrollbar_->isOverlay())
51 SetShouldScrollOnMainThread(true);
52 }
53
54 ScrollbarLayer::~ScrollbarLayer() {}
55
56 void ScrollbarLayer::SetScrollLayerId(int id) {
57 if (id == scroll_layer_id_)
58 return;
59
60 scroll_layer_id_ = id;
61 SetNeedsFullTreeSync();
62 }
63
64 bool ScrollbarLayer::OpacityCanAnimateOnImplThread() const {
65 return scrollbar_->isOverlay();
66 }
67
68 WebKit::WebScrollbar::Orientation ScrollbarLayer::Orientation() const {
69 return scrollbar_->orientation();
70 }
71
72 int ScrollbarLayer::MaxTextureSize() {
73 DCHECK(layer_tree_host());
74 return layer_tree_host()->GetRendererCapabilities().max_texture_size;
75 }
76
77 float ScrollbarLayer::ClampScaleToMaxTextureSize(float scale) {
78 if (layer_tree_host()->settings().solidColorScrollbars)
79 return scale;
80
81 // If the scaled content_bounds() is bigger than the max texture size of the
82 // device, we need to clamp it by rescaling, since content_bounds() is used
83 // below to set the texture size.
84 gfx::Size scaled_bounds = ComputeContentBoundsForScale(scale, scale);
85 if (scaled_bounds.width() > MaxTextureSize() ||
86 scaled_bounds.height() > MaxTextureSize()) {
87 if (scaled_bounds.width() > scaled_bounds.height())
88 return (MaxTextureSize() - 1) / static_cast<float>(bounds().width());
89 else
90 return (MaxTextureSize() - 1) / static_cast<float>(bounds().height());
91 }
92 return scale;
93 }
94
95 void ScrollbarLayer::CalculateContentsScale(float ideal_contents_scale,
96 bool animating_transform_to_screen,
97 float* contents_scale_x,
98 float* contents_scale_y,
99 gfx::Size* contentBounds) {
100 ContentsScalingLayer::CalculateContentsScale(
101 ClampScaleToMaxTextureSize(ideal_contents_scale),
102 animating_transform_to_screen,
103 contents_scale_x,
104 contents_scale_y,
105 contentBounds);
106 DCHECK_LE(contentBounds->width(), MaxTextureSize());
107 DCHECK_LE(contentBounds->height(), MaxTextureSize());
108 }
109
110 void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
111 ContentsScalingLayer::PushPropertiesTo(layer);
112
113 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer);
114
115 scrollbar_layer->SetScrollbarData(scrollbar_.get());
116 scrollbar_layer->SetThumbSize(thumb_size_);
117
118 if (back_track_ && back_track_->texture()->haveBackingTexture()) {
119 scrollbar_layer->set_back_track_resource_id(
120 back_track_->texture()->resourceId());
121 } else {
122 scrollbar_layer->set_back_track_resource_id(0);
123 }
124
125 if (fore_track_ && fore_track_->texture()->haveBackingTexture()) {
126 scrollbar_layer->set_fore_track_resource_id(
127 fore_track_->texture()->resourceId());
128 } else {
129 scrollbar_layer->set_fore_track_resource_id(0);
130 }
131
132 if (thumb_ && thumb_->texture()->haveBackingTexture())
133 scrollbar_layer->set_thumb_resource_id(thumb_->texture()->resourceId());
134 else
135 scrollbar_layer->set_thumb_resource_id(0);
136
137 // Pinch zoom scrollbarLayerImpl does not get its scroll_layer_id_
138 // set in LayerImpl, so we need to push it here.
139 if (scroll_layer_id_ == Layer::PINCH_ZOOM_ROOT_SCROLL_LAYER_ID)
140 scrollbar_layer->set_scroll_layer_id(scroll_layer_id_);
141 }
142
143 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() {
144 return this;
145 }
146
147 class ScrollbarBackgroundPainter : public LayerPainter {
148 public:
149 static scoped_ptr<ScrollbarBackgroundPainter> Create(
150 WebKit::WebScrollbar* scrollbar,
151 ScrollbarThemePainter *painter,
152 WebKit::WebScrollbarThemeGeometry* geometry,
153 WebKit::WebScrollbar::ScrollbarPart trackPart) {
154 return make_scoped_ptr(new ScrollbarBackgroundPainter(scrollbar,
155 painter,
156 geometry,
157 trackPart));
158 }
159
160 virtual void Paint(SkCanvas* canvas,
161 gfx::Rect content_rect,
162 gfx::RectF* opaque) OVERRIDE {
163 // The following is a simplification of ScrollbarThemeComposite::paint.
164 painter_->PaintScrollbarBackground(canvas, content_rect);
165
166 if (geometry_->hasButtons(scrollbar_)) {
167 gfx::Rect back_button_start_paint_rect =
168 geometry_->backButtonStartRect(scrollbar_);
169 painter_->PaintBackButtonStart(canvas, back_button_start_paint_rect);
170
171 gfx::Rect back_button_end_paint_rect =
172 geometry_->backButtonEndRect(scrollbar_);
173 painter_->PaintBackButtonEnd(canvas, back_button_end_paint_rect);
174
175 gfx::Rect forward_button_start_paint_rect =
176 geometry_->forwardButtonStartRect(scrollbar_);
177 painter_->PaintForwardButtonStart(canvas,
178 forward_button_start_paint_rect);
179
180 gfx::Rect forward_button_end_paint_rect =
181 geometry_->forwardButtonEndRect(scrollbar_);
182 painter_->PaintForwardButtonEnd(canvas, forward_button_end_paint_rect);
183 }
184
185 gfx::Rect track_paint_rect = geometry_->trackRect(scrollbar_);
186 painter_->PaintTrackBackground(canvas, track_paint_rect);
187
188 bool thumb_present = geometry_->hasThumb(scrollbar_);
189 if (thumb_present) {
190 if (track_part_ == WebKit::WebScrollbar::ForwardTrackPart)
191 painter_->PaintForwardTrackPart(canvas, track_paint_rect);
192 else
193 painter_->PaintBackTrackPart(canvas, track_paint_rect);
194 }
195
196 painter_->PaintTickmarks(canvas, track_paint_rect);
197 }
198 private:
199 ScrollbarBackgroundPainter(WebKit::WebScrollbar* scrollbar,
200 ScrollbarThemePainter *painter,
201 WebKit::WebScrollbarThemeGeometry* geometry,
202 WebKit::WebScrollbar::ScrollbarPart trackPart)
203 : scrollbar_(scrollbar),
204 painter_(painter),
205 geometry_(geometry),
206 track_part_(trackPart) {}
207
208 WebKit::WebScrollbar* scrollbar_;
209 ScrollbarThemePainter* painter_;
210 WebKit::WebScrollbarThemeGeometry* geometry_;
211 WebKit::WebScrollbar::ScrollbarPart track_part_;
212
213 DISALLOW_COPY_AND_ASSIGN(ScrollbarBackgroundPainter);
214 };
215
216 class ScrollbarThumbPainter : public LayerPainter {
217 public:
218 static scoped_ptr<ScrollbarThumbPainter> Create(
219 WebKit::WebScrollbar* scrollbar,
220 ScrollbarThemePainter* painter,
221 WebKit::WebScrollbarThemeGeometry* geometry) {
222 return make_scoped_ptr(new ScrollbarThumbPainter(scrollbar,
223 painter,
224 geometry));
225 }
226
227 virtual void Paint(SkCanvas* canvas,
228 gfx::Rect content_rect,
229 gfx::RectF* opaque) OVERRIDE {
230 // Consider the thumb to be at the origin when painting.
231 gfx::Rect thumb_rect = geometry_->thumbRect(scrollbar_);
232 painter_->PaintThumb(canvas, gfx::Rect(thumb_rect.size()));
233 }
234
235 private:
236 ScrollbarThumbPainter(WebKit::WebScrollbar* scrollbar,
237 ScrollbarThemePainter* painter,
238 WebKit::WebScrollbarThemeGeometry* geometry)
239 : scrollbar_(scrollbar),
240 painter_(painter),
241 geometry_(geometry) {}
242
243 WebKit::WebScrollbar* scrollbar_;
244 ScrollbarThemePainter* painter_;
245 WebKit::WebScrollbarThemeGeometry* geometry_;
246
247 DISALLOW_COPY_AND_ASSIGN(ScrollbarThumbPainter);
248 };
249
250 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
251 if (!host || host != layer_tree_host()) {
252 back_track_updater_ = NULL;
253 back_track_.reset();
254 thumb_updater_ = NULL;
255 thumb_.reset();
256 }
257
258 ContentsScalingLayer::SetLayerTreeHost(host);
259 }
260
261 void ScrollbarLayer::CreateUpdaterIfNeeded() {
262 if (layer_tree_host()->settings().solidColorScrollbars)
263 return;
264
265 texture_format_ =
266 layer_tree_host()->GetRendererCapabilities().best_texture_format;
267
268 if (!back_track_updater_) {
269 back_track_updater_ = CachingBitmapContentLayerUpdater::Create(
270 ScrollbarBackgroundPainter::Create(
271 scrollbar_.get(),
272 painter_.get(),
273 geometry_.get(),
274 WebKit::WebScrollbar::BackTrackPart).PassAs<LayerPainter>());
275 }
276 if (!back_track_) {
277 back_track_ = back_track_updater_->CreateResource(
278 layer_tree_host()->contents_texture_manager());
279 }
280
281 // Only create two-part track if we think the two parts could be different in
282 // appearance.
283 if (scrollbar_->isCustomScrollbar()) {
284 if (!fore_track_updater_) {
285 fore_track_updater_ = CachingBitmapContentLayerUpdater::Create(
286 ScrollbarBackgroundPainter::Create(
287 scrollbar_.get(),
288 painter_.get(),
289 geometry_.get(),
290 WebKit::WebScrollbar::ForwardTrackPart).PassAs<LayerPainter>());
291 }
292 if (!fore_track_) {
293 fore_track_ = fore_track_updater_->CreateResource(
294 layer_tree_host()->contents_texture_manager());
295 }
296 }
297
298 if (!thumb_updater_) {
299 thumb_updater_ = CachingBitmapContentLayerUpdater::Create(
300 ScrollbarThumbPainter::Create(scrollbar_.get(),
301 painter_.get(),
302 geometry_.get()).PassAs<LayerPainter>());
303 }
304 if (!thumb_) {
305 thumb_ = thumb_updater_->CreateResource(
306 layer_tree_host()->contents_texture_manager());
307 }
308 }
309
310 void ScrollbarLayer::UpdatePart(CachingBitmapContentLayerUpdater* painter,
311 LayerUpdater::Resource* resource,
312 gfx::Rect rect,
313 ResourceUpdateQueue* queue,
314 RenderingStats* stats) {
315 if (layer_tree_host()->settings().solidColorScrollbars)
316 return;
317
318 // Skip painting and uploading if there are no invalidations and
319 // we already have valid texture data.
320 if (resource->texture()->haveBackingTexture() &&
321 resource->texture()->size() == rect.size() &&
322 !is_dirty())
323 return;
324
325 // We should always have enough memory for UI.
326 DCHECK(resource->texture()->canAcquireBackingTexture());
327 if (!resource->texture()->canAcquireBackingTexture())
328 return;
329
330 // Paint and upload the entire part.
331 gfx::Rect painted_opaque_rect;
332 painter->PrepareToUpdate(rect,
333 rect.size(),
334 contents_scale_x(),
335 contents_scale_y(),
336 &painted_opaque_rect,
337 stats);
338 if (!painter->pixels_did_change() &&
339 resource->texture()->haveBackingTexture()) {
340 TRACE_EVENT_INSTANT0("cc",
341 "ScrollbarLayer::updatePart no texture upload needed");
342 return;
343 }
344
345 bool partial_updates_allowed =
346 layer_tree_host()->settings().maxPartialTextureUpdates > 0;
347 if (!partial_updates_allowed)
348 resource->texture()->returnBackingTexture();
349
350 gfx::Vector2d dest_offset(0, 0);
351 resource->Update(queue, rect, dest_offset, partial_updates_allowed, stats);
352 }
353
354 gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect(
355 gfx::Rect layer_rect) const {
356 // Don't intersect with the bounds as in LayerRectToContentRect() because
357 // layer_rect here might be in coordinates of the containing layer.
358 gfx::RectF content_rect = gfx::ScaleRect(layer_rect,
359 contents_scale_y(),
360 contents_scale_y());
361 return gfx::ToEnclosingRect(content_rect);
362 }
363
364 void ScrollbarLayer::SetTexturePriorities(
365 const PriorityCalculator& priority_calc) {
366 if (layer_tree_host()->settings().solidColorScrollbars)
367 return;
368
369 if (content_bounds().IsEmpty())
370 return;
371 DCHECK_LE(content_bounds().width(), MaxTextureSize());
372 DCHECK_LE(content_bounds().height(), MaxTextureSize());
373
374 CreateUpdaterIfNeeded();
375
376 bool draws_to_root = !render_target()->parent();
377 if (back_track_) {
378 back_track_->texture()->setDimensions(content_bounds(), texture_format_);
379 back_track_->texture()->setRequestPriority(
380 PriorityCalculator::UIPriority(draws_to_root));
381 }
382 if (fore_track_) {
383 fore_track_->texture()->setDimensions(content_bounds(), texture_format_);
384 fore_track_->texture()->setRequestPriority(
385 PriorityCalculator::UIPriority(draws_to_root));
386 }
387 if (thumb_) {
388 gfx::Rect thumb_layer_rect = geometry_->thumbRect(scrollbar_.get());
389 gfx::Size thumb_size =
390 ScrollbarLayerRectToContentRect(thumb_layer_rect).size();
391 thumb_->texture()->setDimensions(thumb_size, texture_format_);
392 thumb_->texture()->setRequestPriority(
393 PriorityCalculator::UIPriority(draws_to_root));
394 }
395 }
396
397 void ScrollbarLayer::Update(ResourceUpdateQueue* queue,
398 const OcclusionTracker* occlusion,
399 RenderingStats* stats) {
400 ContentsScalingLayer::Update(queue, occlusion, stats);
401
402 dirty_rect_.Union(update_rect_);
403 if (content_bounds().IsEmpty())
404 return;
405 if (visible_content_rect().IsEmpty())
406 return;
407
408 CreateUpdaterIfNeeded();
409
410 gfx::Rect content_rect = ScrollbarLayerRectToContentRect(
411 gfx::Rect(scrollbar_->location(), bounds()));
412 UpdatePart(back_track_updater_.get(),
413 back_track_.get(),
414 content_rect,
415 queue,
416 stats);
417 if (fore_track_ && fore_track_updater_) {
418 UpdatePart(fore_track_updater_.get(),
419 fore_track_.get(),
420 content_rect,
421 queue,
422 stats);
423 }
424
425 // Consider the thumb to be at the origin when painting.
426 gfx::Rect thumb_rect = geometry_->thumbRect(scrollbar_.get());
427 thumb_size_ = thumb_rect.size();
428 gfx::Rect origin_thumb_rect =
429 ScrollbarLayerRectToContentRect(gfx::Rect(thumb_rect.size()));
430 if (!origin_thumb_rect.IsEmpty()) {
431 UpdatePart(thumb_updater_.get(),
432 thumb_.get(),
433 origin_thumb_rect,
434 queue,
435 stats);
436 }
437
438 dirty_rect_ = gfx::RectF();
439 }
440
441 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scrollbar_layer.h ('k') | cc/scrollbar_layer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698