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

Side by Side Diff: cc/layers/scrollbar_layer.cc

Issue 18191020: UI Resource Manager (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 5 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
OLDNEW
1
2 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
3 // 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
4 // found in the LICENSE file. 3 // found in the LICENSE file.
5 4
6 #include "cc/layers/scrollbar_layer.h" 5 #include "cc/layers/scrollbar_layer.h"
7 6
8 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
9 #include "base/basictypes.h" 8 #include "base/basictypes.h"
10 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
11 #include "cc/layers/scrollbar_layer_impl.h" 10 #include "cc/layers/scrollbar_layer_impl.h"
12 #include "cc/resources/caching_bitmap_content_layer_updater.h" 11 #include "cc/resources/ui_resource_bitmap.h"
13 #include "cc/resources/layer_painter.h" 12 #include "cc/resources/ui_resource_manager_client.h"
14 #include "cc/resources/prioritized_resource.h"
15 #include "cc/resources/resource_update_queue.h"
16 #include "cc/trees/layer_tree_host.h" 13 #include "cc/trees/layer_tree_host.h"
14 #include "cc/trees/layer_tree_impl.h"
15 #include "skia/ext/platform_canvas.h"
16 #include "skia/ext/refptr.h"
17 #include "third_party/skia/include/core/SkSize.h"
17 #include "ui/gfx/rect_conversions.h" 18 #include "ui/gfx/rect_conversions.h"
18 19
19 namespace cc { 20 namespace cc {
20 21
21 scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl( 22 scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl(
22 LayerTreeImpl* tree_impl) { 23 LayerTreeImpl* tree_impl) {
23 return ScrollbarLayerImpl::Create( 24 return ScrollbarLayerImpl::Create(
24 tree_impl, id(), scrollbar_->Orientation()).PassAs<LayerImpl>(); 25 tree_impl, id(), scrollbar_->Orientation()).PassAs<LayerImpl>();
25 } 26 }
26 27
27 scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create( 28 scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create(
28 scoped_ptr<Scrollbar> scrollbar, 29 scoped_ptr<Scrollbar> scrollbar,
29 int scroll_layer_id) { 30 int scroll_layer_id) {
30 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(), 31 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(),
31 scroll_layer_id)); 32 scroll_layer_id));
32 } 33 }
33 34
34 ScrollbarLayer::ScrollbarLayer( 35 ScrollbarLayer::ScrollbarLayer(
35 scoped_ptr<Scrollbar> scrollbar, 36 scoped_ptr<Scrollbar> scrollbar,
36 int scroll_layer_id) 37 int scroll_layer_id)
37 : scrollbar_(scrollbar.Pass()), 38 : scrollbar_(scrollbar.Pass()),
38 scroll_layer_id_(scroll_layer_id), 39 scroll_layer_id_(scroll_layer_id),
39 texture_format_(GL_INVALID_ENUM) { 40 track_ui_resource_id_(0),
41 thumb_ui_resource_id_(0) {
40 if (!scrollbar_->IsOverlay()) 42 if (!scrollbar_->IsOverlay())
41 SetShouldScrollOnMainThread(true); 43 SetShouldScrollOnMainThread(true);
42 } 44 }
43 45
44 ScrollbarLayer::~ScrollbarLayer() {} 46 ScrollbarLayer::~ScrollbarLayer() {}
45 47
46 void ScrollbarLayer::SetScrollLayerId(int id) { 48 void ScrollbarLayer::SetScrollLayerId(int id) {
47 if (id == scroll_layer_id_) 49 if (id == scroll_layer_id_)
48 return; 50 return;
49 51
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 float* contents_scale_y, 92 float* contents_scale_y,
91 gfx::Size* content_bounds) { 93 gfx::Size* content_bounds) {
92 ContentsScalingLayer::CalculateContentsScale( 94 ContentsScalingLayer::CalculateContentsScale(
93 ClampScaleToMaxTextureSize(ideal_contents_scale), 95 ClampScaleToMaxTextureSize(ideal_contents_scale),
94 device_scale_factor, 96 device_scale_factor,
95 page_scale_factor, 97 page_scale_factor,
96 animating_transform_to_screen, 98 animating_transform_to_screen,
97 contents_scale_x, 99 contents_scale_x,
98 contents_scale_y, 100 contents_scale_y,
99 content_bounds); 101 content_bounds);
102
103 track_rect_ = scrollbar_->TrackRect();
enne (OOO) 2013/07/22 23:09:15 Why does this come before the solid color early-ou
powei 2013/07/24 02:28:29 Done. I moved this from Update originally thinkin
104
105 if (layer_tree_host()->settings().solid_color_scrollbars)
106 return;
107
108 if (scrollbar_->HasThumb()) {
109 thumb_thickness_ = scrollbar_->ThumbThickness();
110 thumb_length_ = scrollbar_->ThumbLength();
111 }
100 } 112 }
101 113
102 void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { 114 void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
103 ContentsScalingLayer::PushPropertiesTo(layer); 115 ContentsScalingLayer::PushPropertiesTo(layer);
104 116
105 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer); 117 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer);
106 118
107 if (layer_tree_host() && 119 if (layer_tree_host() &&
108 layer_tree_host()->settings().solid_color_scrollbars) { 120 layer_tree_host()->settings().solid_color_scrollbars) {
109 int thickness_override = 121 int thickness_override =
(...skipping 11 matching lines...) Expand all
121 } 133 }
122 scrollbar_layer->set_thumb_length(thumb_length_); 134 scrollbar_layer->set_thumb_length(thumb_length_);
123 if (Orientation() == HORIZONTAL) { 135 if (Orientation() == HORIZONTAL) {
124 scrollbar_layer->set_track_start(track_rect_.x()); 136 scrollbar_layer->set_track_start(track_rect_.x());
125 scrollbar_layer->set_track_length(track_rect_.width()); 137 scrollbar_layer->set_track_length(track_rect_.width());
126 } else { 138 } else {
127 scrollbar_layer->set_track_start(track_rect_.y()); 139 scrollbar_layer->set_track_start(track_rect_.y());
128 scrollbar_layer->set_track_length(track_rect_.height()); 140 scrollbar_layer->set_track_length(track_rect_.height());
129 } 141 }
130 142
131 if (track_ && track_->texture()->have_backing_texture()) 143 scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_);
132 scrollbar_layer->set_track_resource_id(track_->texture()->resource_id()); 144 scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_);
133 else
134 scrollbar_layer->set_track_resource_id(0);
135
136 if (thumb_ && thumb_->texture()->have_backing_texture())
137 scrollbar_layer->set_thumb_resource_id(thumb_->texture()->resource_id());
138 else
139 scrollbar_layer->set_thumb_resource_id(0);
140 } 145 }
141 146
142 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { 147 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() {
143 return this; 148 return this;
144 } 149 }
145 150
146 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { 151 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
152 // When the LTH is set to null, then this layer should remove all of
153 // its associated textures.
147 if (!host || host != layer_tree_host()) { 154 if (!host || host != layer_tree_host()) {
148 track_updater_ = NULL; 155 if (track_ui_resource_id_) {
149 track_.reset(); 156 if (layer_tree_host()) {
150 thumb_updater_ = NULL; 157 layer_tree_host()->DeleteUIResource(track_ui_resource_id_);
151 thumb_.reset(); 158 }
159 track_ui_resource_id_ = 0;
160 track_bitmap_ = NULL;
161 }
162
163 if (thumb_ui_resource_id_) {
164 if (layer_tree_host()) {
165 layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_);
166 }
167 thumb_ui_resource_id_ = 0;
168 thumb_bitmap_ = NULL;
169 }
152 } 170 }
153 171
154 ContentsScalingLayer::SetLayerTreeHost(host); 172 ContentsScalingLayer::SetLayerTreeHost(host);
155 } 173 }
156 174
157 class ScrollbarPartPainter : public LayerPainter {
158 public:
159 ScrollbarPartPainter(Scrollbar* scrollbar, ScrollbarPart part)
160 : scrollbar_(scrollbar),
161 part_(part) {}
162 virtual ~ScrollbarPartPainter() {}
163
164 // LayerPainter implementation
165 virtual void Paint(SkCanvas* canvas,
166 gfx::Rect content_rect,
167 gfx::RectF* opaque) OVERRIDE {
168 scrollbar_->PaintPart(canvas, part_, content_rect);
169 }
170
171 private:
172 Scrollbar* scrollbar_;
173 ScrollbarPart part_;
174 };
175
176 void ScrollbarLayer::CreateUpdaterIfNeeded() {
177 if (layer_tree_host()->settings().solid_color_scrollbars)
178 return;
179
180 texture_format_ =
181 layer_tree_host()->GetRendererCapabilities().best_texture_format;
182
183 if (!track_updater_.get()) {
184 track_updater_ = CachingBitmapContentLayerUpdater::Create(
185 scoped_ptr<LayerPainter>(
186 new ScrollbarPartPainter(scrollbar_.get(), TRACK))
187 .Pass(),
188 rendering_stats_instrumentation(),
189 id());
190 }
191 if (!track_) {
192 track_ = track_updater_->CreateResource(
193 layer_tree_host()->contents_texture_manager());
194 }
195
196 if (!thumb_updater_.get()) {
197 thumb_updater_ = CachingBitmapContentLayerUpdater::Create(
198 scoped_ptr<LayerPainter>(
199 new ScrollbarPartPainter(scrollbar_.get(), THUMB))
200 .Pass(),
201 rendering_stats_instrumentation(),
202 id());
203 }
204 if (!thumb_ && scrollbar_->HasThumb()) {
205 thumb_ = thumb_updater_->CreateResource(
206 layer_tree_host()->contents_texture_manager());
207 }
208 }
209
210 void ScrollbarLayer::UpdatePart(CachingBitmapContentLayerUpdater* painter,
211 LayerUpdater::Resource* resource,
212 gfx::Rect rect,
213 ResourceUpdateQueue* queue) {
214 if (layer_tree_host()->settings().solid_color_scrollbars)
215 return;
216
217 // Skip painting and uploading if there are no invalidations and
218 // we already have valid texture data.
219 if (resource->texture()->have_backing_texture() &&
220 resource->texture()->size() == rect.size() &&
221 !is_dirty())
222 return;
223
224 // We should always have enough memory for UI.
225 DCHECK(resource->texture()->can_acquire_backing_texture());
226 if (!resource->texture()->can_acquire_backing_texture())
227 return;
228
229 // Paint and upload the entire part.
230 gfx::Rect painted_opaque_rect;
231 painter->PrepareToUpdate(rect,
232 rect.size(),
233 contents_scale_x(),
234 contents_scale_y(),
235 &painted_opaque_rect);
236 if (!painter->pixels_did_change() &&
237 resource->texture()->have_backing_texture()) {
238 TRACE_EVENT_INSTANT0("cc",
239 "ScrollbarLayer::UpdatePart no texture upload needed",
240 TRACE_EVENT_SCOPE_THREAD);
241 return;
242 }
243
244 bool partial_updates_allowed =
245 layer_tree_host()->settings().max_partial_texture_updates > 0;
246 if (!partial_updates_allowed)
247 resource->texture()->ReturnBackingTexture();
248
249 gfx::Vector2d dest_offset(0, 0);
250 resource->Update(queue, rect, dest_offset, partial_updates_allowed);
251 }
252
253 gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( 175 gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect(
254 gfx::Rect layer_rect) const { 176 gfx::Rect layer_rect) const {
255 // Don't intersect with the bounds as in LayerRectToContentRect() because 177 // Don't intersect with the bounds as in LayerRectToContentRect() because
256 // layer_rect here might be in coordinates of the containing layer. 178 // layer_rect here might be in coordinates of the containing layer.
257 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect( 179 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect(
258 layer_rect, contents_scale_y(), contents_scale_y()); 180 layer_rect, contents_scale_y(), contents_scale_y());
259 // We should never return a rect bigger than the content_bounds(). 181 // We should never return a rect bigger than the content_bounds().
260 gfx::Size clamped_size = expanded_rect.size(); 182 gfx::Size clamped_size = expanded_rect.size();
261 clamped_size.SetToMin(content_bounds()); 183 clamped_size.SetToMin(content_bounds());
262 expanded_rect.set_size(clamped_size); 184 expanded_rect.set_size(clamped_size);
263 return expanded_rect; 185 return expanded_rect;
264 } 186 }
265 187
266 void ScrollbarLayer::SetTexturePriorities(
267 const PriorityCalculator& priority_calc) {
268 if (layer_tree_host()->settings().solid_color_scrollbars)
269 return;
270
271 if (content_bounds().IsEmpty())
272 return;
273 DCHECK_LE(content_bounds().width(), MaxTextureSize());
274 DCHECK_LE(content_bounds().height(), MaxTextureSize());
275
276 CreateUpdaterIfNeeded();
277
278 bool draws_to_root = !render_target()->parent();
279 if (track_) {
280 track_->texture()->SetDimensions(content_bounds(), texture_format_);
281 track_->texture()->set_request_priority(
282 PriorityCalculator::UIPriority(draws_to_root));
283 }
284 if (thumb_) {
285 gfx::Size thumb_size = OriginThumbRect().size();
286 thumb_->texture()->SetDimensions(thumb_size, texture_format_);
287 thumb_->texture()->set_request_priority(
288 PriorityCalculator::UIPriority(draws_to_root));
289 }
290 }
291
292 void ScrollbarLayer::Update(ResourceUpdateQueue* queue,
293 const OcclusionTracker* occlusion) {
294 track_rect_ = scrollbar_->TrackRect();
295
296 if (layer_tree_host()->settings().solid_color_scrollbars)
297 return;
298
299 {
300 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
301 true);
302 ContentsScalingLayer::Update(queue, occlusion);
303 }
304
305 dirty_rect_.Union(update_rect_);
306 if (content_bounds().IsEmpty())
307 return;
308 if (visible_content_rect().IsEmpty())
309 return;
310
311 CreateUpdaterIfNeeded();
312
313 gfx::Rect content_rect = ScrollbarLayerRectToContentRect(
314 gfx::Rect(scrollbar_->Location(), bounds()));
315 UpdatePart(track_updater_.get(),
316 track_.get(),
317 content_rect,
318 queue);
319
320 if (scrollbar_->HasThumb()) {
321 thumb_thickness_ = scrollbar_->ThumbThickness();
322 thumb_length_ = scrollbar_->ThumbLength();
323 gfx::Rect origin_thumb_rect = OriginThumbRect();
324 if (!origin_thumb_rect.IsEmpty()) {
325 UpdatePart(thumb_updater_.get(),
326 thumb_.get(),
327 origin_thumb_rect,
328 queue);
329 }
330 }
331
332 dirty_rect_ = gfx::RectF();
333 }
334
335 gfx::Rect ScrollbarLayer::OriginThumbRect() const { 188 gfx::Rect ScrollbarLayer::OriginThumbRect() const {
336 gfx::Size thumb_size; 189 gfx::Size thumb_size;
337 if (Orientation() == HORIZONTAL) { 190 if (Orientation() == HORIZONTAL) {
338 thumb_size = gfx::Size(scrollbar_->ThumbLength(), 191 thumb_size = gfx::Size(scrollbar_->ThumbLength(),
339 scrollbar_->ThumbThickness()); 192 scrollbar_->ThumbThickness());
340 } else { 193 } else {
341 thumb_size = gfx::Size(scrollbar_->ThumbThickness(), 194 thumb_size = gfx::Size(scrollbar_->ThumbThickness(),
342 scrollbar_->ThumbLength()); 195 scrollbar_->ThumbLength());
343 } 196 }
344 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); 197 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size));
345 } 198 }
346 199
200
201 void ScrollbarLayer::Update(ResourceUpdateQueue* queue,
202 const OcclusionTracker* occlusion) {
203 if (layer_tree_host()->settings().solid_color_scrollbars)
204 return;
205
206 // Setting this boolean is still necessary to ensure no extra commits.
207 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
208 true);
209 ContentsScalingLayer::Update(queue, occlusion);
210
211 RasterizeTrackAndThumb();
212
213 if (track_ui_resource_id_) {
aelias_OOO_until_Jul13 2013/07/23 00:06:48 nit: no {}
powei 2013/07/24 02:28:29 Done.
214 layer_tree_host()->DeleteUIResource(track_ui_resource_id_);
215 }
216 track_ui_resource_id_ = layer_tree_host()->CreateUIResource(
217 base::Bind(&ScrollbarLayer::GetTrackBitmap, this));
218
219 if (scrollbar_->HasThumb()) {
220 if (thumb_ui_resource_id_) {
aelias_OOO_until_Jul13 2013/07/23 00:06:48 nit: no {}
powei 2013/07/24 02:28:29 Done.
221 layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_);
222 }
223
224 thumb_ui_resource_id_ = layer_tree_host()->CreateUIResource(
225 base::Bind(&ScrollbarLayer::GetThumbBitmap, this));
aelias_OOO_until_Jul13 2013/07/23 00:06:48 This will crash if the ScrollbarLayer no longer ex
powei 2013/07/24 02:28:29 Apparently, "WeakCalls" are only supported for nul
aelias_OOO_until_Jul13 2013/07/24 02:57:46 OK, that makes sense. We should address the issue
226 }
227 }
228
229 void ScrollbarLayer::RasterizeTrackAndThumb() {
aelias_OOO_until_Jul13 2013/07/23 00:06:48 Add a DCHECK(!layer_tree_host()->settings().solid_
powei 2013/07/24 02:28:29 Done.
230 {
aelias_OOO_until_Jul13 2013/07/23 00:06:48 nit: this block looks weird, I suggest removing it
powei 2013/07/24 02:28:29 Done.
231 gfx::Rect track_rect = ScrollbarLayerRectToContentRect(
232 gfx::Rect(scrollbar_->Location(), bounds()));
233 track_bitmap_ = UIResourceBitmap::Create(
234 new uint8_t[track_rect.width() * track_rect.height() * 4],
235 UIResourceBitmap::RGBA8,
236 track_rect.size());
237
238 skia::RefPtr<SkCanvas> track_canvas = skia::AdoptRef(
239 skia::CreatePlatformCanvas(track_rect.width(),
240 track_rect.height(),
241 false,
242 reinterpret_cast<uint8_t*>(
aelias_OOO_until_Jul13 2013/07/23 00:06:48 Should be static_cast<>
powei 2013/07/24 02:28:29 Done.
243 track_bitmap_->GetPixels()),
244 skia::CRASH_ON_FAILURE));
245
246 track_canvas->save();
247 track_canvas->translate(SkFloatToScalar(-track_rect.x()),
248 SkFloatToScalar(-track_rect.y()));
249 SkPaint paint;
250 paint.setAntiAlias(false);
251 paint.setXfermodeMode(SkXfermode::kClear_Mode);
252 SkRect layer_sk_rect = SkRect::MakeXYWH(track_rect.x(),
253 track_rect.y(),
254 track_rect.width(),
255 track_rect.height());
256
257 track_canvas->drawRect(layer_sk_rect, paint);
aelias_OOO_until_Jul13 2013/07/23 00:06:48 You are clearing the track canvas but not the thum
powei 2013/07/24 02:28:29 Done.
258 track_canvas->clipRect(layer_sk_rect);
259 scrollbar_->PaintPart(track_canvas.get(), TRACK, track_rect);
260 track_canvas->restore();
261 }
262
263 if (scrollbar_->HasThumb()) {
264 gfx::Rect thumb_rect = OriginThumbRect();
265 thumb_bitmap_ = UIResourceBitmap::Create(
266 new uint8_t[thumb_rect.width() * thumb_rect.height() * 4],
267 UIResourceBitmap::RGBA8,
268 thumb_rect.size());
269
270 skia::RefPtr<SkCanvas> thumb_canvas = skia::AdoptRef(
271 skia::CreatePlatformCanvas(thumb_rect.width(),
272 thumb_rect.height(),
273 false,
274 reinterpret_cast<uint8_t*>(
aelias_OOO_until_Jul13 2013/07/23 00:06:48 Should be static_cast<>
powei 2013/07/24 02:28:29 Done.
275 thumb_bitmap_->GetPixels()),
276 skia::CRASH_ON_FAILURE));
277
278 scrollbar_->PaintPart(thumb_canvas.get(),
279 THUMB,
280 thumb_rect);
281 }
282 }
283
284 scoped_refptr<UIResourceBitmap>
285 ScrollbarLayer::GetTrackBitmap(bool resource_lost) {
286 return track_bitmap_;
287 }
288
289 scoped_refptr<UIResourceBitmap>
290 ScrollbarLayer::GetThumbBitmap(bool resource_lost) {
291 return thumb_bitmap_;
292 }
293
347 } // namespace cc 294 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698