Bug 695763. Part 3. Invalidate the background images of buttons, fieldsets, and mathml chars if they are not decoded and we are asked to do a sync decode. r=matt.woodrow

This commit is contained in:
Timothy Nikkel 2013-06-26 11:43:26 -05:00
parent e19b88cdad
commit 5942372742
7 changed files with 87 additions and 0 deletions

View File

@ -3036,6 +3036,24 @@ nsCSSRendering::GetBackgroundLayerRect(nsPresContext* aPresContext,
return state.mFillArea;
}
/* static */ bool
nsCSSRendering::AreAllBackgroundImagesDecodedForFrame(nsIFrame* aFrame)
{
const nsStyleBackground *bg = aFrame->StyleContext()->StyleBackground();
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
const nsStyleImage* image = &bg->mLayers[i].mImage;
if (image->GetType() == eStyleImageType_Image) {
nsCOMPtr<imgIContainer> img;
if (NS_SUCCEEDED(image->GetImageData()->GetImage(getter_AddRefs(img)))) {
if (!img->IsDecoded()) {
return false;
}
}
}
}
return true;
}
static void
DrawBorderImage(nsPresContext* aPresContext,
nsRenderingContext& aRenderingContext,

View File

@ -396,6 +396,12 @@ struct nsCSSRendering {
const nsStyleBackground::Layer& aLayer,
uint32_t aFlags);
/**
* Checks if all images that are part of the background for aFrame are
* currently decoded.
*/
static bool AreAllBackgroundImagesDecodedForFrame(nsIFrame* aFrame);
/**
* Called when we start creating a display list. The frame tree will not
* change until a matching EndFrameTreeLocked is called.

View File

@ -1468,6 +1468,20 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder,
::Sort(this, Count(), aCmp, aClosure);
}
void
nsDisplayItem::AddInvalidRegionForSyncDecodeBackgroundImages(
nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion)
{
if (aBuilder->ShouldSyncDecodeImages()) {
if (!nsCSSRendering::AreAllBackgroundImagesDecodedForFrame(mFrame)) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
}
}
/* static */ bool
nsDisplayItem::ForceActiveLayers()
{

View File

@ -937,6 +937,16 @@ public:
}
}
/**
* For display items types that just draw a background we use this function
* to do any invalidation that might be needed if we are asked to sync decode
* images.
*/
void AddInvalidRegionForSyncDecodeBackgroundImages(
nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion);
/**
* Called when the area rendered by this display item has changed (been
* invalidated or changed geometry) since the last paint. This includes

View File

@ -118,6 +118,9 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
private:
nsButtonFrameRenderer* mBFR;
@ -150,6 +153,16 @@ private:
nsButtonFrameRenderer* mBFR;
};
void
nsDisplayButtonBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
AddInvalidRegionForSyncDecodeBackgroundImages(aBuilder, aGeometry, aInvalidRegion);
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void nsDisplayButtonBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{

View File

@ -194,6 +194,9 @@ public:
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("FieldSetBorderBackground", TYPE_FIELDSET_BORDER_BACKGROUND)
};
@ -215,6 +218,16 @@ nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
mVisibleRect, aBuilder->GetBackgroundPaintFlags());
}
void
nsDisplayFieldSetBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
AddInvalidRegionForSyncDecodeBackgroundImages(aBuilder, aGeometry, aInvalidRegion);
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void
nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,

View File

@ -1644,6 +1644,9 @@ public:
}
#endif
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
NS_DISPLAY_DECL_NAME("MathMLCharBackground", TYPE_MATHML_CHAR_BACKGROUND)
@ -1652,6 +1655,16 @@ private:
nsRect mRect;
};
void
nsDisplayMathMLCharBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
AddInvalidRegionForSyncDecodeBackgroundImages(aBuilder, aGeometry, aInvalidRegion);
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void nsDisplayMathMLCharBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{