Bug 1128225 (Part 6) - Record the last draw result in nsDisplayXULImage and use it to decide whether to sync decode. r=tn

This commit is contained in:
Seth Fowler 2015-02-04 13:50:56 -08:00
parent 486a068ce5
commit d47eca8426
2 changed files with 40 additions and 19 deletions

View File

@ -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<imgIContainer> 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<nsImageBoxFrame*>(mFrame)->
DrawResult result = static_cast<nsImageBoxFrame*>(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<nsImageBoxFrame*>(mFrame);
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages()) {
nsImageBoxFrame* boxFrame = static_cast<nsImageBoxFrame*>(mFrame);
nsCOMPtr<imgIContainer> 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);

View File

@ -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<mozilla::layers::ImageContainer> 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;