Bug 811927 - Allow conversion of nsDisplayBackgroundImage into ImageLayers. r=roc

This commit is contained in:
Matt Woodrow 2012-11-19 16:28:18 +13:00
parent 2a1f87cb39
commit 5dc466f953
8 changed files with 54 additions and 32 deletions

View File

@ -368,7 +368,7 @@ protected:
* supports being optimized to an ImageLayer (TYPE_RASTER only) returns
* an ImageContainer for the image.
*/
already_AddRefed<ImageContainer> CanOptimizeImageLayer();
already_AddRefed<ImageContainer> CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder);
/**
* The region of visible content in the layer, relative to the
@ -1525,13 +1525,13 @@ ContainerState::ThebesLayerData::UpdateCommonClipCount(
}
already_AddRefed<ImageContainer>
ContainerState::ThebesLayerData::CanOptimizeImageLayer()
ContainerState::ThebesLayerData::CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder)
{
if (!mImage) {
return nullptr;
}
return mImage->GetContainer();
return mImage->GetContainer(aBuilder);
}
void
@ -1543,7 +1543,7 @@ ContainerState::PopThebesLayerData()
ThebesLayerData* data = mThebesLayerDataStack[lastIndex];
nsRefPtr<Layer> layer;
nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer();
nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer(mBuilder);
if ((data->mIsSolidColorInVisibleRegion || imageContainer) &&
data->mLayer->GetValidRegion().IsEmpty()) {
@ -1735,8 +1735,7 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState,
* we are the first visible item in the ThebesLayerData object.
*/
if (mVisibleRegion.IsEmpty() &&
(aItem->GetType() == nsDisplayItem::TYPE_IMAGE ||
aItem->GetType() == nsDisplayItem::TYPE_XUL_IMAGE)) {
aItem->SupportsOptimizingToImage()) {
mImage = static_cast<nsDisplayImageContainer*>(aItem);
} else {
mImage = nullptr;

View File

@ -1470,7 +1470,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
uint32_t aLayer,
bool aIsThemed,
const nsStyleBackground* aBackgroundStyle)
: nsDisplayItem(aBuilder, aFrame)
: nsDisplayImageContainer(aBuilder, aFrame)
, mBackgroundStyle(aBackgroundStyle)
, mLayer(aLayer)
, mIsThemed(aIsThemed)
@ -1711,7 +1711,7 @@ nsDisplayBackgroundImage::TryOptimizeToImageLayer(nsDisplayListBuilder* aBuilder
nsImageRenderer* imageRenderer = &state.mImageRenderer;
// We only care about images here, not gradients.
if (imageRenderer->IsRasterImage())
if (!imageRenderer->IsRasterImage())
return false;
nsRefPtr<ImageContainer> imageContainer = imageRenderer->GetContainer();
@ -1737,6 +1737,18 @@ nsDisplayBackgroundImage::TryOptimizeToImageLayer(nsDisplayListBuilder* aBuilder
return true;
}
already_AddRefed<ImageContainer>
nsDisplayBackgroundImage::GetContainer(nsDisplayListBuilder *aBuilder)
{
if (!TryOptimizeToImageLayer(aBuilder)) {
return nullptr;
}
nsRefPtr<ImageContainer> container = mImageContainer;
return container.forget();
}
LayerState
nsDisplayBackgroundImage::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@ -1779,12 +1791,12 @@ nsDisplayBackgroundImage::BuildLayer(nsDisplayListBuilder* aBuilder,
{
nsRefPtr<ImageLayer> layer = aManager->CreateImageLayer();
layer->SetContainer(mImageContainer);
ConfigureLayer(layer);
ConfigureLayer(layer, aParameters.mOffset);
return layer.forget();
}
void
nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer)
nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset)
{
aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
@ -1792,7 +1804,7 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer)
NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!");
gfxMatrix transform;
transform.Translate(mDestRect.TopLeft());
transform.Translate(mDestRect.TopLeft() + aOffset);
transform.Scale(mDestRect.width/imageSize.width,
mDestRect.height/imageSize.height);
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));

