mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1163878 (Part 2) - Use IsImageContainerAvailable() when making layerization decisions and only call GetImageContainer() if we layerize. r=tn
This commit is contained in:
parent
23ee589538
commit
f8b4b72216
@ -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<ImageContainer> 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<ImageContainer> 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<Layer> PrepareImageLayer(PaintedLayerData* aData);
|
||||
|
||||
/**
|
||||
* Attempt to prepare a ColorLayer based upon the provided PaintedLayerData.
|
||||
* Returns nullptr on failure.
|
||||
*/
|
||||
already_AddRefed<Layer> 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<ImageContainer>
|
||||
PaintedLayerData::CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder)
|
||||
PaintedLayerData::GetContainerForImageLayer(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
if (!mImage) {
|
||||
return nullptr;
|
||||
@ -2786,6 +2815,58 @@ static int32_t FindIndexOfLayerIn(nsTArray<NewLayerEntry>& aArray,
|
||||
}
|
||||
#endif
|
||||
|
||||
already_AddRefed<Layer>
|
||||
ContainerState::PrepareImageLayer(PaintedLayerData* aData)
|
||||
{
|
||||
nsRefPtr<ImageContainer> imageContainer =
|
||||
aData->GetContainerForImageLayer(mBuilder);
|
||||
if (!imageContainer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<ImageLayer> 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<ParentLayerPixel>(ScaleToNearestPixels(aData->mItemClip.GetClipRect()));
|
||||
clip.MoveBy(ViewAs<ParentLayerPixel>(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<Layer>
|
||||
ContainerState::PrepareColorLayer(PaintedLayerData* aData)
|
||||
{
|
||||
nsRefPtr<ColorLayer> 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<typename FindOpaqueBackgroundColorCallbackType>
|
||||
void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueBackgroundColorCallbackType aFindOpaqueBackgroundColor)
|
||||
@ -2814,72 +2895,46 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
||||
NewLayerEntry* newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex];
|
||||
|
||||
nsRefPtr<Layer> layer;
|
||||
nsRefPtr<ImageContainer> 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> 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<ParentLayerPixel>(ScaleToNearestPixels(data->mItemClip.GetClipRect()));
|
||||
clip.MoveBy(ViewAs<ParentLayerPixel>(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> 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());
|
||||
}
|
||||
|
@ -5193,14 +5193,30 @@ nsImageRenderer::IsAnimatedImage()
|
||||
return false;
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::layers::ImageContainer>
|
||||
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<imgIContainer>
|
||||
nsImageRenderer::GetImage()
|
||||
{
|
||||
if (mType != eStyleImageType_Image || !mImageContainer) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mImageContainer->GetImageContainer(aManager, imgIContainer::FLAG_NONE);
|
||||
nsCOMPtr<imgIContainer> image = mImageContainer;
|
||||
return image.forget();
|
||||
}
|
||||
|
||||
#define MAX_BLUR_RADIUS 300
|
||||
|
@ -237,7 +237,19 @@ public:
|
||||
|
||||
bool IsRasterImage();
|
||||
bool IsAnimatedImage();
|
||||
already_AddRefed<ImageContainer> 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<imgIContainer> GetImage();
|
||||
|
||||
bool IsReady() { return mIsReady; }
|
||||
|
||||
|
@ -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> 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<ImageContainer>
|
||||
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<ImageContainer> 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<ImageContainer> 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> 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));
|
||||
}
|
||||
|
||||
|
@ -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<ImageContainer> 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<ImageContainer> 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<imgIContainer> mImage;
|
||||
nsRefPtr<ImageContainer> mImageContainer;
|
||||
LayoutDeviceRect mDestRect;
|
||||
/* Bounds of this display item */
|
||||
|
@ -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<ImageContainer>
|
||||
nsDisplayImage::GetContainer(LayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder)
|
||||
@ -1503,9 +1514,7 @@ nsDisplayImage::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
? imgIContainer::FLAG_SYNC_DECODE
|
||||
: imgIContainer::FLAG_NONE;
|
||||
|
||||
nsRefPtr<ImageContainer> container =
|
||||
mImage->GetImageContainer(aManager, flags);
|
||||
if (!container) {
|
||||
if (!mImage->IsImageContainerAvailable(aManager, flags)) {
|
||||
return LAYER_NONE;
|
||||
}
|
||||
|
||||
|
@ -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).
|
||||
|
@ -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<nsImageBoxFrame*>(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<imgIContainer> imgCon;
|
||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||
if (!imgCon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return imgCon->IsImageContainerAvailable(aManager, aFlags);
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer>
|
||||
nsDisplayXULImage::GetContainer(LayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder)
|
||||
@ -451,17 +481,23 @@ nsDisplayXULImage::GetContainer(LayerManager* aManager,
|
||||
already_AddRefed<ImageContainer>
|
||||
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<imgIContainer> 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);
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
const nsRect& aDirtyRect,
|
||||
nsPoint aPt, uint32_t aFlags);
|
||||
|
||||
bool IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags);
|
||||
already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
||||
uint32_t aFlags);
|
||||
|
||||
@ -142,6 +143,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) override;
|
||||
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) override;
|
||||
virtual void ConfigureLayer(ImageLayer* aLayer,
|
||||
|
Loading…
Reference in New Issue
Block a user