void WebRenderLayerScrollData::Initialize(
    WebRenderScrollData& aOwner, nsDisplayItem* aItem, int32_t aDescendantCount,
    const ActiveScrolledRoot* aStopAtAsr,
    const Maybe<gfx::Matrix4x4>& aAncestorTransform) {
  MOZ_ASSERT(aDescendantCount >= 0);  // Ensure value is valid
  MOZ_ASSERT(mDescendantCount ==
             -1);  // Don't allow re-setting an already set value
  mDescendantCount = aDescendantCount;

  MOZ_ASSERT(aItem);
  aItem->UpdateScrollData(&aOwner, this);

  const ActiveScrolledRoot* asr = aItem->GetActiveScrolledRoot();
  if (ActiveScrolledRoot::IsAncestor(asr, aStopAtAsr)) {
    // If the item's ASR is an ancestor of the stop-at ASR, then we don't need
    // any more metrics information because we'll end up duplicating what the
    // ancestor WebRenderLayerScrollData already has.
    asr = nullptr;
  }

  while (asr && asr != aStopAtAsr) {
    MOZ_ASSERT(aOwner.GetManager());
    ScrollableLayerGuid::ViewID scrollId = asr->GetViewId();
    if (Maybe<size_t> index = aOwner.HasMetadataFor(scrollId)) {
      mScrollIds.AppendElement(index.ref());
    } else {
      Maybe<ScrollMetadata> metadata =
          asr->mScrollableFrame->ComputeScrollMetadata(
              aOwner.GetManager(), aItem->ReferenceFrame(), Nothing(), nullptr);
      asr->mScrollableFrame->NotifyApzTransaction();
      if (metadata) {
        MOZ_ASSERT(metadata->GetMetrics().GetScrollId() == scrollId);
        mScrollIds.AppendElement(aOwner.AddMetadata(metadata.ref()));
      } else {
        MOZ_ASSERT_UNREACHABLE("Expected scroll metadata to be available!");
      }
    }
    asr = asr->mParent;
  }

  // See the comments on StackingContextHelper::mDeferredTransformItem for an
  // overview of what deferred transforms are.
  // aAncestorTransform, if present, is the transform from a deferred transform
  // item that is an ancestor of |aItem|. We store this transform value
  // separately from mTransform because in the case where we have multiple
  // scroll metadata on this layer item, the mAncestorTransform is associated
  // with the "topmost" scroll metadata, and the mTransform is associated with
  // the "bottommost" scroll metadata. The code in
  // WebRenderScrollDataWrapper::GetTransform() is responsible for combining
  // these transforms and exposing them appropriately. Also, we don't save the
  // ancestor transform for thumb layers, because those are a special case in
  // APZ; we need to keep the ancestor transform for the scrollable content that
  // the thumb scrolls, but not for the thumb itself, as it will result in
  // incorrect visual positioning of the thumb.
  if (aAncestorTransform &&
      mScrollbarData.mScrollbarLayerType != ScrollbarLayerType::Thumb) {
    mAncestorTransform = *aAncestorTransform;
  }
}
void
WebRenderLayerScrollData::Initialize(WebRenderScrollData& aOwner,
                                     Layer* aLayer,
                                     int32_t aDescendantCount)
{
  MOZ_ASSERT(aDescendantCount >= 0); // Ensure value is valid
  MOZ_ASSERT(mDescendantCount == -1); // Don't allow re-setting an already set value
  mDescendantCount = aDescendantCount;

  MOZ_ASSERT(aLayer);
  for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) {
    mScrollIds.AppendElement(aOwner.AddMetadata(aLayer->GetScrollMetadata(i)));
  }

  mIsScrollInfoLayer = aLayer->AsContainerLayer() && !aLayer->GetFirstChild();
  mTransform = aLayer->GetTransform();
  mTransformIsPerspective = aLayer->GetTransformIsPerspective();
  mEventRegions = aLayer->GetEventRegions();
  mReferentId = aLayer->AsRefLayer()
      ? Some(aLayer->AsRefLayer()->GetReferentId())
      : Nothing();
  mEventRegionsOverride = aLayer->AsContainerLayer()
      ? aLayer->AsContainerLayer()->GetEventRegionsOverride()
      : EventRegionsOverride::NoOverride;
  mScrollThumbData = aLayer->GetScrollThumbData();
  mScrollbarTargetContainerId = aLayer->GetScrollbarTargetContainerId();
  mIsScrollbarContainer = aLayer->IsScrollbarContainer();
  mFixedPosScrollContainerId = aLayer->GetFixedPositionScrollContainerId();
}
void
WebRenderLayerScrollData::Dump(const WebRenderScrollData& aOwner) const
{
  printf_stderr("LayerScrollData(%p) descendants %d\n", this, mDescendantCount);
  for (size_t i : mScrollIds) {
    printf_stderr("  metadata: %s\n", Stringify(aOwner.GetScrollMetadata(i)).c_str());
  }
  printf_stderr("  ancestor transform: %s\n", Stringify(mAncestorTransform).c_str());
  printf_stderr("  transform: %s perspective: %d visible: %s\n",
    Stringify(mTransform).c_str(), mTransformIsPerspective,
    Stringify(mVisibleRegion).c_str());
  printf_stderr("  event regions: %s override: 0x%x\n",
    Stringify(mEventRegions).c_str(), mEventRegionsOverride);
  if (mReferentId) {
    printf_stderr("  ref layers id: 0x%" PRIx64 "\n", uint64_t(*mReferentId));
  }
  printf_stderr("  scrollbar type: %d animation: %" PRIx64 "\n",
    (int)mScrollbarData.mScrollbarLayerType, mScrollbarAnimationId);
  printf_stderr("  fixed pos container: %" PRIu64 "\n",
    mFixedPosScrollContainerId);
}
void
WebRenderLayerScrollData::AppendScrollMetadata(WebRenderScrollData& aOwner,
                                               const ScrollMetadata& aData)
{
  mScrollIds.AppendElement(aOwner.AddMetadata(aData));
}