DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (02a75a0b91b8)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef ACTIVELAYERTRACKER_H_
#define ACTIVELAYERTRACKER_H_

#include "nsCSSPropertyID.h"

class nsIFrame;
class nsIContent;
class nsCSSPropertyIDSet;
class nsDisplayListBuilder;
class nsDOMCSSDeclaration;

namespace mozilla {

/**
 * This class receives various notifications about style changes and content
 * changes that affect layerization decisions, and implements the heuristics
 * that drive those decisions. It manages per-frame state to support those
 * heuristics.
 */
class ActiveLayerTracker {
 public:
  static void Shutdown();

  /*
   * We track style changes to selected styles:
   *   eCSSProperty_transform, eCSSProperty_translate,
   *   eCSSProperty_rotate, eCSSProperty_scale
   *   eCSSProperty_opacity
   *   eCSSProperty_left, eCSSProperty_top,
   *   eCSSProperty_right, eCSSProperty_bottom
   * and use that information to guess whether style changes are animated.
   */

  /**
   * Notify aFrame's style property as having changed due to a restyle,
   * and therefore possibly wanting an active layer to render that style.
   * Any such marking will time out after a short period.
   * @param aProperty the property that has changed
   */
  static void NotifyRestyle(nsIFrame* aFrame, nsCSSPropertyID aProperty);
  /**
   * Notify aFrame's left/top/right/bottom properties as having (maybe)
   * changed due to a restyle, and therefore possibly wanting an active layer
   * to render that style. Any such marking will time out after a short period.
   */
  static void NotifyOffsetRestyle(nsIFrame* aFrame);
  /**
   * Mark aFrame as being known to have an animation of aProperty.
   * Any such marking will time out after a short period.
   * aNewValue and aDOMCSSDecl are used to determine whether the property's
   * value has changed.
   */
  static void NotifyAnimated(nsIFrame* aFrame, nsCSSPropertyID aProperty,
                             const nsAString& aNewValue,
                             nsDOMCSSDeclaration* aDOMCSSDecl);
  /**
   * Notify aFrame as being known to have an animation of aProperty through an
   * inline style modification during aScrollFrame's scroll event handler.
   */
  static void NotifyAnimatedFromScrollHandler(nsIFrame* aFrame,
                                              nsCSSPropertyID aProperty,
                                              nsIFrame* aScrollFrame);
  /**
   * Notify that a property in the inline style rule of aFrame's element
   * has been modified.
   * This notification is incomplete --- not all modifications to inline
   * style will trigger this.
   * aNewValue and aDOMCSSDecl are used to determine whether the property's
   * value has changed.
   */
  static void NotifyInlineStyleRuleModified(nsIFrame* aFrame,
                                            nsCSSPropertyID aProperty,
                                            const nsAString& aNewValue,
                                            nsDOMCSSDeclaration* aDOMCSSDecl);
  /**
   * Notify that a frame needs to be repainted. This is important for layering
   * decisions where, say, aFrame's transform is updated from JS, but we need
   * to repaint aFrame anyway, so we get no benefit from giving it its own
   * layer.
   */
  static void NotifyNeedsRepaint(nsIFrame* aFrame);
  /**
   * Return true if aFrame's property style in |aPropertySet| should be
   * considered as being animated for constructing active layers.
   */
  static bool IsStyleAnimated(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                              const nsCSSPropertyIDSet& aPropertySet);
  /**
   * Return true if any of aFrame's offset property styles should be considered
   * as being animated for constructing active layers.
   */
  static bool IsOffsetStyleAnimated(nsIFrame* aFrame);
  /**
   * Return true if aFrame's background-position-x or background-position-y
   * property is animated.
   */
  static bool IsBackgroundPositionAnimated(nsDisplayListBuilder* aBuilder,
                                           nsIFrame* aFrame);
  /**
   * Return true if aFrame's transform-like property,
   * i.e. transform/translate/rotate/scale, is animated.
   */
  static bool IsTransformAnimated(nsDisplayListBuilder* aBuilder,
                                  nsIFrame* aFrame);
  /**
   * Return true if aFrame's transform style should be considered as being
   * animated for pre-rendering.
   */
  static bool IsTransformMaybeAnimated(nsIFrame* aFrame);
  /**
   * Return true if aFrame either has an animated scale now, or is likely to
   * have one in the future because it has a CSS animation or transition
   * (which may not be playing right now) that affects its scale.
   */
  static bool IsScaleSubjectToAnimation(nsIFrame* aFrame);

  /**
   * Transfer the LayerActivity property to the frame's content node when the
   * frame is about to be destroyed so that layer activity can be tracked
   * throughout reframes of an element. Only call this when aFrame is the
   * primary frame of aContent.
   */
  static void TransferActivityToContent(nsIFrame* aFrame, nsIContent* aContent);
  /**
   * Transfer the LayerActivity property back to the content node's primary
   * frame after the frame has been created.
   */
  static void TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFrame);

  /*
   * We track modifications to the content of certain frames (i.e. canvas
   * frames) and use that to make layering decisions.
   */

  /**
   * Mark aFrame's content as being active. This marking will time out after
   * a short period.
   */
  static void NotifyContentChange(nsIFrame* aFrame);
  /**
   * Return true if this frame's content is still marked as active.
   */
  static bool IsContentActive(nsIFrame* aFrame);

  /**
   * Called before and after a scroll event handler is executed, with the
   * scrollframe or nullptr, respectively. This acts as a hint to treat
   * inline style changes during the handler differently.
   */
  static void SetCurrentScrollHandlerFrame(nsIFrame* aFrame);
};

}  // namespace mozilla

#endif /* ACTIVELAYERTRACKER_H_ */