Bug 1254134 - Use the full image size as the bounds for image layers during layer tree invalidation. r?mattwoodrow
MozReview-Commit-ID: DBF3H3I4rbS
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -491,22 +491,52 @@ struct ImageLayerProperties : public Lay
, mImageHost(GetImageHost(aImage))
, mFilter(aImage->GetFilter())
, mScaleToSize(aImage->GetScaleToSize())
, mScaleMode(aImage->GetScaleMode())
, mLastProducerID(-1)
, mLastFrameID(-1)
, mIsMask(aIsMask)
{
+ if (mContainer) {
+ mRect.SizeTo(mContainer->GetCurrentSize());
+ }
if (mImageHost) {
+ mRect.SizeTo(mImageHost->GetImageSize());
mLastProducerID = mImageHost->GetLastProducerID();
mLastFrameID = mImageHost->GetLastFrameID();
}
}
+ // For image layers we want to use the image size rather than the
+ // visible region for two reasons:
+ // 1) If the image is mask layer, then the visible region is empty
+ // 2) If the image is partially outside the displayport then the visible
+ // region is truncated, but the compositor is still drawing the full
+ // image each time. Partial composition on the image can result in
+ // the un-composited portion of the image becoming visibly stale in
+ // a checkerboarding area.
+ IntRect NewTransformedBounds() override
+ {
+ IntRect rect;
+ ImageLayer* imageLayer = static_cast<ImageLayer*>(mLayer.get());
+ if (ImageContainer* container = imageLayer->GetContainer()) {
+ rect.SizeTo(container->GetCurrentSize());
+ }
+ if (ImageHost* host = GetImageHost(imageLayer)) {
+ rect.SizeTo(host->GetImageSize());
+ }
+ return TransformRect(rect, GetTransformForInvalidation(mLayer));
+ }
+
+ IntRect OldTransformedBounds() override
+ {
+ return TransformRect(mRect, mTransform);
+ }
+
virtual nsIntRegion ComputeChangeInternal(const char* aPrefix,
NotifySubDocInvalidationFunc aCallback,
bool& aGeometryChanged)
{
ImageLayer* imageLayer = static_cast<ImageLayer*>(mLayer.get());
if (!imageLayer->GetLocalVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
aGeometryChanged = true;
@@ -522,42 +552,29 @@ struct ImageLayerProperties : public Lay
mFilter != imageLayer->GetFilter() ||
mScaleToSize != imageLayer->GetScaleToSize() ||
mScaleMode != imageLayer->GetScaleMode() ||
host != mImageHost ||
(host && host->GetProducerID() != mLastProducerID) ||
(host && host->GetFrameID() != mLastFrameID)) {
aGeometryChanged = true;
- if (mIsMask) {
- // Mask layers have an empty visible region, so we have to
- // use the image size instead.
- IntSize size;
- if (container) {
- size = container->GetCurrentSize();
- }
- if (host) {
- size = host->GetImageSize();
- }
- IntRect rect(0, 0, size.width, size.height);
- LTI_DUMP(rect, "mask");
- return TransformRect(rect, GetTransformForInvalidation(mLayer));
- }
LTI_DUMP(NewTransformedBounds(), "bounds");
return NewTransformedBounds();
}
return IntRect();
}
RefPtr<ImageContainer> mContainer;
RefPtr<ImageHost> mImageHost;
Filter mFilter;
gfx::IntSize mScaleToSize;
ScaleMode mScaleMode;
+ IntRect mRect;
int32_t mLastProducerID;
int32_t mLastFrameID;
bool mIsMask;
};
struct CanvasLayerProperties : public LayerPropertiesBase
{
explicit CanvasLayerProperties(CanvasLayer* aCanvas)