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

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/caching_bitmap_content_layer_updater.h"
aelias_OOO_until_Jul13 2013/07/10 23:07:22 Three more includes to delete here.
powei 2013/07/11 23:54:44 Done.
13 #include "cc/resources/layer_painter.h" 12 #include "cc/resources/layer_painter.h"
14 #include "cc/resources/prioritized_resource.h"
15 #include "cc/resources/resource_update_queue.h" 13 #include "cc/resources/resource_update_queue.h"
14 #include "cc/resources/ui_resource_manager.h"
16 #include "cc/trees/layer_tree_host.h" 15 #include "cc/trees/layer_tree_host.h"
16 #include "cc/trees/layer_tree_impl.h"
17 #include "skia/ext/platform_canvas.h"
18 #include "skia/ext/refptr.h"
19 #include "third_party/skia/include/core/SkSize.h"
17 #include "ui/gfx/rect_conversions.h" 20 #include "ui/gfx/rect_conversions.h"
18 21
19 namespace cc { 22 namespace cc {
20 23
21 scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl( 24 scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl(
22 LayerTreeImpl* tree_impl) { 25 LayerTreeImpl* tree_impl) {
26
aelias_OOO_until_Jul13 2013/07/10 23:07:22 nit: accidental spacing change
powei 2013/07/11 23:54:44 Done.
23 return ScrollbarLayerImpl::Create( 27 return ScrollbarLayerImpl::Create(
24 tree_impl, id(), scrollbar_->Orientation()).PassAs<LayerImpl>(); 28 tree_impl, id(), scrollbar_->Orientation()).PassAs<LayerImpl>();
25 } 29 }
26 30
27 scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create( 31 scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create(
28 scoped_ptr<Scrollbar> scrollbar, 32 scoped_ptr<Scrollbar> scrollbar,
29 int scroll_layer_id) { 33 int scroll_layer_id) {
30 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(), 34 return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(),
31 scroll_layer_id)); 35 scroll_layer_id));
32 } 36 }
33 37
34 ScrollbarLayer::ScrollbarLayer( 38 ScrollbarLayer::ScrollbarLayer(
35 scoped_ptr<Scrollbar> scrollbar, 39 scoped_ptr<Scrollbar> scrollbar,
36 int scroll_layer_id) 40 int scroll_layer_id)
37 : scrollbar_(scrollbar.Pass()), 41 : scrollbar_(scrollbar.Pass()),
38 scroll_layer_id_(scroll_layer_id), 42 scroll_layer_id_(scroll_layer_id),
39 texture_format_(GL_INVALID_ENUM) { 43 track_ui_resource_id_(0),
44 thumb_ui_resource_id_(0),
45 skip_update_(false) {
40 if (!scrollbar_->IsOverlay()) 46 if (!scrollbar_->IsOverlay())
41 SetShouldScrollOnMainThread(true); 47 SetShouldScrollOnMainThread(true);
42 } 48 }
43 49
44 ScrollbarLayer::~ScrollbarLayer() {} 50 ScrollbarLayer::~ScrollbarLayer() {}
45 51
46 void ScrollbarLayer::SetScrollLayerId(int id) { 52 void ScrollbarLayer::SetScrollLayerId(int id) {
47 if (id == scroll_layer_id_) 53 if (id == scroll_layer_id_)
48 return; 54 return;
49 55
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 } 106 }
101 107
102 void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { 108 void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
103 ContentsScalingLayer::PushPropertiesTo(layer); 109 ContentsScalingLayer::PushPropertiesTo(layer);
104 110
105 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer); 111 ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer);
106 112
107 if (layer_tree_host() && 113 if (layer_tree_host() &&
108 layer_tree_host()->settings().solid_color_scrollbars) { 114 layer_tree_host()->settings().solid_color_scrollbars) {
109 int thickness_override = 115 int thickness_override =
110 layer_tree_host()->settings().solid_color_scrollbar_thickness_dip; 116 layer_tree_host()->settings().solid_color_scrollbar_thickness_dip;
aelias_OOO_until_Jul13 2013/07/10 23:07:22 nit: accidental spacing change
powei 2013/07/11 23:54:44 Done.
111 if (thickness_override != -1) { 117 if (thickness_override != -1) {
112 scrollbar_layer->set_thumb_thickness(thickness_override); 118 scrollbar_layer->set_thumb_thickness(thickness_override);
113 } else { 119 } else {
114 if (Orientation() == HORIZONTAL) 120 if (Orientation() == HORIZONTAL)
115 scrollbar_layer->set_thumb_thickness(bounds().height()); 121 scrollbar_layer->set_thumb_thickness(bounds().height());
116 else 122 else
117 scrollbar_layer->set_thumb_thickness(bounds().width()); 123 scrollbar_layer->set_thumb_thickness(bounds().width());
118 } 124 }
119 } else { 125 } else {
120 scrollbar_layer->set_thumb_thickness(thumb_thickness_); 126 scrollbar_layer->set_thumb_thickness(thumb_thickness_);
121 } 127 }
122 scrollbar_layer->set_thumb_length(thumb_length_); 128 scrollbar_layer->set_thumb_length(thumb_length_);
129
aelias_OOO_until_Jul13 2013/07/10 23:07:22 nit: accidental spacing change
powei 2013/07/11 23:54:44 Done.
123 if (Orientation() == HORIZONTAL) { 130 if (Orientation() == HORIZONTAL) {
124 scrollbar_layer->set_track_start(track_rect_.x()); 131 scrollbar_layer->set_track_start(track_rect_.x());
125 scrollbar_layer->set_track_length(track_rect_.width()); 132 scrollbar_layer->set_track_length(track_rect_.width());
126 } else { 133 } else {
127 scrollbar_layer->set_track_start(track_rect_.y()); 134 scrollbar_layer->set_track_start(track_rect_.y());
128 scrollbar_layer->set_track_length(track_rect_.height()); 135 scrollbar_layer->set_track_length(track_rect_.height());
129 } 136 }
130 137
131 if (track_ && track_->texture()->have_backing_texture()) 138 scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_);
132 scrollbar_layer->set_track_resource_id(track_->texture()->resource_id()); 139 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 } 140 }
141 141
142 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { 142 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() {
143 return this; 143 return this;
144 } 144 }
145 145
146 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { 146 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
147 if (!host || host != layer_tree_host()) { 147 // When the LTH is set to null, then this layer should remove all of
148 track_updater_ = NULL; 148 // its associated textures.
149 track_.reset(); 149 if (host != layer_tree_host() && host == NULL) {
aelias_OOO_until_Jul13 2013/07/10 23:07:22 You changed the behavior here by changing this lin
powei 2013/07/11 23:54:44 Done.
150 thumb_updater_ = NULL; 150 if (track_ui_resource_id_) {
151 thumb_.reset(); 151 layer_tree_host()->DeleteUIResource(track_ui_resource_id_);
aelias_OOO_until_Jul13 2013/07/10 23:07:22 Also throw out the UIResourceBitmaps here.
powei 2013/07/11 23:54:44 Done.
152 track_ui_resource_id_ = 0;
153 }
154
155 if (thumb_ui_resource_id_) {
156 layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_);
157 thumb_ui_resource_id_ = 0;
158 }
152 } 159 }
153
154 ContentsScalingLayer::SetLayerTreeHost(host); 160 ContentsScalingLayer::SetLayerTreeHost(host);
155 } 161 }
156 162
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( 163 gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect(
254 gfx::Rect layer_rect) const { 164 gfx::Rect layer_rect) const {
255 // Don't intersect with the bounds as in LayerRectToContentRect() because 165 // Don't intersect with the bounds as in LayerRectToContentRect() because
256 // layer_rect here might be in coordinates of the containing layer. 166 // layer_rect here might be in coordinates of the containing layer.
257 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect( 167 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect(
258 layer_rect, contents_scale_y(), contents_scale_y()); 168 layer_rect, contents_scale_y(), contents_scale_y());
259 // We should never return a rect bigger than the content_bounds(). 169 // We should never return a rect bigger than the content_bounds().
260 gfx::Size clamped_size = expanded_rect.size(); 170 gfx::Size clamped_size = expanded_rect.size();
261 clamped_size.SetToMin(content_bounds()); 171 clamped_size.SetToMin(content_bounds());
262 expanded_rect.set_size(clamped_size); 172 expanded_rect.set_size(clamped_size);
263 return expanded_rect; 173 return expanded_rect;
264 } 174 }
265 175
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, 176 void ScrollbarLayer::Update(ResourceUpdateQueue* queue,
293 const OcclusionTracker* occlusion) { 177 const OcclusionTracker* occlusion) {
294 track_rect_ = scrollbar_->TrackRect(); 178 track_rect_ = scrollbar_->TrackRect();
295 179
296 if (layer_tree_host()->settings().solid_color_scrollbars) 180 if (layer_tree_host()->settings().solid_color_scrollbars)
297 return; 181 return;
298 182
299 { 183 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
300 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, 184 true);
301 true); 185 ContentsScalingLayer::Update(queue, occlusion);
302 ContentsScalingLayer::Update(queue, occlusion); 186
187 if (skip_update_) {
188 skip_update_ = false;
189 return;
303 } 190 }
304 191
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()) { 192 if (scrollbar_->HasThumb()) {
321 thumb_thickness_ = scrollbar_->ThumbThickness(); 193 thumb_thickness_ = scrollbar_->ThumbThickness();
322 thumb_length_ = scrollbar_->ThumbLength(); 194 thumb_length_ = scrollbar_->ThumbLength();
323 gfx::Rect origin_thumb_rect = OriginThumbRect(); 195 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 } 196 }
331 197
332 dirty_rect_ = gfx::RectF(); 198
199 gfx::Rect track_rect = ScrollbarLayerRectToContentRect(
200 gfx::Rect(scrollbar_->Location(), bounds()));
201 gfx::Rect thumb_rect = OriginThumbRect();
202
203 {
204 track_bitmap_ = UIResourceBitmap::Create(
205 new uint8_t[track_rect.width()*track_rect.height()*4],
aelias_OOO_until_Jul13 2013/07/10 23:07:22 nit: spaces around *
powei 2013/07/11 23:54:44 Done.
206 UIResourceBitmap::RGBA8,
207 track_rect.size());
208
209 // raster track
210 skia::RefPtr<SkCanvas> track_canvas = skia::AdoptRef(
211 skia::CreatePlatformCanvas(track_rect.width(),
212 track_rect.height(),
213 false,
214 reinterpret_cast<uint8_t*>(
215 track_bitmap_->GetPixels()),
216 skia::CRASH_ON_FAILURE));
217
218 track_canvas->save();
219 track_canvas->translate(SkFloatToScalar(-track_rect.x()),
220 SkFloatToScalar(-track_rect.y()));
221 SkPaint paint;
222 paint.setAntiAlias(false);
223 paint.setXfermodeMode(SkXfermode::kClear_Mode);
224 SkRect layer_sk_rect = SkRect::MakeXYWH(track_rect.x(),
225 track_rect.y(),
226 track_rect.width(),
227 track_rect.height());
228
229 track_canvas->drawRect(layer_sk_rect, paint);
230 track_canvas->clipRect(layer_sk_rect);
231 scrollbar_->PaintPart(track_canvas.get(), TRACK, track_rect);
232 track_canvas->restore();
233
234 if (track_ui_resource_id_)
235 layer_tree_host()->DeleteUIResource(track_ui_resource_id_);
236 track_ui_resource_id_ = layer_tree_host()->CreateUIResource(track_bitmap_,
237 this);
238 }
239
240 if (scrollbar_->HasThumb()) {
241 thumb_bitmap_ = UIResourceBitmap::Create(
242 new uint8_t[thumb_rect.width()*thumb_rect.height()*4],
aelias_OOO_until_Jul13 2013/07/10 23:07:22 nit: spaces around *
powei 2013/07/11 23:54:44 Done.
243 UIResourceBitmap::RGBA8,
244 thumb_rect.size());
245
246 // raster thumb
247 skia::RefPtr<SkCanvas> thumb_canvas = skia::AdoptRef(
248 skia::CreatePlatformCanvas(thumb_rect.width(),
249 thumb_rect.height(),
250 false,
251 reinterpret_cast<uint8_t*>(
252 thumb_bitmap_->GetPixels()),
253 skia::CRASH_ON_FAILURE));
254
255 scrollbar_->PaintPart(thumb_canvas.get(),
256 THUMB,
257 thumb_rect);
258
259 if (thumb_ui_resource_id_)
260 layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_);
261 thumb_ui_resource_id_ = layer_tree_host()->CreateUIResource(thumb_bitmap_,
262 this);
263 }
333 } 264 }
334 265
335 gfx::Rect ScrollbarLayer::OriginThumbRect() const { 266 gfx::Rect ScrollbarLayer::OriginThumbRect() const {
336 gfx::Size thumb_size; 267 gfx::Size thumb_size;
337 if (Orientation() == HORIZONTAL) { 268 if (Orientation() == HORIZONTAL) {
338 thumb_size = gfx::Size(scrollbar_->ThumbLength(), 269 thumb_size = gfx::Size(scrollbar_->ThumbLength(),
339 scrollbar_->ThumbThickness()); 270 scrollbar_->ThumbThickness());
340 } else { 271 } else {
341 thumb_size = gfx::Size(scrollbar_->ThumbThickness(), 272 thumb_size = gfx::Size(scrollbar_->ThumbThickness(),
342 scrollbar_->ThumbLength()); 273 scrollbar_->ThumbLength());
343 } 274 }
344 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); 275 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size));
345 } 276 }
346 277
278 void ScrollbarLayer::UIResourceReady(UIResourceId id) {
aelias_OOO_until_Jul13 2013/07/10 23:07:22 This code is unnecessary, please delete it. It's
powei 2013/07/11 23:54:44 Done.
279 if (thumb_ui_resource_id_ == id) {
280 // Need to push the ui resource id to the impl thread.
281 SetNeedsCommit();
282 // If we do not have this flag, we will always have a
283 // SetNeedsCommimt request in the scheduler
284 skip_update_ = true;
285 }
286
287 if (track_ui_resource_id_ == id) {
288 SetNeedsCommit();
289 skip_update_ = true;
290 }
291 }
292
347 } // namespace cc 293 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698