blob: e7d88471aff26137d0512db10fb54e08d9ff2e4d [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.
#ifndef CC_INPUT_MAIN_THREAD_SCROLLING_REASON_H_
#define CC_INPUT_MAIN_THREAD_SCROLLING_REASON_H_
#include <string>
#include "base/stl_util.h"
#include "base/trace_event/trace_event_argument.h"
namespace cc {
// Ensure this stays in sync with MainThreadScrollingReason in histograms.xml.
// When adding a new MainThreadScrollingReason, make sure the corresponding
// [MainThread/Compositor]CanSetScrollReasons function is also updated.
struct MainThreadScrollingReason {
enum : uint32_t {
// Non-transient scrolling reasons.
kNotScrollingOnMain = 0,
kHasBackgroundAttachmentFixedObjects = 1 << 0,
kHasNonLayerViewportConstrainedObjects = 1 << 1,
kThreadedScrollingDisabled = 1 << 2,
kScrollbarScrolling = 1 << 3,
kPageOverlay = 1 << 4,
// This bit is set when any of the other main thread scrolling reasons cause
// an input event to be handled on the main thread, and the main thread
// blink::ScrollAnimator is in the middle of running a scroll offset
// animation. Note that a scroll handled by the main thread can result in an
// animation running on the main thread or on the compositor thread.
kHandlingScrollFromMainThread = 1 << 13,
kCustomScrollbarScrolling = 1 << 15,
// Style-related scrolling on main reasons.
// These *AndLCDText reasons are due to subpixel text rendering which can
// only be applied by blending glyphs with the background at a specific
// screen position; transparency and transforms break this.
kNonCompositedReasonsFirst = 16,
kHasOpacityAndLCDText = 1 << 16,
kHasTransformAndLCDText = 1 << 17,
kBackgroundNotOpaqueInRectAndLCDText = 1 << 18,
kHasBorderRadius = 1 << 19,
kHasClipRelatedProperty = 1 << 20,
kHasBoxShadowFromNonRootLayer = 1 << 21,
kIsNotStackingContextAndLCDText = 1 << 22,
kNonCompositedReasonsLast = 22,
// Transient scrolling reasons. These are computed for each scroll begin.
kNonFastScrollableRegion = 1 << 5,
kFailedHitTest = 1 << 7,
kNoScrollingLayer = 1 << 8,
kNotScrollable = 1 << 9,
kContinuingMainThreadScroll = 1 << 10,
kNonInvertibleTransform = 1 << 11,
kPageBasedScrolling = 1 << 12,
// The maximum number of flags in this struct (excluding itself).
// New flags should increment this number but it should never be decremented
// because the values are used in UMA histograms. It should also be noted
// that it excludes the kNotScrollingOnMain value.
kMainThreadScrollingReasonCount = 23,
};
static const uint32_t kNonCompositedReasons =
kHasOpacityAndLCDText | kHasTransformAndLCDText |
kBackgroundNotOpaqueInRectAndLCDText | kHasBorderRadius |
kHasClipRelatedProperty | kHasBoxShadowFromNonRootLayer |
kIsNotStackingContextAndLCDText;
// Returns true if the given MainThreadScrollingReason can be set by the main
// thread.
static bool MainThreadCanSetScrollReasons(uint32_t reasons) {
uint32_t reasons_set_by_main_thread =
kNotScrollingOnMain | kHasBackgroundAttachmentFixedObjects |
kHasNonLayerViewportConstrainedObjects | kThreadedScrollingDisabled |
kScrollbarScrolling | kPageOverlay | kHandlingScrollFromMainThread |
kCustomScrollbarScrolling;
return (reasons & reasons_set_by_main_thread) == reasons;
}
// Returns true if the given MainThreadScrollingReason can be set by the
// compositor.
static bool CompositorCanSetScrollReasons(uint32_t reasons) {
uint32_t reasons_set_by_compositor =
kNonFastScrollableRegion | kFailedHitTest | kNoScrollingLayer |
kNotScrollable | kContinuingMainThreadScroll | kNonInvertibleTransform |
kPageBasedScrolling;
return (reasons & reasons_set_by_compositor) == reasons;
}
// Returns true if there are any reasons that prevented the scroller
// from being composited.
static bool HasNonCompositedScrollReasons(uint32_t reasons) {
return (reasons & kNonCompositedReasons) != 0;
}
static std::string mainThreadScrollingReasonsAsText(uint32_t reasons) {
base::trace_event::TracedValue tracedValue;
mainThreadScrollingReasonsAsTracedValue(reasons, &tracedValue);
std::string result_in_array_foramt = tracedValue.ToString();
// Remove '{main_thread_scrolling_reasons:[', ']}', and any '"' chars.
std::string result =
result_in_array_foramt.substr(34, result_in_array_foramt.length() - 36);
base::Erase(result, '\"');
return result;
}
static void mainThreadScrollingReasonsAsTracedValue(
uint32_t reasons,
base::trace_event::TracedValue* tracedValue) {
tracedValue->BeginArray("main_thread_scrolling_reasons");
if (reasons &
MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)
tracedValue->AppendString("Has background-attachment:fixed");
if (reasons &
MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects)
tracedValue->AppendString("Has non-layer viewport-constrained objects");
if (reasons & MainThreadScrollingReason::kThreadedScrollingDisabled)
tracedValue->AppendString("Threaded scrolling is disabled");
if (reasons & MainThreadScrollingReason::kScrollbarScrolling)
tracedValue->AppendString("Scrollbar scrolling");
if (reasons & MainThreadScrollingReason::kPageOverlay)
tracedValue->AppendString("Page overlay");
if (reasons & MainThreadScrollingReason::kHandlingScrollFromMainThread)
tracedValue->AppendString("Handling scroll from main thread");
if (reasons & MainThreadScrollingReason::kCustomScrollbarScrolling)
tracedValue->AppendString("Custom scrollbar scrolling");
if (reasons & MainThreadScrollingReason::kHasOpacityAndLCDText)
tracedValue->AppendString("Has opacity and LCD text");
if (reasons & MainThreadScrollingReason::kHasTransformAndLCDText)
tracedValue->AppendString("Has transform and LCD text");
if (reasons &
MainThreadScrollingReason::kBackgroundNotOpaqueInRectAndLCDText) {
tracedValue->AppendString(
"Background is not opaque in rect and LCD text");
}
if (reasons & MainThreadScrollingReason::kHasBorderRadius)
tracedValue->AppendString("Has border radius");
if (reasons & MainThreadScrollingReason::kHasClipRelatedProperty)
tracedValue->AppendString("Has clip related property");
if (reasons & MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer)
tracedValue->AppendString("Has box shadow from non-root layer");
if (reasons & MainThreadScrollingReason::kIsNotStackingContextAndLCDText)
tracedValue->AppendString("Is not stacking context and LCD text");
// Transient scrolling reasons.
if (reasons & MainThreadScrollingReason::kNonFastScrollableRegion)
tracedValue->AppendString("Non fast scrollable region");
if (reasons & MainThreadScrollingReason::kFailedHitTest)
tracedValue->AppendString("Failed hit test");
if (reasons & MainThreadScrollingReason::kNoScrollingLayer)
tracedValue->AppendString("No scrolling layer");
if (reasons & MainThreadScrollingReason::kNotScrollable)
tracedValue->AppendString("Not scrollable");
if (reasons & MainThreadScrollingReason::kContinuingMainThreadScroll)
tracedValue->AppendString("Continuing main thread scroll");
if (reasons & MainThreadScrollingReason::kNonInvertibleTransform)
tracedValue->AppendString("Non-invertible transform");
if (reasons & MainThreadScrollingReason::kPageBasedScrolling)
tracedValue->AppendString("Page-based scrolling");
tracedValue->EndArray();
}
};
} // namespace cc
#endif // CC_INPUT_MAIN_THREAD_SCROLLING_REASON_H_