Index: cc/layers/picture_scrollbar_layer.cc |
=================================================================== |
--- cc/layers/picture_scrollbar_layer.cc (revision 0) |
+++ cc/layers/picture_scrollbar_layer.cc (revision 0) |
@@ -0,0 +1,307 @@ |
+// 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. |
+ |
+#include "cc/layers/picture_scrollbar_layer.h" |
+ |
+#if !USE_REGULAR_SCROLLBAR |
+ |
+#include "base/auto_reset.h" |
+#include "base/basictypes.h" |
+#include "base/debug/trace_event.h" |
+#include "cc/layers/picture_scrollbar_layer_impl.h" |
+#include "cc/resources/caching_bitmap_content_layer_updater.h" |
+#include "cc/resources/layer_painter.h" |
+#include "cc/resources/resource_update_queue.h" |
+#include "cc/resources/ui_resource_manager.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 { |
+ |
+scoped_ptr<LayerImpl> ScrollbarLayer::CreateLayerImpl( |
+ LayerTreeImpl* tree_impl) { |
+ return ScrollbarLayerImpl::Create( |
+ tree_impl, id(), scrollbar_->Orientation()).PassAs<LayerImpl>(); |
+} |
+ |
+scoped_refptr<ScrollbarLayer> ScrollbarLayer::Create( |
+ scoped_ptr<Scrollbar> scrollbar, |
+ int 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), |
+ track_ui_resource_id_(0), |
+ thumb_ui_resource_id_(0), |
+ track_ui_resource_status_(UIResourceManagerClient::NOT_READY), |
+ thumb_ui_resource_status_(UIResourceManagerClient::NOT_READY), |
+ skip_update_(false) { |
+ if (!scrollbar_->IsOverlay()) |
+ SetShouldScrollOnMainThread(true); |
+} |
+ |
+ScrollbarLayer::~ScrollbarLayer() {} |
+ |
+void ScrollbarLayer::SetScrollLayerId(int id) { |
+ if (id == scroll_layer_id_) |
+ return; |
+ |
+ scroll_layer_id_ = id; |
+ SetNeedsFullTreeSync(); |
+} |
+ |
+bool ScrollbarLayer::OpacityCanAnimateOnImplThread() const { |
+ return scrollbar_->IsOverlay(); |
+} |
+ |
+ScrollbarOrientation ScrollbarLayer::Orientation() const { |
+ return scrollbar_->Orientation(); |
+} |
+ |
+int ScrollbarLayer::MaxTextureSize() { |
+ DCHECK(layer_tree_host()); |
+ return layer_tree_host()->GetRendererCapabilities().max_texture_size; |
+} |
+ |
+float ScrollbarLayer::ClampScaleToMaxTextureSize(float scale) { |
+ if (layer_tree_host()->settings().solid_color_scrollbars) |
+ return scale; |
+ |
+ // If the scaled content_bounds() is bigger than the max texture size of the |
+ // device, we need to clamp it by rescaling, since content_bounds() is used |
+ // below to set the texture size. |
+ gfx::Size scaled_bounds = ComputeContentBoundsForScale(scale, scale); |
+ if (scaled_bounds.width() > MaxTextureSize() || |
+ scaled_bounds.height() > MaxTextureSize()) { |
+ if (scaled_bounds.width() > scaled_bounds.height()) |
+ return (MaxTextureSize() - 1) / static_cast<float>(bounds().width()); |
+ else |
+ return (MaxTextureSize() - 1) / static_cast<float>(bounds().height()); |
+ } |
+ return scale; |
+} |
+ |
+void ScrollbarLayer::CalculateContentsScale(float ideal_contents_scale, |
+ float device_scale_factor, |
+ float page_scale_factor, |
+ bool animating_transform_to_screen, |
+ float* contents_scale_x, |
+ float* contents_scale_y, |
+ gfx::Size* content_bounds) { |
+ ContentsScalingLayer::CalculateContentsScale( |
+ ClampScaleToMaxTextureSize(ideal_contents_scale), |
+ device_scale_factor, |
+ page_scale_factor, |
+ animating_transform_to_screen, |
+ contents_scale_x, |
+ contents_scale_y, |
+ content_bounds); |
+} |
+ |
+void ScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { |
+ ContentsScalingLayer::PushPropertiesTo(layer); |
+ |
+ ScrollbarLayerImpl* scrollbar_layer = static_cast<ScrollbarLayerImpl*>(layer); |
+ |
+ if (layer_tree_host() && |
+ layer_tree_host()->settings().solid_color_scrollbars) { |
+ int thickness_override = |
+ layer_tree_host()->settings().solid_color_scrollbar_thickness_dip; |
+ if (thickness_override != -1) { |
+ scrollbar_layer->set_thumb_thickness(thickness_override); |
+ } else { |
+ if (Orientation() == HORIZONTAL) |
+ scrollbar_layer->set_thumb_thickness(bounds().height()); |
+ else |
+ scrollbar_layer->set_thumb_thickness(bounds().width()); |
+ } |
+ } else { |
+ scrollbar_layer->set_thumb_thickness(thumb_thickness_); |
+ } |
+ scrollbar_layer->set_thumb_length(thumb_length_); |
+ |
+ if (Orientation() == HORIZONTAL) { |
+ scrollbar_layer->set_track_start(track_rect_.x()); |
+ scrollbar_layer->set_track_length(track_rect_.width()); |
+ } else { |
+ scrollbar_layer->set_track_start(track_rect_.y()); |
+ scrollbar_layer->set_track_length(track_rect_.height()); |
+ } |
+ |
+ if (track_ui_resource_status_ == UIResourceManagerClient::READY) { |
+ scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_); |
+ } else { |
+ scrollbar_layer->set_track_ui_resource_id(0); |
+ } |
+ |
+ if (thumb_ui_resource_status_ == UIResourceManagerClient::READY) { |
+ scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_); |
+ } else { |
+ scrollbar_layer->set_thumb_ui_resource_id(0); |
+ } |
+} |
+ |
+ScrollbarLayer* ScrollbarLayer::ToScrollbarLayer() { |
+ return this; |
+} |
+ |
+void ScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { |
+ ContentsScalingLayer::SetLayerTreeHost(host); |
+} |
+ |
+gfx::Rect ScrollbarLayer::ScrollbarLayerRectToContentRect( |
+ gfx::Rect layer_rect) const { |
+ // Don't intersect with the bounds as in LayerRectToContentRect() because |
+ // layer_rect here might be in coordinates of the containing layer. |
+ gfx::Rect expanded_rect = gfx::ScaleToEnclosingRect( |
+ layer_rect, contents_scale_y(), contents_scale_y()); |
+ // We should never return a rect bigger than the content_bounds(). |
+ gfx::Size clamped_size = expanded_rect.size(); |
+ clamped_size.SetToMin(content_bounds()); |
+ expanded_rect.set_size(clamped_size); |
+ return expanded_rect; |
+} |
+ |
+void ScrollbarLayer::Update(ResourceUpdateQueue* queue, |
+ const OcclusionTracker* occlusion) { |
+ track_rect_ = scrollbar_->TrackRect(); |
+ |
+ if (layer_tree_host()->settings().solid_color_scrollbars) |
+ return; |
+ |
+ base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, |
+ true); |
+ ContentsScalingLayer::Update(queue, occlusion); |
+ |
+ if (scrollbar_->HasThumb()) { |
+ thumb_thickness_ = scrollbar_->ThumbThickness(); |
+ thumb_length_ = scrollbar_->ThumbLength(); |
+ gfx::Rect origin_thumb_rect = OriginThumbRect(); |
+ } |
+ |
+ if (skip_update_) { |
+ skip_update_ = false; |
+ return; |
+ } |
+ |
+ gfx::Rect track_rect = ScrollbarLayerRectToContentRect( |
+ gfx::Rect(scrollbar_->Location(), bounds())); |
+ gfx::Rect thumb_rect = OriginThumbRect(); |
+ |
+ { |
+ track_bitmap_ = UIResourceBitmap::Create( |
+ new uint8_t[track_rect.width()*track_rect.height()*4], |
+ UIResourceBitmap::RGBA8, |
+ track_rect.size()); |
+ |
+ // raster track |
+ skia::RefPtr<SkCanvas> track_canvas = skia::AdoptRef( |
+ skia::CreatePlatformCanvas(track_rect.width(), |
+ track_rect.height(), |
+ false, |
+ reinterpret_cast<uint8_t*>( |
+ track_bitmap_->GetPixels()), |
+ skia::CRASH_ON_FAILURE)); |
+ |
+ 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()); |
+ |
+ track_canvas->drawRect(layer_sk_rect, paint); |
+ track_canvas->clipRect(layer_sk_rect); |
+ scrollbar_->PaintPart(track_canvas.get(), TRACK, track_rect); |
+ track_canvas->restore(); |
+ |
+ if (track_ui_resource_id_) { |
+ layer_tree_host()->DeleteUIResource(track_ui_resource_id_); |
+ } |
+ track_ui_resource_id_ = layer_tree_host()->CreateUIResource(track_bitmap_, |
+ this); |
+ } |
+ |
+ if (scrollbar_->HasThumb()) { |
+ thumb_bitmap_ = UIResourceBitmap::Create( |
+ new uint8_t[thumb_rect.width()*thumb_rect.height()*4], |
+ UIResourceBitmap::RGBA8, |
+ thumb_rect.size()); |
+ |
+ // raster thumb |
+ skia::RefPtr<SkCanvas> thumb_canvas = skia::AdoptRef( |
+ skia::CreatePlatformCanvas(thumb_rect.width(), |
+ thumb_rect.height(), |
+ false, |
+ reinterpret_cast<uint8_t*>( |
+ thumb_bitmap_->GetPixels()), |
+ skia::CRASH_ON_FAILURE)); |
+ |
+ scrollbar_->PaintPart(thumb_canvas.get(), |
+ THUMB, |
+ thumb_rect); |
+ |
+ if (thumb_ui_resource_id_) |
+ layer_tree_host()->DeleteUIResource(thumb_ui_resource_id_); |
+ thumb_ui_resource_id_ = layer_tree_host()->CreateUIResource(thumb_bitmap_, |
+ this); |
+ } |
+} |
+ |
+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::UIResourceReady(UIResourceId id) { |
+ if (thumb_ui_resource_id_ == id) { |
+ thumb_ui_resource_status_ = UIResourceManagerClient::READY; |
+ // need to push the ui resource id to the impl thread. |
+ // Is this the only way? |
enne (OOO)
2013/07/09 17:57:48
I think you're looking for SetNeedsCommit.
powei
2013/07/10 17:47:21
Done.
|
+ SetNeedsDisplay(); |
+ // if we do not have this flag, we will always have a |
+ // setneedsdisplay request in the scheduler |
+ skip_update_ = true; |
+ } |
+ |
+ if (track_ui_resource_id_ == id) { |
+ track_ui_resource_status_ = UIResourceManagerClient::READY; |
+ SetNeedsDisplay(); |
+ skip_update_ = true; |
+ } |
+} |
+ |
+void ScrollbarLayer::UIResourceLost(UIResourceId id) { |
enne (OOO)
2013/07/09 17:57:48
As I mentioned in the doc about this, I would real
aelias_OOO_until_Jul13
2013/07/09 20:22:19
OK, after discussing it with dtrainor@, we agree.
|
+ if (thumb_ui_resource_id_ == id) |
+ thumb_ui_resource_status_ = UIResourceManagerClient::LOST; |
+ thumb_ui_resource_id_ = 0; |
+ |
+ if (track_ui_resource_id_ == id) |
+ track_ui_resource_status_ = UIResourceManagerClient::LOST; |
+ track_ui_resource_id_ = 0; |
+} |
+ |
+} // namespace cc |
+ |
+#endif |