summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorpowei@chromium.org <powei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-14 02:18:58 +0000
committerpowei@chromium.org <powei@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-14 02:18:58 +0000
commit45b46d3861c832db5879f08afad54a962c958abd (patch)
tree878f87f2dc914158d5cb7a7448d0771a9342133d /cc
parent88a4366fe322086306ff3977fedb936348113e9a (diff)
downloadchromium_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.cc249
-rw-r--r--cc/layers/scrollbar_layer.h38
-rw-r--r--cc/layers/scrollbar_layer_impl.cc38
-rw-r--r--cc/layers/scrollbar_layer_impl.h15
-rw-r--r--cc/layers/scrollbar_layer_unittest.cc122
-rw-r--r--cc/test/fake_scrollbar_layer.cc10
-rw-r--r--cc/test/fake_scrollbar_layer.h16
-rw-r--r--cc/trees/layer_tree_host_impl.cc4
-rw-r--r--cc/trees/layer_tree_host_unittest.cc75
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,