Bug 739671 - Store optimized Color/ImageLayers on the ThebesLayers that they replace. r=roc

This commit is contained in:
Matt Woodrow 2012-06-11 16:45:38 +12:00
parent d1be0e0364
commit 2c20f79d85

View File

@ -76,8 +76,7 @@ public:
mLayerBuilder(aLayerBuilder),
mContainerFrame(aContainerFrame), mContainerLayer(aContainerLayer),
mParameters(aParameters),
mNextFreeRecycledThebesLayer(0), mNextFreeRecycledColorLayer(0),
mNextFreeRecycledImageLayer(0)
mNextFreeRecycledThebesLayer(0)
{
nsPresContext* presContext = aContainerFrame->PresContext();
mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
@ -286,12 +285,12 @@ protected:
* Grab the next recyclable ColorLayer, or create one if there are no
* more recyclable ColorLayers.
*/
already_AddRefed<ColorLayer> CreateOrRecycleColorLayer();
already_AddRefed<ColorLayer> CreateOrRecycleColorLayer(ThebesLayer* aThebes);
/**
* Grab the next recyclable ImageLayer, or create one if there are no
* more recyclable ImageLayers.
*/
already_AddRefed<ImageLayer> CreateOrRecycleImageLayer();
already_AddRefed<ImageLayer> CreateOrRecycleImageLayer(ThebesLayer* aThebes);
/**
* 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
@ -383,13 +382,9 @@ protected:
typedef nsAutoTArray<nsRefPtr<Layer>,1> AutoLayersArray;
AutoLayersArray mNewChildLayers;
nsTArray<nsRefPtr<ThebesLayer> > mRecycledThebesLayers;
nsTArray<nsRefPtr<ColorLayer> > mRecycledColorLayers;
nsTArray<nsRefPtr<ImageLayer> > mRecycledImageLayers;
nsDataHashtable<nsPtrHashKey<Layer>, nsRefPtr<ImageLayer> >
mRecycledMaskImageLayers;
PRUint32 mNextFreeRecycledThebesLayer;
PRUint32 mNextFreeRecycledColorLayer;
PRUint32 mNextFreeRecycledImageLayer;
nscoord mAppUnitsPerDevPixel;
bool mSnappingEnabled;
};
@ -425,6 +420,9 @@ public:
gfxPoint mActiveScrolledRootPosition;
nsIntRegion mRegionToInvalidate;
nsRefPtr<ColorLayer> mColorLayer;
nsRefPtr<ImageLayer> mImageLayer;
};
/*
@ -913,15 +911,12 @@ FrameLayerBuilder::GetInactiveLayerManagerFor(nsDisplayItem* aItem)
}
already_AddRefed<ColorLayer>
ContainerState::CreateOrRecycleColorLayer()
ContainerState::CreateOrRecycleColorLayer(ThebesLayer *aThebes)
{
nsRefPtr<ColorLayer> layer;
if (mNextFreeRecycledColorLayer < mRecycledColorLayers.Length()) {
// Recycle a layer
layer = mRecycledColorLayers[mNextFreeRecycledColorLayer];
++mNextFreeRecycledColorLayer;
// Clear clip rect and mask layer so we don't accidentally stay clipped.
// We will reapply any necessary clipping.
ThebesDisplayItemLayerUserData* data =
static_cast<ThebesDisplayItemLayerUserData*>(aThebes->GetUserData(&gThebesDisplayItemLayerUserData));
nsRefPtr<ColorLayer> layer = data->mColorLayer;
if (layer) {
layer->SetClipRect(nsnull);
layer->SetMaskLayer(nsnull);
} else {
@ -930,21 +925,22 @@ ContainerState::CreateOrRecycleColorLayer()
if (!layer)
return nsnull;
// Mark this layer as being used for Thebes-painting display items
data->mColorLayer = layer;
layer->SetUserData(&gColorLayerUserData, nsnull);
// Remove other layer types we might have stored for this ThebesLayer
data->mImageLayer = nsnull;
}
return layer.forget();
}
already_AddRefed<ImageLayer>
ContainerState::CreateOrRecycleImageLayer()
ContainerState::CreateOrRecycleImageLayer(ThebesLayer *aThebes)
{
nsRefPtr<ImageLayer> layer;
if (mNextFreeRecycledImageLayer < mRecycledImageLayers.Length()) {
// Recycle a layer
layer = mRecycledImageLayers[mNextFreeRecycledImageLayer];
++mNextFreeRecycledImageLayer;
// Clear clip rect and mask layer so we don't accidentally stay clipped.
// We will reapply any necessary clipping.
ThebesDisplayItemLayerUserData* data =
static_cast<ThebesDisplayItemLayerUserData*>(aThebes->GetUserData(&gThebesDisplayItemLayerUserData));
nsRefPtr<ImageLayer> layer = data->mImageLayer;
if (layer) {
layer->SetClipRect(nsnull);
layer->SetMaskLayer(nsnull);
} else {
@ -953,7 +949,11 @@ ContainerState::CreateOrRecycleImageLayer()
if (!layer)
return nsnull;
// Mark this layer as being used for Thebes-painting display items
data->mImageLayer = layer;
layer->SetUserData(&gImageLayerUserData, nsnull);
// Remove other layer types we might have stored for this ThebesLayer
data->mColorLayer = nsnull;
}
return layer.forget();
}
@ -1276,7 +1276,7 @@ ContainerState::PopThebesLayerData()
NS_ASSERTION(!(data->mIsSolidColorInVisibleRegion && imageContainer),
"Can't be a solid color as well as an image!");
if (imageContainer) {
nsRefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer();
nsRefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer(data->mLayer);
imageLayer->SetContainer(imageContainer);
data->mImage->ConfigureLayer(imageLayer);
// The layer's current transform is applied first, then the result is scaled.
@ -1289,7 +1289,7 @@ ContainerState::PopThebesLayerData()
}
layer = imageLayer;
} else {
nsRefPtr<ColorLayer> colorLayer = CreateOrRecycleColorLayer();
nsRefPtr<ColorLayer> colorLayer = CreateOrRecycleColorLayer(data->mLayer);
colorLayer->SetIsFixedPosition(data->mLayer->GetIsFixedPosition());
colorLayer->SetColor(data->mSolidColor);
@ -2136,11 +2136,7 @@ ContainerState::CollectOldLayers()
layer = layer->GetNextSibling()) {
NS_ASSERTION(!layer->HasUserData(&gMaskLayerUserData),
"Mask layer in layer tree; could not be recycled.");
if (layer->HasUserData(&gColorLayerUserData)) {
mRecycledColorLayers.AppendElement(static_cast<ColorLayer*>(layer));
} else if (layer->HasUserData(&gImageLayerUserData)) {
mRecycledImageLayers.AppendElement(static_cast<ImageLayer*>(layer));
} else if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
if (layer->HasUserData(&gThebesDisplayItemLayerUserData)) {
NS_ASSERTION(layer->AsThebesLayer(), "Wrong layer type");
mRecycledThebesLayers.AppendElement(static_cast<ThebesLayer*>(layer));
}