View File

@ -1087,6 +1087,8 @@ public:
virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
return false;
}
virtual bool SupportsOptimizingToImage() { return false; }
protected:
friend class nsDisplayList;
@ -1539,6 +1541,22 @@ private:
nsDisplayList mLists[6];
};
class nsDisplayImageContainer : public nsDisplayItem {
public:
typedef mozilla::layers::ImageContainer ImageContainer;
typedef mozilla::layers::ImageLayer ImageLayer;
nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
{}
virtual already_AddRefed<ImageContainer> GetContainer(nsDisplayListBuilder* aBuilder) = 0;
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0;
virtual bool SupportsOptimizingToImage() { return true; }
};
/**
* Use this class to implement not-very-frequently-used display items
* that are not opaque, do not receive events, and are bounded by a frame's
@ -1785,7 +1803,7 @@ private:
* A display item to paint one background-image for a frame. Each background
* image layer gets its own nsDisplayBackgroundImage.
*/
class nsDisplayBackgroundImage : public nsDisplayItem {
class nsDisplayBackgroundImage : public nsDisplayImageContainer {
public:
/**
* aLayer signifies which background layer this item represents.
@ -1850,14 +1868,17 @@ public:
*/
bool RenderingMightDependOnPositioningAreaSizeChange();
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
{
return new nsDisplayBackgroundGeometry(this, aBuilder);
}
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion);
nsRegion* aInvalidRegion) MOZ_OVERRIDE;
virtual already_AddRefed<ImageContainer> GetContainer(nsDisplayListBuilder *aBuilder) MOZ_OVERRIDE;
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip,
const nsRect& aRect, bool* aSnap);
@ -1869,7 +1890,6 @@ protected:
bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
const nsRect& aClipRect,
gfxRect* aDestRect);
void ConfigureLayer(ImageLayer* aLayer);
// Cache the result of nsCSSRendering::FindBackground. Always null if
// mIsThemed is true or if FindBackground returned false.
@ -2865,17 +2885,4 @@ public:
nscoord mRightEdge; // length from the right side
};
class nsDisplayImageContainer : public nsDisplayItem {
public:
typedef mozilla::layers::ImageContainer ImageContainer;
typedef mozilla::layers::ImageLayer ImageLayer;
nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
{}
virtual already_AddRefed<ImageContainer> GetContainer() = 0;
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0;
};
#endif /*NSDISPLAYLIST_H_*/

View File

@ -184,6 +184,10 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) MOZ_OVERRIDE;
// We still need to paint a background color as well as an image for this item,
// so we can't support this yet.
virtual bool SupportsOptimizingToImage() { return false; }
void SetExtraBackgroundColor(nscolor aColor)
{

View File

@ -1229,7 +1229,7 @@ nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder,
}
already_AddRefed<ImageContainer>
nsDisplayImage::GetContainer()
nsDisplayImage::GetContainer(nsDisplayListBuilder* aBuilder)
{
nsRefPtr<ImageContainer> container;
nsresult rv = mImage->GetImageContainer(getter_AddRefs(container));

View File

@ -370,7 +370,7 @@ public:
* Returns an ImageContainer for this image if the image type
* supports it (TYPE_RASTER only).
*/
virtual already_AddRefed<ImageContainer> GetContainer() MOZ_OVERRIDE;
virtual already_AddRefed<ImageContainer> GetContainer(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
gfxRect GetDestRect();

View File

@ -388,7 +388,7 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset)
}
already_AddRefed<ImageContainer>
nsDisplayXULImage::GetContainer()
nsDisplayXULImage::GetContainer(nsDisplayListBuilder* aBuilder)
{
return static_cast<nsImageBoxFrame*>(mFrame)->GetContainer();
}

View File

@ -130,7 +130,7 @@ public:
}
#endif
virtual already_AddRefed<ImageContainer> GetContainer() MOZ_OVERRIDE;
virtual already_AddRefed<ImageContainer> GetContainer(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{