diff options
author | powei@chromium.org <powei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-14 02:18:58 +0000 |
---|---|---|
committer | powei@chromium.org <powei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-14 02:18:58 +0000 |
commit | 45b46d3861c832db5879f08afad54a962c958abd (patch) | |
tree | 878f87f2dc914158d5cb7a7448d0771a9342133d /cc | |
parent | 88a4366fe322086306ff3977fedb936348113e9a (diff) | |
download | chromium_src-45b46d3861c832db5879f08afad54a962c958abd.zip chromium_src-45b46d3861c832db5879f08afad54a962c958abd.tar.gz chromium_src-45b46d3861c832db5879f08afad54a962c958abd.tar.bz2 |
Change the ScrollbarLayer to use UI Resource as oppose to prioritized resource manager.
First attemped as a part of the UI resource CL:
https://chromiumcodereview.appspot.com/18191020
Reverted due to failed tests:
https://chromiumcodereview.appspot.com/21555004
This patch clears the SkCanvas (bitmap) for the thumb/track before painting, and scales the canvas with respect to the content_scale (closer to the original scrollbar implementation that used cc/resources/content_layer_updater).
Also change the pixel swizzling format to best_texture_format().
BUG=173947
Review URL: https://chromiumcodereview.appspot.com/21917004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217446 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/scrollbar_layer.cc | 249 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer.h | 38 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_impl.cc | 38 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_impl.h | 15 | ||||
-rw-r--r-- | cc/layers/scrollbar_layer_unittest.cc | 122 | ||||
-rw-r--r-- | cc/test/fake_scrollbar_layer.cc | 10 | ||||
-rw-r--r-- | cc/test/fake_scrollbar_layer.h | 16 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 75 |
9 files changed, 267 insertions, 300 deletions
diff --git a/cc/layers/scrollbar_layer.cc b/cc/layers/scrollbar_layer.cc index 4a63835..14d038f 100644 --- a/cc/layers/scrollbar_layer.cc +++ b/cc/layers/scrollbar_layer.cc @@ -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,12 +8,15 @@ #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/trees/layer_tree_host.h" -#include "ui/gfx/rect_conversions.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/SkBitmap.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkSize.h" +#include "ui/gfx/skia_util.h" namespace cc { @@ -27,16 +29,15 @@ scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl( scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create( scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id) { - return make_scoped_refptr(new ScrollbarLayer(scrollbar.Pass(), - scroll_layer_id)); + return make_scoped_refptr( + new ScrollbarLayer(scrollbar.Pass(), scroll_layer_id)); } ScrollbarLayer::ScrollbarLayer( scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id) : scrollbar_(scrollbar.Pass()), - scroll_layer_id_(scroll_layer_id), - texture_format_(GL_INVALID_ENUM) { + scroll_layer_id_(scroll_layer_id) { if (!scrollbar_->IsOverlay()) SetShouldScrollOnMainThread(true); } @@ -128,15 +129,10 @@ void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { 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); + if (track_resource_.get()) + scrollbar_layer->set_track_ui_resource_id(track_resource_->id()); + if (thumb_resource_.get()) + scrollbar_layer->set_thumb_ui_resource_id(thumb_resource_->id()); scrollbar_layer->set_is_overlay_scrollbar(scrollbar_->IsOverlay()); @@ -149,113 +145,16 @@ ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { } void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { + // When the LTH is set to null or has changed, then this layer should remove + // all of its associated resources. if (!host || host != layer_tree_host()) { - track_updater_ = NULL; - track_.reset(); - thumb_updater_ = NULL; - thumb_.reset(); + track_resource_.reset(); + thumb_resource_.reset(); } 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()); - } -} - -bool ScrollbarLayer::UpdatePart(CachingBitmapContentLayerUpdater* painter, - LayerUpdater::Resource* resource, - gfx::Rect rect, - ResourceUpdateQueue* queue) { - if (layer_tree_host()->settings().solid_color_scrollbars) - return false; - - // 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 false; - - // We should always have enough memory for UI. - DCHECK(resource->texture()->can_acquire_backing_texture()); - if (!resource->texture()->can_acquire_backing_texture()) - return false; - - // 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 false; - } - - 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); - return true; -} - gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( gfx::Rect layer_rect) const { // Don't intersect with the bounds as in LayerRectToContentRect() because @@ -269,84 +168,80 @@ gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( return expanded_rect; } -void ScrollbarLayer::SetTexturePriorities( - const PriorityCalculator& priority_calc) { - 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()); - - CreateUpdaterIfNeeded(); - - 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 (thumb_) { - gfx::Size thumb_size = OriginThumbRect().size(); - thumb_->texture()->SetDimensions(thumb_size, texture_format_); - thumb_->texture()->set_request_priority( - PriorityCalculator::UIPriority(draws_to_root)); +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)); } bool ScrollbarLayer::Update(ResourceUpdateQueue* queue, const OcclusionTracker* occlusion) { track_rect_ = scrollbar_->TrackRect(); + gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect( + gfx::Rect(scrollbar_->Location(), bounds())); - if (layer_tree_host()->settings().solid_color_scrollbars) + if (layer_tree_host()->settings().solid_color_scrollbars || + track_rect_.IsEmpty() || scaled_track_rect.IsEmpty()) return false; - bool updated = false; - { base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, true); - updated = ContentsScalingLayer::Update(queue, occlusion); + ContentsScalingLayer::Update(queue, occlusion); } - dirty_rect_.Union(update_rect_); - if (content_bounds().IsEmpty()) - return false; - if (visible_content_rect().IsEmpty()) - return false; - - CreateUpdaterIfNeeded(); + track_resource_ = ScopedUIResource::Create( + layer_tree_host(), RasterizeScrollbarPart(scaled_track_rect, TRACK)); + gfx::Rect thumb_rect = OriginThumbRect(); - gfx::Rect content_rect = ScrollbarLayerRectToContentRect( - gfx::Rect(scrollbar_->Location(), bounds())); - updated |= UpdatePart(track_updater_.get(), track_.get(), content_rect, - queue); - - if (scrollbar_->HasThumb()) { + if (scrollbar_->HasThumb() && !thumb_rect.IsEmpty()) { thumb_thickness_ = scrollbar_->ThumbThickness(); thumb_length_ = scrollbar_->ThumbLength(); - gfx::Rect origin_thumb_rect = OriginThumbRect(); - if (!origin_thumb_rect.IsEmpty()) { - updated |= UpdatePart(thumb_updater_.get(), thumb_.get(), - origin_thumb_rect, queue); - } + thumb_resource_ = ScopedUIResource::Create( + layer_tree_host(), RasterizeScrollbarPart(thumb_rect, THUMB)); } - dirty_rect_ = gfx::RectF(); - return updated; + return true; } -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::RasterizeScrollbarPart( + gfx::Rect rect, + ScrollbarPart part) { + DCHECK(!layer_tree_host()->settings().solid_color_scrollbars); + DCHECK(!rect.size().IsEmpty()); + + scoped_refptr<UIResourceBitmap> bitmap = + UIResourceBitmap::Create(new uint8_t[rect.width() * rect.height() * 4], + UIResourceBitmap::RGBA8, + rect.size()); + + SkBitmap skbitmap; + skbitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height()); + skbitmap.setPixels(bitmap->GetPixels()); + + SkCanvas skcanvas(skbitmap); + skcanvas.translate(SkFloatToScalar(-rect.x()), SkFloatToScalar(-rect.y())); + skcanvas.scale(SkFloatToScalar(contents_scale_x()), + SkFloatToScalar(contents_scale_y())); + + gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( + rect, 1.f / contents_scale_x(), 1.f / contents_scale_y()); + SkRect layer_skrect = RectToSkRect(layer_rect); + SkPaint paint; + paint.setAntiAlias(false); + paint.setXfermodeMode(SkXfermode::kClear_Mode); + skcanvas.drawRect(layer_skrect, paint); + skcanvas.clipRect(layer_skrect); + + scrollbar_->PaintPart(&skcanvas, part, layer_rect); + + return bitmap; } } // namespace cc diff --git a/cc/layers/scrollbar_layer.h b/cc/layers/scrollbar_layer.h index f500dcc..a162a7f 100644 --- a/cc/layers/scrollbar_layer.h +++ b/cc/layers/scrollbar_layer.h @@ -10,10 +10,9 @@ #include "cc/layers/contents_scaling_layer.h" #include "cc/layers/scrollbar_theme_painter.h" #include "cc/resources/layer_updater.h" +#include "cc/resources/scoped_ui_resource.h" namespace cc { -class CachingBitmapContentLayerUpdater; -class ResourceUpdateQueue; class ScrollbarThemeComposite; class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { @@ -33,8 +32,6 @@ class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { ScrollbarOrientation Orientation() const; // Layer interface - virtual void SetTexturePriorities(const PriorityCalculator& priority_calc) - OVERRIDE; virtual bool Update(ResourceUpdateQueue* queue, const OcclusionTracker* occlusion) OVERRIDE; virtual void SetLayerTreeHost(LayerTreeHost* host) OVERRIDE; @@ -50,24 +47,27 @@ class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { virtual ScrollbarLayer* ToScrollbarLayer() OVERRIDE; protected: - ScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, - int scroll_layer_id); + ScrollbarLayer(scoped_ptr<Scrollbar> scrollbar, int scroll_layer_id); virtual ~ScrollbarLayer(); + // For unit tests + UIResourceId track_resource_id() { + return track_resource_.get() ? track_resource_->id() : 0; + } + UIResourceId thumb_resource_id() { + return thumb_resource_.get() ? thumb_resource_->id() : 0; + } + private: - bool UpdatePart(CachingBitmapContentLayerUpdater* painter, - LayerUpdater::Resource* resource, - gfx::Rect rect, - ResourceUpdateQueue* queue); - void CreateUpdaterIfNeeded(); gfx::Rect ScrollbarLayerRectToContentRect(gfx::Rect layer_rect) const; gfx::Rect OriginThumbRect() const; - bool is_dirty() const { return !dirty_rect_.IsEmpty(); } - int MaxTextureSize(); float ClampScaleToMaxTextureSize(float scale); + scoped_refptr<UIResourceBitmap> RasterizeScrollbarPart(gfx::Rect rect, + ScrollbarPart part); + scoped_ptr<Scrollbar> scrollbar_; int thumb_thickness_; @@ -75,16 +75,8 @@ class CC_EXPORT ScrollbarLayer : public ContentsScalingLayer { gfx::Rect track_rect_; int scroll_layer_id_; - unsigned texture_format_; - - gfx::RectF dirty_rect_; - - scoped_refptr<CachingBitmapContentLayerUpdater> track_updater_; - scoped_refptr<CachingBitmapContentLayerUpdater> thumb_updater_; - - // All the parts of the scrollbar except the thumb - scoped_ptr<LayerUpdater::Resource> track_; - scoped_ptr<LayerUpdater::Resource> thumb_; + scoped_ptr<ScopedUIResource> track_resource_; + scoped_ptr<ScopedUIResource> thumb_resource_; DISALLOW_COPY_AND_ASSIGN(ScrollbarLayer); }; diff --git a/cc/layers/scrollbar_layer_impl.cc b/cc/layers/scrollbar_layer_impl.cc index 0dcfcde..51dbe07 100644 --- a/cc/layers/scrollbar_layer_impl.cc +++ b/cc/layers/scrollbar_layer_impl.cc @@ -31,8 +31,8 @@ ScrollbarLayerImpl::ScrollbarLayerImpl( int id, ScrollbarOrientation orientation) : LayerImpl(tree_impl, id), - track_resource_id_(0), - thumb_resource_id_(0), + track_ui_resource_id_(0), + thumb_ui_resource_id_(0), current_pos_(0.f), maximum_(0), thumb_thickness_(0), @@ -69,8 +69,8 @@ void ScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { scrollbar_layer->set_track_length(track_length_); scrollbar_layer->set_is_overlay_scrollbar(is_overlay_scrollbar_); - scrollbar_layer->set_track_resource_id(track_resource_id_); - scrollbar_layer->set_thumb_resource_id(thumb_resource_id_); + scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_); + scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_); } bool ScrollbarLayerImpl::WillDraw(DrawMode draw_mode, @@ -106,14 +106,19 @@ void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, return; } - if (thumb_resource_id_ && !thumb_quad_rect.IsEmpty()) { + ResourceProvider::ResourceId thumb_resource_id = + layer_tree_impl()->ResourceIdForUIResource(thumb_ui_resource_id_); + ResourceProvider::ResourceId track_resource_id = + layer_tree_impl()->ResourceIdForUIResource(track_ui_resource_id_); + + if (thumb_resource_id && !thumb_quad_rect.IsEmpty()) { gfx::Rect opaque_rect; const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); quad->SetNew(shared_quad_state, thumb_quad_rect, opaque_rect, - thumb_resource_id_, + thumb_resource_id, premultipled_alpha, uv_top_left, uv_bottom_right, @@ -123,21 +128,15 @@ void ScrollbarLayerImpl::AppendQuads(QuadSink* quad_sink, quad_sink->Append(quad.PassAs<DrawQuad>(), append_quads_data); } - if (!track_resource_id_) - return; - - // Order matters here: since the back track texture is being drawn to the - // entire contents rect, we must append it after the thumb and fore track - // quads. The back track texture contains (and displays) the buttons. - if (!content_bounds_rect.IsEmpty()) { - gfx::Rect quad_rect(content_bounds_rect); - gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect()); + gfx::Rect track_quad_rect = content_bounds_rect; + if (track_resource_id && !track_quad_rect.IsEmpty()) { + gfx::Rect opaque_rect(contents_opaque() ? track_quad_rect : gfx::Rect()); const float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create(); quad->SetNew(shared_quad_state, - quad_rect, + track_quad_rect, opaque_rect, - track_resource_id_, + track_resource_id, premultipled_alpha, uv_top_left, uv_bottom_right, @@ -261,11 +260,6 @@ gfx::Rect ScrollbarLayerImpl::ComputeThumbQuadRect() const { return ScrollbarLayerRectToContentRect(thumb_rect); } -void ScrollbarLayerImpl::DidLoseOutputSurface() { - track_resource_id_ = 0; - thumb_resource_id_ = 0; -} - const char* ScrollbarLayerImpl::LayerTypeAsString() const { return "cc::ScrollbarLayerImpl"; } diff --git a/cc/layers/scrollbar_layer_impl.h b/cc/layers/scrollbar_layer_impl.h index f61b660..ffc758f 100644 --- a/cc/layers/scrollbar_layer_impl.h +++ b/cc/layers/scrollbar_layer_impl.h @@ -8,6 +8,7 @@ #include "cc/base/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer_impl.h" +#include "cc/resources/ui_resource_client.h" namespace cc { @@ -33,8 +34,6 @@ class CC_EXPORT ScrollbarLayerImpl : public LayerImpl { virtual void AppendQuads(QuadSink* quad_sink, AppendQuadsData* append_quads_data) OVERRIDE; - virtual void DidLoseOutputSurface() OVERRIDE; - int scroll_layer_id() const { return scroll_layer_id_; } void set_scroll_layer_id(int id) { scroll_layer_id_ = id; } @@ -58,11 +57,11 @@ class CC_EXPORT ScrollbarLayerImpl : public LayerImpl { void set_vertical_adjust(float vertical_adjust) { vertical_adjust_ = vertical_adjust; } - void set_track_resource_id(ResourceProvider::ResourceId id) { - track_resource_id_ = id; + void set_track_ui_resource_id(UIResourceId uid) { + track_ui_resource_id_ = uid; } - void set_thumb_resource_id(ResourceProvider::ResourceId id) { - thumb_resource_id_ = id; + void set_thumb_ui_resource_id(UIResourceId uid) { + thumb_ui_resource_id_ = uid; } void set_visible_to_total_length_ratio(float ratio) { visible_to_total_length_ratio_ = ratio; @@ -87,8 +86,8 @@ class CC_EXPORT ScrollbarLayerImpl : public LayerImpl { gfx::Rect ScrollbarLayerRectToContentRect(gfx::RectF layer_rect) const; - ResourceProvider::ResourceId track_resource_id_; - ResourceProvider::ResourceId thumb_resource_id_; + UIResourceId track_ui_resource_id_; + UIResourceId thumb_ui_resource_id_; float current_pos_; int maximum_; diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 962efa0..c4db0f8 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc @@ -4,22 +4,23 @@ #include "cc/layers/scrollbar_layer.h" +#include "base/containers/hash_tables.h" #include "cc/animation/scrollbar_animation_controller.h" #include "cc/debug/test_web_graphics_context_3d.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/scrollbar_layer_impl.h" #include "cc/quads/solid_color_draw_quad.h" -#include "cc/resources/prioritized_resource_manager.h" -#include "cc/resources/priority_calculator.h" #include "cc/resources/resource_update_queue.h" #include "cc/test/fake_impl_proxy.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_scrollbar.h" +#include "cc/test/fake_scrollbar_layer.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_tree_test.h" #include "cc/test/mock_quad_culler.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/tree_synchronizer.h" @@ -404,9 +405,48 @@ class MockLayerTreeHost : public LayerTreeHost { public: MockLayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings) - : LayerTreeHost(client, settings) { + : LayerTreeHost(client, settings), + next_id_(1), + total_ui_resource_created_(0), + total_ui_resource_deleted_(0) { Initialize(NULL); } + + virtual UIResourceId CreateUIResource(UIResourceClient* content) OVERRIDE { + total_ui_resource_created_++; + UIResourceId nid = next_id_++; + ui_resource_bitmap_map_[nid] = content->GetBitmap(nid, false); + return nid; + } + + // Deletes a UI resource. May safely be called more than once. + virtual void DeleteUIResource(UIResourceId id) OVERRIDE { + UIResourceBitmapMap::iterator iter = ui_resource_bitmap_map_.find(id); + if (iter != ui_resource_bitmap_map_.end()) { + ui_resource_bitmap_map_.erase(iter); + total_ui_resource_deleted_++; + } + } + + size_t UIResourceCount() { return ui_resource_bitmap_map_.size(); } + int TotalUIResourceDeleted() { return total_ui_resource_deleted_; } + int TotalUIResourceCreated() { return total_ui_resource_created_; } + + gfx::Size ui_resource_size(UIResourceId id) { + UIResourceBitmapMap::iterator iter = ui_resource_bitmap_map_.find(id); + if (iter != ui_resource_bitmap_map_.end() && iter->second.get()) + return iter->second->GetSize(); + return gfx::Size(); + } + + private: + typedef base::hash_map<UIResourceId, scoped_refptr<UIResourceBitmap> > + UIResourceBitmapMap; + UIResourceBitmapMap ui_resource_bitmap_map_; + + int next_id_; + int total_ui_resource_created_; + int total_ui_resource_deleted_; }; @@ -415,7 +455,10 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { ScrollbarLayerTestResourceCreation() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} - void TestResourceUpload(size_t expected_resources) { + void TestResourceUpload(int num_updates, + size_t expected_resources, + int expected_created, + int expected_deleted) { layer_tree_host_.reset( new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); @@ -423,13 +466,11 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); scoped_refptr<Layer> scrollbar_layer = - ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); + ScrollbarLayer::Create(scrollbar.Pass(), layer_tree_root->id()); layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); layer_tree_host_->InitializeOutputSurfaceIfNeeded(); - layer_tree_host_->contents_texture_manager()-> - SetMaxMemoryLimitBytes(1024 * 1024); layer_tree_host_->SetRootLayer(layer_tree_root); scrollbar_layer->SetIsDrawable(true); @@ -447,16 +488,17 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); - PriorityCalculator calculator; ResourceUpdateQueue queue; OcclusionTracker occlusion_tracker(gfx::Rect(), false); scrollbar_layer->SavePaintProperties(); - scrollbar_layer->SetTexturePriorities(calculator); - layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); - scrollbar_layer->Update(&queue, &occlusion_tracker); - EXPECT_EQ(0u, queue.FullUploadSize()); - EXPECT_EQ(expected_resources, queue.PartialUploadSize()); + for (int update_counter = 0; update_counter < num_updates; update_counter++) + scrollbar_layer->Update(&queue, &occlusion_tracker); + + // A non-solid-color scrollbar should have requested two textures. + EXPECT_EQ(expected_resources, layer_tree_host_->UIResourceCount()); + EXPECT_EQ(expected_created, layer_tree_host_->TotalUIResourceCreated()); + EXPECT_EQ(expected_deleted, layer_tree_host_->TotalUIResourceDeleted()); testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); @@ -471,12 +513,18 @@ class ScrollbarLayerTestResourceCreation : public testing::Test { TEST_F(ScrollbarLayerTestResourceCreation, ResourceUpload) { layer_tree_settings_.solid_color_scrollbars = false; - TestResourceUpload(2); + TestResourceUpload(0, 0, 0, 0); + int num_updates[3] = {1, 5, 10}; + for (int j = 0; j < 3; j++) { + TestResourceUpload( + num_updates[j], 2, num_updates[j] * 2, (num_updates[j] - 1) * 2); + } } TEST_F(ScrollbarLayerTestResourceCreation, SolidColorNoResourceUpload) { layer_tree_settings_.solid_color_scrollbars = true; - TestResourceUpload(0); + TestResourceUpload(0, 0, 0, 0); + TestResourceUpload(1, 0, 0, 0); } class ScaledScrollbarLayerTestResourceCreation : public testing::Test { @@ -484,25 +532,20 @@ class ScaledScrollbarLayerTestResourceCreation : public testing::Test { ScaledScrollbarLayerTestResourceCreation() : fake_client_(FakeLayerTreeHostClient::DIRECT_3D) {} - void TestResourceUpload(size_t expected_resources, const float test_scale) { + void TestResourceUpload(const float test_scale) { layer_tree_host_.reset( new MockLayerTreeHost(&fake_client_, layer_tree_settings_)); gfx::Point scrollbar_location(0, 185); - scoped_ptr<FakeScrollbar> scrollbar(new FakeScrollbar(false, true, false)); - scrollbar->set_location(scrollbar_location); - scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); - scoped_refptr<Layer> scrollbar_layer = - ScrollbarLayer::Create(scrollbar.PassAs<cc::Scrollbar>(), - layer_tree_root->id()); + scoped_refptr<FakeScrollbarLayer> scrollbar_layer = + FakeScrollbarLayer::Create(false, true, layer_tree_root->id()); + layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); layer_tree_host_->InitializeOutputSurfaceIfNeeded(); - layer_tree_host_->contents_texture_manager()-> - SetMaxMemoryLimitBytes(1024 * 1024); layer_tree_host_->SetRootLayer(layer_tree_root); scrollbar_layer->SetIsDrawable(true); @@ -529,30 +572,23 @@ class ScaledScrollbarLayerTestResourceCreation : public testing::Test { testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); - PriorityCalculator calculator; ResourceUpdateQueue queue; OcclusionTracker occlusion_tracker(gfx::Rect(), false); - scrollbar_layer->SavePaintProperties(); - scrollbar_layer->SetTexturePriorities(calculator); - layer_tree_host_->contents_texture_manager()->PrioritizeTextures(); scrollbar_layer->Update(&queue, &occlusion_tracker); - EXPECT_EQ(expected_resources, queue.PartialUploadSize()); // Verify that we have not generated any content uploads that are larger // than their destination textures. - while (queue.HasMoreUpdates()) { - ResourceUpdate update = queue.TakeFirstPartialUpload(); - EXPECT_LE(update.texture->size().width(), - scrollbar_layer->content_bounds().width()); - EXPECT_LE(update.texture->size().height(), - scrollbar_layer->content_bounds().height()); - - EXPECT_LE(update.dest_offset.x() + update.content_rect.width(), - update.texture->size().width()); - EXPECT_LE(update.dest_offset.y() + update.content_rect.height(), - update.texture->size().height()); - } + + gfx::Size track_size = layer_tree_host_->ui_resource_size( + scrollbar_layer->track_resource_id()); + gfx::Size thumb_size = layer_tree_host_->ui_resource_size( + scrollbar_layer->thumb_resource_id()); + + EXPECT_LE(track_size.width(), scrollbar_layer->content_bounds().width()); + EXPECT_LE(track_size.height(), scrollbar_layer->content_bounds().height()); + EXPECT_LE(thumb_size.width(), scrollbar_layer->content_bounds().width()); + EXPECT_LE(thumb_size.height(), scrollbar_layer->content_bounds().height()); testing::Mock::VerifyAndClearExpectations(layer_tree_host_.get()); @@ -569,7 +605,9 @@ TEST_F(ScaledScrollbarLayerTestResourceCreation, ScaledResourceUpload) { layer_tree_settings_.solid_color_scrollbars = false; // Pick a test scale that moves the scrollbar's (non-zero) position to // a non-pixel-aligned location. - TestResourceUpload(2, 1.41f); + TestResourceUpload(.041f); + TestResourceUpload(1.41f); + TestResourceUpload(4.1f); } } // namespace diff --git a/cc/test/fake_scrollbar_layer.cc b/cc/test/fake_scrollbar_layer.cc index 64e08ad..77cf826 100644 --- a/cc/test/fake_scrollbar_layer.cc +++ b/cc/test/fake_scrollbar_layer.cc @@ -18,9 +18,7 @@ FakeScrollbarLayer::FakeScrollbarLayer(bool paint_during_update, new FakeScrollbar(paint_during_update, has_thumb, false)).Pass(), scrolling_layer_id), update_count_(0), - push_properties_count_(0), - last_update_full_upload_size_(0), - last_update_partial_upload_size_(0) { + push_properties_count_(0) { SetAnchorPoint(gfx::PointF(0.f, 0.f)); SetBounds(gfx::Size(1, 1)); SetIsDrawable(true); @@ -30,12 +28,8 @@ FakeScrollbarLayer::~FakeScrollbarLayer() {} bool FakeScrollbarLayer::Update(ResourceUpdateQueue* queue, const OcclusionTracker* occlusion) { - size_t full = queue->FullUploadSize(); - size_t partial = queue->PartialUploadSize(); bool updated = ScrollbarLayer::Update(queue, occlusion); - update_count_++; - last_update_full_upload_size_ = queue->FullUploadSize() - full; - last_update_partial_upload_size_ = queue->PartialUploadSize() - partial; + ++update_count_; return updated; } diff --git a/cc/test/fake_scrollbar_layer.h b/cc/test/fake_scrollbar_layer.h index 43be832..21d0399 100644 --- a/cc/test/fake_scrollbar_layer.h +++ b/cc/test/fake_scrollbar_layer.h @@ -23,12 +23,6 @@ class FakeScrollbarLayer : public ScrollbarLayer { int update_count() const { return update_count_; } void reset_update_count() { update_count_ = 0; } - size_t last_update_full_upload_size() const { - return last_update_full_upload_size_; - } - size_t last_update_partial_upload_size() const { - return last_update_partial_upload_size_; - } virtual bool Update(ResourceUpdateQueue* queue, const OcclusionTracker* occlusion) OVERRIDE; @@ -40,6 +34,14 @@ class FakeScrollbarLayer : public ScrollbarLayer { size_t push_properties_count() const { return push_properties_count_; } void reset_push_properties_count() { push_properties_count_ = 0; } + // For unit tests + UIResourceId track_resource_id() { + return ScrollbarLayer::track_resource_id(); + } + UIResourceId thumb_resource_id() { + return ScrollbarLayer::thumb_resource_id(); + } + private: FakeScrollbarLayer(bool paint_during_update, bool has_thumb, @@ -48,8 +50,6 @@ class FakeScrollbarLayer : public ScrollbarLayer { int update_count_; size_t push_properties_count_; - size_t last_update_full_upload_size_; - size_t last_update_partial_upload_size_; }; } // namespace cc diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index d4a9498..28112d1 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -2500,7 +2500,9 @@ void LayerTreeHostImpl::CreateUIResource( if (id) DeleteUIResource(uid); id = resource_provider_->CreateResource( - bitmap->GetSize(), GL_RGBA, ResourceProvider::TextureUsageAny); + bitmap->GetSize(), + resource_provider_->best_texture_format(), + ResourceProvider::TextureUsageAny); ui_resource_map_[uid] = id; resource_provider_->SetPixels(id, diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index b18a88a..55841e5 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -1111,7 +1111,7 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); // Verify atomicity of commits and reuse of textures. -class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest { +class LayerTreeHostTestDirectRendererAtomicCommit : public LayerTreeHostTest { public: virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE { // Make sure partial texture updates are turned off. @@ -1162,19 +1162,18 @@ class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest { PostSetNeedsCommitToMainThread(); break; case 1: - // Number of textures should be doubled as the first textures - // are used by impl thread and cannot by used for update. - ASSERT_EQ(4u, context->NumTextures()); - // Number of textures used for commit should still be - // one for each layer. + // Number of textures should be one for scrollbar layer since it was + // requested and deleted on the impl-thread, and double for the content + // layer since its first texture is used by impl thread and cannot by + // used for update. + ASSERT_EQ(3u, context->NumTextures()); + // Number of textures used for commit should be one for each layer. EXPECT_EQ(2u, context->NumUsedTextures()); // First textures should not have been used. EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); - EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); + EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); // New textures should have been used. EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); - EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); - context->ResetUsedTextures(); PostSetNeedsCommitToMainThread(); break; @@ -1209,14 +1208,68 @@ class LayerTreeHostTestAtomicCommit : public LayerTreeHostTest { virtual void AfterTest() OVERRIDE {} - private: + protected: FakeContentLayerClient client_; scoped_refptr<FakeContentLayer> layer_; scoped_refptr<FakeScrollbarLayer> scrollbar_; int drew_frame_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestAtomicCommit); +MULTI_THREAD_DIRECT_RENDERER_TEST_F( + LayerTreeHostTestDirectRendererAtomicCommit); + +class LayerTreeHostTestDelegatingRendererAtomicCommit + : public LayerTreeHostTestDirectRendererAtomicCommit { + public: + virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE { + ASSERT_EQ(0u, layer_tree_host()->settings().max_partial_texture_updates); + + TestWebGraphicsContext3D* context = static_cast<TestWebGraphicsContext3D*>( + impl->output_surface()->context3d()); + + switch (impl->active_tree()->source_frame_number()) { + case 0: + // Number of textures should be one for each layer + ASSERT_EQ(2u, context->NumTextures()); + // Number of textures used for commit should be one for each layer. + EXPECT_EQ(2u, context->NumUsedTextures()); + // Verify that used texture is correct. + EXPECT_TRUE(context->UsedTexture(context->TextureAt(0))); + EXPECT_TRUE(context->UsedTexture(context->TextureAt(1))); + context->ResetUsedTextures(); + PostSetNeedsCommitToMainThread(); + break; + case 1: + // Number of textures should be doubled as the first context layer + // texture is being used by the impl-thread and cannot be used for + // update. The scrollbar behavior is different direct renderer because + // UI resource deletion with delegating renderer occurs after tree + // activation. + ASSERT_EQ(4u, context->NumTextures()); + // Number of textures used for commit should still be + // one for each layer. + EXPECT_EQ(2u, context->NumUsedTextures()); + // First textures should not have been used. + EXPECT_FALSE(context->UsedTexture(context->TextureAt(0))); + EXPECT_FALSE(context->UsedTexture(context->TextureAt(1))); + // New textures should have been used. + EXPECT_TRUE(context->UsedTexture(context->TextureAt(2))); + EXPECT_TRUE(context->UsedTexture(context->TextureAt(3))); + context->ResetUsedTextures(); + PostSetNeedsCommitToMainThread(); + break; + case 2: + EndTest(); + break; + default: + NOTREACHED(); + break; + } + } +}; + +MULTI_THREAD_DELEGATING_RENDERER_TEST_F( + LayerTreeHostTestDelegatingRendererAtomicCommit); static void SetLayerPropertiesForTesting(Layer* layer, Layer* parent, |