blob: 115d4ce132b36925dcd49fe2966166bbc449b107 [file] [log] [blame]
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_SCROLLING_COORDINATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_SCROLLING_COORDINATOR_H_
#include <memory>
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/hit_test_rect.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h"
#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace cc {
class Layer;
class ScrollbarLayerInterface;
} // namespace cc
namespace blink {
using MainThreadScrollingReasons = uint32_t;
class CompositorAnimationHost;
class CompositorAnimationTimeline;
class LayoutBox;
class LocalFrame;
class LocalFrameView;
class GraphicsLayer;
class Page;
class PaintLayer;
class Region;
class ScrollableArea;
class WebLayerTreeView;
using ScrollbarId = uint64_t;
// ScrollingCoordinator is a page-level object that mediates interactions
// between Blink and the compositor's scroll-related APIs on the composited
// layer representing the scrollbar.
//
// It's responsible for propagating scroll offsets, main-thread scrolling
// reasons, touch action regions, and non-fast-scrollable regions into the
// compositor, as well as creating and managing scrollbar layers.
class CORE_EXPORT ScrollingCoordinator final
: public GarbageCollectedFinalized<ScrollingCoordinator> {
public:
struct ScrollbarLayerGroup {
// The compositor layer for the scrollbar. It can be one of a few
// concrete types, so we store the base type.
scoped_refptr<cc::Layer> layer;
// An interface shared by all scrollbar layer types since we don't know
// the concrete |layer| type.
cc::ScrollbarLayerInterface* scrollbar_layer = nullptr;
};
static ScrollingCoordinator* Create(Page*);
explicit ScrollingCoordinator(Page*);
~ScrollingCoordinator();
void Trace(blink::Visitor*);
// The LocalFrameView argument is optional, nullptr causes the the scrolling
// animation host and timeline to be owned by the ScrollingCoordinator. When
// not null, the host and timeline are attached to the specified
// LocalFrameView. A LocalFrameView only needs to own them when it is the view
// for an OOPIF.
void LayerTreeViewInitialized(WebLayerTreeView&, LocalFrameView*);
void WillCloseLayerTreeView(WebLayerTreeView&, LocalFrameView*);
void WillBeDestroyed();
// Return whether this scrolling coordinator handles scrolling for the given
// frame view.
bool CoordinatesScrollingForFrameView(LocalFrameView*) const;
// Called when any frame has done its layout or compositing has changed.
void NotifyGeometryChanged(LocalFrameView*);
// Called when any layoutBox has transform changed
void NotifyTransformChanged(LocalFrame*, const LayoutBox&);
// Update non-fast scrollable regions, touch event target rects, main thread
// scrolling reasons, and whether the visual viewport is user scrollable.
// TODO(pdr): Refactor this out of ScrollingCoordinator.
void UpdateAfterPaint(LocalFrameView*);
// Should be called whenever the slow repaint objects counter changes between
// zero and one.
void FrameViewHasBackgroundAttachmentFixedObjectsDidChange(LocalFrameView*);
// Should be called whenever the set of fixed objects changes.
void FrameViewFixedObjectsDidChange(LocalFrameView*);
// Should be called whenever the root layer for the given frame view changes.
void FrameViewRootLayerDidChange(LocalFrameView*);
std::unique_ptr<ScrollbarLayerGroup> CreateSolidColorScrollbarLayer(
ScrollbarOrientation,
int thumb_thickness,
int track_start,
bool is_left_side_vertical_scrollbar,
cc::ElementId);
void WillDestroyScrollableArea(ScrollableArea*);
// Udates scroll offset, if the appropriate composited layers exist,
// and if successful, returns true. Otherwise returns false.
bool UpdateCompositedScrollOffset(ScrollableArea* scrollable_area);
// Updates the compositor layers and returns true if the scrolling coordinator
// handled this change.
// TODO(pdr): Factor the container bounds change out of this function. The
// compositor tracks scroll container bounds on the scroll layer whereas
// blink uses a separate layer. To ensure the compositor scroll layer has the
// updated scroll container bounds, this needs to be called when the scrolling
// contents layer is resized.
void ScrollableAreaScrollLayerDidChange(ScrollableArea*);
void ScrollableAreaScrollbarLayerDidChange(ScrollableArea*,
ScrollbarOrientation);
void UpdateLayerPositionConstraint(PaintLayer*);
// LocalFrame* must be a local root if non-null.
void TouchEventTargetRectsDidChange(LocalFrame*);
void WillDestroyLayer(PaintLayer*);
void UpdateScrollParentForGraphicsLayer(GraphicsLayer* child,
const PaintLayer* parent);
void UpdateClipParentForGraphicsLayer(GraphicsLayer* child,
const PaintLayer* parent);
Region ComputeShouldHandleScrollGestureOnMainThreadRegion(
const LocalFrame*) const;
void UpdateTouchEventTargetRectsIfNeeded(LocalFrame*);
void UpdateUserInputScrollable(ScrollableArea*);
CompositorAnimationHost* GetCompositorAnimationHost() {
return animation_host_.get();
}
CompositorAnimationTimeline* GetCompositorAnimationTimeline() {
return programmatic_scroll_animator_timeline_.get();
}
// Callback for compositor-side layer scrolls.
void DidScroll(const gfx::ScrollOffset&, const CompositorElementId&);
// For testing purposes only. This ScrollingCoordinator is reused between
// web tests, and must be reset for the results to be valid.
void Reset(LocalFrame*);
protected:
bool IsForRootLayer(ScrollableArea*) const;
bool IsForMainFrame(ScrollableArea*) const;
Member<Page> page_;
// Dirty flags used to idenfity what really needs to be computed after
// compositing is updated.
bool touch_event_target_rects_are_dirty_;
bool should_scroll_on_main_thread_dirty_;
private:
void SetShouldUpdateScrollLayerPositionOnMainThread(
LocalFrame*,
MainThreadScrollingReasons);
void SetShouldHandleScrollGestureOnMainThreadRegion(const Region&,
LocalFrameView*);
void SetTouchEventTargetRects(LocalFrame*, const LayerHitTestRects&);
void ComputeTouchEventTargetRects(LocalFrame*, LayerHitTestRects&);
void AddScrollbarLayerGroup(ScrollableArea*,
ScrollbarOrientation,
std::unique_ptr<ScrollbarLayerGroup>);
ScrollbarLayerGroup* GetScrollbarLayerGroup(ScrollableArea*,
ScrollbarOrientation);
void RemoveScrollbarLayerGroup(ScrollableArea*, ScrollbarOrientation);
bool FrameScrollerIsDirty(LocalFrameView*) const;
std::unique_ptr<CompositorAnimationHost> animation_host_;
std::unique_ptr<CompositorAnimationTimeline>
programmatic_scroll_animator_timeline_;
using ScrollbarMap =
HeapHashMap<Member<ScrollableArea>, std::unique_ptr<ScrollbarLayerGroup>>;
ScrollbarMap horizontal_scrollbars_;
ScrollbarMap vertical_scrollbars_;
DISALLOW_COPY_AND_ASSIGN(ScrollingCoordinator);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_SCROLLING_SCROLLING_COORDINATOR_H_