зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1414264 - Check invalidation region when we use layer system to paint items. r=jrmuizel
MozReview-Commit-ID: Dc5e13NQmP5 --HG-- extra : rebase_source : e4f96edcd5e6dcc75d916aad28c3507ee8bdc7b6
This commit is contained in:
Родитель
7a9dcc4806
Коммит
e9e332b74c
|
@ -339,7 +339,7 @@ WebRenderCommandBuilder::PushImage(nsDisplayItem* aItem,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
PaintByLayer(nsDisplayItem* aItem,
|
PaintByLayer(nsDisplayItem* aItem,
|
||||||
nsDisplayListBuilder* aDisplayListBuilder,
|
nsDisplayListBuilder* aDisplayListBuilder,
|
||||||
RefPtr<BasicLayerManager>& aManager,
|
RefPtr<BasicLayerManager>& aManager,
|
||||||
|
@ -350,22 +350,36 @@ PaintByLayer(nsDisplayItem* aItem,
|
||||||
aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniquePtr<LayerProperties> props;
|
||||||
|
if (aManager->GetRoot()) {
|
||||||
|
props = Move(LayerProperties::CloneFrom(aManager->GetRoot()));
|
||||||
|
}
|
||||||
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
||||||
layerBuilder->Init(aDisplayListBuilder, aManager, nullptr, true);
|
layerBuilder->Init(aDisplayListBuilder, aManager, nullptr, true);
|
||||||
layerBuilder->DidBeginRetainedLayerTransaction(aManager);
|
layerBuilder->DidBeginRetainedLayerTransaction(aManager);
|
||||||
|
|
||||||
aManager->BeginTransactionWithTarget(aContext);
|
aManager->BeginTransactionWithTarget(aContext);
|
||||||
|
bool isInvalidated = false;
|
||||||
|
|
||||||
ContainerLayerParameters param;
|
ContainerLayerParameters param;
|
||||||
RefPtr<Layer> layer = aItem->BuildLayer(aDisplayListBuilder, aManager, param);
|
RefPtr<Layer> root = aItem->BuildLayer(aDisplayListBuilder, aManager, param);
|
||||||
if (layer) {
|
|
||||||
UniquePtr<LayerProperties> props;
|
|
||||||
props = Move(LayerProperties::CloneFrom(aManager->GetRoot()));
|
|
||||||
|
|
||||||
aManager->SetRoot(layer);
|
if (root) {
|
||||||
|
aManager->SetRoot(root);
|
||||||
layerBuilder->WillEndTransaction();
|
layerBuilder->WillEndTransaction();
|
||||||
|
|
||||||
aPaintFunc();
|
aPaintFunc();
|
||||||
|
|
||||||
|
// Check if there is any invalidation region.
|
||||||
|
nsIntRegion invalid;
|
||||||
|
if (props) {
|
||||||
|
props->ComputeDifferences(root, invalid, nullptr);
|
||||||
|
if (!invalid.IsEmpty()) {
|
||||||
|
isInvalidated = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isInvalidated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
|
@ -382,9 +396,11 @@ PaintByLayer(nsDisplayItem* aItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
aManager->SetTarget(nullptr);
|
aManager->SetTarget(nullptr);
|
||||||
|
|
||||||
|
return isInvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
PaintItemByDrawTarget(nsDisplayItem* aItem,
|
PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
gfx::DrawTarget* aDT,
|
gfx::DrawTarget* aDT,
|
||||||
const LayerRect& aImageRect,
|
const LayerRect& aImageRect,
|
||||||
|
@ -396,6 +412,7 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aDT);
|
MOZ_ASSERT(aDT);
|
||||||
|
|
||||||
|
bool isInvalidated = false;
|
||||||
aDT->ClearRect(aImageRect.ToUnknownRect());
|
aDT->ClearRect(aImageRect.ToUnknownRect());
|
||||||
RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT);
|
RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT);
|
||||||
MOZ_ASSERT(context);
|
MOZ_ASSERT(context);
|
||||||
|
@ -405,10 +422,11 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
switch (aItem->GetType()) {
|
switch (aItem->GetType()) {
|
||||||
case DisplayItemType::TYPE_MASK:
|
case DisplayItemType::TYPE_MASK:
|
||||||
static_cast<nsDisplayMask*>(aItem)->PaintMask(aDisplayListBuilder, context);
|
static_cast<nsDisplayMask*>(aItem)->PaintMask(aDisplayListBuilder, context);
|
||||||
|
isInvalidated = true;
|
||||||
break;
|
break;
|
||||||
case DisplayItemType::TYPE_SVG_WRAPPER:
|
case DisplayItemType::TYPE_SVG_WRAPPER:
|
||||||
{
|
{
|
||||||
PaintByLayer(aItem, aDisplayListBuilder, aManager, context, [&]() {
|
isInvalidated = PaintByLayer(aItem, aDisplayListBuilder, aManager, context, [&]() {
|
||||||
aManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, aDisplayListBuilder);
|
aManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, aDisplayListBuilder);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -416,7 +434,7 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
|
|
||||||
case DisplayItemType::TYPE_FILTER:
|
case DisplayItemType::TYPE_FILTER:
|
||||||
{
|
{
|
||||||
PaintByLayer(aItem, aDisplayListBuilder, aManager, context, [&]() {
|
isInvalidated = PaintByLayer(aItem, aDisplayListBuilder, aManager, context, [&]() {
|
||||||
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder,
|
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder,
|
||||||
context, aManager);
|
context, aManager);
|
||||||
});
|
});
|
||||||
|
@ -425,6 +443,7 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
|
|
||||||
default:
|
default:
|
||||||
aItem->Paint(aDisplayListBuilder, context);
|
aItem->Paint(aDisplayListBuilder, context);
|
||||||
|
isInvalidated = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,13 +451,15 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||||
aDT->SetTransform(gfx::Matrix());
|
aDT->SetTransform(gfx::Matrix());
|
||||||
aDT->FillRect(gfx::Rect(0, 0, aImageRect.Width(), aImageRect.Height()), gfx::ColorPattern(gfx::Color(1.0, 0.0, 0.0, 0.5)));
|
aDT->FillRect(gfx::Rect(0, 0, aImageRect.Width(), aImageRect.Height()), gfx::ColorPattern(gfx::Color(1.0, 0.0, 0.0, 0.5)));
|
||||||
}
|
}
|
||||||
if (aItem->Frame()->PresContext()->GetPaintFlashing()) {
|
if (aItem->Frame()->PresContext()->GetPaintFlashing() && isInvalidated) {
|
||||||
aDT->SetTransform(gfx::Matrix());
|
aDT->SetTransform(gfx::Matrix());
|
||||||
float r = float(rand()) / RAND_MAX;
|
float r = float(rand()) / RAND_MAX;
|
||||||
float g = float(rand()) / RAND_MAX;
|
float g = float(rand()) / RAND_MAX;
|
||||||
float b = float(rand()) / RAND_MAX;
|
float b = float(rand()) / RAND_MAX;
|
||||||
aDT->FillRect(gfx::Rect(0, 0, aImageRect.Width(), aImageRect.Height()), gfx::ColorPattern(gfx::Color(r, g, b, 0.5)));
|
aDT->FillRect(gfx::Rect(0, 0, aImageRect.Width(), aImageRect.Height()), gfx::ColorPattern(gfx::Color(r, g, b, 0.5)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isInvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<WebRenderFallbackData>
|
already_AddRefed<WebRenderFallbackData>
|
||||||
|
@ -542,22 +563,33 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
|
||||||
RefPtr<gfx::DrawTarget> dummyDt =
|
RefPtr<gfx::DrawTarget> dummyDt =
|
||||||
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
|
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
|
||||||
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
|
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
|
||||||
PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
|
bool isInvalidated = PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
|
||||||
fallbackData->mBasicLayerManager, mManager, scale);
|
fallbackData->mBasicLayerManager, mManager, scale);
|
||||||
recorder->FlushItem(IntRect());
|
recorder->FlushItem(IntRect());
|
||||||
recorder->Finish();
|
recorder->Finish();
|
||||||
|
|
||||||
Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
|
if (isInvalidated) {
|
||||||
|
Range<uint8_t> bytes((uint8_t *)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
|
||||||
wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
|
wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
|
||||||
wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
|
wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
|
||||||
if (!aResources.AddBlobImage(key, descriptor, bytes)) {
|
if (!aResources.AddBlobImage(key, descriptor, bytes)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
fallbackData->SetKey(key);
|
fallbackData->SetKey(key);
|
||||||
|
} else {
|
||||||
|
// If there is no invalidation region and we don't have a image key,
|
||||||
|
// it means we don't need to push image for the item.
|
||||||
|
if (!fallbackData->GetKey().isSome()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fallbackData->CreateImageClientIfNeeded();
|
fallbackData->CreateImageClientIfNeeded();
|
||||||
RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
|
RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
|
||||||
RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
|
RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
|
||||||
|
bool isInvalidated = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
UpdateImageHelper helper(imageContainer, imageClient, paintSize.ToUnknownSize(), format);
|
UpdateImageHelper helper(imageContainer, imageClient, paintSize.ToUnknownSize(), format);
|
||||||
|
@ -566,19 +598,29 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
|
||||||
if (!dt) {
|
if (!dt) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
PaintItemByDrawTarget(aItem, dt, paintRect, offset,
|
isInvalidated = PaintItemByDrawTarget(aItem, dt, paintRect, offset,
|
||||||
aDisplayListBuilder,
|
aDisplayListBuilder,
|
||||||
fallbackData->mBasicLayerManager, mManager, scale);
|
fallbackData->mBasicLayerManager, mManager, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isInvalidated) {
|
||||||
|
// Update image if there it's invalidated.
|
||||||
if (!helper.UpdateImage()) {
|
if (!helper.UpdateImage()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// If there is no invalidation region and we don't have a image key,
|
||||||
|
// it means we don't need to push image for the item.
|
||||||
|
if (!fallbackData->GetKey().isSome()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force update the key in fallback data since we repaint the image in this path.
|
// Force update the key in fallback data since we repaint the image in this path.
|
||||||
// If not force update, fallbackData may reuse the original key because it
|
// If not force update, fallbackData may reuse the original key because it
|
||||||
// doesn't know UpdateImageHelper already updated the image container.
|
// doesn't know UpdateImageHelper already updated the image container.
|
||||||
if (!fallbackData->UpdateImageKey(imageContainer, aResources, true)) {
|
if (isInvalidated && !fallbackData->UpdateImageKey(imageContainer, aResources, true)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче