зеркало из https://github.com/mozilla/gecko-dev.git
Bug 852754 - Part 1: Share the code for limiting scale factors to all image types. r=mstange
This commit is contained in:
Родитель
8232d31724
Коммит
46ff4c4fc7
|
@ -5404,21 +5404,6 @@ nsImageRenderer::IsAnimatedImage()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
already_AddRefed<imgIContainer>
|
||||||
nsImageRenderer::GetImage()
|
nsImageRenderer::GetImage()
|
||||||
{
|
{
|
||||||
|
|
|
@ -251,16 +251,6 @@ public:
|
||||||
bool IsRasterImage();
|
bool IsRasterImage();
|
||||||
bool IsAnimatedImage();
|
bool IsAnimatedImage();
|
||||||
|
|
||||||
/**
|
|
||||||
* @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.
|
/// Retrieves the image associated with this nsImageRenderer, if there is one.
|
||||||
already_AddRefed<imgIContainer> GetImage();
|
already_AddRefed<imgIContainer> GetImage();
|
||||||
|
|
||||||
|
|
|
@ -2309,32 +2309,33 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
|
||||||
: nsDisplayImageContainer(aBuilder, aFrame)
|
: nsDisplayImageContainer(aBuilder, aFrame)
|
||||||
, mBackgroundStyle(aBackgroundStyle)
|
, mBackgroundStyle(aBackgroundStyle)
|
||||||
, mLayer(aLayer)
|
, mLayer(aLayer)
|
||||||
|
, mIsRasterImage(false)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
|
MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
|
||||||
|
|
||||||
mBounds = GetBoundsInternal(aBuilder);
|
mBounds = GetBoundsInternal(aBuilder);
|
||||||
mDestArea = GetDestAreaInternal(aBuilder);
|
|
||||||
if (ShouldFixToViewport(aBuilder)) {
|
if (ShouldFixToViewport(aBuilder)) {
|
||||||
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
|
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nsRect
|
|
||||||
nsDisplayBackgroundImage::GetDestAreaInternal(nsDisplayListBuilder* aBuilder)
|
|
||||||
{
|
|
||||||
if (!mBackgroundStyle) {
|
|
||||||
return nsRect();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsPresContext* presContext = mFrame->PresContext();
|
nsPresContext* presContext = mFrame->PresContext();
|
||||||
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
||||||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||||
const nsStyleImageLayers::Layer& layer = mBackgroundStyle->mImage.mLayers[mLayer];
|
const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mImage.mLayers[mLayer];
|
||||||
|
|
||||||
nsBackgroundLayerState state =
|
nsBackgroundLayerState state =
|
||||||
nsCSSRendering::PrepareImageLayer(presContext, mFrame, flags,
|
nsCSSRendering::PrepareImageLayer(presContext, mFrame, flags,
|
||||||
borderArea, borderArea, layer);
|
borderArea, borderArea, layer);
|
||||||
return state.mDestArea;
|
|
||||||
|
mFillRect = state.mFillArea;
|
||||||
|
mDestRect = state.mDestArea;
|
||||||
|
|
||||||
|
nsImageRenderer* imageRenderer = &state.mImageRenderer;
|
||||||
|
// We only care about images here, not gradients.
|
||||||
|
if (imageRenderer->IsRasterImage()) {
|
||||||
|
mIsRasterImage = true;
|
||||||
|
mImage = imageRenderer->GetImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
|
nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
|
||||||
|
@ -2566,24 +2567,16 @@ nsDisplayBackgroundImage::IsSingleFixedPositionImage(nsDisplayListBuilder* aBuil
|
||||||
if (mBackgroundStyle->mImage.mLayers.Length() != 1)
|
if (mBackgroundStyle->mImage.mLayers.Length() != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nsPresContext* presContext = mFrame->PresContext();
|
|
||||||
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
|
||||||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
|
||||||
const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mImage.mLayers[mLayer];
|
const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mImage.mLayers[mLayer];
|
||||||
|
|
||||||
if (layer.mAttachment != NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED)
|
if (layer.mAttachment != NS_STYLE_IMAGELAYER_ATTACHMENT_FIXED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nsBackgroundLayerState state =
|
|
||||||
nsCSSRendering::PrepareImageLayer(presContext, mFrame, flags,
|
|
||||||
borderArea, aClipRect, layer);
|
|
||||||
nsImageRenderer* imageRenderer = &state.mImageRenderer;
|
|
||||||
// We only care about images here, not gradients.
|
// We only care about images here, not gradients.
|
||||||
if (!imageRenderer->IsRasterImage())
|
if (!mIsRasterImage)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
*aDestRect = nsLayoutUtils::RectToGfxRect(state.mFillArea, appUnitsPerDevPixel);
|
*aDestRect = nsLayoutUtils::RectToGfxRect(mFillRect, appUnitsPerDevPixel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2618,51 +2611,35 @@ nsDisplayBackgroundImage::CanOptimizeToImageLayer(LayerManager* aManager,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPresContext* presContext = mFrame->PresContext();
|
|
||||||
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
|
||||||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
|
||||||
const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mImage.mLayers[mLayer];
|
|
||||||
|
|
||||||
nsBackgroundLayerState state =
|
|
||||||
nsCSSRendering::PrepareImageLayer(presContext, mFrame, flags,
|
|
||||||
borderArea, borderArea, layer);
|
|
||||||
nsImageRenderer* imageRenderer = &state.mImageRenderer;
|
|
||||||
// We only care about images here, not gradients.
|
|
||||||
if (!imageRenderer->IsRasterImage()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 backgrounds.
|
// We currently can't handle tiled backgrounds.
|
||||||
if (!state.mDestArea.Contains(state.mFillArea)) {
|
if (!mDestRect.Contains(mFillRect)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For 'contain' and 'cover', we allow any pixel of the image to be sampled
|
// For 'contain' and 'cover', we allow any pixel of the image to be sampled
|
||||||
// because there isn't going to be any spriting/atlasing going on.
|
// because there isn't going to be any spriting/atlasing going on.
|
||||||
|
const nsStyleImageLayers::Layer &layer = mBackgroundStyle->mImage.mLayers[mLayer];
|
||||||
bool allowPartialImages =
|
bool allowPartialImages =
|
||||||
(layer.mSize.mWidthType == nsStyleImageLayers::Size::eContain ||
|
(layer.mSize.mWidthType == nsStyleImageLayers::Size::eContain ||
|
||||||
layer.mSize.mWidthType == nsStyleImageLayers::Size::eCover);
|
layer.mSize.mWidthType == nsStyleImageLayers::Size::eCover);
|
||||||
if (!allowPartialImages && !state.mFillArea.Contains(state.mDestArea)) {
|
if (!allowPartialImages && !mFillRect.Contains(mDestRect)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Ignoring state.mAnchor. ImageLayer drawing snaps mDestArea edges to
|
return nsDisplayImageContainer::CanOptimizeToImageLayer(aManager, aBuilder);
|
||||||
// layer pixel boundaries. This should be OK for now.
|
}
|
||||||
|
|
||||||
int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
nsRect
|
||||||
mImageLayerDestRect =
|
nsDisplayBackgroundImage::GetDestRect()
|
||||||
LayoutDeviceRect::FromAppUnits(state.mDestArea, appUnitsPerDevPixel);
|
{
|
||||||
|
return mDestRect;
|
||||||
|
}
|
||||||
|
|
||||||
// Ok, we can turn this into a layer if needed.
|
already_AddRefed<imgIContainer>
|
||||||
mImage = imageRenderer->GetImage();
|
nsDisplayBackgroundImage::GetImage()
|
||||||
MOZ_ASSERT(mImage);
|
{
|
||||||
|
nsCOMPtr<imgIContainer> image = mImage;
|
||||||
return true;
|
return image.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
already_AddRefed<ImageContainer>
|
||||||
|
@ -2747,8 +2724,11 @@ nsDisplayBackgroundImage::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
mImage->GetWidth(&imageWidth);
|
mImage->GetWidth(&imageWidth);
|
||||||
mImage->GetHeight(&imageHeight);
|
mImage->GetHeight(&imageHeight);
|
||||||
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
|
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
|
||||||
|
|
||||||
|
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
|
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(GetDestRect(), appUnitsPerDevPixel);
|
||||||
|
|
||||||
const LayerRect destLayerRect = mImageLayerDestRect * aParameters.Scale();
|
const LayerRect destLayerRect = destRect * aParameters.Scale();
|
||||||
|
|
||||||
// Calculate the scaling factor for the frame.
|
// Calculate the scaling factor for the frame.
|
||||||
const gfxSize scale = gfxSize(destLayerRect.width / imageWidth,
|
const gfxSize scale = gfxSize(destLayerRect.width / imageWidth,
|
||||||
|
@ -2821,11 +2801,15 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer,
|
||||||
IntSize containerSize = aLayer->GetContainer()
|
IntSize containerSize = aLayer->GetContainer()
|
||||||
? aLayer->GetContainer()->GetCurrentSize()
|
? aLayer->GetContainer()->GetCurrentSize()
|
||||||
: IntSize(imageWidth, imageHeight);
|
: IntSize(imageWidth, imageHeight);
|
||||||
|
|
||||||
|
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
|
const LayoutDeviceRect destRect =
|
||||||
|
LayoutDeviceRect::FromAppUnits(GetDestRect(), factor);
|
||||||
|
|
||||||
const LayoutDevicePoint p = mImageLayerDestRect.TopLeft();
|
const LayoutDevicePoint p = destRect.TopLeft();
|
||||||
Matrix transform = Matrix::Translation(p.x, p.y);
|
Matrix transform = Matrix::Translation(p.x, p.y);
|
||||||
transform.PreScale(mImageLayerDestRect.width / containerSize.width,
|
transform.PreScale(destRect.width / containerSize.width,
|
||||||
mImageLayerDestRect.height / containerSize.height);
|
destRect.height / containerSize.height);
|
||||||
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
|
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3022,7 +3006,7 @@ void nsDisplayBackgroundImage::ComputeInvalidationRegion(nsDisplayListBuilder* a
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mDestArea.IsEqualInterior(geometry->mDestArea)) {
|
if (!mDestRect.IsEqualInterior(geometry->mDestRect)) {
|
||||||
// Dest area changed in a way that could cause everything to change,
|
// Dest area changed in a way that could cause everything to change,
|
||||||
// so invalidate everything (both old and new painting areas).
|
// so invalidate everything (both old and new painting areas).
|
||||||
aInvalidRegion->Or(bounds, geometry->mBounds);
|
aInvalidRegion->Or(bounds, geometry->mBounds);
|
||||||
|
@ -3248,6 +3232,50 @@ nsDisplayThemedBackground::GetBoundsInternal() {
|
||||||
return r + ToReferenceFrame();
|
return r + ToReferenceFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsDisplayImageContainer::CanOptimizeToImageLayer(LayerManager* aManager,
|
||||||
|
nsDisplayListBuilder* aBuilder)
|
||||||
|
{
|
||||||
|
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
||||||
|
? imgIContainer::FLAG_SYNC_DECODE
|
||||||
|
: imgIContainer::FLAG_NONE;
|
||||||
|
|
||||||
|
nsCOMPtr<imgIContainer> image = GetImage();
|
||||||
|
if (!image) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image->IsImageContainerAvailable(aManager, flags)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t imageWidth;
|
||||||
|
int32_t imageHeight;
|
||||||
|
image->GetWidth(&imageWidth);
|
||||||
|
image->GetHeight(&imageHeight);
|
||||||
|
|
||||||
|
if (imageWidth == 0 || imageHeight == 0) {
|
||||||
|
NS_ASSERTION(false, "invalid image size");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
|
const LayoutDeviceRect destRect =
|
||||||
|
LayoutDeviceRect::FromAppUnits(GetDestRect(), factor);
|
||||||
|
|
||||||
|
// Calculate the scaling factor for the frame.
|
||||||
|
const gfxSize scale = gfxSize(destRect.width / imageWidth,
|
||||||
|
destRect.height / imageHeight);
|
||||||
|
|
||||||
|
if (scale.width < 0.2 || scale.height < 0.2) {
|
||||||
|
// This would look awful as long as we can't use high-quality downscaling
|
||||||
|
// for image layers (bug 803703), so don't turn this into an image layer.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
|
|
|
@ -2323,13 +2323,17 @@ public:
|
||||||
* CanOptimizeToImageLayer() first and it returned true.
|
* CanOptimizeToImageLayer() first and it returned true.
|
||||||
*/
|
*/
|
||||||
virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
|
virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder) = 0;
|
nsDisplayListBuilder* aBuilder);
|
||||||
|
|
||||||
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder) = 0;
|
nsDisplayListBuilder* aBuilder) = 0;
|
||||||
virtual void ConfigureLayer(ImageLayer* aLayer,
|
virtual void ConfigureLayer(ImageLayer* aLayer,
|
||||||
const ContainerLayerParameters& aParameters) = 0;
|
const ContainerLayerParameters& aParameters) = 0;
|
||||||
|
|
||||||
|
virtual already_AddRefed<imgIContainer> GetImage() = 0;
|
||||||
|
|
||||||
|
virtual nsRect GetDestRect() = 0;
|
||||||
|
|
||||||
virtual bool SupportsOptimizingToImage() override { return true; }
|
virtual bool SupportsOptimizingToImage() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2698,11 +2702,6 @@ public:
|
||||||
*/
|
*/
|
||||||
nsRect GetPositioningArea();
|
nsRect GetPositioningArea();
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the destination area of one instance of the image.
|
|
||||||
*/
|
|
||||||
nsRect GetDestArea() const { return mDestArea; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if existing rendered pixels of this display item may need
|
* Returns true if existing rendered pixels of this display item may need
|
||||||
* to be redrawn if the positioning area size changes but its position does
|
* to be redrawn if the positioning area size changes but its position does
|
||||||
|
@ -2723,6 +2722,8 @@ public:
|
||||||
|
|
||||||
virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
|
virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder) override;
|
nsDisplayListBuilder* aBuilder) override;
|
||||||
|
virtual already_AddRefed<imgIContainer> GetImage() override;
|
||||||
|
virtual nsRect GetDestRect() override;
|
||||||
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder *aBuilder) override;
|
nsDisplayListBuilder *aBuilder) override;
|
||||||
virtual void ConfigureLayer(ImageLayer* aLayer,
|
virtual void ConfigureLayer(ImageLayer* aLayer,
|
||||||
|
@ -2743,7 +2744,6 @@ protected:
|
||||||
gfxRect* aDestRect);
|
gfxRect* aDestRect);
|
||||||
bool IsNonEmptyFixedImage() const;
|
bool IsNonEmptyFixedImage() const;
|
||||||
nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
|
nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
|
||||||
nsRect GetDestAreaInternal(nsDisplayListBuilder* aBuilder);
|
|
||||||
|
|
||||||
void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
|
void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
|
||||||
const nsRect& aBounds, nsRect* aClipRect);
|
const nsRect& aBounds, nsRect* aClipRect);
|
||||||
|
@ -2763,11 +2763,12 @@ protected:
|
||||||
const nsStyleBackground* mBackgroundStyle;
|
const nsStyleBackground* mBackgroundStyle;
|
||||||
nsCOMPtr<imgIContainer> mImage;
|
nsCOMPtr<imgIContainer> mImage;
|
||||||
RefPtr<ImageContainer> mImageContainer;
|
RefPtr<ImageContainer> mImageContainer;
|
||||||
LayoutDeviceRect mImageLayerDestRect;
|
nsRect mFillRect;
|
||||||
|
nsRect mDestRect;
|
||||||
/* Bounds of this display item */
|
/* Bounds of this display item */
|
||||||
nsRect mBounds;
|
nsRect mBounds;
|
||||||
nsRect mDestArea;
|
|
||||||
uint32_t mLayer;
|
uint32_t mLayer;
|
||||||
|
bool mIsRasterImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ nsDisplayBackgroundGeometry::nsDisplayBackgroundGeometry(nsDisplayBackgroundImag
|
||||||
: nsDisplayItemGeometry(aItem, aBuilder)
|
: nsDisplayItemGeometry(aItem, aBuilder)
|
||||||
, nsImageGeometryMixin(aItem, aBuilder)
|
, nsImageGeometryMixin(aItem, aBuilder)
|
||||||
, mPositioningArea(aItem->GetPositioningArea())
|
, mPositioningArea(aItem->GetPositioningArea())
|
||||||
, mDestArea(aItem->GetDestArea())
|
, mDestRect(aItem->GetDestRect())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -71,7 +71,7 @@ nsDisplayBackgroundGeometry::MoveBy(const nsPoint& aOffset)
|
||||||
{
|
{
|
||||||
nsDisplayItemGeometry::MoveBy(aOffset);
|
nsDisplayItemGeometry::MoveBy(aOffset);
|
||||||
mPositioningArea.MoveBy(aOffset);
|
mPositioningArea.MoveBy(aOffset);
|
||||||
mDestArea.MoveBy(aOffset);
|
mDestRect.MoveBy(aOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDisplayThemedBackgroundGeometry::nsDisplayThemedBackgroundGeometry(nsDisplayThemedBackground* aItem,
|
nsDisplayThemedBackgroundGeometry::nsDisplayThemedBackgroundGeometry(nsDisplayThemedBackground* aItem,
|
||||||
|
|
|
@ -194,7 +194,7 @@ public:
|
||||||
virtual void MoveBy(const nsPoint& aOffset) override;
|
virtual void MoveBy(const nsPoint& aOffset) override;
|
||||||
|
|
||||||
nsRect mPositioningArea;
|
nsRect mPositioningArea;
|
||||||
nsRect mDestArea;
|
nsRect mDestRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsDisplayThemedBackgroundGeometry : public nsDisplayItemGeometry
|
class nsDisplayThemedBackgroundGeometry : public nsDisplayItemGeometry
|
||||||
|
|
|
@ -1524,45 +1524,6 @@ nsDisplayImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
|
nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
nsDisplayImage::CanOptimizeToImageLayer(LayerManager* aManager,
|
|
||||||
nsDisplayListBuilder* aBuilder)
|
|
||||||
{
|
|
||||||
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
|
||||||
? imgIContainer::FLAG_SYNC_DECODE
|
|
||||||
: imgIContainer::FLAG_NONE;
|
|
||||||
|
|
||||||
if (!mImage->IsImageContainerAvailable(aManager, flags)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t imageWidth;
|
|
||||||
int32_t imageHeight;
|
|
||||||
mImage->GetWidth(&imageWidth);
|
|
||||||
mImage->GetHeight(&imageHeight);
|
|
||||||
|
|
||||||
if (imageWidth == 0 || imageHeight == 0) {
|
|
||||||
NS_ASSERTION(false, "invalid image size");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
|
||||||
const LayoutDeviceRect destRect =
|
|
||||||
LayoutDeviceRect::FromAppUnits(GetDestRect(), factor);
|
|
||||||
|
|
||||||
// Calculate the scaling factor for the frame.
|
|
||||||
const gfxSize scale = gfxSize(destRect.width / imageWidth,
|
|
||||||
destRect.height / imageHeight);
|
|
||||||
|
|
||||||
if (scale.width < 0.2 || scale.height < 0.2) {
|
|
||||||
// This would look awful as long as we can't use high-quality downscaling
|
|
||||||
// for image layers (bug 803703), so don't turn this into an image layer.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
already_AddRefed<ImageContainer>
|
||||||
nsDisplayImage::GetContainer(LayerManager* aManager,
|
nsDisplayImage::GetContainer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder)
|
nsDisplayListBuilder* aBuilder)
|
||||||
|
@ -1574,14 +1535,18 @@ nsDisplayImage::GetContainer(LayerManager* aManager,
|
||||||
return mImage->GetImageContainer(aManager, flags);
|
return mImage->GetImageContainer(aManager, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<imgIContainer>
|
||||||
|
nsDisplayImage::GetImage()
|
||||||
|
{
|
||||||
|
nsCOMPtr<imgIContainer> image = mImage;
|
||||||
|
return image.forget();
|
||||||
|
}
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
nsDisplayImage::GetDestRect(bool* aSnap)
|
nsDisplayImage::GetDestRect()
|
||||||
{
|
{
|
||||||
bool snap = true;
|
bool snap = true;
|
||||||
const nsRect frameContentBox = GetBounds(&snap);
|
const nsRect frameContentBox = GetBounds(&snap);
|
||||||
if (aSnap) {
|
|
||||||
*aSnap = snap;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsImageFrame* imageFrame = static_cast<nsImageFrame*>(mFrame);
|
nsImageFrame* imageFrame = static_cast<nsImageFrame*>(mFrame);
|
||||||
return imageFrame->PredictedDestRect(frameContentBox);
|
return imageFrame->PredictedDestRect(frameContentBox);
|
||||||
|
|
|
@ -428,8 +428,7 @@ public:
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||||
nsRenderingContext* aCtx) override;
|
nsRenderingContext* aCtx) override;
|
||||||
|
|
||||||
virtual bool CanOptimizeToImageLayer(LayerManager* aManager,
|
virtual already_AddRefed<imgIContainer> GetImage() override;
|
||||||
nsDisplayListBuilder* aBuilder) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an ImageContainer for this image if the image type
|
* Returns an ImageContainer for this image if the image type
|
||||||
|
@ -442,7 +441,7 @@ public:
|
||||||
* @return The dest rect we'll use when drawing this image, in app units.
|
* @return The dest rect we'll use when drawing this image, in app units.
|
||||||
* Not necessarily contained in this item's bounds.
|
* Not necessarily contained in this item's bounds.
|
||||||
*/
|
*/
|
||||||
nsRect GetDestRect(bool* aSnap = nullptr);
|
virtual nsRect GetDestRect() override;
|
||||||
|
|
||||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
|
|
|
@ -450,17 +450,10 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer,
|
||||||
{
|
{
|
||||||
aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
|
aLayer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(mFrame));
|
||||||
|
|
||||||
nsImageBoxFrame* imageFrame = static_cast<nsImageBoxFrame*>(mFrame);
|
|
||||||
|
|
||||||
nsRect clientRect;
|
|
||||||
imageFrame->GetClientRect(clientRect);
|
|
||||||
|
|
||||||
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
const LayoutDeviceRect destRect =
|
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(GetDestRect(), factor);
|
||||||
LayoutDeviceRect::FromAppUnits(clientRect + ToReferenceFrame(), factor);
|
|
||||||
|
|
||||||
nsCOMPtr<imgIContainer> imgCon;
|
nsCOMPtr<imgIContainer> imgCon = GetImage();
|
||||||
imageFrame->mImageRequest->GetImage(getter_AddRefs(imgCon));
|
|
||||||
int32_t imageWidth;
|
int32_t imageWidth;
|
||||||
int32_t imageHeight;
|
int32_t imageHeight;
|
||||||
imgCon->GetWidth(&imageWidth);
|
imgCon->GetWidth(&imageWidth);
|
||||||
|
@ -503,30 +496,47 @@ bool
|
||||||
nsDisplayXULImage::CanOptimizeToImageLayer(LayerManager* aManager,
|
nsDisplayXULImage::CanOptimizeToImageLayer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder)
|
nsDisplayListBuilder* aBuilder)
|
||||||
{
|
{
|
||||||
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
nsImageBoxFrame* imageFrame = static_cast<nsImageBoxFrame*>(mFrame);
|
||||||
? imgIContainer::FLAG_SYNC_DECODE
|
if (!imageFrame->CanOptimizeToImageLayer()) {
|
||||||
: imgIContainer::FLAG_NONE;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return static_cast<nsImageBoxFrame*>(mFrame)
|
return nsDisplayImageContainer::CanOptimizeToImageLayer(aManager, aBuilder);
|
||||||
->IsImageContainerAvailable(aManager, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
already_AddRefed<imgIContainer>
|
||||||
nsImageBoxFrame::IsImageContainerAvailable(LayerManager* aManager,
|
nsDisplayXULImage::GetImage()
|
||||||
uint32_t aFlags)
|
|
||||||
{
|
{
|
||||||
bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0);
|
nsImageBoxFrame* imageFrame = static_cast<nsImageBoxFrame*>(mFrame);
|
||||||
if (hasSubRect || !mImageRequest) {
|
if (!imageFrame->mImageRequest) {
|
||||||
return false;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<imgIContainer> imgCon;
|
nsCOMPtr<imgIContainer> imgCon;
|
||||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
imageFrame->mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||||
if (!imgCon) {
|
|
||||||
|
return imgCon.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRect
|
||||||
|
nsDisplayXULImage::GetDestRect()
|
||||||
|
{
|
||||||
|
nsImageBoxFrame* imageFrame = static_cast<nsImageBoxFrame*>(mFrame);
|
||||||
|
|
||||||
|
nsRect clientRect;
|
||||||
|
imageFrame->GetClientRect(clientRect);
|
||||||
|
|
||||||
|
return clientRect + ToReferenceFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsImageBoxFrame::CanOptimizeToImageLayer()
|
||||||
|
{
|
||||||
|
bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0);
|
||||||
|
if (hasSubRect) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return imgCon->IsImageContainerAvailable(aManager, aFlags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
already_AddRefed<ImageContainer>
|
||||||
|
@ -537,30 +547,11 @@ nsDisplayXULImage::GetContainer(LayerManager* aManager,
|
||||||
? imgIContainer::FLAG_SYNC_DECODE
|
? imgIContainer::FLAG_SYNC_DECODE
|
||||||
: imgIContainer::FLAG_NONE;
|
: imgIContainer::FLAG_NONE;
|
||||||
|
|
||||||
return static_cast<nsImageBoxFrame*>(mFrame)->GetContainer(aManager, flags);
|
nsCOMPtr<imgIContainer> image = GetImage();
|
||||||
}
|
if (image) {
|
||||||
|
return image->GetImageContainer(aManager, flags);
|
||||||
already_AddRefed<ImageContainer>
|
|
||||||
nsImageBoxFrame::GetContainer(LayerManager* aManager, uint32_t aFlags)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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,9 +96,7 @@ public:
|
||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
nsPoint aPt, uint32_t aFlags);
|
nsPoint aPt, uint32_t aFlags);
|
||||||
|
|
||||||
bool IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags);
|
bool CanOptimizeToImageLayer();
|
||||||
already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
|
||||||
uint32_t aFlags);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit nsImageBoxFrame(nsStyleContext* aContext);
|
explicit nsImageBoxFrame(nsStyleContext* aContext);
|
||||||
|
@ -146,6 +144,8 @@ public:
|
||||||
nsDisplayListBuilder* aBuilder) override;
|
nsDisplayListBuilder* aBuilder) override;
|
||||||
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
|
||||||
nsDisplayListBuilder* aBuilder) override;
|
nsDisplayListBuilder* aBuilder) override;
|
||||||
|
virtual already_AddRefed<imgIContainer> GetImage() override;
|
||||||
|
virtual nsRect GetDestRect() override;
|
||||||
virtual void ConfigureLayer(ImageLayer* aLayer,
|
virtual void ConfigureLayer(ImageLayer* aLayer,
|
||||||
const ContainerLayerParameters& aParameters) override;
|
const ContainerLayerParameters& aParameters) override;
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override
|
||||||
|
|
Загрузка…
Ссылка в новой задаче