mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 05:11:03 +00:00
e1776c67f8
- Bug 1199885 - Part 2: Add AsyncDragMetrics. r=kats (220a4f445e)
- Bug 1149482 - Localize the 'none' string for APZ in about:support. r=dvander (3e0128f62e)
- Bug 1199885 - Part 3: Add 'apz.drag.enabled' preference for async scrollbars. r=kats (5133061d3f)
- Bug 1199885 - Part 4: Let the hit testing tree know about the scroll thumb. r=kats (26a9a69443)
- Bug 1199885 - Part 5: Make mRootLayerTreeID const to prove that there's no data races. r=kats (88e2eb80f1)
- Bug 1199885 - Part 8: Add FindScrollNode to locate the scrollbar thumb. r=kats (a545ec9569)
- Bug 1199885 - Part 9: Let APZC handle the drag events. r=kats (4cc0f88153)
- Bug 1199885 - Part 9.5: Make the mouse events APZC aware. r=kats (69bd4caf94)
- Bug 1199885 - Part 10: Add APZTeeManager API to start an async scroll. r=kats (e212ee2750)
- Bug 1199885 - Part 12: Add StartScrollbarDrag IPC message. r=kats (705af3b233)
- Bug 1199885 - Part 13: Let nsSliderFrame trigger async scrolling via StartScrollbarDrag. r=kats (d31b5a790d)
- put in gstreamer as of 2015-10-05 Bug 1146482 (7cca45858c)
- pointer style (f8041af438)
- Bug 1197097 - Don't use a context-wide cycle-detection mechanism for detecting cycles during JSON.stringify. This prevents nested (yet separate) JSON.stringify, and it causes that algorithm to be affected by specification-unrelated operations like toSource. r=jonco (09652471c1)
- align to ugly grammaer of 1114782 (c760693693)
- remove space (7158a0c2bf)
- align to FF/TFF (27138a55bb)
- Bug 1205887 - Verify that MOZILLA_VERSION was set correctly, r=glandium (2269e8f31b)
- Bug 1205012 - Allow rust source code in SpiderMonkey; r=mshal (9ebca9ed28)
- Bug 1197281 - Use MOZ_FIND_WINSDK_VERSION for MOZ_WINSDK_MAXVER on mingw. r=glandium (2910b2160e)
- Bug 1207893 - Refactor how build backend execution is summarized. r=gps (56d8fecbc2)
- Bug 1207893 - Allow to create multiple build backends at once. r=gps (d8cba87d2b)
- Bug 1207897 - Add a configure option to build multiple build backends. r=gps (f9c7851d02)
- Bug 1188555 - part 1 - remove write-only configure.in variable NO_LD_ARCHIVE_FLAGS; r=mshal (461958b100)
- Bug 1188555 - part 2 - remove write-only configure.in variables MKSHLIB_{UN,}FORCE_ALL; r=mshal (1813210dda)
- Bug 1207882 - Ensure chrome manifests are created in a directory that exists when processing jar manifests. r=gps (59165a64cb)
- Bug 1204712 - Handle wildcards properly for localized content in jar manifests. r=gps (54dfb632c7)
- Bug 1188551: treat assertion failures as bad mozconfig; r=mshal (e307769de7)
- Bug 1181040 - Set ${var}_IS_SET variables for mk_add_options-defined variables. r=gps (19f169556b)
- Bug 1193015 - Require MOZ_GLX_USE_SURFACE_SHARING to enable WebGL surface sharing on GLX. r=jgilbert (9aa4fa8f41)
- Bug 1211324 (part 1) - Remove BILINEAR and GAUSSIAN filter constants. (3d9290ef02)
- Bug 1211324 (part 2) - Make gfx::FILTER::GOOD convert to GraphicsFilter::FILTER_GOOD. r=mattwoodrow. (16e7607c70)
- Bug 1208365 (part 1) - Remove unused EXTEND_PAD_EDGE. r=Bas. (10920e2bb6)
- Bug 1208365 (part 2) - Remove gfxPattern::Extend(). r=bas. (3703b9748a)
- Bug 1208365 (part 3) - Change gfxPattern::mExtend from a GraphicsExtend to a gfx::ExtendMode. r=bas. (b105d06e91)
- Bug 1208365 (part 4) - Remove gfxPattern::GraphicsExtend. r=bas. (7a16d48995)
- Bug 1211324 (part 3) - Remove GraphicsFilter::FILTER_FAST and replace it with FILTER_BEST. r=mattwoodrow. (b5101e049f)
- Bug 1211324 (part 4) - Replace GraphicsFilter constants with gfx::Filter equivalents. r=mattwoodrow. (c19b6b030e)
- Bug 1190117 - Track mLastProducerID and mLastFrameID explicitly in ImageLayerProperties. r=roc (ed9a5c777f)
- Bug 1211324 (part 5) - Remove GraphicsFilter and gfxGraphicsFilter. r=mattwoodrow. (0bd4ce7160)
- Bug 1194954 - Fix -Wunreachable-code warnings in gfx/layers and gfx/thebes. r=BenWa (1a3d68c490)
- Bug 1180509 - Fix judder of icons in Australis doorhanger menu at the end of its scale-in animation. r=roc (9b4df470fa)
- Bug 1206915 - Make paint dumping to a file e10s-friendly. r=mattwoodrow (87d2e12c2b)
- Bug 1206915 - Handle nested PaintFrame() calls correctly during paint dumping. r=mattwoodrow,BenWa (d30f77fbdd)
- Fix max texture size handling in displayport clamping. (bug 1135907 follow-up, r=kats) (a791894332)
- Fix bogus assertion in nsLayoutUtils::SetDisplayPortMargins. (bug 1156409, r=botond, a=philor) (b635b21c34)
- Bug 1169879 - Use only the critical displayport when computing image visibility. r=tn (9ec91c9527)
- Bug 1169881 - Recompute image visibility when display port margins change. r=tn (35a5bd3a51)
- Bug 1197765 - Compare text content inside frame instead of the content node for ruby autohiding. r=dbaron (00cf5b7674)
- Bug 1173580 - Record content descriptions in APZ test data. r=kats (7a72d1ac0a)
- Bug 1178971 - Changed line snapping behaviour depending on even/odd-ness of stroke width. r=mstange (495b32dc23)
- Bug 1208953: [mp3] Don't parse data we've already parsed. r=cpearce (72eed4309f)
- Bug 1137151: Marked destructor of |android::MediaCodecReader| as protected, r=sotaro (0632b34bc5)
- Bug 1205351 - Replace nsBaseHashtable::Enumerate() calls in dom/media/ with iterators r=cpearce (45976c24c0)
- Bug 1133624 - Add lang-specific ruby rules to ua.css. r=dbaron (46788cc220)
- Bug 1133624 - followup add fuzzy maxdiff on CLOSED TREE (1b6b62aded)
- Bug 1180443 - Consider whitespace collapse when calculating intrinsic isize of ruby. r=dbaron (3862184acd)
- Bug 1153764 - Avoid explicitly doing break before when there is ruby span. r=roc (71b4ec7749)
- add gstreamer parts (7e562556be)
- some preferences aligned to FF (b26d0b389c)
- Bug 1166301 - If APZ is enabled, clip fixed background images at the layer level rather than the display item level. r=mattwoodrow (5644e22090)
- Bug 1144990 - Dump display items with class id and name, r=roc (aa2e227e35)
- Bug 1205087 - Remove LayerManager parameter for ShouldFixToViewport. r=roc (00a1f2e36f)
- Bug 1205087 - Make nsSVGIntegrationUtils paint frame continuations manually since combining them meant that our reference frame wasn't an ancestor of all painted frames. r=roc (e40f6b7b81)
- Bug 1195400 - Check ancestor geometry roots when determining scrollability of a layer. r=mattwoodrow (4699b7e935)
- Bug 1205087 - Cache the AnimatedGeometryRoot on DisplayItem. r=roc (06bba311c3)
- Back out the bits of bug 1205087 that cache the AnimatedGeometryRoot on DisplayItem. r=backout (254057a6b6)
- Bug 1203190 - Don't intersect with the visible rect for fixed background images. r=mattwoodrow (1c5a432459)
- Bug 1208438 - Don't allow layers with scrolling clips to occlusion-cull layers behind them. r=mattwoodrow (c3d77a9846)
- Bug 1205630 - Translate a fixed background display item's clip rect correctly when setting it on the layer. r=mstange (49039f0e2d)
- Bug 1205630 - Reftest. r=mstange (a8db59eaee)
- Bug 1105832 - Also dump inactive layer managers when display list dumping is enabled. r=mattwoodrow (564fe5fcbc)
- Bug 1208661 - Move Dump() up from ContentClient to CompositableClient. r=BenWa (37915312b3)
558 lines
18 KiB
C++
558 lines
18 KiB
C++
/*-*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* 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/. */
|
|
|
|
#include "LayerTreeInvalidation.h"
|
|
|
|
#include <stdint.h> // for uint32_t
|
|
#include "ImageContainer.h" // for ImageContainer
|
|
#include "ImageLayers.h" // for ImageLayer, etc
|
|
#include "Layers.h" // for Layer, ContainerLayer, etc
|
|
#include "Units.h" // for ParentLayerIntRect
|
|
#include "gfxRect.h" // for gfxRect
|
|
#include "gfxUtils.h" // for gfxUtils
|
|
#include "mozilla/gfx/BaseSize.h" // for BaseSize
|
|
#include "mozilla/gfx/Point.h" // for IntSize
|
|
#include "mozilla/mozalloc.h" // for operator new, etc
|
|
#include "nsAutoPtr.h" // for nsRefPtr, nsAutoPtr, etc
|
|
#include "nsDataHashtable.h" // for nsDataHashtable
|
|
#include "nsDebug.h" // for NS_ASSERTION
|
|
#include "nsHashKeys.h" // for nsPtrHashKey
|
|
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
|
|
#include "nsRect.h" // for IntRect
|
|
#include "nsTArray.h" // for nsAutoTArray, nsTArray_Impl
|
|
#include "mozilla/layers/ImageHost.h"
|
|
#include "mozilla/layers/LayerManagerComposite.h"
|
|
|
|
using namespace mozilla::gfx;
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
|
|
struct LayerPropertiesBase;
|
|
UniquePtr<LayerPropertiesBase> CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask = false);
|
|
|
|
static IntRect
|
|
TransformRect(const IntRect& aRect, const Matrix4x4& aTransform)
|
|
{
|
|
if (aRect.IsEmpty()) {
|
|
return IntRect();
|
|
}
|
|
|
|
Rect rect(aRect.x, aRect.y, aRect.width, aRect.height);
|
|
rect = aTransform.TransformAndClipBounds(rect, Rect::MaxIntRect());
|
|
rect.RoundOut();
|
|
|
|
IntRect intRect;
|
|
if (!gfxUtils::GfxRectToIntRect(ThebesRect(rect), &intRect)) {
|
|
return IntRect();
|
|
}
|
|
|
|
return intRect;
|
|
}
|
|
|
|
static void
|
|
AddTransformedRegion(nsIntRegion& aDest, const nsIntRegion& aSource, const Matrix4x4& aTransform)
|
|
{
|
|
nsIntRegionRectIterator iter(aSource);
|
|
const IntRect *r;
|
|
while ((r = iter.Next())) {
|
|
aDest.Or(aDest, TransformRect(*r, aTransform));
|
|
}
|
|
aDest.SimplifyOutward(20);
|
|
}
|
|
|
|
static void
|
|
AddRegion(nsIntRegion& aDest, const nsIntRegion& aSource)
|
|
{
|
|
aDest.Or(aDest, aSource);
|
|
aDest.SimplifyOutward(20);
|
|
}
|
|
|
|
/**
|
|
* Walks over this layer, and all descendant layers.
|
|
* If any of these are a ContainerLayer that reports invalidations to a PresShell,
|
|
* then report that the entire bounds have changed.
|
|
*/
|
|
static void
|
|
NotifySubdocumentInvalidationRecursive(Layer* aLayer, NotifySubDocInvalidationFunc aCallback)
|
|
{
|
|
aLayer->ClearInvalidRect();
|
|
ContainerLayer* container = aLayer->AsContainerLayer();
|
|
|
|
if (aLayer->GetMaskLayer()) {
|
|
NotifySubdocumentInvalidationRecursive(aLayer->GetMaskLayer(), aCallback);
|
|
}
|
|
for (size_t i = 0; i < aLayer->GetAncestorMaskLayerCount(); i++) {
|
|
Layer* maskLayer = aLayer->GetAncestorMaskLayerAt(i);
|
|
NotifySubdocumentInvalidationRecursive(maskLayer, aCallback);
|
|
}
|
|
|
|
if (!container) {
|
|
return;
|
|
}
|
|
|
|
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
|
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
|
}
|
|
|
|
aCallback(container, container->GetVisibleRegion());
|
|
}
|
|
|
|
struct LayerPropertiesBase : public LayerProperties
|
|
{
|
|
explicit LayerPropertiesBase(Layer* aLayer)
|
|
: mLayer(aLayer)
|
|
, mMaskLayer(nullptr)
|
|
, mVisibleRegion(aLayer->GetVisibleRegion())
|
|
, mInvalidRegion(aLayer->GetInvalidRegion())
|
|
, mPostXScale(aLayer->GetPostXScale())
|
|
, mPostYScale(aLayer->GetPostYScale())
|
|
, mOpacity(aLayer->GetLocalOpacity())
|
|
, mUseClipRect(!!aLayer->GetClipRect())
|
|
{
|
|
MOZ_COUNT_CTOR(LayerPropertiesBase);
|
|
if (aLayer->GetMaskLayer()) {
|
|
mMaskLayer = CloneLayerTreePropertiesInternal(aLayer->GetMaskLayer(), true);
|
|
}
|
|
for (size_t i = 0; i < aLayer->GetAncestorMaskLayerCount(); i++) {
|
|
Layer* maskLayer = aLayer->GetAncestorMaskLayerAt(i);
|
|
mAncestorMaskLayers.AppendElement(CloneLayerTreePropertiesInternal(maskLayer, true));
|
|
}
|
|
if (mUseClipRect) {
|
|
mClipRect = *aLayer->GetClipRect();
|
|
}
|
|
mTransform = aLayer->GetLocalTransform();
|
|
}
|
|
LayerPropertiesBase()
|
|
: mLayer(nullptr)
|
|
, mMaskLayer(nullptr)
|
|
{
|
|
MOZ_COUNT_CTOR(LayerPropertiesBase);
|
|
}
|
|
~LayerPropertiesBase()
|
|
{
|
|
MOZ_COUNT_DTOR(LayerPropertiesBase);
|
|
}
|
|
|
|
virtual nsIntRegion ComputeDifferences(Layer* aRoot,
|
|
NotifySubDocInvalidationFunc aCallback,
|
|
bool* aGeometryChanged);
|
|
|
|
virtual void MoveBy(const IntPoint& aOffset);
|
|
|
|
nsIntRegion ComputeChange(NotifySubDocInvalidationFunc aCallback,
|
|
bool& aGeometryChanged)
|
|
{
|
|
bool transformChanged = !mTransform.FuzzyEqualsMultiplicative(mLayer->GetLocalTransform()) ||
|
|
mLayer->GetPostXScale() != mPostXScale ||
|
|
mLayer->GetPostYScale() != mPostYScale;
|
|
const Maybe<ParentLayerIntRect>& otherClip = mLayer->GetClipRect();
|
|
nsIntRegion result;
|
|
|
|
bool ancestorMaskChanged = mAncestorMaskLayers.Length() != mLayer->GetAncestorMaskLayerCount();
|
|
if (!ancestorMaskChanged) {
|
|
for (size_t i = 0; i < mAncestorMaskLayers.Length(); i++) {
|
|
if (mLayer->GetAncestorMaskLayerAt(i) != mAncestorMaskLayers[i]->mLayer) {
|
|
ancestorMaskChanged = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Layer* otherMask = mLayer->GetMaskLayer();
|
|
if ((mMaskLayer ? mMaskLayer->mLayer : nullptr) != otherMask ||
|
|
ancestorMaskChanged ||
|
|
(mUseClipRect != !!otherClip) ||
|
|
mLayer->GetLocalOpacity() != mOpacity ||
|
|
transformChanged)
|
|
{
|
|
aGeometryChanged = true;
|
|
result = OldTransformedBounds();
|
|
AddRegion(result, NewTransformedBounds());
|
|
|
|
// We can't bail out early because we need to update mChildrenChanged.
|
|
}
|
|
|
|
AddRegion(result, ComputeChangeInternal(aCallback, aGeometryChanged));
|
|
AddTransformedRegion(result, mLayer->GetInvalidRegion(), mTransform);
|
|
|
|
if (mMaskLayer && otherMask) {
|
|
AddTransformedRegion(result, mMaskLayer->ComputeChange(aCallback, aGeometryChanged),
|
|
mTransform);
|
|
}
|
|
|
|
for (size_t i = 0;
|
|
i < std::min(mAncestorMaskLayers.Length(), mLayer->GetAncestorMaskLayerCount());
|
|
i++)
|
|
{
|
|
AddTransformedRegion(result,
|
|
mAncestorMaskLayers[i]->ComputeChange(aCallback, aGeometryChanged),
|
|
mTransform);
|
|
}
|
|
|
|
if (mUseClipRect && otherClip) {
|
|
if (!mClipRect.IsEqualInterior(*otherClip)) {
|
|
aGeometryChanged = true;
|
|
nsIntRegion tmp;
|
|
tmp.Xor(ParentLayerIntRect::ToUntyped(mClipRect), ParentLayerIntRect::ToUntyped(*otherClip));
|
|
AddRegion(result, tmp);
|
|
}
|
|
}
|
|
|
|
mLayer->ClearInvalidRect();
|
|
return result;
|
|
}
|
|
|
|
IntRect NewTransformedBounds()
|
|
{
|
|
return TransformRect(mLayer->GetVisibleRegion().GetBounds(), mLayer->GetLocalTransform());
|
|
}
|
|
|
|
IntRect OldTransformedBounds()
|
|
{
|
|
return TransformRect(mVisibleRegion.GetBounds(), mTransform);
|
|
}
|
|
|
|
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
|
|
bool& aGeometryChanged)
|
|
{
|
|
return IntRect();
|
|
}
|
|
|
|
nsRefPtr<Layer> mLayer;
|
|
UniquePtr<LayerPropertiesBase> mMaskLayer;
|
|
nsTArray<UniquePtr<LayerPropertiesBase>> mAncestorMaskLayers;
|
|
nsIntRegion mVisibleRegion;
|
|
nsIntRegion mInvalidRegion;
|
|
Matrix4x4 mTransform;
|
|
float mPostXScale;
|
|
float mPostYScale;
|
|
float mOpacity;
|
|
ParentLayerIntRect mClipRect;
|
|
bool mUseClipRect;
|
|
};
|
|
|
|
struct ContainerLayerProperties : public LayerPropertiesBase
|
|
{
|
|
explicit ContainerLayerProperties(ContainerLayer* aLayer)
|
|
: LayerPropertiesBase(aLayer)
|
|
, mPreXScale(aLayer->GetPreXScale())
|
|
, mPreYScale(aLayer->GetPreYScale())
|
|
{
|
|
for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) {
|
|
mChildren.AppendElement(Move(CloneLayerTreePropertiesInternal(child)));
|
|
}
|
|
}
|
|
|
|
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
|
|
bool& aGeometryChanged)
|
|
{
|
|
ContainerLayer* container = mLayer->AsContainerLayer();
|
|
nsIntRegion result;
|
|
|
|
bool childrenChanged = false;
|
|
|
|
if (mPreXScale != container->GetPreXScale() ||
|
|
mPreYScale != container->GetPreYScale()) {
|
|
aGeometryChanged = true;
|
|
result = OldTransformedBounds();
|
|
AddRegion(result, NewTransformedBounds());
|
|
childrenChanged = true;
|
|
|
|
// Can't bail out early, we need to update the child container layers
|
|
}
|
|
|
|
// A low frame rate is especially visible to users when scrolling, so we
|
|
// particularly want to avoid unnecessary invalidation at that time. For us
|
|
// here, that means avoiding unnecessary invalidation of child items when
|
|
// other children are added to or removed from our container layer, since
|
|
// that may be caused by children being scrolled in or out of view. We are
|
|
// less concerned with children changing order.
|
|
// TODO: Consider how we could avoid unnecessary invalidation when children
|
|
// change order, and whether the overhead would be worth it.
|
|
|
|
nsDataHashtable<nsPtrHashKey<Layer>, uint32_t> oldIndexMap(mChildren.Length());
|
|
for (uint32_t i = 0; i < mChildren.Length(); ++i) {
|
|
oldIndexMap.Put(mChildren[i]->mLayer, i);
|
|
}
|
|
|
|
uint32_t i = 0; // cursor into the old child list mChildren
|
|
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
|
bool invalidateChildsCurrentArea = false;
|
|
if (i < mChildren.Length()) {
|
|
uint32_t childsOldIndex;
|
|
if (oldIndexMap.Get(child, &childsOldIndex)) {
|
|
if (childsOldIndex >= i) {
|
|
// Invalidate the old areas of layers that used to be between the
|
|
// current |child| and the previous |child| that was also in the
|
|
// old list mChildren (if any of those children have been reordered
|
|
// rather than removed, we will invalidate their new area when we
|
|
// encounter them in the new list):
|
|
for (uint32_t j = i; j < childsOldIndex; ++j) {
|
|
AddRegion(result, mChildren[j]->OldTransformedBounds());
|
|
childrenChanged |= true;
|
|
}
|
|
// Invalidate any regions of the child that have changed:
|
|
nsIntRegion region = mChildren[childsOldIndex]->ComputeChange(aCallback, aGeometryChanged);
|
|
i = childsOldIndex + 1;
|
|
if (!region.IsEmpty()) {
|
|
AddRegion(result, region);
|
|
childrenChanged |= true;
|
|
}
|
|
} else {
|
|
// We've already seen this child in mChildren (which means it must
|
|
// have been reordered) and invalidated its old area. We need to
|
|
// invalidate its new area too:
|
|
invalidateChildsCurrentArea = true;
|
|
}
|
|
} else {
|
|
// |child| is new
|
|
invalidateChildsCurrentArea = true;
|
|
}
|
|
} else {
|
|
// |child| is new, or was reordered to a higher index
|
|
invalidateChildsCurrentArea = true;
|
|
}
|
|
if (invalidateChildsCurrentArea) {
|
|
aGeometryChanged = true;
|
|
AddTransformedRegion(result, child->GetVisibleRegion(), child->GetLocalTransform());
|
|
if (aCallback) {
|
|
NotifySubdocumentInvalidationRecursive(child, aCallback);
|
|
} else {
|
|
ClearInvalidations(child);
|
|
}
|
|
}
|
|
childrenChanged |= invalidateChildsCurrentArea;
|
|
}
|
|
|
|
// Process remaining removed children.
|
|
while (i < mChildren.Length()) {
|
|
childrenChanged |= true;
|
|
AddRegion(result, mChildren[i]->OldTransformedBounds());
|
|
i++;
|
|
}
|
|
|
|
if (aCallback) {
|
|
aCallback(container, result);
|
|
}
|
|
|
|
if (childrenChanged) {
|
|
container->SetChildrenChanged(true);
|
|
}
|
|
|
|
result.Transform(mLayer->GetLocalTransform());
|
|
|
|
return result;
|
|
}
|
|
|
|
// The old list of children:
|
|
nsAutoTArray<UniquePtr<LayerPropertiesBase>,1> mChildren;
|
|
float mPreXScale;
|
|
float mPreYScale;
|
|
};
|
|
|
|
struct ColorLayerProperties : public LayerPropertiesBase
|
|
{
|
|
explicit ColorLayerProperties(ColorLayer *aLayer)
|
|
: LayerPropertiesBase(aLayer)
|
|
, mColor(aLayer->GetColor())
|
|
, mBounds(aLayer->GetBounds())
|
|
{ }
|
|
|
|
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
|
|
bool& aGeometryChanged)
|
|
{
|
|
ColorLayer* color = static_cast<ColorLayer*>(mLayer.get());
|
|
|
|
if (mColor != color->GetColor()) {
|
|
aGeometryChanged = true;
|
|
return NewTransformedBounds();
|
|
}
|
|
|
|
nsIntRegion boundsDiff;
|
|
boundsDiff.Xor(mBounds, color->GetBounds());
|
|
|
|
nsIntRegion result;
|
|
AddTransformedRegion(result, boundsDiff, mTransform);
|
|
|
|
return result;
|
|
}
|
|
|
|
Color mColor;
|
|
IntRect mBounds;
|
|
};
|
|
|
|
static ImageHost* GetImageHost(ImageLayer* aLayer)
|
|
{
|
|
LayerComposite* composite = aLayer->AsLayerComposite();
|
|
if (composite) {
|
|
return static_cast<ImageHost*>(composite->GetCompositableHost());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
struct ImageLayerProperties : public LayerPropertiesBase
|
|
{
|
|
explicit ImageLayerProperties(ImageLayer* aImage, bool aIsMask)
|
|
: LayerPropertiesBase(aImage)
|
|
, mContainer(aImage->GetContainer())
|
|
, mImageHost(GetImageHost(aImage))
|
|
, mFilter(aImage->GetFilter())
|
|
, mScaleToSize(aImage->GetScaleToSize())
|
|
, mScaleMode(aImage->GetScaleMode())
|
|
, mLastProducerID(-1)
|
|
, mLastFrameID(-1)
|
|
, mIsMask(aIsMask)
|
|
{
|
|
if (mImageHost) {
|
|
mLastProducerID = mImageHost->GetLastProducerID();
|
|
mLastFrameID = mImageHost->GetLastFrameID();
|
|
}
|
|
}
|
|
|
|
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
|
|
bool& aGeometryChanged)
|
|
{
|
|
ImageLayer* imageLayer = static_cast<ImageLayer*>(mLayer.get());
|
|
|
|
if (!imageLayer->GetVisibleRegion().IsEqual(mVisibleRegion)) {
|
|
aGeometryChanged = true;
|
|
IntRect result = NewTransformedBounds();
|
|
result = result.Union(OldTransformedBounds());
|
|
return result;
|
|
}
|
|
|
|
ImageContainer* container = imageLayer->GetContainer();
|
|
ImageHost* host = GetImageHost(imageLayer);
|
|
if (mContainer != container ||
|
|
mFilter != imageLayer->GetFilter() ||
|
|
mScaleToSize != imageLayer->GetScaleToSize() ||
|
|
mScaleMode != imageLayer->GetScaleMode() ||
|
|
host != mImageHost ||
|
|
(host && host->GetProducerID() != mLastProducerID) ||
|
|
(host && host->GetFrameID() != mLastFrameID)) {
|
|
aGeometryChanged = true;
|
|
|
|
if (mIsMask) {
|
|
// Mask layers have an empty visible region, so we have to
|
|
// use the image size instead.
|
|
IntSize size;
|
|
if (container) {
|
|
size = container->GetCurrentSize();
|
|
}
|
|
if (host) {
|
|
size = host->GetImageSize();
|
|
}
|
|
IntRect rect(0, 0, size.width, size.height);
|
|
return TransformRect(rect, mLayer->GetLocalTransform());
|
|
}
|
|
return NewTransformedBounds();
|
|
}
|
|
|
|
return IntRect();
|
|
}
|
|
|
|
nsRefPtr<ImageContainer> mContainer;
|
|
nsRefPtr<ImageHost> mImageHost;
|
|
Filter mFilter;
|
|
gfx::IntSize mScaleToSize;
|
|
ScaleMode mScaleMode;
|
|
int32_t mLastProducerID;
|
|
int32_t mLastFrameID;
|
|
bool mIsMask;
|
|
};
|
|
|
|
UniquePtr<LayerPropertiesBase>
|
|
CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask /* = false */)
|
|
{
|
|
if (!aRoot) {
|
|
return MakeUnique<LayerPropertiesBase>();
|
|
}
|
|
|
|
MOZ_ASSERT(!aIsMask || aRoot->GetType() == Layer::TYPE_IMAGE);
|
|
|
|
switch (aRoot->GetType()) {
|
|
case Layer::TYPE_CONTAINER:
|
|
case Layer::TYPE_REF:
|
|
return MakeUnique<ContainerLayerProperties>(aRoot->AsContainerLayer());
|
|
case Layer::TYPE_COLOR:
|
|
return MakeUnique<ColorLayerProperties>(static_cast<ColorLayer*>(aRoot));
|
|
case Layer::TYPE_IMAGE:
|
|
return MakeUnique<ImageLayerProperties>(static_cast<ImageLayer*>(aRoot), aIsMask);
|
|
case Layer::TYPE_CANVAS:
|
|
case Layer::TYPE_READBACK:
|
|
case Layer::TYPE_SHADOW:
|
|
case Layer::TYPE_PAINTED:
|
|
return MakeUnique<LayerPropertiesBase>(aRoot);
|
|
}
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected root layer type");
|
|
return MakeUnique<LayerPropertiesBase>(aRoot);
|
|
}
|
|
|
|
/* static */ UniquePtr<LayerProperties>
|
|
LayerProperties::CloneFrom(Layer* aRoot)
|
|
{
|
|
return CloneLayerTreePropertiesInternal(aRoot);
|
|
}
|
|
|
|
/* static */ void
|
|
LayerProperties::ClearInvalidations(Layer *aLayer)
|
|
{
|
|
aLayer->ClearInvalidRect();
|
|
if (aLayer->GetMaskLayer()) {
|
|
ClearInvalidations(aLayer->GetMaskLayer());
|
|
}
|
|
for (size_t i = 0; i < aLayer->GetAncestorMaskLayerCount(); i++) {
|
|
ClearInvalidations(aLayer->GetAncestorMaskLayerAt(i));
|
|
}
|
|
|
|
ContainerLayer* container = aLayer->AsContainerLayer();
|
|
if (!container) {
|
|
return;
|
|
}
|
|
|
|
for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
|
|
ClearInvalidations(child);
|
|
}
|
|
}
|
|
|
|
nsIntRegion
|
|
LayerPropertiesBase::ComputeDifferences(Layer* aRoot, NotifySubDocInvalidationFunc aCallback,
|
|
bool* aGeometryChanged = nullptr)
|
|
{
|
|
NS_ASSERTION(aRoot, "Must have a layer tree to compare against!");
|
|
if (mLayer != aRoot) {
|
|
if (aCallback) {
|
|
NotifySubdocumentInvalidationRecursive(aRoot, aCallback);
|
|
} else {
|
|
ClearInvalidations(aRoot);
|
|
}
|
|
IntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(),
|
|
aRoot->GetLocalTransform());
|
|
result = result.Union(OldTransformedBounds());
|
|
if (aGeometryChanged != nullptr) {
|
|
*aGeometryChanged = true;
|
|
}
|
|
return result;
|
|
} else {
|
|
bool geometryChanged = (aGeometryChanged != nullptr) ? *aGeometryChanged : false;
|
|
nsIntRegion invalid = ComputeChange(aCallback, geometryChanged);
|
|
if (aGeometryChanged != nullptr) {
|
|
*aGeometryChanged = geometryChanged;
|
|
}
|
|
return invalid;
|
|
}
|
|
}
|
|
|
|
void
|
|
LayerPropertiesBase::MoveBy(const IntPoint& aOffset)
|
|
{
|
|
mTransform.PostTranslate(aOffset.x, aOffset.y, 0);
|
|
}
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|