Bug 867770 - Layerize all animated images. r=mattwoodrow

This commit is contained in:
Joe Drew 2013-05-30 09:50:50 -04:00
parent 09a6269c24
commit ac3b24a51f
5 changed files with 66 additions and 38 deletions

View File

@ -4688,6 +4688,18 @@ nsImageRenderer::IsRasterImage()
return mImageContainer->GetType() == imgIContainer::TYPE_RASTER;
}
bool
nsImageRenderer::IsAnimatedImage()
{
if (mType != eStyleImageType_Image || !mImageContainer)
return false;
bool animated = false;
if (NS_SUCCEEDED(mImageContainer->GetAnimated(&animated)) && animated)
return true;
return false;
}
already_AddRefed<mozilla::layers::ImageContainer>
nsImageRenderer::GetContainer(LayerManager* aManager)
{

View File

@ -63,6 +63,7 @@ public:
const nsRect& aDirty);
bool IsRasterImage();
bool IsAnimatedImage();
already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager);
private:

View File

@ -1559,6 +1559,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
, mLayer(aLayer)
, mIsThemed(aIsThemed)
, mIsBottommostLayer(true)
, mIsAnimated(false)
{
MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
@ -1820,6 +1821,7 @@ nsDisplayBackgroundImage::TryOptimizeToImageLayer(LayerManager* aManager,
int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
mDestRect = nsLayoutUtils::RectToGfxRect(state.mDestArea, appUnitsPerDevPixel);
mImageContainer = imageContainer;
mIsAnimated = imageRenderer->IsAnimatedImage();
// Ok, we can turn this into a layer if needed.
return true;
@ -1843,31 +1845,35 @@ nsDisplayBackgroundImage::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const FrameLayerBuilder::ContainerParameters& aParameters)
{
if (!aManager->IsCompositingCheap() ||
!nsLayoutUtils::GPUImageScalingEnabled() ||
!TryOptimizeToImageLayer(aManager, aBuilder)) {
return LAYER_NONE;
if (!TryOptimizeToImageLayer(aManager, aBuilder) ||
!mIsAnimated) {
if (!aManager->IsCompositingCheap() ||
!nsLayoutUtils::GPUImageScalingEnabled()) {
return LAYER_NONE;
}
}
gfxSize imageSize = mImageContainer->GetCurrentSize();
NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!");
if (!mIsAnimated) {
gfxSize imageSize = mImageContainer->GetCurrentSize();
NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!");
gfxRect destRect = mDestRect;
gfxRect destRect = mDestRect;
destRect.width *= aParameters.mXScale;
destRect.height *= aParameters.mYScale;
destRect.width *= aParameters.mXScale;
destRect.height *= aParameters.mYScale;
// Calculate the scaling factor for the frame.
gfxSize scale = gfxSize(destRect.width / imageSize.width, destRect.height / imageSize.height);
// Calculate the scaling factor for the frame.
gfxSize scale = gfxSize(destRect.width / imageSize.width, destRect.height / imageSize.height);
// If we are not scaling at all, no point in separating this into a layer.
if (scale.width == 1.0f && scale.height == 1.0f) {
return LAYER_NONE;
}
// If we are not scaling at all, no point in separating this into a layer.
if (scale.width == 1.0f && scale.height == 1.0f) {
return LAYER_NONE;
}
// If the target size is pretty small, no point in using a layer.
if (destRect.width * destRect.height < 64 * 64) {
return LAYER_NONE;
// If the target size is pretty small, no point in using a layer.
if (destRect.width * destRect.height < 64 * 64) {
return LAYER_NONE;
}
}
return LAYER_ACTIVE;

View File

@ -2030,6 +2030,8 @@ protected:
bool mIsThemed;
/* true if this item represents the bottom-most background layer */
bool mIsBottommostLayer;
/* true if this image is known to be animated */
bool mIsAnimated;
};
class nsDisplayBackgroundColor : public nsDisplayItem

View File

@ -1258,35 +1258,42 @@ nsDisplayImage::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const FrameLayerBuilder::ContainerParameters& aParameters)
{
bool animated = false;
if (mImage->GetType() != imgIContainer::TYPE_RASTER ||
!aManager->IsCompositingCheap() ||
!nsLayoutUtils::GPUImageScalingEnabled()) {
return LAYER_NONE;
NS_FAILED(mImage->GetAnimated(&animated)) ||
!animated) {
if (!aManager->IsCompositingCheap() ||
!nsLayoutUtils::GPUImageScalingEnabled()) {
return LAYER_NONE;
}
}
int32_t imageWidth;
int32_t imageHeight;
mImage->GetWidth(&imageWidth);
mImage->GetHeight(&imageHeight);
if (!animated) {
int32_t imageWidth;
int32_t imageHeight;
mImage->GetWidth(&imageWidth);
mImage->GetHeight(&imageHeight);
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
gfxRect destRect = GetDestRect();
gfxRect destRect = GetDestRect();
destRect.width *= aParameters.mXScale;
destRect.height *= aParameters.mYScale;
destRect.width *= aParameters.mXScale;
destRect.height *= aParameters.mYScale;
// Calculate the scaling factor for the frame.
gfxSize scale = gfxSize(destRect.width / imageWidth, destRect.height / imageHeight);
// Calculate the scaling factor for the frame.
gfxSize scale = gfxSize(destRect.width / imageWidth,
destRect.height / imageHeight);
// If we are not scaling at all, no point in separating this into a layer.
if (scale.width == 1.0f && scale.height == 1.0f) {
return LAYER_NONE;
}
// If we are not scaling at all, no point in separating this into a layer.
if (scale.width == 1.0f && scale.height == 1.0f) {
return LAYER_NONE;
}
// If the target size is pretty small, no point in using a layer.
if (destRect.width * destRect.height < 64 * 64) {
return LAYER_NONE;
// If the target size is pretty small, no point in using a layer.
if (destRect.width * destRect.height < 64 * 64) {
return LAYER_NONE;
}
}
nsRefPtr<ImageContainer> container;