blob: c7e055e541d869df2fca1939281d36eaa1265bd4 [file] [log] [blame]
// Copyright 2016 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/painted_overlay_scrollbar_layer_impl.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/texture_draw_quad.h"
namespace cc {
std::unique_ptr<PaintedOverlayScrollbarLayerImpl>
PaintedOverlayScrollbarLayerImpl::Create(LayerTreeImpl* tree_impl,
int id,
ScrollbarOrientation orientation,
bool is_left_side_vertical_scrollbar) {
return base::WrapUnique(new PaintedOverlayScrollbarLayerImpl(
tree_impl, id, orientation, is_left_side_vertical_scrollbar));
}
PaintedOverlayScrollbarLayerImpl::PaintedOverlayScrollbarLayerImpl(
LayerTreeImpl* tree_impl,
int id,
ScrollbarOrientation orientation,
bool is_left_side_vertical_scrollbar)
: ScrollbarLayerImplBase(tree_impl,
id,
orientation,
is_left_side_vertical_scrollbar,
true),
thumb_ui_resource_id_(0),
track_ui_resource_id_(0),
thumb_thickness_(0),
thumb_length_(0),
track_start_(0),
track_length_(0) {}
PaintedOverlayScrollbarLayerImpl::~PaintedOverlayScrollbarLayerImpl() = default;
std::unique_ptr<LayerImpl> PaintedOverlayScrollbarLayerImpl::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
return PaintedOverlayScrollbarLayerImpl::Create(
tree_impl, id(), orientation(), is_left_side_vertical_scrollbar());
}
void PaintedOverlayScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) {
ScrollbarLayerImplBase::PushPropertiesTo(layer);
PaintedOverlayScrollbarLayerImpl* scrollbar_layer =
static_cast<PaintedOverlayScrollbarLayerImpl*>(layer);
scrollbar_layer->SetThumbThickness(thumb_thickness_);
scrollbar_layer->SetThumbLength(thumb_length_);
scrollbar_layer->SetTrackStart(track_start_);
scrollbar_layer->SetTrackLength(track_length_);
scrollbar_layer->SetImageBounds(image_bounds_);
scrollbar_layer->SetAperture(aperture_);
scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_);
scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_);
}
bool PaintedOverlayScrollbarLayerImpl::WillDraw(
DrawMode draw_mode,
viz::ClientResourceProvider* resource_provider) {
DCHECK(draw_mode != DRAW_MODE_RESOURCELESS_SOFTWARE);
return LayerImpl::WillDraw(draw_mode, resource_provider);
}
void PaintedOverlayScrollbarLayerImpl::AppendQuads(
viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data) {
viz::SharedQuadState* shared_quad_state =
render_pass->CreateAndAppendSharedQuadState();
AppendThumbQuads(render_pass, append_quads_data, shared_quad_state);
AppendTrackQuads(render_pass, append_quads_data, shared_quad_state);
}
void PaintedOverlayScrollbarLayerImpl::AppendThumbQuads(
viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data,
viz::SharedQuadState* shared_quad_state) {
if (aperture_.IsEmpty())
return;
bool is_resource =
thumb_ui_resource_id_ &&
layer_tree_impl()->ResourceIdForUIResource(thumb_ui_resource_id_);
bool are_contents_opaque =
is_resource
? layer_tree_impl()->IsUIResourceOpaque(thumb_ui_resource_id_) ||
contents_opaque()
: false;
PopulateSharedQuadState(shared_quad_state, are_contents_opaque);
AppendDebugBorderQuad(render_pass, gfx::Rect(bounds()), shared_quad_state,
append_quads_data);
if (!is_resource)
return;
// For overlay scrollbars, the border should match the inset of the aperture
// and be symmetrical.
gfx::Rect border(aperture_.x(), aperture_.y(), aperture_.x() * 2,
aperture_.y() * 2);
gfx::Rect thumb_quad_rect(ComputeThumbQuadRect());
gfx::Rect layer_occlusion;
bool fill_center = true;
bool nearest_neighbor = false;
// Avoid drawing a scrollber in the degenerate case where the scroller is
// smaller than the border size.
if (thumb_quad_rect.height() < border.height() ||
thumb_quad_rect.width() < border.width())
return;
quad_generator_.SetLayout(image_bounds_, thumb_quad_rect.size(), aperture_,
border, layer_occlusion, fill_center,
nearest_neighbor);
quad_generator_.CheckGeometryLimitations();
std::vector<NinePatchGenerator::Patch> patches =
quad_generator_.GeneratePatches();
gfx::Vector2dF offset = thumb_quad_rect.OffsetFromOrigin();
for (auto& patch : patches)
patch.output_rect += offset;
quad_generator_.AppendQuads(this, thumb_ui_resource_id_, render_pass,
shared_quad_state, patches);
}
void PaintedOverlayScrollbarLayerImpl::AppendTrackQuads(
viz::RenderPass* render_pass,
AppendQuadsData* append_quads_data,
viz::SharedQuadState* shared_quad_state) {
viz::ResourceId track_resource_id =
layer_tree_impl()->ResourceIdForUIResource(track_ui_resource_id_);
if (!track_resource_id)
return;
bool nearest_neighbor = false;
gfx::Rect track_quad_rect(bounds());
gfx::Rect scaled_track_quad_rect(bounds());
gfx::Rect visible_track_quad_rect =
draw_properties().occlusion_in_content_space.GetUnoccludedContentRect(
track_quad_rect);
gfx::Rect scaled_visible_track_quad_rect =
gfx::ScaleToEnclosingRect(visible_track_quad_rect, 1.f);
bool needs_blending = !contents_opaque();
bool premultipled_alpha = true;
bool flipped = false;
gfx::PointF uv_top_left(0.f, 0.f);
gfx::PointF uv_bottom_right(1.f, 1.f);
float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
viz::TextureDrawQuad* quad =
render_pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>();
quad->SetNew(
shared_quad_state, scaled_track_quad_rect, scaled_visible_track_quad_rect,
needs_blending, track_resource_id, premultipled_alpha, uv_top_left,
uv_bottom_right, SK_ColorTRANSPARENT, opacity, flipped, nearest_neighbor,
/*secure_output_only=*/false, ui::ProtectedVideoType::kClear);
ValidateQuadResources(quad);
}
void PaintedOverlayScrollbarLayerImpl::SetThumbThickness(int thumb_thickness) {
if (thumb_thickness_ == thumb_thickness)
return;
thumb_thickness_ = thumb_thickness;
NoteLayerPropertyChanged();
}
int PaintedOverlayScrollbarLayerImpl::ThumbThickness() const {
return thumb_thickness_;
}
void PaintedOverlayScrollbarLayerImpl::SetThumbLength(int thumb_length) {
if (thumb_length_ == thumb_length)
return;
thumb_length_ = thumb_length;
NoteLayerPropertyChanged();
}
int PaintedOverlayScrollbarLayerImpl::ThumbLength() const {
return thumb_length_;
}
void PaintedOverlayScrollbarLayerImpl::SetTrackStart(int track_start) {
if (track_start_ == track_start)
return;
track_start_ = track_start;
NoteLayerPropertyChanged();
}
int PaintedOverlayScrollbarLayerImpl::TrackStart() const {
return track_start_;
}
void PaintedOverlayScrollbarLayerImpl::SetTrackLength(int track_length) {
if (track_length_ == track_length)
return;
track_length_ = track_length;
NoteLayerPropertyChanged();
}
void PaintedOverlayScrollbarLayerImpl::SetImageBounds(const gfx::Size& bounds) {
if (image_bounds_ == bounds)
return;
image_bounds_ = bounds;
NoteLayerPropertyChanged();
}
void PaintedOverlayScrollbarLayerImpl::SetAperture(const gfx::Rect& aperture) {
if (aperture_ == aperture)
return;
aperture_ = aperture;
NoteLayerPropertyChanged();
}
float PaintedOverlayScrollbarLayerImpl::TrackLength() const {
return track_length_ + (orientation() == VERTICAL ? vertical_adjust() : 0);
}
bool PaintedOverlayScrollbarLayerImpl::IsThumbResizable() const {
return false;
}
const char* PaintedOverlayScrollbarLayerImpl::LayerTypeAsString() const {
return "cc::PaintedOverlayScrollbarLayerImpl";
}
bool PaintedOverlayScrollbarLayerImpl::HasFindInPageTickmarks() const {
return track_ui_resource_id_ != 0;
}
} // namespace cc