зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1148582 - Recycle mask layers attached to FrameMetrics. r=mattwoodrow
--HG-- extra : rebase_source : f74699e5c40598ca8b7aa0163897c74524e32419 extra : source : be49031960aa935f2f0d6fa594251c9e1fa12536
This commit is contained in:
Родитель
55a0f8ee25
Коммит
16262c38a8
|
@ -1088,8 +1088,14 @@ protected:
|
||||||
* Grab a recyclable ImageLayer for use as a mask layer for aLayer (that is a
|
* Grab a recyclable ImageLayer for use as a mask layer for aLayer (that is a
|
||||||
* mask layer which has been used for aLayer before), or create one if such
|
* mask layer which has been used for aLayer before), or create one if such
|
||||||
* a layer doesn't exist.
|
* a layer doesn't exist.
|
||||||
|
*
|
||||||
|
* Since mask layers can exist either on the layer directly, or as a side-
|
||||||
|
* attachment to FrameMetrics (for ancestor scrollframe clips), we key the
|
||||||
|
* recycle operation on both the originating layer and the mask layer's
|
||||||
|
* index in the layer, if any.
|
||||||
*/
|
*/
|
||||||
already_AddRefed<ImageLayer> CreateOrRecycleMaskImageLayerFor(Layer* aLayer, const Maybe<size_t>& aForAncestorMaskLayer);
|
struct MaskLayerKey;
|
||||||
|
already_AddRefed<ImageLayer> CreateOrRecycleMaskImageLayerFor(const MaskLayerKey& aKey);
|
||||||
/**
|
/**
|
||||||
* Grabs all PaintedLayers and ColorLayers from the ContainerLayer and makes them
|
* Grabs all PaintedLayers and ColorLayers from the ContainerLayer and makes them
|
||||||
* available for recycling.
|
* available for recycling.
|
||||||
|
@ -1229,11 +1235,33 @@ protected:
|
||||||
typedef nsAutoTArray<NewLayerEntry,1> AutoLayersArray;
|
typedef nsAutoTArray<NewLayerEntry,1> AutoLayersArray;
|
||||||
AutoLayersArray mNewChildLayers;
|
AutoLayersArray mNewChildLayers;
|
||||||
nsTHashtable<nsRefPtrHashKey<PaintedLayer>> mPaintedLayersAvailableForRecycling;
|
nsTHashtable<nsRefPtrHashKey<PaintedLayer>> mPaintedLayersAvailableForRecycling;
|
||||||
nsDataHashtable<nsPtrHashKey<Layer>, nsRefPtr<ImageLayer> >
|
|
||||||
mRecycledMaskImageLayers;
|
|
||||||
nscoord mAppUnitsPerDevPixel;
|
nscoord mAppUnitsPerDevPixel;
|
||||||
bool mSnappingEnabled;
|
bool mSnappingEnabled;
|
||||||
bool mFlattenToSingleLayer;
|
bool mFlattenToSingleLayer;
|
||||||
|
|
||||||
|
struct MaskLayerKey {
|
||||||
|
MaskLayerKey() : mLayer(nullptr) {}
|
||||||
|
MaskLayerKey(Layer* aLayer, const Maybe<size_t>& aAncestorIndex)
|
||||||
|
: mLayer(aLayer),
|
||||||
|
mAncestorIndex(aAncestorIndex)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PLDHashNumber Hash() const {
|
||||||
|
// Hash the layer and add the layer index to the hash.
|
||||||
|
return (NS_PTR_TO_UINT32(mLayer) >> 2)
|
||||||
|
+ (mAncestorIndex ? (*mAncestorIndex + 1) : 0);
|
||||||
|
}
|
||||||
|
bool operator ==(const MaskLayerKey& aOther) const {
|
||||||
|
return mLayer == aOther.mLayer &&
|
||||||
|
mAncestorIndex == aOther.mAncestorIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layer* mLayer;
|
||||||
|
Maybe<size_t> mAncestorIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
nsDataHashtable<nsGenericHashKey<MaskLayerKey>, nsRefPtr<ImageLayer>>
|
||||||
|
mRecycledMaskImageLayers;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PaintedDisplayItemLayerUserData : public LayerUserData
|
class PaintedDisplayItemLayerUserData : public LayerUserData
|
||||||
|
@ -1933,12 +1961,12 @@ ContainerState::CreateOrRecycleImageLayer(PaintedLayer *aPainted)
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ImageLayer>
|
already_AddRefed<ImageLayer>
|
||||||
ContainerState::CreateOrRecycleMaskImageLayerFor(Layer* aLayer, const Maybe<size_t>& aForAncestorMaskLayer)
|
ContainerState::CreateOrRecycleMaskImageLayerFor(const MaskLayerKey& aKey)
|
||||||
{
|
{
|
||||||
nsRefPtr<ImageLayer> result = mRecycledMaskImageLayers.Get(aLayer);
|
nsRefPtr<ImageLayer> result = mRecycledMaskImageLayers.Get(aKey);
|
||||||
if (result && !aForAncestorMaskLayer) {
|
if (result) {
|
||||||
mRecycledMaskImageLayers.Remove(aLayer);
|
mRecycledMaskImageLayers.Remove(aKey);
|
||||||
aLayer->ClearExtraDumpInfo();
|
aKey.mLayer->ClearExtraDumpInfo();
|
||||||
// XXX if we use clip on mask layers, null it out here
|
// XXX if we use clip on mask layers, null it out here
|
||||||
} else {
|
} else {
|
||||||
// Create a new layer
|
// Create a new layer
|
||||||
|
@ -4326,7 +4354,14 @@ ContainerState::CollectOldLayers()
|
||||||
if (Layer* maskLayer = layer->GetMaskLayer()) {
|
if (Layer* maskLayer = layer->GetMaskLayer()) {
|
||||||
NS_ASSERTION(maskLayer->GetType() == Layer::TYPE_IMAGE,
|
NS_ASSERTION(maskLayer->GetType() == Layer::TYPE_IMAGE,
|
||||||
"Could not recycle mask layer, unsupported layer type.");
|
"Could not recycle mask layer, unsupported layer type.");
|
||||||
mRecycledMaskImageLayers.Put(layer, static_cast<ImageLayer*>(maskLayer));
|
mRecycledMaskImageLayers.Put(MaskLayerKey(layer, Nothing()), static_cast<ImageLayer*>(maskLayer));
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < layer->GetAncestorMaskLayerCount(); i++) {
|
||||||
|
Layer* maskLayer = layer->GetAncestorMaskLayerAt(i);
|
||||||
|
|
||||||
|
NS_ASSERTION(maskLayer->GetType() == Layer::TYPE_IMAGE,
|
||||||
|
"Could not recycle mask layer, unsupported layer type.");
|
||||||
|
mRecycledMaskImageLayers.Put(MaskLayerKey(layer, Some(i)), static_cast<ImageLayer*>(maskLayer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5697,7 +5732,8 @@ ContainerState::CreateMaskLayer(Layer *aLayer,
|
||||||
uint32_t aRoundedRectClipCount)
|
uint32_t aRoundedRectClipCount)
|
||||||
{
|
{
|
||||||
// check if we can re-use the mask layer
|
// check if we can re-use the mask layer
|
||||||
nsRefPtr<ImageLayer> maskLayer = CreateOrRecycleMaskImageLayerFor(aLayer, aForAncestorMaskLayer);
|
MaskLayerKey recycleKey(aLayer, aForAncestorMaskLayer);
|
||||||
|
nsRefPtr<ImageLayer> maskLayer = CreateOrRecycleMaskImageLayerFor(recycleKey);
|
||||||
MaskLayerUserData* userData = GetMaskLayerUserData(maskLayer);
|
MaskLayerUserData* userData = GetMaskLayerUserData(maskLayer);
|
||||||
|
|
||||||
MaskLayerUserData newData;
|
MaskLayerUserData newData;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче