Bug 1384839 - Part1. Extract the generation of fallback data from PushItemAsImage into a helper function to reuse it for mask painting. r=kats
MozReview-Commit-ID: FUP6bZyfalQ
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -381,21 +381,22 @@ PaintItemByDrawTarget(nsDisplayItem* aIt
aDT->SetTransform(Matrix());
float r = float(rand()) / RAND_MAX;
float g = float(rand()) / RAND_MAX;
float b = float(rand()) / RAND_MAX;
aDT->FillRect(Rect(0, 0, aImageRect.width, aImageRect.height), ColorPattern(Color(r, g, b, 0.5)));
}
}
-bool
-WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder)
+already_AddRefed<WebRenderFallbackData>
+WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ LayerRect& aImageRect,
+ LayerPoint& aOffset)
{
RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
bool snap;
nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
nsRect clippedBounds = itemBounds;
const DisplayItemClip& clip = aItem->GetClip();
@@ -404,24 +405,23 @@ WebRenderLayerManager::PushItemAsImage(n
}
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
LayerRect bounds = ViewAs<LayerPixel>(
LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
LayerIntSize imageSize = RoundedToInt(bounds.Size());
- LayerRect imageRect;
- imageRect.SizeTo(LayerSize(imageSize));
+ aImageRect = LayerRect(LayerPoint(0, 0), LayerSize(imageSize));
if (imageSize.width == 0 || imageSize.height == 0) {
- return true;
+ return nullptr;
}
nsPoint shift = clippedBounds.TopLeft() - itemBounds.TopLeft();
- LayerPoint offset = ViewAs<LayerPixel>(
+ aOffset = ViewAs<LayerPixel>(
LayoutDevicePoint::FromAppUnits(aItem->ToReferenceFrame() + shift, appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
nsRegion invalidRegion;
nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
if (geometry) {
nsRect invalid;
@@ -443,57 +443,74 @@ WebRenderLayerManager::PushItemAsImage(n
}
if (!geometry || !invalidRegion.IsEmpty() || fallbackData->IsInvalid()) {
if (gfxPrefs::WebRenderBlobImages()) {
RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
RefPtr<gfx::DrawTarget> dummyDt =
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8X8);
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
- PaintItemByDrawTarget(aItem, dt, imageRect, offset, aDisplayListBuilder);
+ PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
recorder->Finish();
wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
wr::ImageKey key = WrBridge()->GetNextImageKey();
WrBridge()->SendAddBlobImage(key, imageSize.ToUnknownSize(), imageSize.width * 4, dt->GetFormat(), bytes);
fallbackData->SetKey(key);
} else {
fallbackData->CreateImageClientIfNeeded();
RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
{
UpdateImageHelper helper(imageContainer, imageClient, imageSize.ToUnknownSize());
{
RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
- PaintItemByDrawTarget(aItem, dt, imageRect, offset, aDisplayListBuilder);
+ PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
}
if (!helper.UpdateImage()) {
- return false;
+ return nullptr;
}
}
// 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
// doesn't know UpdateImageHelper already updated the image container.
if (!fallbackData->UpdateImageKey(imageContainer, true)) {
- return false;
+ return nullptr;
}
}
geometry = aItem->AllocateGeometry(aDisplayListBuilder);
fallbackData->SetInvalid(false);
}
// Update current bounds to fallback data
fallbackData->SetGeometry(Move(geometry));
fallbackData->SetBounds(clippedBounds);
MOZ_ASSERT(fallbackData->GetKey());
+ return fallbackData.forget();
+}
+
+bool
+WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ LayerRect imageRect;
+ LayerPoint offset;
+ RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aDisplayListBuilder,
+ imageRect, offset);
+ if (!fallbackData) {
+ return false;
+ }
+
wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect + offset);
aBuilder.PushImage(dest,
dest,
wr::ImageRendering::Auto,
fallbackData->GetKey().value());
return true;
}
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -65,16 +65,21 @@ public:
mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
gfx::IntSize& aSize);
bool PushImage(nsDisplayItem* aItem,
ImageContainer* aContainer,
mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
const LayerRect& aRect);
+ already_AddRefed<WebRenderFallbackData> GenerateFallbackData(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ LayerRect& aImageRect,
+ LayerPoint& aOffset);
bool PushItemAsImage(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsDisplayListBuilder* aDisplayListBuilder);
void CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
nsDisplayListBuilder* aDisplayListBuilder,
const StackingContextHelper& aSc,
wr::DisplayListBuilder& aBuilder);