diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index b8185a2a435..e4b5566ef9e 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -56,6 +56,7 @@ using namespace mozilla; using namespace mozilla::gfx; +using namespace mozilla::image; using namespace mozilla::layers; class nsImageBoxFrameEvent : public nsRunnable @@ -317,7 +318,7 @@ nsImageBoxFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, aLists.Content()->AppendToTop(&list); } -void +DrawResult nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsPoint aPt, uint32_t aFlags) @@ -327,25 +328,32 @@ nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext, rect += aPt; - if (!mImageRequest) - return; + if (!mImageRequest) { + // This probably means we're drawn by a native theme. + return DrawResult::SUCCESS; + } // don't draw if the image is not dirty + // XXX(seth): Can this actually happen anymore? nsRect dirty; - if (!dirty.IntersectRect(aDirtyRect, rect)) - return; + if (!dirty.IntersectRect(aDirtyRect, rect)) { + return DrawResult::TEMPORARY_ERROR; + } nsCOMPtr imgCon; mImageRequest->GetImage(getter_AddRefs(imgCon)); if (imgCon) { bool hasSubRect = !mUseSrcAttr && (mSubRect.width > 0 || mSubRect.height > 0); - nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), + return + nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(), PresContext(), imgCon, nsLayoutUtils::GetGraphicsFilterForFrame(this), rect, dirty, nullptr, aFlags, nullptr, hasSubRect ? &mSubRect : nullptr); } + + return DrawResult::NOT_READY; } void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, @@ -357,8 +365,16 @@ void nsDisplayXULImage::Paint(nsDisplayListBuilder* aBuilder, if (aBuilder->IsPaintingToWindow()) flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING; - static_cast(mFrame)-> + DrawResult result = static_cast(mFrame)-> PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(), flags); + + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); +} + +nsDisplayItemGeometry* +nsDisplayXULImage::AllocateGeometry(nsDisplayListBuilder* aBuilder) +{ + return new nsDisplayItemGenericImageGeometry(this, aBuilder); } void @@ -366,18 +382,15 @@ nsDisplayXULImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) { + auto boxFrame = static_cast(mFrame); + auto geometry = + static_cast(aGeometry); - if (aBuilder->ShouldSyncDecodeImages()) { - nsImageBoxFrame* boxFrame = static_cast(mFrame); - nsCOMPtr image; - if (boxFrame->mImageRequest) { - boxFrame->mImageRequest->GetImage(getter_AddRefs(image)); - } - - if (image && !image->IsDecoded()) { + if (aBuilder->ShouldSyncDecodeImages() && + boxFrame->mImageRequest && + geometry->LastDrawResult() != DrawResult::SUCCESS) { bool snap; aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap)); - } } nsDisplayImageContainer::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); @@ -405,6 +418,12 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) imgCon->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. + nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, + DrawResult::SUCCESS); + } gfxPoint p = destRect.TopLeft() + aOffset; Matrix transform = Matrix::Translation(p.x, p.y); diff --git a/layout/xul/nsImageBoxFrame.h b/layout/xul/nsImageBoxFrame.h index 05c6615b5c5..4580fe0141e 100644 --- a/layout/xul/nsImageBoxFrame.h +++ b/layout/xul/nsImageBoxFrame.h @@ -40,6 +40,7 @@ private: class nsImageBoxFrame MOZ_FINAL : public nsLeafBoxFrame { public: + typedef mozilla::image::DrawResult DrawResult; typedef mozilla::layers::LayerManager LayerManager; friend class nsDisplayXULImage; @@ -90,9 +91,9 @@ public: virtual ~nsImageBoxFrame(); - void PaintImage(nsRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsPoint aPt, uint32_t aFlags); + DrawResult PaintImage(nsRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsPoint aPt, uint32_t aFlags); already_AddRefed GetContainer(LayerManager* aManager); protected: @@ -146,6 +147,7 @@ public: *aSnap = true; return nsRect(ToReferenceFrame(), Frame()->GetSize()); } + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry, nsRegion* aInvalidRegion) MOZ_OVERRIDE;