Bug 1422013 - Invalidate image items for webrender. r=mattwoodrow

MozReview-Commit-ID: 701MZhcrf4l

--HG--
extra : rebase_source : 8bed0e5f812570685cf04f5b371da885294513e0
This commit is contained in:
Ethan Lin 2017-12-04 11:12:25 +08:00
Родитель caac6a3325
Коммит 87408bd0b0
6 изменённых файлов: 58 добавлений и 31 удалений

Просмотреть файл

@ -531,7 +531,7 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
LayoutDeviceIntPoint offset = RoundedToInt(bounds.TopLeft());
aImageRect = LayoutDeviceRect(offset, LayoutDeviceSize(RoundedToInt(bounds.Size())));
LayerRect paintRect = LayerRect(LayerPoint(0, 0), LayerSize(paintSize));
nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
nsDisplayItemGeometry* geometry = fallbackData->GetGeometry();
// nsDisplayFilter is rendered via BasicLayerManager which means the invalidate
// region is unknown until we traverse the displaylist contained by it.
@ -561,6 +561,10 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
}
if (needPaint || !fallbackData->GetKey()) {
nsAutoPtr<nsDisplayItemGeometry> newGeometry;
newGeometry = aItem->AllocateGeometry(aDisplayListBuilder);
fallbackData->SetGeometry(Move(newGeometry));
gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
if (useBlobImage) {
@ -645,13 +649,11 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
}
}
geometry = aItem->AllocateGeometry(aDisplayListBuilder);
fallbackData->SetScale(scale);
fallbackData->SetInvalid(false);
}
// Update current bounds to fallback data
fallbackData->SetGeometry(Move(geometry));
fallbackData->SetBounds(paintBounds);
MOZ_ASSERT(fallbackData->GetKey());

Просмотреть файл

@ -246,10 +246,10 @@ WebRenderFallbackData::~WebRenderFallbackData()
{
}
nsAutoPtr<nsDisplayItemGeometry>
nsDisplayItemGeometry*
WebRenderFallbackData::GetGeometry()
{
return mGeometry;
return mGeometry.get();
}
void

Просмотреть файл

@ -58,6 +58,7 @@ public:
uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
void RemoveFromTable();
virtual void ClearCachedResources() {};
virtual nsDisplayItemGeometry* GetGeometry() { return nullptr; }
protected:
virtual ~WebRenderUserData();
@ -121,7 +122,7 @@ public:
virtual WebRenderFallbackData* AsFallbackData() override { return this; }
virtual UserDataType GetType() override { return UserDataType::eFallback; }
static UserDataType Type() { return UserDataType::eFallback; }
nsAutoPtr<nsDisplayItemGeometry> GetGeometry();
nsDisplayItemGeometry* GetGeometry() override;
void SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry);
nsRect GetBounds() { return mBounds; }
void SetBounds(const nsRect& aRect) { mBounds = aRect; }

Просмотреть файл

@ -2060,20 +2060,14 @@ FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey
return true;
}
}
return false;
}
void
FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback)
{
const SmallPointerArray<DisplayItemData>& array = aFrame->DisplayItemData();
for (uint32_t i = 0; i < array.Length(); i++) {
DisplayItemData* data = DisplayItemData::AssertDisplayItemData(array.ElementAt(i));
if (data->mDisplayItemKey != 0) {
aCallback(aFrame, data);
if (auto userDataTable =
aFrame->GetProperty(nsIFrame::WebRenderUserDataProperty())) {
RefPtr<WebRenderUserData> data = userDataTable->Get(aDisplayItemKey);
if (data) {
return true;
}
}
return false;
}
DisplayItemData*
@ -6279,6 +6273,12 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
return data->GetGeometry();
}
}
if (auto userDataTable =
aItem->Frame()->GetProperty(nsIFrame::WebRenderUserDataProperty())) {
if (RefPtr<WebRenderUserData> data = userDataTable->Get(itemPerFrameKey)) {
return data->GetGeometry();
}
}
return nullptr;
}

Просмотреть файл

@ -555,8 +555,6 @@ public:
typedef void (*DisplayItemDataCallback)(nsIFrame *aFrame, DisplayItemData* aItem);
static void IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback);
/**
* Save transform that was in aLayer when we last painted, and the position
* of the active scrolled root frame. It must be an integer

Просмотреть файл

@ -324,22 +324,48 @@ ImageLoader::GetPresContext()
return shell->GetPresContext();
}
void InvalidateImagesCallback(nsIFrame* aFrame,
DisplayItemData* aItem)
static bool
IsRenderNoImages(uint32_t aDisplayItemKey)
{
DisplayItemType type = GetDisplayItemTypeFromKey(aItem->GetDisplayItemKey());
DisplayItemType type = GetDisplayItemTypeFromKey(aDisplayItemKey);
uint8_t flags = GetDisplayItemFlagsForType(type);
return flags & TYPE_RENDERS_NO_IMAGES;
}
if (flags & TYPE_RENDERS_NO_IMAGES) {
return;
void InvalidateImages(nsIFrame* aFrame)
{
bool invalidateFrame = false;
const SmallPointerArray<DisplayItemData>& array = aFrame->DisplayItemData();
for (uint32_t i = 0; i < array.Length(); i++) {
DisplayItemData* data = DisplayItemData::AssertDisplayItemData(array.ElementAt(i));
uint32_t displayItemKey = data->GetDisplayItemKey();
if (displayItemKey != 0 && !IsRenderNoImages(displayItemKey)) {
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
DisplayItemType type = GetDisplayItemTypeFromKey(displayItemKey);
printf_stderr("Invalidating display item(type=%d) based on frame %p \
because it might contain an invalidated image\n",
static_cast<uint32_t>(type), aFrame);
}
data->Invalidate();
invalidateFrame = true;
}
}
if (auto userDataTable =
aFrame->GetProperty(nsIFrame::WebRenderUserDataProperty())) {
for (auto iter = userDataTable->Iter(); !iter.Done(); iter.Next()) {
RefPtr<layers::WebRenderUserData> data = iter.UserData();
if (data->GetType() == layers::WebRenderAnimationData::UserDataType::eFallback &&
!IsRenderNoImages(data->GetDisplayItemKey())) {
static_cast<layers::WebRenderFallbackData*>(data.get())->SetInvalid(true);
}
invalidateFrame = true;
}
}
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
printf_stderr("Invalidating display item(type=%d) based on frame %p \
because it might contain an invalidated image\n", static_cast<uint32_t>(type), aFrame);
if (invalidateFrame) {
aFrame->SchedulePaint();
}
aItem->Invalidate();
aFrame->SchedulePaint();
}
void
@ -359,7 +385,7 @@ ImageLoader::DoRedraw(FrameSet* aFrameSet, bool aForcePaint)
// might not find the right display item.
frame->InvalidateFrame();
} else {
FrameLayerBuilder::IterateRetainedDataFor(frame, InvalidateImagesCallback);
InvalidateImages(frame);
// Update ancestor rendering observers (-moz-element etc)
nsIFrame *f = frame;