diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 967da7d48520..0ed30e2887fc 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -350,11 +350,17 @@ public: } /** - * If this represents only a nsDisplayImage, and the image type - * supports being optimized to an ImageLayer (TYPE_RASTER only) returns - * an ImageContainer for the image. + * If this represents only a nsDisplayImage, and the image type supports being + * optimized to an ImageLayer, returns true. */ - already_AddRefed CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder); + bool CanOptimizeToImageLayer(nsDisplayListBuilder* aBuilder); + + /** + * If this represents only a nsDisplayImage, and the image type supports being + * optimized to an ImageLayer, returns an ImageContainer for the underlying + * image if one is available. + */ + already_AddRefed GetContainerForImageLayer(nsDisplayListBuilder* aBuilder); bool VisibleAboveRegionIntersects(const nsIntRect& aRect) const { return mVisibleAboveRegion.Intersects(aRect); } @@ -1051,6 +1057,19 @@ protected: const nsIFrame* aReferenceFrame, const nsPoint& aTopLeft, bool aDidResetScrollPositionForLayerPixelAlignment); + + /** + * Attempt to prepare an ImageLayer based upon the provided PaintedLayerData. + * Returns nullptr on failure. + */ + already_AddRefed PrepareImageLayer(PaintedLayerData* aData); + + /** + * Attempt to prepare a ColorLayer based upon the provided PaintedLayerData. + * Returns nullptr on failure. + */ + already_AddRefed PrepareColorLayer(PaintedLayerData* aData); + /** * Grab the next recyclable ColorLayer, or create one if there are no * more recyclable ColorLayers. @@ -2352,8 +2371,18 @@ PaintedLayerData::UpdateCommonClipCount( } } +bool +PaintedLayerData::CanOptimizeToImageLayer(nsDisplayListBuilder* aBuilder) +{ + if (!mImage) { + return nullptr; + } + + return mImage->CanOptimizeToImageLayer(mLayer->Manager(), aBuilder); +} + already_AddRefed -PaintedLayerData::CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder) +PaintedLayerData::GetContainerForImageLayer(nsDisplayListBuilder* aBuilder) { if (!mImage) { return nullptr; @@ -2786,6 +2815,58 @@ static int32_t FindIndexOfLayerIn(nsTArray& aArray, } #endif +already_AddRefed +ContainerState::PrepareImageLayer(PaintedLayerData* aData) +{ + nsRefPtr imageContainer = + aData->GetContainerForImageLayer(mBuilder); + if (!imageContainer) { + return nullptr; + } + + nsRefPtr imageLayer = CreateOrRecycleImageLayer(aData->mLayer); + imageLayer->SetContainer(imageContainer); + aData->mImage->ConfigureLayer(imageLayer, mParameters); + imageLayer->SetPostScale(mParameters.mXScale, + mParameters.mYScale); + + if (aData->mItemClip.HasClip()) { + ParentLayerIntRect clip = + ViewAs(ScaleToNearestPixels(aData->mItemClip.GetClipRect())); + clip.MoveBy(ViewAs(mParameters.mOffset)); + imageLayer->SetClipRect(Some(clip)); + } else { + imageLayer->SetClipRect(Nothing()); + } + + mLayerBuilder->StoreOptimizedLayerForFrame(aData->mImage, imageLayer); + FLB_LOG_PAINTED_LAYER_DECISION(aData, + " Selected image layer=%p\n", imageLayer.get()); + + return imageLayer.forget(); +} + +already_AddRefed +ContainerState::PrepareColorLayer(PaintedLayerData* aData) +{ + nsRefPtr colorLayer = CreateOrRecycleColorLayer(aData->mLayer); + colorLayer->SetColor(aData->mSolidColor); + + // Copy transform + colorLayer->SetBaseTransform(aData->mLayer->GetBaseTransform()); + colorLayer->SetPostScale(aData->mLayer->GetPostXScale(), + aData->mLayer->GetPostYScale()); + + nsIntRect visibleRect = aData->mVisibleRegion.GetBounds(); + visibleRect.MoveBy(-GetTranslationForPaintedLayer(aData->mLayer)); + colorLayer->SetBounds(visibleRect); + colorLayer->SetClipRect(Nothing()); + + FLB_LOG_PAINTED_LAYER_DECISION(aData, + " Selected color layer=%p\n", colorLayer.get()); + + return colorLayer.forget(); +} template void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueBackgroundColorCallbackType aFindOpaqueBackgroundColor) @@ -2814,72 +2895,46 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB NewLayerEntry* newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex]; nsRefPtr layer; - nsRefPtr imageContainer = data->CanOptimizeImageLayer(mBuilder); + bool canOptimizeToImageLayer = data->CanOptimizeToImageLayer(mBuilder); FLB_LOG_PAINTED_LAYER_DECISION(data, "Selecting layer for pld=%p\n", data); - FLB_LOG_PAINTED_LAYER_DECISION(data, " Solid=%i, hasImage=%i, canOptimizeAwayPaintedLayer=%i\n", - data->mIsSolidColorInVisibleRegion, !!imageContainer, + FLB_LOG_PAINTED_LAYER_DECISION(data, " Solid=%i, hasImage=%c, canOptimizeAwayPaintedLayer=%i\n", + data->mIsSolidColorInVisibleRegion, canOptimizeToImageLayer ? 'y' : 'n', CanOptimizeAwayPaintedLayer(data, mLayerBuilder)); - if ((data->mIsSolidColorInVisibleRegion || imageContainer) && + if ((data->mIsSolidColorInVisibleRegion || canOptimizeToImageLayer) && CanOptimizeAwayPaintedLayer(data, mLayerBuilder)) { - NS_ASSERTION(!(data->mIsSolidColorInVisibleRegion && imageContainer), + NS_ASSERTION(!(data->mIsSolidColorInVisibleRegion && canOptimizeToImageLayer), "Can't be a solid color as well as an image!"); - if (imageContainer) { - nsRefPtr imageLayer = CreateOrRecycleImageLayer(data->mLayer); - imageLayer->SetContainer(imageContainer); - data->mImage->ConfigureLayer(imageLayer, mParameters); - imageLayer->SetPostScale(mParameters.mXScale, - mParameters.mYScale); - if (data->mItemClip.HasClip()) { - ParentLayerIntRect clip = ViewAs(ScaleToNearestPixels(data->mItemClip.GetClipRect())); - clip.MoveBy(ViewAs(mParameters.mOffset)); - imageLayer->SetClipRect(Some(clip)); - } else { - imageLayer->SetClipRect(Nothing()); - } - layer = imageLayer; - mLayerBuilder->StoreOptimizedLayerForFrame(data->mImage, - imageLayer); - FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected image layer=%p\n", layer.get()); - } else { - nsRefPtr colorLayer = CreateOrRecycleColorLayer(data->mLayer); - colorLayer->SetColor(data->mSolidColor); - // Copy transform - colorLayer->SetBaseTransform(data->mLayer->GetBaseTransform()); - colorLayer->SetPostScale(data->mLayer->GetPostXScale(), data->mLayer->GetPostYScale()); + layer = canOptimizeToImageLayer ? PrepareImageLayer(data) + : PrepareColorLayer(data); - nsIntRect visibleRect = data->mVisibleRegion.GetBounds(); - visibleRect.MoveBy(-GetTranslationForPaintedLayer(data->mLayer)); - colorLayer->SetBounds(visibleRect); - colorLayer->SetClipRect(Nothing()); + if (layer) { + NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, layer) < 0, + "Layer already in list???"); + NS_ASSERTION(newLayerEntry->mLayer == data->mLayer, + "Painted layer at wrong index"); + // Store optimized layer in reserved slot + newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex + 1]; + NS_ASSERTION(!newLayerEntry->mLayer, "Slot already occupied?"); + newLayerEntry->mLayer = layer; + newLayerEntry->mAnimatedGeometryRoot = data->mAnimatedGeometryRoot; + newLayerEntry->mFixedPosFrameForLayerData = data->mFixedPosFrameForLayerData; - layer = colorLayer; - FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected color layer=%p\n", layer.get()); + // Hide the PaintedLayer. We leave it in the layer tree so that we + // can find and recycle it later. + ParentLayerIntRect emptyRect; + data->mLayer->SetClipRect(Some(emptyRect)); + data->mLayer->SetVisibleRegion(nsIntRegion()); + data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion().GetBounds()); + data->mLayer->SetEventRegions(EventRegions()); } - - NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, layer) < 0, - "Layer already in list???"); - NS_ASSERTION(newLayerEntry->mLayer == data->mLayer, - "Painted layer at wrong index"); - // Store optimized layer in reserved slot - newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex + 1]; - NS_ASSERTION(!newLayerEntry->mLayer, "Slot already occupied?"); - newLayerEntry->mLayer = layer; - newLayerEntry->mAnimatedGeometryRoot = data->mAnimatedGeometryRoot; - newLayerEntry->mFixedPosFrameForLayerData = data->mFixedPosFrameForLayerData; - - // Hide the PaintedLayer. We leave it in the layer tree so that we - // can find and recycle it later. - ParentLayerIntRect emptyRect; - data->mLayer->SetClipRect(Some(emptyRect)); - data->mLayer->SetVisibleRegion(nsIntRegion()); - data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion().GetBounds()); - data->mLayer->SetEventRegions(EventRegions()); - } else { + } + + if (!layer) { + // We couldn't optimize to an image layer or a color layer above. layer = data->mLayer; - imageContainer = nullptr; layer->SetClipRect(Nothing()); FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected painted layer=%p\n", layer.get()); } diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 35edff69d280..be81cfba9288 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -5193,14 +5193,30 @@ nsImageRenderer::IsAnimatedImage() return false; } -already_AddRefed -nsImageRenderer::GetContainer(LayerManager* aManager) +bool +nsImageRenderer::IsContainerAvailable(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) +{ + if (mType != eStyleImageType_Image || !mImageContainer) { + return false; + } + + uint32_t flags = aBuilder->ShouldSyncDecodeImages() + ? imgIContainer::FLAG_SYNC_DECODE + : imgIContainer::FLAG_NONE; + + return mImageContainer->IsImageContainerAvailable(aManager, flags); +} + +already_AddRefed +nsImageRenderer::GetImage() { if (mType != eStyleImageType_Image || !mImageContainer) { return nullptr; } - return mImageContainer->GetImageContainer(aManager, imgIContainer::FLAG_NONE); + nsCOMPtr image = mImageContainer; + return image.forget(); } #define MAX_BLUR_RADIUS 300 diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index aa3b6acce863..d6dfc38ae81d 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -237,7 +237,19 @@ public: bool IsRasterImage(); bool IsAnimatedImage(); - already_AddRefed GetContainer(LayerManager* aManager); + + /** + * @return true if this nsImageRenderer wraps an image which has an + * ImageContainer available. + * + * If IsContainerAvailable() returns true, GetImage() will return a non-null + * imgIContainer which callers can use to retrieve the ImageContainer. + */ + bool IsContainerAvailable(LayerManager* aManager, + nsDisplayListBuilder* aBuilder); + + /// Retrieves the image associated with this nsImageRenderer, if there is one. + already_AddRefed GetImage(); bool IsReady() { return mIsReady; } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 502dc559e88a..084a3fdfd82a 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2296,11 +2296,12 @@ nsDisplayBackgroundImage::ShouldFixToViewport(LayerManager* aManager) } bool -nsDisplayBackgroundImage::TryOptimizeToImageLayer(LayerManager* aManager, +nsDisplayBackgroundImage::CanOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder) { - if (!mBackgroundStyle) + if (!mBackgroundStyle) { return false; + } nsPresContext* presContext = mFrame->PresContext(); uint32_t flags = aBuilder->GetBackgroundPaintFlags(); @@ -2320,13 +2321,14 @@ nsDisplayBackgroundImage::TryOptimizeToImageLayer(LayerManager* aManager, borderArea, borderArea, layer); nsImageRenderer* imageRenderer = &state.mImageRenderer; // We only care about images here, not gradients. - if (!imageRenderer->IsRasterImage()) + if (!imageRenderer->IsRasterImage()) { return false; + } - nsRefPtr imageContainer = imageRenderer->GetContainer(aManager); - // Image is not ready to be made into a layer yet - if (!imageContainer) + if (!imageRenderer->IsContainerAvailable(aManager, aBuilder)) { + // The image is not ready to be made into a layer yet. return false; + } // We currently can't handle tiled or partial backgrounds. if (!state.mDestArea.IsEqualEdges(state.mFillArea)) { @@ -2339,9 +2341,11 @@ nsDisplayBackgroundImage::TryOptimizeToImageLayer(LayerManager* aManager, int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); mDestRect = LayoutDeviceRect::FromAppUnits(state.mDestArea, appUnitsPerDevPixel); - mImageContainer = imageContainer; // Ok, we can turn this into a layer if needed. + mImage = imageRenderer->GetImage(); + MOZ_ASSERT(mImage); + return true; } @@ -2349,12 +2353,23 @@ already_AddRefed nsDisplayBackgroundImage::GetContainer(LayerManager* aManager, nsDisplayListBuilder *aBuilder) { - if (!TryOptimizeToImageLayer(aManager, aBuilder)) { + if (!mImage) { + MOZ_ASSERT_UNREACHABLE("Must call CanOptimizeToImage() and get true " + "before calling GetContainer()"); return nullptr; } - nsRefPtr container = mImageContainer; + if (!mImageContainer) { + // We don't have an ImageContainer yet; get it from mImage. + uint32_t flags = aBuilder->ShouldSyncDecodeImages() + ? imgIContainer::FLAG_SYNC_DECODE + : imgIContainer::FLAG_NONE; + + mImageContainer = mImage->GetImageContainer(aManager, flags); + } + + nsRefPtr container = mImageContainer; return container.forget(); } @@ -2386,19 +2401,24 @@ nsDisplayBackgroundImage::GetLayerState(nsDisplayListBuilder* aBuilder, } } - if (!TryOptimizeToImageLayer(aManager, aBuilder)) { + if (!CanOptimizeToImageLayer(aManager, aBuilder)) { return LAYER_NONE; } + MOZ_ASSERT(mImage); + if (!animated) { - mozilla::gfx::IntSize imageSize = mImageContainer->GetCurrentSize(); - NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!"); + int32_t imageWidth; + int32_t imageHeight; + mImage->GetWidth(&imageWidth); + mImage->GetHeight(&imageHeight); + NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!"); const LayerRect destLayerRect = mDestRect * aParameters.Scale(); // Calculate the scaling factor for the frame. - const gfxSize scale = gfxSize(destLayerRect.width / imageSize.width, - destLayerRect.height / imageSize.height); + const gfxSize scale = gfxSize(destLayerRect.width / imageWidth, + destLayerRect.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) { @@ -2426,7 +2446,8 @@ nsDisplayBackgroundImage::BuildLayer(nsDisplayListBuilder* aBuilder, if (!layer) return nullptr; } - layer->SetContainer(mImageContainer); + nsRefPtr imageContainer = GetContainer(aManager, aBuilder); + layer->SetContainer(imageContainer); ConfigureLayer(layer, aParameters); return layer.forget(); } @@ -2437,9 +2458,14 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer, { aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame)); - mozilla::gfx::IntSize imageSize = mImageContainer->GetCurrentSize(); - NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!"); - if (imageSize.width > 0 && imageSize.height > 0) { + MOZ_ASSERT(mImage); + int32_t imageWidth; + int32_t imageHeight; + mImage->GetWidth(&imageWidth); + mImage->GetHeight(&imageHeight); + NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!"); + + if (imageWidth > 0 && imageHeight > 0) { // We're actually using the ImageContainer. Let our frame know that it // should consider itself to have painted successfully. nsDisplayBackgroundGeometry::UpdateDrawResult(this, DrawResult::SUCCESS); @@ -2453,8 +2479,8 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer, const LayoutDevicePoint p = mDestRect.TopLeft(); Matrix transform = Matrix::Translation(p.x, p.y); - transform.PreScale(mDestRect.width / imageSize.width, - mDestRect.height / imageSize.height); + transform.PreScale(mDestRect.width / imageWidth, + mDestRect.height / imageHeight); aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform)); } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 998e01a7f047..4a678edc5665 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1988,6 +1988,14 @@ public: : nsDisplayItem(aBuilder, aFrame) {} + /** + * @return true if this display item can be optimized into an image layer. + * It is an error to call GetContainer() unless you've called + * CanOptimizeToImageLayer() first and it returned true. + */ + virtual bool CanOptimizeToImageLayer(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) = 0; + virtual already_AddRefed GetContainer(LayerManager* aManager, nsDisplayListBuilder* aBuilder) = 0; virtual void ConfigureLayer(ImageLayer* aLayer, @@ -2336,6 +2344,8 @@ public: const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) override; + virtual bool CanOptimizeToImageLayer(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) override; virtual already_AddRefed GetContainer(LayerManager* aManager, nsDisplayListBuilder *aBuilder) override; virtual void ConfigureLayer(ImageLayer* aLayer, @@ -2362,7 +2372,7 @@ protected: // Cache the result of nsCSSRendering::FindBackground. Always null if // mIsThemed is true or if FindBackground returned false. const nsStyleBackground* mBackgroundStyle; - /* If this background can be a simple image layer, we store the format here. */ + nsCOMPtr mImage; nsRefPtr mImageContainer; LayoutDeviceRect mDestRect; /* Bounds of this display item */ diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index a13ec91ba7c7..1203da52b522 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1415,6 +1415,17 @@ nsDisplayImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); } +bool +nsDisplayImage::CanOptimizeToImageLayer(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) +{ + uint32_t flags = aBuilder->ShouldSyncDecodeImages() + ? imgIContainer::FLAG_SYNC_DECODE + : imgIContainer::FLAG_NONE; + + return mImage->IsImageContainerAvailable(aManager, flags); +} + already_AddRefed nsDisplayImage::GetContainer(LayerManager* aManager, nsDisplayListBuilder* aBuilder) @@ -1503,9 +1514,7 @@ nsDisplayImage::GetLayerState(nsDisplayListBuilder* aBuilder, ? imgIContainer::FLAG_SYNC_DECODE : imgIContainer::FLAG_NONE; - nsRefPtr container = - mImage->GetImageContainer(aManager, flags); - if (!container) { + if (!mImage->IsImageContainerAvailable(aManager, flags)) { return LAYER_NONE; } diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index 59a824414825..5ba27bd65c7d 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -394,6 +394,9 @@ public: virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override; + virtual bool CanOptimizeToImageLayer(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) override; + /** * Returns an ImageContainer for this image if the image type * supports it (TYPE_RASTER only). diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index 6eda612931ad..bac3bee8b9ea 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -437,6 +437,36 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform)); } +bool +nsDisplayXULImage::CanOptimizeToImageLayer(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) +{ + uint32_t flags = aBuilder->ShouldSyncDecodeImages() + ? imgIContainer::FLAG_SYNC_DECODE + : imgIContainer::FLAG_NONE; + + return static_cast(mFrame) + ->IsImageContainerAvailable(aManager, flags); +} + +bool +nsImageBoxFrame::IsImageContainerAvailable(LayerManager* aManager, + uint32_t aFlags) +{ + bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0); + if (hasSubRect || !mImageRequest) { + return false; + } + + nsCOMPtr imgCon; + mImageRequest->GetImage(getter_AddRefs(imgCon)); + if (!imgCon) { + return false; + } + + return imgCon->IsImageContainerAvailable(aManager, aFlags); +} + already_AddRefed nsDisplayXULImage::GetContainer(LayerManager* aManager, nsDisplayListBuilder* aBuilder) @@ -451,17 +481,23 @@ nsDisplayXULImage::GetContainer(LayerManager* aManager, already_AddRefed nsImageBoxFrame::GetContainer(LayerManager* aManager, uint32_t aFlags) { - bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0); - if (hasSubRect || !mImageRequest) { + MOZ_ASSERT(IsImageContainerAvailable(aManager, aFlags), + "Should call IsImageContainerAvailable and get true before " + "calling GetContainer"); + if (!mImageRequest) { + MOZ_ASSERT_UNREACHABLE("mImageRequest should be available if " + "IsImageContainerAvailable returned true"); return nullptr; } nsCOMPtr imgCon; mImageRequest->GetImage(getter_AddRefs(imgCon)); if (!imgCon) { + MOZ_ASSERT_UNREACHABLE("An imgIContainer should be available if " + "IsImageContainerAvailable returned true"); return nullptr; } - + return imgCon->GetImageContainer(aManager, aFlags); } diff --git a/layout/xul/nsImageBoxFrame.h b/layout/xul/nsImageBoxFrame.h index 11ca301b61e1..3d9c1ad75f42 100644 --- a/layout/xul/nsImageBoxFrame.h +++ b/layout/xul/nsImageBoxFrame.h @@ -96,6 +96,7 @@ public: const nsRect& aDirtyRect, nsPoint aPt, uint32_t aFlags); + bool IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags); already_AddRefed GetContainer(LayerManager* aManager, uint32_t aFlags); @@ -142,6 +143,8 @@ public: } #endif + virtual bool CanOptimizeToImageLayer(LayerManager* aManager, + nsDisplayListBuilder* aBuilder) override; virtual already_AddRefed GetContainer(LayerManager* aManager, nsDisplayListBuilder* aBuilder) override; virtual void ConfigureLayer(ImageLayer* aLayer,