| Index: cc/layers/scrollbar_layer.cc
|
| ===================================================================
|
| --- cc/layers/scrollbar_layer.cc (revision 215030)
|
| +++ cc/layers/scrollbar_layer.cc (working copy)
|
| @@ -1,3 +1,4 @@
|
| +
|
| // 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.
|
| @@ -8,14 +9,11 @@
|
| #include "base/basictypes.h"
|
| #include "base/debug/trace_event.h"
|
| #include "cc/layers/scrollbar_layer_impl.h"
|
| -#include "cc/resources/ui_resource_bitmap.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/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/SkBitmap.h"
|
| -#include "third_party/skia/include/core/SkCanvas.h"
|
| -#include "third_party/skia/include/core/SkSize.h"
|
| #include "ui/gfx/rect_conversions.h"
|
|
|
| namespace cc {
|
| @@ -29,15 +27,16 @@
|
| 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) {
|
| + scroll_layer_id_(scroll_layer_id),
|
| + texture_format_(GL_INVALID_ENUM) {
|
| if (!scrollbar_->IsOverlay())
|
| SetShouldScrollOnMainThread(true);
|
| }
|
| @@ -129,11 +128,16 @@
|
| scrollbar_layer->set_track_length(track_rect_.height());
|
| }
|
|
|
| - 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());
|
| + 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_is_overlay_scrollbar(scrollbar_->IsOverlay());
|
|
|
| // ScrollbarLayer must push properties every frame. crbug.com/259095
|
| @@ -145,16 +149,113 @@
|
| }
|
|
|
| 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_resource_.reset();
|
| - thumb_resource_.reset();
|
| + track_updater_ = NULL;
|
| + track_.reset();
|
| + thumb_updater_ = NULL;
|
| + thumb_.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
|
| @@ -168,16 +269,30 @@
|
| return expanded_rect;
|
| }
|
|
|
| -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());
|
| +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));
|
| }
|
| - return ScrollbarLayerRectToContentRect(gfx::Rect(thumb_size));
|
| + 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));
|
| + }
|
| }
|
|
|
| bool ScrollbarLayer::Update(ResourceUpdateQueue* queue,
|
| @@ -193,62 +308,43 @@
|
| ContentsScalingLayer::Update(queue, occlusion);
|
| }
|
|
|
| + dirty_rect_.Union(update_rect_);
|
| + if (content_bounds().IsEmpty())
|
| + return false;
|
| + if (visible_content_rect().IsEmpty())
|
| + return false;
|
| +
|
| + CreateUpdaterIfNeeded();
|
| +
|
| + gfx::Rect content_rect = ScrollbarLayerRectToContentRect(
|
| + gfx::Rect(scrollbar_->Location(), bounds()));
|
| + bool updated = UpdatePart(track_updater_.get(), track_.get(), content_rect,
|
| + queue);
|
| +
|
| if (scrollbar_->HasThumb()) {
|
| 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);
|
| + }
|
| }
|
|
|
| - track_resource_ =
|
| - ScopedUIResource::Create(layer_tree_host(), RasterizeTrack());
|
| - if (scrollbar_->HasThumb())
|
| - thumb_resource_ =
|
| - ScopedUIResource::Create(layer_tree_host(), RasterizeThumb());
|
| -
|
| - return true;
|
| + dirty_rect_ = gfx::RectF();
|
| + return updated;
|
| }
|
|
|
| -scoped_refptr<UIResourceBitmap> ScrollbarLayer::RasterizeTrack() {
|
| - DCHECK(!layer_tree_host()->settings().solid_color_scrollbars);
|
| -
|
| - gfx::Rect track_rect = ScrollbarLayerRectToContentRect(
|
| - gfx::Rect(scrollbar_->Location(), bounds()));
|
| - scoped_refptr<UIResourceBitmap> track_bitmap = UIResourceBitmap::Create(
|
| - new uint8_t[track_rect.width() * track_rect.height() * 4],
|
| - UIResourceBitmap::RGBA8,
|
| - track_rect.size());
|
| -
|
| - SkBitmap skbitmap;
|
| - skbitmap.setConfig(
|
| - SkBitmap::kARGB_8888_Config, track_rect.width(), track_rect.height());
|
| - skbitmap.setPixels(track_bitmap->GetPixels());
|
| -
|
| - SkCanvas track_canvas(skbitmap);
|
| - track_canvas.translate(SkFloatToScalar(-track_rect.x()),
|
| - SkFloatToScalar(-track_rect.y()));
|
| - scrollbar_->PaintPart(&track_canvas, TRACK, track_rect);
|
| -
|
| - 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::RasterizeThumb() {
|
| - DCHECK(!layer_tree_host()->settings().solid_color_scrollbars);
|
| - DCHECK(scrollbar_->HasThumb());
|
| -
|
| - gfx::Rect thumb_rect = OriginThumbRect();
|
| - scoped_refptr<UIResourceBitmap> thumb_bitmap = UIResourceBitmap::Create(
|
| - new uint8_t[thumb_rect.width() * thumb_rect.height() * 4],
|
| - UIResourceBitmap::RGBA8,
|
| - thumb_rect.size());
|
| -
|
| - SkBitmap skbitmap;
|
| - skbitmap.setConfig(
|
| - SkBitmap::kARGB_8888_Config, thumb_rect.width(), thumb_rect.height());
|
| - skbitmap.setPixels(thumb_bitmap->GetPixels());
|
| -
|
| - SkCanvas thumb_canvas(skbitmap);
|
| - scrollbar_->PaintPart(&thumb_canvas, THUMB, thumb_rect);
|
| -
|
| - return thumb_bitmap;
|
| -}
|
| -
|
| } // namespace cc
|
|
|