blob: 2bc052ea2bbfbfc1caff84a4280a24da922b9cd2 [file] [log] [blame]
// Copyright 2019 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 "third_party/blink/renderer/platform/graphics/paint/scrollbar_display_item.h"
#include "base/trace_event/traced_value.h"
#include "cc/input/scrollbar.h"
#include "cc/layers/painted_overlay_scrollbar_layer.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/layers/solid_color_scrollbar_layer.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
namespace blink {
ScrollbarDisplayItem::ScrollbarDisplayItem(
const DisplayItemClient& client,
Type type,
scoped_refptr<cc::Scrollbar> scrollbar,
const IntRect& visual_rect,
const TransformPaintPropertyNode* scroll_translation,
CompositorElementId element_id)
: DisplayItem(client,
type,
sizeof(*this),
visual_rect,
/*draws_content*/ true),
scrollbar_(std::move(scrollbar)),
scroll_translation_(scroll_translation),
element_id_(element_id) {
DCHECK(IsScrollbar());
DCHECK(!scroll_translation || scroll_translation->ScrollNode());
}
sk_sp<const PaintRecord> ScrollbarDisplayItem::Paint() const {
if (record_) {
DCHECK(!scrollbar_->NeedsRepaintPart(
cc::ScrollbarPart::TRACK_BUTTONS_TICKMARKS));
DCHECK(!scrollbar_->NeedsRepaintPart(cc::ScrollbarPart::THUMB));
return record_;
}
PaintRecorder recorder;
const IntRect& rect = VisualRect();
recorder.beginRecording(rect);
auto* canvas = recorder.getRecordingCanvas();
scrollbar_->PaintPart(canvas, cc::ScrollbarPart::TRACK_BUTTONS_TICKMARKS,
rect);
gfx::Rect thumb_rect = scrollbar_->ThumbRect();
thumb_rect.Offset(rect.X(), rect.Y());
scrollbar_->PaintPart(canvas, cc::ScrollbarPart::THUMB, thumb_rect);
record_ = recorder.finishRecordingAsPicture();
return record_;
}
scoped_refptr<cc::ScrollbarLayerBase> ScrollbarDisplayItem::CreateOrReuseLayer(
cc::ScrollbarLayerBase* existing_layer) const {
// This function is called when the scrollbar is composited. We don't need
// record_ which is for non-composited scrollbars.
record_ = nullptr;
auto layer =
cc::ScrollbarLayerBase::CreateOrReuse(scrollbar_, existing_layer);
layer->SetIsDrawable(true);
if (!scrollbar_->IsSolidColor())
layer->SetHitTestable(true);
layer->SetElementId(element_id_);
layer->SetScrollElementId(
scroll_translation_
? scroll_translation_->ScrollNode()->GetCompositorElementId()
: CompositorElementId());
layer->SetOffsetToTransformParent(
gfx::Vector2dF(FloatPoint(VisualRect().Location())));
layer->SetBounds(gfx::Size(VisualRect().Size()));
if (scrollbar_->NeedsRepaintPart(cc::ScrollbarPart::THUMB) ||
scrollbar_->NeedsRepaintPart(cc::ScrollbarPart::TRACK_BUTTONS_TICKMARKS))
layer->SetNeedsDisplay();
return layer;
}
bool ScrollbarDisplayItem::Equals(const DisplayItem& other) const {
if (!DisplayItem::Equals(other))
return false;
// Don't check scrollbar_ because it's always newly created when we repaint
// a scrollbar (including forced repaint for PaintUnderInvalidationChecking).
// Don't check record_ because it's lazily created, and the DCHECKs in Paint()
// can catch most under-invalidation cases.
const auto& other_scrollbar_item =
static_cast<const ScrollbarDisplayItem&>(other);
return scroll_translation_ == other_scrollbar_item.scroll_translation_ &&
element_id_ == other_scrollbar_item.element_id_;
}
#if DCHECK_IS_ON()
void ScrollbarDisplayItem::PropertiesAsJSON(JSONObject& json) const {
DisplayItem::PropertiesAsJSON(json);
json.SetString("scrollTranslation",
String::Format("%p", scroll_translation_));
}
#endif
void ScrollbarDisplayItem::Record(
GraphicsContext& context,
const DisplayItemClient& client,
DisplayItem::Type type,
scoped_refptr<cc::Scrollbar> scrollbar,
const IntRect& visual_rect,
const TransformPaintPropertyNode* scroll_translation,
CompositorElementId element_id) {
PaintController& paint_controller = context.GetPaintController();
// Must check PaintController::UseCachedItemIfPossible before this function.
DCHECK(RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() ||
!paint_controller.UseCachedItemIfPossible(client, type));
paint_controller.CreateAndAppend<ScrollbarDisplayItem>(
client, type, std::move(scrollbar), visual_rect, scroll_translation,
element_id);
}
} // namespace blink