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

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"
10 #include "base/memory/weak_ptr.h"
11 #include "cc/layers/scrollbar_layer_impl.h" 11 #include "cc/layers/scrollbar_layer_impl.h"
12 #include "cc/resources/caching_bitmap_content_layer_updater.h" 12 #include "cc/resources/ui_resource_bitmap.h"
13 #include "cc/resources/layer_painter.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(
31 scroll_layer_id)); 32 new ScrollbarLayer(scrollbar.Pass(), 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 } 123 }
122 scrollbar_layer->set_thumb_length(thumb_length_); 124 scrollbar_layer->set_thumb_length(thumb_length_);
123 if (Orientation() == HORIZONTAL) { 125 if (Orientation() == HORIZONTAL) {
124 scrollbar_layer->set_track_start(track_rect_.x()); 126 scrollbar_layer->set_track_start(track_rect_.x());
125 scrollbar_layer->set_track_length(track_rect_.width()); 127 scrollbar_layer->set_track_length(track_rect_.width());
126 } else { 128 } else {
127 scrollbar_layer->set_track_start(track_rect_.y()); 129 scrollbar_layer->set_track_start(track_rect_.y());
128 scrollbar_layer->set_track_length(track_rect_.height()); 130 scrollbar_layer->set_track_length(track_rect_.height());
129 } 131 }
130 132
131 if (track_ && track_->texture()->have_backing_texture()) 133 scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_);
132 scrollbar_layer->set_track_resource_id(track_->texture()->resource_id()); 134 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 135
141 scrollbar_layer->set_is_overlay_scrollbar(scrollbar_->IsOverlay()); 136 scrollbar_layer->set_is_overlay_scrollbar(scrollbar_->IsOverlay());
142 137
143 // ScrollbarLayer must push properties every frame. crbug.com/259095 138 // ScrollbarLayer must push properties every frame. crbug.com/259095
144 needs_push_properties_ = true; 139 needs_push_properties_ = true;
145 } 140 }
146 141
147 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { 142 ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() {
148 return this; 143 return this;
149 } 144 }
150 145
151 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { 146 void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
147 // When the LTH is set to null, then this layer should remove all of
148 // its associated textures.
152 if (!host || host != layer_tree_host()) { 149 if (!host || host != layer_tree_host()) {
153 track_updater_ = NULL; 150 if (track_ui_resource_id_) {
154 track_.reset(); 151 if (layer_tree_host())
155 thumb_updater_ = NULL; 152 layer_tree_host()->DeleteUIResource(track_ui_resource_id_);
156 thumb_.reset(); 153 track_ui_resource_id_ = 0;
154 track_bitmap_ = NULL;
155 }
156
157 if (thumb_ui_resource_id_) {
158 if (layer_tree_host())
159 layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_);
160 thumb_ui_resource_id_ = 0;
161 thumb_bitmap_ = NULL;
162 }
157 } 163 }
158 164
159 ContentsScalingLayer::SetLayerTreeHost(host); 165 ContentsScalingLayer::SetLayerTreeHost(host);
160 } 166 }
161 167
162 class ScrollbarPartPainter : public LayerPainter {
163 public:
164 ScrollbarPartPainter(Scrollbar* scrollbar, ScrollbarPart part)
165 : scrollbar_(scrollbar),
166 part_(part) {}
167 virtual ~ScrollbarPartPainter() {}
168
169 // LayerPainter implementation
170 virtual void Paint(SkCanvas* canvas,
171 gfx::Rect content_rect,
172 gfx::RectF* opaque) OVERRIDE {
173 scrollbar_->PaintPart(canvas, part_, content_rect);
174 }
175
176 private:
177 Scrollbar* scrollbar_;
178 ScrollbarPart part_;
179 };
180
181 void ScrollbarLayer::CreateUpdaterIfNeeded() {
182 if (layer_tree_host()->settings().solid_color_scrollbars)
183 return;
184
185 texture_format_ =
186 layer_tree_host()->GetRendererCapabilities().best_texture_format;
187
188 if (!track_updater_.get()) {
189 track_updater_ = CachingBitmapContentLayerUpdater::Create(
190 scoped_ptr<LayerPainter>(
191 new ScrollbarPartPainter(scrollbar_.get(), TRACK))
192 .Pass(),
193 rendering_stats_instrumentation(),
194 id());
195 }
196 if (!track_) {
197 track_ = track_updater_->CreateResource(
198 layer_tree_host()->contents_texture_manager());
199 }
200
201 if (!thumb_updater_.get()) {
202 thumb_updater_ = CachingBitmapContentLayerUpdater::Create(
203 scoped_ptr<LayerPainter>(
204 new ScrollbarPartPainter(scrollbar_.get(), THUMB))
205 .Pass(),
206 rendering_stats_instrumentation(),
207 id());
208 }
209 if (!thumb_ && scrollbar_->HasThumb()) {
210 thumb_ = thumb_updater_->CreateResource(
211 layer_tree_host()->contents_texture_manager());
212 }
213 }
214
215 bool ScrollbarLayer::UpdatePart(CachingBitmapContentLayerUpdater* painter,
216 LayerUpdater::Resource* resource,
217 gfx::Rect rect,
218 ResourceUpdateQueue* queue) {
219 if (layer_tree_host()->settings().solid_color_scrollbars)
220 return false;
221
222 // Skip painting and uploading if there are no invalidations and
223 // we already have valid texture data.
224 if (resource->texture()->have_backing_texture() &&
225 resource->texture()->size() == rect.size() &&
226 !is_dirty())
227 return false;
228
229 // We should always have enough memory for UI.
230 DCHECK(resource->texture()->can_acquire_backing_texture());
231 if (!resource->texture()->can_acquire_backing_texture())
232 return false;
233
234 // Paint and upload the entire part.
235 gfx::Rect painted_opaque_rect;
236 painter->PrepareToUpdate(rect,
237 rect.size(),
238 contents_scale_x(),
239 contents_scale_y(),
240 &painted_opaque_rect);
241 if (!painter->pixels_did_change() &&
242 resource->texture()->have_backing_texture()) {
243 TRACE_EVENT_INSTANT0("cc",
244 "ScrollbarLayer::UpdatePart no texture upload needed",
245 TRACE_EVENT_SCOPE_THREAD);
246 return false;
247 }
248
249 bool partial_updates_allowed =
250 layer_tree_host()->settings().max_partial_texture_updates > 0;
251 if (!partial_updates_allowed)
252 resource->texture()->ReturnBackingTexture();
253
254 gfx::Vector2d dest_offset(0, 0);
255 resource->Update(queue, rect, dest_offset, partial_updates_allowed);
256 return true;
257 }
258
259 gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( 168 gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect(
260 gfx::Rect layer_rect) const { 169 gfx::Rect layer_rect) const {
261 // Don't intersect with the bounds as in LayerRectToContentRect() because 170 // Don't intersect with the bounds as in LayerRectToContentRect() because
262 // layer_rect here might be in coordinates of the containing layer. 171 // layer_rect here might be in coordinates of the containing layer.
263 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect( 172 gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect(
264 layer_rect, contents_scale_y(), contents_scale_y()); 173 layer_rect, contents_scale_y(), contents_scale_y());
265 // We should never return a rect bigger than the content_bounds(). 174 // We should never return a rect bigger than the content_bounds().
266 gfx::Size clamped_size = expanded_rect.size(); 175 gfx::Size clamped_size = expanded_rect.size();
267 clamped_size.SetToMin(content_bounds()); 176 clamped_size.SetToMin(content_bounds());
268 expanded_rect.set_size(clamped_size); 177 expanded_rect.set_size(clamped_size);
269 return expanded_rect; 178 return expanded_rect;
270 } 179 }
271 180
272 void ScrollbarLayer::SetTexturePriorities( 181 gfx::Rect ScrollbarLayer::OriginThumbRect() const {
273 const PriorityCalculator& priority_calc) { 182 gfx::Size thumb_size;
274 if (layer_tree_host()->settings().solid_color_scrollbars) 183 if (Orientation() == HORIZONTAL) {
275 return; 184 thumb_size =
276 185 gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness());
277 if (content_bounds().IsEmpty()) 186 } else {
278 return; 187 thumb_size =
279 DCHECK_LE(content_bounds().width(), MaxTextureSize()); 188 gfx::Size(scrollbar_->ThumbThickness(), scrollbar_->ThumbLength());
280 DCHECK_LE(content_bounds().height(), MaxTextureSize());
281
282 CreateUpdaterIfNeeded();
283
284 bool draws_to_root = !render_target()->parent();
285 if (track_) {
286 track_->texture()->SetDimensions(content_bounds(), texture_format_);
287 track_->texture()->set_request_priority(
288 PriorityCalculator::UIPriority(draws_to_root));
289 } 189 }
290 if (thumb_) { 190 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size));
291 gfx::Size thumb_size = OriginThumbRect().size();
292 thumb_->texture()->SetDimensions(thumb_size, texture_format_);
293 thumb_->texture()->set_request_priority(
294 PriorityCalculator::UIPriority(draws_to_root));
295 }
296 } 191 }
297 192
298 bool ScrollbarLayer::Update(ResourceUpdateQueue* queue, 193 bool ScrollbarLayer::Update(ResourceUpdateQueue* queue,
299 const OcclusionTracker* occlusion) { 194 const OcclusionTracker* occlusion) {
300 track_rect_ = scrollbar_->TrackRect(); 195 track_rect_ = scrollbar_->TrackRect();
301 196
302 if (layer_tree_host()->settings().solid_color_scrollbars) 197 if (layer_tree_host()->settings().solid_color_scrollbars)
303 return false; 198 return false;
304 199
200 // Setting this boolean is still necessary to ensure no extra commits.
305 { 201 {
306 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, 202 base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_,
307 true); 203 true);
308 ContentsScalingLayer::Update(queue, occlusion); 204 ContentsScalingLayer::Update(queue, occlusion);
309 } 205 }
310 206
311 dirty_rect_.Union(update_rect_);
312 if (content_bounds().IsEmpty())
313 return false;
314 if (visible_content_rect().IsEmpty())
315 return false;
316
317 CreateUpdaterIfNeeded();
318
319 gfx::Rect content_rect = ScrollbarLayerRectToContentRect(
320 gfx::Rect(scrollbar_->Location(), bounds()));
321 bool updated = UpdatePart(track_updater_.get(), track_.get(), content_rect,
322 queue);
323
324 if (scrollbar_->HasThumb()) { 207 if (scrollbar_->HasThumb()) {
325 thumb_thickness_ = scrollbar_->ThumbThickness(); 208 thumb_thickness_ = scrollbar_->ThumbThickness();
326 thumb_length_ = scrollbar_->ThumbLength(); 209 thumb_length_ = scrollbar_->ThumbLength();
327 gfx::Rect origin_thumb_rect = OriginThumbRect();
328 if (!origin_thumb_rect.IsEmpty()) {
329 updated |= UpdatePart(thumb_updater_.get(), thumb_.get(),
330 origin_thumb_rect, queue);
331 }
332 } 210 }
333 211
334 dirty_rect_ = gfx::RectF(); 212 RasterizeTrackAndThumb();
335 return updated; 213
214 if (track_ui_resource_id_)
215 layer_tree_host()->DeleteUIResource(track_ui_resource_id_);
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_)
221 layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_);
222 thumb_ui_resource_id_ = layer_tree_host()->CreateUIResource(
223 base::Bind(&ScrollbarLayer::GetThumbBitmap, this));
224 }
225
226 return true;
336 } 227 }
337 228
338 gfx::Rect ScrollbarLayer::OriginThumbRect() const { 229 void ScrollbarLayer::RasterizeTrackAndThumb() {
339 gfx::Size thumb_size; 230 DCHECK(!layer_tree_host()->settings().solid_color_scrollbars);
340 if (Orientation() == HORIZONTAL) { 231
341 thumb_size = gfx::Size(scrollbar_->ThumbLength(), 232 gfx::Rect track_rect = ScrollbarLayerRectToContentRect(
342 scrollbar_->ThumbThickness()); 233 gfx::Rect(scrollbar_->Location(), bounds()));
343 } else { 234 track_bitmap_ = UIResourceBitmap::Create(
344 thumb_size = gfx::Size(scrollbar_->ThumbThickness(), 235 new uint8_t[track_rect.width() * track_rect.height() * 4],
345 scrollbar_->ThumbLength()); 236 UIResourceBitmap::RGBA8,
237 track_rect.size());
238
239 skia::RefPtr<SkCanvas> track_canvas =
240 skia::AdoptRef(skia::CreatePlatformCanvas(track_rect.width(),
241 track_rect.height(),
242 false,
243 track_bitmap_->GetPixels(),
244 skia::CRASH_ON_FAILURE));
245 track_canvas->save();
246 track_canvas->translate(SkFloatToScalar(-track_rect.x()),
247 SkFloatToScalar(-track_rect.y()));
248 SkRect layer_sk_rect = SkRect::MakeXYWH(
249 track_rect.x(), track_rect.y(), track_rect.width(), track_rect.height());
250
251 track_canvas->clipRect(layer_sk_rect);
252 scrollbar_->PaintPart(track_canvas.get(), TRACK, track_rect);
253 track_canvas->restore();
254
255 if (scrollbar_->HasThumb()) {
256 gfx::Rect thumb_rect = OriginThumbRect();
257 thumb_bitmap_ = UIResourceBitmap::Create(
258 new uint8_t[thumb_rect.width() * thumb_rect.height() * 4],
259 UIResourceBitmap::RGBA8,
260 thumb_rect.size());
261
262 skia::RefPtr<SkCanvas> thumb_canvas =
263 skia::AdoptRef(skia::CreatePlatformCanvas(thumb_rect.width(),
264 thumb_rect.height(),
265 false,
266 thumb_bitmap_->GetPixels(),
267 skia::CRASH_ON_FAILURE));
268
269 scrollbar_->PaintPart(thumb_canvas.get(), THUMB, thumb_rect);
346 } 270 }
347 return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); 271 }
272
273 scoped_refptr<UIResourceBitmap> ScrollbarLayer::GetTrackBitmap(
274 bool resource_lost) {
275 return track_bitmap_;
276 }
277
278 scoped_refptr<UIResourceBitmap> ScrollbarLayer::GetThumbBitmap(
279 bool resource_lost) {
280 return thumb_bitmap_;
348 } 281 }
349 282
350 } // namespace cc 283 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698