Chromium Code Reviews| Index: cc/layers/scrollbar_layer.cc |
| =================================================================== |
| --- cc/layers/scrollbar_layer.cc (revision 210393) |
| +++ cc/layers/scrollbar_layer.cc (working copy) |
| @@ -1,4 +1,3 @@ |
| - |
| // Copyright 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @@ -9,11 +8,13 @@ |
| #include "base/basictypes.h" |
| #include "base/debug/trace_event.h" |
| #include "cc/layers/scrollbar_layer_impl.h" |
| -#include "cc/resources/caching_bitmap_content_layer_updater.h" |
| -#include "cc/resources/layer_painter.h" |
| -#include "cc/resources/prioritized_resource.h" |
| -#include "cc/resources/resource_update_queue.h" |
| +#include "cc/resources/ui_resource_bitmap.h" |
| +#include "cc/resources/ui_resource_manager_client.h" |
| #include "cc/trees/layer_tree_host.h" |
| +#include "cc/trees/layer_tree_impl.h" |
| +#include "skia/ext/platform_canvas.h" |
| +#include "skia/ext/refptr.h" |
| +#include "third_party/skia/include/core/SkSize.h" |
| #include "ui/gfx/rect_conversions.h" |
| namespace cc { |
| @@ -36,7 +37,8 @@ |
| int scroll_layer_id) |
| : scrollbar_(scrollbar.Pass()), |
| scroll_layer_id_(scroll_layer_id), |
| - texture_format_(GL_INVALID_ENUM) { |
| + track_ui_resource_id_(0), |
| + thumb_ui_resource_id_(0) { |
| if (!scrollbar_->IsOverlay()) |
| SetShouldScrollOnMainThread(true); |
| } |
| @@ -97,6 +99,16 @@ |
| contents_scale_x, |
| contents_scale_y, |
| content_bounds); |
| + |
| + 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
|
| + |
| + if (layer_tree_host()->settings().solid_color_scrollbars) |
| + return; |
| + |
| + if (scrollbar_->HasThumb()) { |
| + thumb_thickness_ = scrollbar_->ThumbThickness(); |
| + thumb_length_ = scrollbar_->ThumbLength(); |
| + } |
| } |
| void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { |
| @@ -128,15 +140,8 @@ |
| scrollbar_layer->set_track_length(track_rect_.height()); |
| } |
| - if (track_ && track_->texture()->have_backing_texture()) |
| - scrollbar_layer->set_track_resource_id(track_->texture()->resource_id()); |
| - else |
| - scrollbar_layer->set_track_resource_id(0); |
| - |
| - if (thumb_ && thumb_->texture()->have_backing_texture()) |
| - scrollbar_layer->set_thumb_resource_id(thumb_->texture()->resource_id()); |
| - else |
| - scrollbar_layer->set_thumb_resource_id(0); |
| + scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_); |
| + scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_); |
| } |
| ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { |
| @@ -144,112 +149,29 @@ |
| } |
| void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { |
| + // When the LTH is set to null, then this layer should remove all of |
| + // its associated textures. |
| if (!host || host != layer_tree_host()) { |
| - track_updater_ = NULL; |
| - track_.reset(); |
| - thumb_updater_ = NULL; |
| - thumb_.reset(); |
| + if (track_ui_resource_id_) { |
| + if (layer_tree_host()) { |
| + layer_tree_host()->DeleteUIResource(track_ui_resource_id_); |
| + } |
| + track_ui_resource_id_ = 0; |
| + track_bitmap_ = NULL; |
| + } |
| + |
| + if (thumb_ui_resource_id_) { |
| + if (layer_tree_host()) { |
| + layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_); |
| + } |
| + thumb_ui_resource_id_ = 0; |
| + thumb_bitmap_ = NULL; |
| + } |
| } |
| ContentsScalingLayer::SetLayerTreeHost(host); |
| } |
| -class ScrollbarPartPainter : public LayerPainter { |
| - public: |
| - ScrollbarPartPainter(Scrollbar* scrollbar, ScrollbarPart part) |
| - : scrollbar_(scrollbar), |
| - part_(part) {} |
| - virtual ~ScrollbarPartPainter() {} |
| - |
| - // LayerPainter implementation |
| - virtual void Paint(SkCanvas* canvas, |
| - gfx::Rect content_rect, |
| - gfx::RectF* opaque) OVERRIDE { |
| - scrollbar_->PaintPart(canvas, part_, content_rect); |
| - } |
| - |
| - private: |
| - Scrollbar* scrollbar_; |
| - ScrollbarPart part_; |
| -}; |
| - |
| -void ScrollbarLayer::CreateUpdaterIfNeeded() { |
| - if (layer_tree_host()->settings().solid_color_scrollbars) |
| - return; |
| - |
| - texture_format_ = |
| - layer_tree_host()->GetRendererCapabilities().best_texture_format; |
| - |
| - if (!track_updater_.get()) { |
| - track_updater_ = CachingBitmapContentLayerUpdater::Create( |
| - scoped_ptr<LayerPainter>( |
| - new ScrollbarPartPainter(scrollbar_.get(), TRACK)) |
| - .Pass(), |
| - rendering_stats_instrumentation(), |
| - id()); |
| - } |
| - if (!track_) { |
| - track_ = track_updater_->CreateResource( |
| - layer_tree_host()->contents_texture_manager()); |
| - } |
| - |
| - if (!thumb_updater_.get()) { |
| - thumb_updater_ = CachingBitmapContentLayerUpdater::Create( |
| - scoped_ptr<LayerPainter>( |
| - new ScrollbarPartPainter(scrollbar_.get(), THUMB)) |
| - .Pass(), |
| - rendering_stats_instrumentation(), |
| - id()); |
| - } |
| - if (!thumb_ && scrollbar_->HasThumb()) { |
| - thumb_ = thumb_updater_->CreateResource( |
| - layer_tree_host()->contents_texture_manager()); |
| - } |
| -} |
| - |
| -void ScrollbarLayer::UpdatePart(CachingBitmapContentLayerUpdater* painter, |
| - LayerUpdater::Resource* resource, |
| - gfx::Rect rect, |
| - ResourceUpdateQueue* queue) { |
| - if (layer_tree_host()->settings().solid_color_scrollbars) |
| - return; |
| - |
| - // Skip painting and uploading if there are no invalidations and |
| - // we already have valid texture data. |
| - if (resource->texture()->have_backing_texture() && |
| - resource->texture()->size() == rect.size() && |
| - !is_dirty()) |
| - return; |
| - |
| - // We should always have enough memory for UI. |
| - DCHECK(resource->texture()->can_acquire_backing_texture()); |
| - if (!resource->texture()->can_acquire_backing_texture()) |
| - return; |
| - |
| - // Paint and upload the entire part. |
| - gfx::Rect painted_opaque_rect; |
| - painter->PrepareToUpdate(rect, |
| - rect.size(), |
| - contents_scale_x(), |
| - contents_scale_y(), |
| - &painted_opaque_rect); |
| - if (!painter->pixels_did_change() && |
| - resource->texture()->have_backing_texture()) { |
| - TRACE_EVENT_INSTANT0("cc", |
| - "ScrollbarLayer::UpdatePart no texture upload needed", |
| - TRACE_EVENT_SCOPE_THREAD); |
| - return; |
| - } |
| - |
| - bool partial_updates_allowed = |
| - layer_tree_host()->settings().max_partial_texture_updates > 0; |
| - if (!partial_updates_allowed) |
| - resource->texture()->ReturnBackingTexture(); |
| - |
| - gfx::Vector2d dest_offset(0, 0); |
| - resource->Update(queue, rect, dest_offset, partial_updates_allowed); |
| -} |
| - |
| gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( |
| gfx::Rect layer_rect) const { |
| // Don't intersect with the bounds as in LayerRectToContentRect() because |
| @@ -263,85 +185,110 @@ |
| return expanded_rect; |
| } |
| -void ScrollbarLayer::SetTexturePriorities( |
| - const PriorityCalculator& priority_calc) { |
| +gfx::Rect ScrollbarLayer::OriginThumbRect() const { |
| + gfx::Size thumb_size; |
| + if (Orientation() == HORIZONTAL) { |
| + thumb_size = gfx::Size(scrollbar_->ThumbLength(), |
| + scrollbar_->ThumbThickness()); |
| + } else { |
| + thumb_size = gfx::Size(scrollbar_->ThumbThickness(), |
| + scrollbar_->ThumbLength()); |
| + } |
| + return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); |
| +} |
| + |
| + |
| +void ScrollbarLayer::Update(ResourceUpdateQueue* queue, |
| + const OcclusionTracker* occlusion) { |
| if (layer_tree_host()->settings().solid_color_scrollbars) |
| return; |
| - if (content_bounds().IsEmpty()) |
| - return; |
| - DCHECK_LE(content_bounds().width(), MaxTextureSize()); |
| - DCHECK_LE(content_bounds().height(), MaxTextureSize()); |
| + // Setting this boolean is still necessary to ensure no extra commits. |
| + base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, |
| + true); |
| + ContentsScalingLayer::Update(queue, occlusion); |
| - CreateUpdaterIfNeeded(); |
| + RasterizeTrackAndThumb(); |
| - bool draws_to_root = !render_target()->parent(); |
| - if (track_) { |
| - track_->texture()->SetDimensions(content_bounds(), texture_format_); |
| - track_->texture()->set_request_priority( |
| - PriorityCalculator::UIPriority(draws_to_root)); |
| + 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.
|
| + layer_tree_host()->DeleteUIResource(track_ui_resource_id_); |
| } |
| - if (thumb_) { |
| - gfx::Size thumb_size = OriginThumbRect().size(); |
| - thumb_->texture()->SetDimensions(thumb_size, texture_format_); |
| - thumb_->texture()->set_request_priority( |
| - PriorityCalculator::UIPriority(draws_to_root)); |
| + track_ui_resource_id_ = layer_tree_host()->CreateUIResource( |
| + base::Bind(&ScrollbarLayer::GetTrackBitmap, this)); |
| + |
| + if (scrollbar_->HasThumb()) { |
| + 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.
|
| + layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_); |
| + } |
| + |
| + thumb_ui_resource_id_ = layer_tree_host()->CreateUIResource( |
| + 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
|
| } |
| } |
| -void ScrollbarLayer::Update(ResourceUpdateQueue* queue, |
| - const OcclusionTracker* occlusion) { |
| - track_rect_ = scrollbar_->TrackRect(); |
| - |
| - if (layer_tree_host()->settings().solid_color_scrollbars) |
| - return; |
| - |
| +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.
|
| { |
|
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.
|
| - base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, |
| - true); |
| - ContentsScalingLayer::Update(queue, occlusion); |
| - } |
| + gfx::Rect track_rect = ScrollbarLayerRectToContentRect( |
| + gfx::Rect(scrollbar_->Location(), bounds())); |
| + track_bitmap_ = UIResourceBitmap::Create( |
| + new uint8_t[track_rect.width() * track_rect.height() * 4], |
| + UIResourceBitmap::RGBA8, |
| + track_rect.size()); |
| - dirty_rect_.Union(update_rect_); |
| - if (content_bounds().IsEmpty()) |
| - return; |
| - if (visible_content_rect().IsEmpty()) |
| - return; |
| + skia::RefPtr<SkCanvas> track_canvas = skia::AdoptRef( |
| + skia::CreatePlatformCanvas(track_rect.width(), |
| + track_rect.height(), |
| + false, |
| + 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.
|
| + track_bitmap_->GetPixels()), |
| + skia::CRASH_ON_FAILURE)); |
| - CreateUpdaterIfNeeded(); |
| + track_canvas->save(); |
| + track_canvas->translate(SkFloatToScalar(-track_rect.x()), |
| + SkFloatToScalar(-track_rect.y())); |
| + SkPaint paint; |
| + paint.setAntiAlias(false); |
| + paint.setXfermodeMode(SkXfermode::kClear_Mode); |
| + SkRect layer_sk_rect = SkRect::MakeXYWH(track_rect.x(), |
| + track_rect.y(), |
| + track_rect.width(), |
| + track_rect.height()); |
| - gfx::Rect content_rect = ScrollbarLayerRectToContentRect( |
| - gfx::Rect(scrollbar_->Location(), bounds())); |
| - UpdatePart(track_updater_.get(), |
| - track_.get(), |
| - content_rect, |
| - queue); |
| + 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.
|
| + track_canvas->clipRect(layer_sk_rect); |
| + scrollbar_->PaintPart(track_canvas.get(), TRACK, track_rect); |
| + track_canvas->restore(); |
| + } |
| if (scrollbar_->HasThumb()) { |
| - thumb_thickness_ = scrollbar_->ThumbThickness(); |
| - thumb_length_ = scrollbar_->ThumbLength(); |
| - gfx::Rect origin_thumb_rect = OriginThumbRect(); |
| - if (!origin_thumb_rect.IsEmpty()) { |
| - UpdatePart(thumb_updater_.get(), |
| - thumb_.get(), |
| - origin_thumb_rect, |
| - queue); |
| - } |
| + gfx::Rect thumb_rect = OriginThumbRect(); |
| + thumb_bitmap_ = UIResourceBitmap::Create( |
| + new uint8_t[thumb_rect.width() * thumb_rect.height() * 4], |
| + UIResourceBitmap::RGBA8, |
| + thumb_rect.size()); |
| + |
| + skia::RefPtr<SkCanvas> thumb_canvas = skia::AdoptRef( |
| + skia::CreatePlatformCanvas(thumb_rect.width(), |
| + thumb_rect.height(), |
| + false, |
| + 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.
|
| + thumb_bitmap_->GetPixels()), |
| + skia::CRASH_ON_FAILURE)); |
| + |
| + scrollbar_->PaintPart(thumb_canvas.get(), |
| + THUMB, |
| + thumb_rect); |
| } |
| +} |
| - dirty_rect_ = gfx::RectF(); |
| +scoped_refptr<UIResourceBitmap> |
| +ScrollbarLayer::GetTrackBitmap(bool resource_lost) { |
| + return track_bitmap_; |
| } |
| -gfx::Rect ScrollbarLayer::OriginThumbRect() const { |
| - gfx::Size thumb_size; |
| - if (Orientation() == HORIZONTAL) { |
| - thumb_size = gfx::Size(scrollbar_->ThumbLength(), |
| - scrollbar_->ThumbThickness()); |
| - } else { |
| - thumb_size = gfx::Size(scrollbar_->ThumbThickness(), |
| - scrollbar_->ThumbLength()); |
| - } |
| - return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size)); |
| +scoped_refptr<UIResourceBitmap> |
| +ScrollbarLayer::GetThumbBitmap(bool resource_lost) { |
| + return thumb_bitmap_; |
| } |
| } // namespace cc |