Bug 1209751 - Make sync decoding more reliable when nsImageRenderer is used with -moz-element. r=roc
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -4692,28 +4692,31 @@ nsImageRenderer::PrepareImage()
NS_LITERAL_STRING("#") + nsDependentString(mImage->GetElementId());
nsCOMPtr<nsIURI> targetURI;
nsCOMPtr<nsIURI> base = mForFrame->GetContent()->GetBaseURI();
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), elementId,
mForFrame->GetContent()->GetCurrentDoc(), base);
nsSVGPaintingProperty* property = nsSVGEffects::GetPaintingPropertyForURI(
targetURI, mForFrame->FirstContinuation(),
nsSVGEffects::BackgroundImageProperty());
- if (!property)
+ if (!property) {
return false;
- mPaintServerFrame = property->GetReferencedFrame();
-
- // If the referenced element doesn't have a frame we might still be able
- // to paint it if it's an <img>, <canvas>, or <video> element.
- if (!mPaintServerFrame) {
- mImageElementSurface =
- nsLayoutUtils::SurfaceFromElement(property->GetReferencedElement());
- if (!mImageElementSurface.mSourceSurface)
+ }
+
+ // If the referenced element is an <img>, <canvas>, or <video> element,
+ // prefer SurfaceFromElement as it's more reliable.
+ mImageElementSurface =
+ nsLayoutUtils::SurfaceFromElement(property->GetReferencedElement());
+ if (!mImageElementSurface.mSourceSurface) {
+ mPaintServerFrame = property->GetReferencedFrame();
+ if (!mPaintServerFrame) {
return false;
+ }
}
+
mIsReady = true;
break;
}
case eStyleImageType_Null:
default:
break;
}
@@ -5013,28 +5016,32 @@ nsImageRenderer::Draw(nsPresContext*
already_AddRefed<gfxDrawable>
nsImageRenderer::DrawableForElement(const nsRect& aImageRect,
nsRenderingContext& aRenderingContext)
{
NS_ASSERTION(mType == eStyleImageType_Element,
"DrawableForElement only makes sense if backed by an element");
if (mPaintServerFrame) {
+ // XXX(seth): In order to not pass FLAG_SYNC_DECODE_IMAGES here,
+ // DrawableFromPaintServer would have to return a DrawResult indicating
+ // whether any images could not be painted because they weren't fully
+ // decoded. Even always passing FLAG_SYNC_DECODE_IMAGES won't eliminate all
+ // problems, as it won't help if there are image which haven't finished
+ // loading, but it's better than nothing.
int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
nsRect destRect = aImageRect - aImageRect.TopLeft();
nsIntSize roundedOut = destRect.ToOutsidePixels(appUnitsPerDevPixel).Size();
IntSize imageSize(roundedOut.width, roundedOut.height);
nsRefPtr<gfxDrawable> drawable =
nsSVGIntegrationUtils::DrawableFromPaintServer(
mPaintServerFrame, mForFrame, mSize, imageSize,
aRenderingContext.GetDrawTarget(),
aRenderingContext.ThebesContext()->CurrentMatrix(),
- mFlags & FLAG_SYNC_DECODE_IMAGES
- ? nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES
- : 0);
+ nsSVGIntegrationUtils::FLAG_SYNC_DECODE_IMAGES);
return drawable.forget();
}
NS_ASSERTION(mImageElementSurface.mSourceSurface, "Surface should be ready.");
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(
mImageElementSurface.mSourceSurface,
mImageElementSurface.mSize);
return drawable.forget();