--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -231,16 +231,17 @@ EXPORTS.mozilla.layers += [
'UpdateImageHelper.h',
'wr/AsyncImagePipelineManager.h',
'wr/IpcResourceUpdateQueue.h',
'wr/ScrollingLayersHelper.h',
'wr/StackingContextHelper.h',
'wr/WebRenderBridgeChild.h',
'wr/WebRenderBridgeParent.h',
'wr/WebRenderCanvasRenderer.h',
+ 'wr/WebRenderCommandsBuilder.h',
'wr/WebRenderImageHost.h',
'wr/WebRenderLayerManager.h',
'wr/WebRenderLayersLogging.h',
'wr/WebRenderMessageUtils.h',
'wr/WebRenderScrollData.h',
'wr/WebRenderScrollDataWrapper.h',
'wr/WebRenderTextureHost.h',
'wr/WebRenderUserData.h',
@@ -461,16 +462,17 @@ UNIFIED_SOURCES += [
'TextureWrapperImage.cpp',
'wr/AsyncImagePipelineManager.cpp',
'wr/IpcResourceUpdateQueue.cpp',
'wr/ScrollingLayersHelper.cpp',
'wr/StackingContextHelper.cpp',
'wr/WebRenderBridgeChild.cpp',
'wr/WebRenderBridgeParent.cpp',
'wr/WebRenderCanvasRenderer.cpp',
+ 'wr/WebRenderCommandsBuilder.cpp',
'wr/WebRenderImageHost.cpp',
'wr/WebRenderLayerManager.cpp',
'wr/WebRenderLayersLogging.cpp',
'wr/WebRenderScrollData.cpp',
'wr/WebRenderUserData.cpp',
# XXX here are some unified build error.
#'wr/WebRenderTextureHost.cpp'
]
--- a/gfx/layers/wr/ScrollingLayersHelper.cpp
+++ b/gfx/layers/wr/ScrollingLayersHelper.cpp
@@ -12,17 +12,17 @@
#include "UnitTransforms.h"
namespace mozilla {
namespace layers {
ScrollingLayersHelper::ScrollingLayersHelper(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aStackingContext,
- WebRenderLayerManager::ClipIdMap& aCache,
+ WebRenderCommandsBuilder::ClipIdMap& aCache,
bool aApzEnabled)
: mBuilder(&aBuilder)
, mPushedClipAndScroll(false)
{
int32_t auPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
if (!aApzEnabled) {
// If APZ is not enabled, we can ignore all the stuff with ASRs; we just
@@ -71,17 +71,17 @@ ScrollingLayersHelper::ScrollingLayersHe
void
ScrollingLayersHelper::DefineAndPushScrollLayers(nsDisplayItem* aItem,
const ActiveScrolledRoot* aAsr,
const DisplayItemClipChain* aChain,
wr::DisplayListBuilder& aBuilder,
int32_t aAppUnitsPerDevPixel,
const StackingContextHelper& aStackingContext,
- WebRenderLayerManager::ClipIdMap& aCache)
+ WebRenderCommandsBuilder::ClipIdMap& aCache)
{
if (!aAsr) {
return;
}
FrameMetrics::ViewID scrollId = nsLayoutUtils::ViewIDForASR(aAsr);
if (aBuilder.TopmostScrollId() == scrollId) {
// it's already been pushed, so we don't need to recurse any further.
return;
@@ -125,17 +125,17 @@ ScrollingLayersHelper::DefineAndPushScro
}
}
void
ScrollingLayersHelper::DefineAndPushChain(const DisplayItemClipChain* aChain,
wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aStackingContext,
int32_t aAppUnitsPerDevPixel,
- WebRenderLayerManager::ClipIdMap& aCache)
+ WebRenderCommandsBuilder::ClipIdMap& aCache)
{
if (!aChain) {
return;
}
auto it = aCache.find(aChain);
Maybe<wr::WrClipId> clipId = (it != aCache.end() ? Some(it->second) : Nothing());
if (clipId && clipId == aBuilder.TopmostClipId()) {
// it was already in the cache and pushed on the WR clip stack, so we don't
--- a/gfx/layers/wr/ScrollingLayersHelper.h
+++ b/gfx/layers/wr/ScrollingLayersHelper.h
@@ -23,33 +23,33 @@ struct FrameMetrics;
class StackingContextHelper;
class MOZ_RAII ScrollingLayersHelper
{
public:
ScrollingLayersHelper(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aStackingContext,
- WebRenderLayerManager::ClipIdMap& aCache,
+ WebRenderCommandsBuilder::ClipIdMap& aCache,
bool aApzEnabled);
~ScrollingLayersHelper();
private:
void DefineAndPushScrollLayers(nsDisplayItem* aItem,
const ActiveScrolledRoot* aAsr,
const DisplayItemClipChain* aChain,
wr::DisplayListBuilder& aBuilder,
int32_t aAppUnitsPerDevPixel,
const StackingContextHelper& aStackingContext,
- WebRenderLayerManager::ClipIdMap& aCache);
+ WebRenderCommandsBuilder::ClipIdMap& aCache);
void DefineAndPushChain(const DisplayItemClipChain* aChain,
wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aStackingContext,
int32_t aAppUnitsPerDevPixel,
- WebRenderLayerManager::ClipIdMap& aCache);
+ WebRenderCommandsBuilder::ClipIdMap& aCache);
bool DefineAndPushScrollLayer(const FrameMetrics& aMetrics,
const StackingContextHelper& aStackingContext);
wr::DisplayListBuilder* mBuilder;
bool mPushedClipAndScroll;
std::vector<wr::ScrollOrClipId> mPushedClips;
};
new file mode 100644
--- /dev/null
+++ b/gfx/layers/wr/WebRenderCommandsBuilder.cpp
@@ -0,0 +1,608 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "WebRenderCommandsBuilder.h"
+
+#include "BasicLayers.h"
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/gfx/DrawEventRecorder.h"
+#include "mozilla/layers/ImageClient.h"
+#include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
+#include "mozilla/layers/IpcResourceUpdateQueue.h"
+#include "mozilla/layers/ScrollingLayersHelper.h"
+#include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/layers/UpdateImageHelper.h"
+#include "nsDisplayListInvalidation.h"
+#include "WebRenderCanvasRenderer.h"
+#include "LayerTreeInvalidation.h"
+
+namespace mozilla {
+namespace layers {
+
+void WebRenderCommandsBuilder::Destroy()
+{
+ mLastCanvasDatas.Clear();
+ RemoveUnusedAndResetWebRenderUserData();
+}
+
+void
+WebRenderCommandsBuilder::BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResourceUpdates,
+ nsDisplayList* aDisplayList,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ WebRenderScrollData& aScrollData,
+ wr::LayoutSize& aContentSize)
+{
+ { // scoping for StackingContextHelper RAII
+
+ StackingContextHelper sc;
+ mParentCommands.Clear();
+ aScrollData = WebRenderScrollData();
+ MOZ_ASSERT(mLayerScrollData.empty());
+ mLastCanvasDatas.Clear();
+ mLastAsr = nullptr;
+
+ CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder, sc,
+ aBuilder, aResourceUpdates);
+
+ aBuilder.Finalize(aContentSize, mBuiltDisplayList);
+
+ // Make a "root" layer data that has everything else as descendants
+ mLayerScrollData.emplace_back();
+ mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
+ if (aDisplayListBuilder->IsBuildingLayerEventRegions()) {
+ nsIPresShell* shell = aDisplayListBuilder->RootReferenceFrame()->PresContext()->PresShell();
+ if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(shell)) {
+ mLayerScrollData.back().SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
+ }
+ }
+ auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
+ return aScrollData.HasMetadataFor(aScrollId);
+ };
+ if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
+ aDisplayListBuilder, nullptr, ContainerLayerParameters(), callback)) {
+ mLayerScrollData.back().AppendScrollMetadata(aScrollData, rootMetadata.ref());
+ }
+ // Append the WebRenderLayerScrollData items into WebRenderScrollData
+ // in reverse order, from topmost to bottommost. This is in keeping with
+ // the semantics of WebRenderScrollData.
+ for (auto i = mLayerScrollData.crbegin(); i != mLayerScrollData.crend(); i++) {
+ aScrollData.AddLayerData(*i);
+ }
+ mLayerScrollData.clear();
+ mClipIdCache.clear();
+
+ // Remove the user data those are not displayed on the screen and
+ // also reset the data to unused for next transaction.
+ RemoveUnusedAndResetWebRenderUserData();
+ }
+
+ aBuilder.PushBuiltDisplayList(mBuiltDisplayList);
+ mManager->WrBridge()->AddWebRenderParentCommands(mParentCommands);
+}
+
+void
+WebRenderCommandsBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ const StackingContextHelper& aSc,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources)
+{
+ bool apzEnabled = mManager->AsyncPanZoomEnabled();
+ EventRegions eventRegions;
+
+ for (nsDisplayItem* i = aDisplayList->GetBottom(); i; i = i->GetAbove()) {
+ nsDisplayItem* item = i;
+ DisplayItemType itemType = item->GetType();
+
+ // If the item is a event regions item, but is empty (has no regions in it)
+ // then we should just throw it out
+ if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
+ nsDisplayLayerEventRegions* eventRegions =
+ static_cast<nsDisplayLayerEventRegions*>(item);
+ if (eventRegions->IsEmpty()) {
+ continue;
+ }
+ }
+
+
+ // Peek ahead to the next item and try merging with it or swapping with it
+ // if necessary.
+ AutoTArray<nsDisplayItem*, 1> mergedItems;
+ mergedItems.AppendElement(item);
+ for (nsDisplayItem* peek = item->GetAbove(); peek; peek = peek->GetAbove()) {
+ if (!item->CanMerge(peek)) {
+ break;
+ }
+
+ mergedItems.AppendElement(peek);
+
+ // Move the iterator forward since we will merge this item.
+ i = peek;
+ }
+
+ if (mergedItems.Length() > 1) {
+ item = aDisplayListBuilder->MergeItems(mergedItems);
+ MOZ_ASSERT(item && itemType == item->GetType());
+ }
+
+ nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
+ if (item->ShouldFlattenAway(aDisplayListBuilder)) {
+ MOZ_ASSERT(childItems);
+ CreateWebRenderCommandsFromDisplayList(childItems, aDisplayListBuilder, aSc,
+ aBuilder, aResources);
+ continue;
+ }
+
+ bool forceNewLayerData = false;
+ size_t layerCountBeforeRecursing = mLayerScrollData.size();
+ if (apzEnabled) {
+ // For some types of display items we want to force a new
+ // WebRenderLayerScrollData object, to ensure we preserve the APZ-relevant
+ // data that is in the display item.
+ forceNewLayerData = item->UpdateScrollData(nullptr, nullptr);
+
+ // Anytime the ASR changes we also want to force a new layer data because
+ // the stack of scroll metadata is going to be different for this
+ // display item than previously, so we can't squash the display items
+ // into the same "layer".
+ const ActiveScrolledRoot* asr = item->GetActiveScrolledRoot();
+ if (asr != mLastAsr) {
+ mLastAsr = asr;
+ forceNewLayerData = true;
+ }
+
+ // If we're creating a new layer data then flush whatever event regions
+ // we've collected onto the old layer.
+ if (forceNewLayerData && !eventRegions.IsEmpty()) {
+ // If eventRegions is non-empty then we must have a layer data already,
+ // because we (below) force one if we encounter an event regions item
+ // with an empty layer data list. Additionally, the most recently
+ // created layer data must have been created from an item whose ASR
+ // is the same as the ASR on the event region items that were collapsed
+ // into |eventRegions|. This is because any ASR change causes us to force
+ // a new layer data which flushes the eventRegions.
+ MOZ_ASSERT(!mLayerScrollData.empty());
+ mLayerScrollData.back().AddEventRegions(eventRegions);
+ eventRegions.SetEmpty();
+ }
+
+ // Collapse event region data into |eventRegions|, which will either be
+ // empty, or filled with stuff from previous display items with the same
+ // ASR.
+ if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
+ nsDisplayLayerEventRegions* regionsItem =
+ static_cast<nsDisplayLayerEventRegions*>(item);
+ int32_t auPerDevPixel = item->Frame()->PresContext()->AppUnitsPerDevPixel();
+ EventRegions regions(
+ regionsItem->HitRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
+ regionsItem->MaybeHitRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
+ regionsItem->DispatchToContentHitRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
+ regionsItem->NoActionRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
+ regionsItem->HorizontalPanRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
+ regionsItem->VerticalPanRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel));
+
+ eventRegions.OrWith(regions);
+ if (mLayerScrollData.empty()) {
+ // If we don't have a layer data yet then create one because we will
+ // need it to store this event region information.
+ forceNewLayerData = true;
+ }
+ }
+
+ // If we're going to create a new layer data for this item, stash the
+ // ASR so that if we recurse into a sublist they will know where to stop
+ // walking up their ASR chain when building scroll metadata.
+ if (forceNewLayerData) {
+ mAsrStack.push_back(asr);
+ }
+ }
+
+ { // scope the ScrollingLayersHelper
+ ScrollingLayersHelper clip(item, aBuilder, aSc, mClipIdCache, apzEnabled);
+
+ // Note: this call to CreateWebRenderCommands can recurse back into
+ // this function if the |item| is a wrapper for a sublist.
+ if (!item->CreateWebRenderCommands(aBuilder, aResources, aSc, mManager,
+ aDisplayListBuilder)) {
+ PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder);
+ }
+ }
+
+ if (apzEnabled && forceNewLayerData) {
+ // Pop the thing we pushed before the recursion, so the topmost item on
+ // the stack is enclosing display item's ASR (or the stack is empty)
+ mAsrStack.pop_back();
+ const ActiveScrolledRoot* stopAtAsr =
+ mAsrStack.empty() ? nullptr : mAsrStack.back();
+
+ int32_t descendants = mLayerScrollData.size() - layerCountBeforeRecursing;
+
+ mLayerScrollData.emplace_back();
+ mLayerScrollData.back().Initialize(mManager->GetScrollData(), item, descendants, stopAtAsr);
+ }
+ }
+
+ // If we have any event region info left over we need to flush it before we
+ // return. Again, at this point the layer data list must be non-empty, and
+ // the most recently created layer data will have been created by an item
+ // with matching ASRs.
+ if (!eventRegions.IsEmpty()) {
+ MOZ_ASSERT(apzEnabled);
+ MOZ_ASSERT(!mLayerScrollData.empty());
+ mLayerScrollData.back().AddEventRegions(eventRegions);
+ }
+}
+
+Maybe<wr::ImageKey>
+WebRenderCommandsBuilder::CreateImageKey(nsDisplayItem* aItem,
+ ImageContainer* aContainer,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ gfx::IntSize& aSize)
+{
+ RefPtr<WebRenderImageData> imageData = CreateOrRecycleWebRenderUserData<WebRenderImageData>(aItem);
+ MOZ_ASSERT(imageData);
+
+ if (aContainer->IsAsync()) {
+ bool snap;
+ nsRect bounds = aItem->GetBounds(nullptr, &snap);
+ int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+ LayerRect rect = ViewAs<LayerPixel>(
+ LayoutDeviceRect::FromAppUnits(bounds, appUnitsPerDevPixel),
+ PixelCastJustification::WebRenderHasUnitResolution);
+ LayerRect scBounds(0, 0, rect.width, rect.Height());
+ gfx::MaybeIntSize scaleToSize;
+ if (!aContainer->GetScaleHint().IsEmpty()) {
+ scaleToSize = Some(aContainer->GetScaleHint());
+ }
+ // TODO!
+ // We appear to be using the image bridge for a lot (most/all?) of
+ // layers-free image handling and that breaks frame consistency.
+ imageData->CreateAsyncImageWebRenderCommands(aBuilder,
+ aContainer,
+ aSc,
+ rect,
+ scBounds,
+ gfx::Matrix4x4(),
+ scaleToSize,
+ wr::ImageRendering::Auto,
+ wr::MixBlendMode::Normal,
+ !aItem->BackfaceIsHidden());
+ return Nothing();
+ }
+
+ AutoLockImage autoLock(aContainer);
+ if (!autoLock.HasImage()) {
+ return Nothing();
+ }
+ mozilla::layers::Image* image = autoLock.GetImage();
+ aSize = image->GetSize();
+
+ return imageData->UpdateImageKey(aContainer, aResources);
+}
+
+bool
+WebRenderCommandsBuilder::PushImage(nsDisplayItem* aItem,
+ ImageContainer* aContainer,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ const LayerRect& aRect)
+{
+ gfx::IntSize size;
+ Maybe<wr::ImageKey> key = CreateImageKey(aItem, aContainer,
+ aBuilder, aResources,
+ aSc, size);
+ if (aContainer->IsAsync()) {
+ // Async ImageContainer does not create ImageKey, instead it uses Pipeline.
+ MOZ_ASSERT(key.isNothing());
+ return true;
+ }
+ if (!key) {
+ return false;
+ }
+
+ auto r = aSc.ToRelativeLayoutRect(aRect);
+ gfx::SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
+ aBuilder.PushImage(r, r, !aItem->BackfaceIsHidden(), wr::ToImageRendering(sampleFilter), key.value());
+
+ return true;
+}
+
+static void
+PaintItemByDrawTarget(nsDisplayItem* aItem,
+ gfx::DrawTarget* aDT,
+ const LayerRect& aImageRect,
+ const LayerPoint& aOffset,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ RefPtr<BasicLayerManager>& aManager,
+ WebRenderLayerManager* aWrManager,
+ const gfx::Size& aScale)
+{
+ MOZ_ASSERT(aDT);
+
+ aDT->ClearRect(aImageRect.ToUnknownRect());
+ RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT);
+ MOZ_ASSERT(context);
+
+ context->SetMatrix(context->CurrentMatrix().PreScale(aScale.width, aScale.height).PreTranslate(-aOffset.x, -aOffset.y));
+
+ switch (aItem->GetType()) {
+ case DisplayItemType::TYPE_MASK:
+ static_cast<nsDisplayMask*>(aItem)->PaintMask(aDisplayListBuilder, context);
+ break;
+ case DisplayItemType::TYPE_FILTER:
+ {
+ if (aManager == nullptr) {
+ aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
+ }
+
+ FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
+ layerBuilder->Init(aDisplayListBuilder, aManager);
+ layerBuilder->DidBeginRetainedLayerTransaction(aManager);
+
+ aManager->BeginTransactionWithTarget(context);
+
+ ContainerLayerParameters param;
+ RefPtr<Layer> layer =
+ static_cast<nsDisplayFilter*>(aItem)->BuildLayer(aDisplayListBuilder,
+ aManager, param);
+
+ if (layer) {
+ UniquePtr<LayerProperties> props;
+ props = Move(LayerProperties::CloneFrom(aManager->GetRoot()));
+
+ aManager->SetRoot(layer);
+ layerBuilder->WillEndTransaction();
+
+ static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder,
+ context, aManager);
+ }
+
+ if (aManager->InTransaction()) {
+ aManager->AbortTransaction();
+ }
+ aManager->SetTarget(nullptr);
+ break;
+ }
+ default:
+ aItem->Paint(aDisplayListBuilder, context);
+ break;
+ }
+
+ if (gfxPrefs::WebRenderHighlightPaintedLayers()) {
+ 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)));
+ }
+ if (aItem->Frame()->PresContext()->GetPaintFlashing()) {
+ aDT->SetTransform(gfx::Matrix());
+ float r = float(rand()) / RAND_MAX;
+ float g = 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)));
+ }
+}
+
+already_AddRefed<WebRenderFallbackData>
+WebRenderCommandsBuilder::GenerateFallbackData(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ LayerRect& aImageRect)
+{
+ RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
+
+ bool snap;
+ nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
+ nsRect clippedBounds = itemBounds;
+
+ const DisplayItemClip& clip = aItem->GetClip();
+ // Blob images will only draw the visible area of the blob so we don't need to clip
+ // them here and can just rely on the webrender clipping.
+ if (clip.HasClip() && !gfxPrefs::WebRenderBlobImages()) {
+ clippedBounds = itemBounds.Intersect(clip.GetClipRect());
+ }
+
+ // nsDisplayItem::Paint() may refer the variables that come from ComputeVisibility().
+ // So we should call ComputeVisibility() before painting. e.g.: nsDisplayBoxShadowInner
+ // uses mVisibleRegion in Paint() and mVisibleRegion is computed in
+ // nsDisplayBoxShadowInner::ComputeVisibility().
+ nsRegion visibleRegion(clippedBounds);
+ aItem->ComputeVisibility(aDisplayListBuilder, &visibleRegion);
+
+ const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+ LayerRect bounds = ViewAs<LayerPixel>(
+ LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel),
+ PixelCastJustification::WebRenderHasUnitResolution);
+
+ gfx::Size scale = aSc.GetInheritedScale();
+ LayerIntSize paintSize = RoundedToInt(LayerSize(bounds.width * scale.width, bounds.height * scale.height));
+ if (paintSize.width == 0 || paintSize.height == 0) {
+ return nullptr;
+ }
+
+ bool needPaint = true;
+ LayerIntPoint offset = RoundedToInt(bounds.TopLeft());
+ aImageRect = LayerRect(offset, LayerSize(RoundedToInt(bounds.Size())));
+ LayerRect paintRect = LayerRect(LayerPoint(0, 0), LayerSize(paintSize));
+ nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
+
+ // nsDisplayFilter is rendered via BasicLayerManager which means the invalidate
+ // region is unknown until we traverse the displaylist contained by it.
+ if (geometry && !fallbackData->IsInvalid() &&
+ aItem->GetType() != DisplayItemType::TYPE_FILTER) {
+ nsRect invalid;
+ nsRegion invalidRegion;
+
+ if (aItem->IsInvalid(invalid)) {
+ invalidRegion.OrWith(clippedBounds);
+ } else {
+ nsPoint shift = itemBounds.TopLeft() - geometry->mBounds.TopLeft();
+ geometry->MoveBy(shift);
+ aItem->ComputeInvalidationRegion(aDisplayListBuilder, geometry, &invalidRegion);
+
+ nsRect lastBounds = fallbackData->GetBounds();
+ lastBounds.MoveBy(shift);
+
+ if (!lastBounds.IsEqualInterior(clippedBounds)) {
+ invalidRegion.OrWith(lastBounds);
+ invalidRegion.OrWith(clippedBounds);
+ }
+ }
+ needPaint = !invalidRegion.IsEmpty();
+ }
+
+ if (needPaint) {
+ gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
+ gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
+ if (gfxPrefs::WebRenderBlobImages()) {
+ bool snapped;
+ bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
+
+ RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
+ RefPtr<gfx::DrawTarget> dummyDt =
+ gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
+ RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
+ PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
+ fallbackData->mBasicLayerManager, mManager, scale);
+ recorder->Finish();
+
+ Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
+ wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
+ wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
+ aResources.AddBlobImage(key, descriptor, bytes);
+ fallbackData->SetKey(key);
+ } else {
+ fallbackData->CreateImageClientIfNeeded();
+ RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
+ RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
+
+ {
+ UpdateImageHelper helper(imageContainer, imageClient, paintSize.ToUnknownSize(), format);
+ {
+ RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
+ if (!dt) {
+ return nullptr;
+ }
+ PaintItemByDrawTarget(aItem, dt, paintRect, offset,
+ aDisplayListBuilder,
+ fallbackData->mBasicLayerManager, mManager, scale);
+ }
+ if (!helper.UpdateImage()) {
+ 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, aResources, true)) {
+ 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();
+}
+
+Maybe<wr::WrImageMask>
+WebRenderCommandsBuilder::BuildWrMaskImage(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ const LayerRect& aBounds)
+{
+ LayerRect imageRect;
+ RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aResources,
+ aSc, aDisplayListBuilder,
+ imageRect);
+ if (!fallbackData) {
+ return Nothing();
+ }
+
+ wr::WrImageMask imageMask;
+ imageMask.image = fallbackData->GetKey().value();
+ imageMask.rect = aSc.ToRelativeLayoutRect(aBounds);
+ imageMask.repeat = false;
+ return Some(imageMask);
+}
+
+bool
+WebRenderCommandsBuilder::PushItemAsImage(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ LayerRect imageRect;
+ RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aResources,
+ aSc, aDisplayListBuilder,
+ imageRect);
+ if (!fallbackData) {
+ return false;
+ }
+
+ wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect);
+ gfx::SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
+ aBuilder.PushImage(dest,
+ dest,
+ !aItem->BackfaceIsHidden(),
+ wr::ToImageRendering(sampleFilter),
+ fallbackData->GetKey().value());
+ return true;
+}
+
+void
+WebRenderCommandsBuilder::RemoveUnusedAndResetWebRenderUserData()
+{
+ for (auto iter = mWebRenderUserDatas.Iter(); !iter.Done(); iter.Next()) {
+ WebRenderUserData* data = iter.Get()->GetKey();
+ if (!data->IsUsed()) {
+ nsIFrame* frame = data->GetFrame();
+
+ MOZ_ASSERT(frame->HasProperty(nsIFrame::WebRenderUserDataProperty()));
+
+ nsIFrame::WebRenderUserDataTable* userDataTable =
+ frame->GetProperty(nsIFrame::WebRenderUserDataProperty());
+
+ MOZ_ASSERT(userDataTable->Count());
+
+ userDataTable->Remove(data->GetDisplayItemKey());
+
+ if (!userDataTable->Count()) {
+ frame->RemoveProperty(nsIFrame::WebRenderUserDataProperty());
+ }
+
+ if (data->GetType() == WebRenderUserData::UserDataType::eCanvas) {
+ mLastCanvasDatas.RemoveEntry(data->AsCanvasData());
+ }
+
+ iter.Remove();
+ continue;
+ }
+
+ data->SetUsed(false);
+ }
+}
+
+} // namespace layers
+} // namespace mozilla
+
new file mode 100644
--- /dev/null
+++ b/gfx/layers/wr/WebRenderCommandsBuilder.h
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GFX_WEBRENDERCOMMANDSBUILDER_H
+#define GFX_WEBRENDERCOMMANDSBUILDER_H
+
+#include "mozilla/webrender/WebRenderAPI.h"
+#include "mozilla/layers/WebRenderMessages.h"
+#include "mozilla/layers/WebRenderScrollData.h"
+#include "mozilla/layers/WebRenderUserData.h"
+#include "nsDisplayList.h"
+#include "nsIFrame.h"
+
+namespace mozilla {
+
+namespace layers {
+
+class CanvasLayer;
+class ImageClient;
+class ImageContainer;
+class WebRenderBridgeChild;
+class WebRenderCanvasData;
+class WebRenderCanvasRendererAsync;
+class WebRenderImageData;
+class WebRenderFallbackData;
+class WebRenderParentCommand;
+class WebRenderUserData;
+
+class WebRenderCommandsBuilder {
+ typedef nsTHashtable<nsRefPtrHashKey<WebRenderUserData>> WebRenderUserDataRefTable;
+ typedef nsTHashtable<nsRefPtrHashKey<WebRenderCanvasData>> CanvasDataSet;
+
+public:
+ explicit WebRenderCommandsBuilder(WebRenderLayerManager* aManager)
+ : mManager(aManager)
+ , mLastAsr(nullptr)
+ {}
+
+ void Destroy();
+
+ void BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResourceUpdates,
+ nsDisplayList* aDisplayList,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ WebRenderScrollData& aScrollData,
+ wr::LayoutSize& aContentSize);
+
+ Maybe<wr::ImageKey> CreateImageKey(nsDisplayItem* aItem,
+ ImageContainer* aContainer,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ gfx::IntSize& aSize);
+
+ WebRenderUserDataRefTable* GetWebRenderUserDataTable() { return &mWebRenderUserDatas; }
+
+ bool PushImage(nsDisplayItem* aItem,
+ ImageContainer* aContainer,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ const LayerRect& aRect);
+
+ Maybe<wr::WrImageMask> BuildWrMaskImage(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ const LayerRect& aBounds);
+
+ bool PushItemAsImage(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder);
+
+ void CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ const StackingContextHelper& aSc,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources);
+
+ already_AddRefed<WebRenderFallbackData> GenerateFallbackData(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder,
+ LayerRect& aImageRect);
+
+ void RemoveUnusedAndResetWebRenderUserData();
+
+ // Those are data that we kept between transactions. We used to cache some
+ // data in the layer. But in layers free mode, we don't have layer which
+ // means we need some other place to cached the data between transaction.
+ // We store the data in frame's property.
+ template<class T> already_AddRefed<T>
+ CreateOrRecycleWebRenderUserData(nsDisplayItem* aItem,
+ bool* aOutIsRecycled = nullptr)
+ {
+ MOZ_ASSERT(aItem);
+ nsIFrame* frame = aItem->Frame();
+ if (aOutIsRecycled) {
+ *aOutIsRecycled = true;
+ }
+
+ nsIFrame::WebRenderUserDataTable* userDataTable =
+ frame->GetProperty(nsIFrame::WebRenderUserDataProperty());
+
+ if (!userDataTable) {
+ userDataTable = new nsIFrame::WebRenderUserDataTable();
+ frame->AddProperty(nsIFrame::WebRenderUserDataProperty(), userDataTable);
+ }
+
+ RefPtr<WebRenderUserData>& data = userDataTable->GetOrInsert(aItem->GetPerFrameKey());
+ if (!data || (data->GetType() != T::Type()) || !data->IsDataValid(mManager)) {
+ // To recreate a new user data, we should remove the data from the table first.
+ if (data) {
+ data->RemoveFromTable();
+ }
+ data = new T(mManager, aItem);
+ mWebRenderUserDatas.PutEntry(data);
+ if (aOutIsRecycled) {
+ *aOutIsRecycled = false;
+ }
+ }
+
+ MOZ_ASSERT(data);
+ MOZ_ASSERT(data->GetType() == T::Type());
+
+ // Mark the data as being used. We will remove unused user data in the end of EndTransaction.
+ data->SetUsed(true);
+
+ if (T::Type() == WebRenderUserData::UserDataType::eCanvas) {
+ mLastCanvasDatas.PutEntry(data->AsCanvasData());
+ }
+ RefPtr<T> res = static_cast<T*>(data.get());
+ return res.forget();
+ }
+
+public:
+ // Note: two DisplayItemClipChain* A and B might actually be "equal" (as per
+ // DisplayItemClipChain::Equal(A, B)) even though they are not the same pointer
+ // (A != B). In this hopefully-rare case, they will get separate entries
+ // in this map when in fact we could collapse them. However, to collapse
+ // them involves writing a custom hash function for the pointer type such that
+ // A and B hash to the same things whenever DisplayItemClipChain::Equal(A, B)
+ // is true, and that will incur a performance penalty for all the hashmap
+ // operations, so is probably not worth it. With the current code we might
+ // end up creating multiple clips in WR that are effectively identical but
+ // have separate clip ids. Hopefully this won't happen very often.
+ typedef std::unordered_map<const DisplayItemClipChain*, wr::WrClipId> ClipIdMap;
+
+private:
+ WebRenderLayerManager* mManager;
+ ClipIdMap mClipIdCache;
+
+ // These fields are used to save a copy of the display list for
+ // empty transactions in layers-free mode.
+ wr::BuiltDisplayList mBuiltDisplayList;
+ nsTArray<WebRenderParentCommand> mParentCommands;
+
+ // We use this as a temporary data structure while building the mScrollData
+ // inside a layers-free transaction.
+ std::vector<WebRenderLayerScrollData> mLayerScrollData;
+ // We use this as a temporary data structure to track the current displayGenerateFallbackData
+ // item's ASR as we recurse in CreateWebRenderCommandsFromDisplayList. We
+ // need this so that WebRenderLayerScrollData items that deeper in the
+ // tree don't duplicate scroll metadata that their ancestors already have.
+ std::vector<const ActiveScrolledRoot*> mAsrStack;
+ const ActiveScrolledRoot* mLastAsr;
+
+ WebRenderUserDataRefTable mWebRenderUserDatas;
+
+ // Store of WebRenderCanvasData objects for use in empty transactions
+ CanvasDataSet mLastCanvasDatas;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif /* GFX_WEBRENDERCOMMANDSBUILDER_H */
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -24,21 +24,21 @@ namespace mozilla {
using namespace gfx;
namespace layers {
WebRenderLayerManager::WebRenderLayerManager(nsIWidget* aWidget)
: mWidget(aWidget)
, mLatestTransactionId(0)
- , mLastAsr(nullptr)
, mNeedsComposite(false)
, mIsFirstPaint(false)
, mTarget(nullptr)
, mPaintSequenceNumber(0)
+ , mWebRenderCommandsBuilder(this)
{
MOZ_COUNT_CTOR(WebRenderLayerManager);
}
KnowsCompositor*
WebRenderLayerManager::AsKnowsCompositor()
{
return mWrChild;
@@ -101,18 +101,17 @@ WebRenderLayerManager::DoDestroy(bool aI
}
// Clear this before calling RemoveUnusedAndResetWebRenderUserData(),
// otherwise that function might destroy some WebRenderAnimationData instances
// which will put stuff back into mDiscardedCompositorAnimationsIds. If
// mActiveCompositorAnimationIds is empty that won't happen.
mActiveCompositorAnimationIds.clear();
- mLastCanvasDatas.Clear();
- RemoveUnusedAndResetWebRenderUserData();
+ mWebRenderCommandsBuilder.Destroy();
if (mTransactionIdAllocator) {
// Make sure to notify the refresh driver just in case it's waiting on a
// pending transaction. Do this at the top of the event loop so we don't
// cause a paint to occur during compositor shutdown.
RefPtr<TransactionIdAllocator> allocator = mTransactionIdAllocator;
uint64_t id = mLatestTransactionId;
@@ -207,499 +206,16 @@ PopulateScrollData(WebRenderScrollData&
for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
descendants += PopulateScrollData(aTarget, child);
}
aTarget.GetLayerDataMutable(index)->Initialize(aTarget, aLayer, descendants);
return descendants + 1;
}
void
-WebRenderLayerManager::CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
- nsDisplayListBuilder* aDisplayListBuilder,
- const StackingContextHelper& aSc,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources)
-{
- bool apzEnabled = AsyncPanZoomEnabled();
- EventRegions eventRegions;
-
- for (nsDisplayItem* i = aDisplayList->GetBottom(); i; i = i->GetAbove()) {
- nsDisplayItem* item = i;
- DisplayItemType itemType = item->GetType();
-
- // If the item is a event regions item, but is empty (has no regions in it)
- // then we should just throw it out
- if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
- nsDisplayLayerEventRegions* eventRegions =
- static_cast<nsDisplayLayerEventRegions*>(item);
- if (eventRegions->IsEmpty()) {
- continue;
- }
- }
-
- // Peek ahead to the next item and try merging with it or swapping with it
- // if necessary.
- AutoTArray<nsDisplayItem*, 1> mergedItems;
- mergedItems.AppendElement(item);
- for (nsDisplayItem* peek = item->GetAbove(); peek; peek = peek->GetAbove()) {
- if (!item->CanMerge(peek)) {
- break;
- }
-
- mergedItems.AppendElement(peek);
-
- // Move the iterator forward since we will merge this item.
- i = peek;
- }
-
- if (mergedItems.Length() > 1) {
- item = aDisplayListBuilder->MergeItems(mergedItems);
- MOZ_ASSERT(item && itemType == item->GetType());
- }
-
- nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
- if (item->ShouldFlattenAway(aDisplayListBuilder)) {
- MOZ_ASSERT(childItems);
- CreateWebRenderCommandsFromDisplayList(childItems, aDisplayListBuilder, aSc,
- aBuilder, aResources);
- continue;
- }
-
- bool forceNewLayerData = false;
- size_t layerCountBeforeRecursing = mLayerScrollData.size();
- if (apzEnabled) {
- // For some types of display items we want to force a new
- // WebRenderLayerScrollData object, to ensure we preserve the APZ-relevant
- // data that is in the display item.
- forceNewLayerData = item->UpdateScrollData(nullptr, nullptr);
-
- // Anytime the ASR changes we also want to force a new layer data because
- // the stack of scroll metadata is going to be different for this
- // display item than previously, so we can't squash the display items
- // into the same "layer".
- const ActiveScrolledRoot* asr = item->GetActiveScrolledRoot();
- if (asr != mLastAsr) {
- mLastAsr = asr;
- forceNewLayerData = true;
- }
-
- // If we're creating a new layer data then flush whatever event regions
- // we've collected onto the old layer.
- if (forceNewLayerData && !eventRegions.IsEmpty()) {
- // If eventRegions is non-empty then we must have a layer data already,
- // because we (below) force one if we encounter an event regions item
- // with an empty layer data list. Additionally, the most recently
- // created layer data must have been created from an item whose ASR
- // is the same as the ASR on the event region items that were collapsed
- // into |eventRegions|. This is because any ASR change causes us to force
- // a new layer data which flushes the eventRegions.
- MOZ_ASSERT(!mLayerScrollData.empty());
- mLayerScrollData.back().AddEventRegions(eventRegions);
- eventRegions.SetEmpty();
- }
-
- // Collapse event region data into |eventRegions|, which will either be
- // empty, or filled with stuff from previous display items with the same
- // ASR.
- if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
- nsDisplayLayerEventRegions* regionsItem =
- static_cast<nsDisplayLayerEventRegions*>(item);
- int32_t auPerDevPixel = item->Frame()->PresContext()->AppUnitsPerDevPixel();
- EventRegions regions(
- regionsItem->HitRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
- regionsItem->MaybeHitRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
- regionsItem->DispatchToContentHitRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
- regionsItem->NoActionRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
- regionsItem->HorizontalPanRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel),
- regionsItem->VerticalPanRegion().ScaleToOutsidePixels(1.0f, 1.0f, auPerDevPixel));
-
- eventRegions.OrWith(regions);
- if (mLayerScrollData.empty()) {
- // If we don't have a layer data yet then create one because we will
- // need it to store this event region information.
- forceNewLayerData = true;
- }
- }
-
- // If we're going to create a new layer data for this item, stash the
- // ASR so that if we recurse into a sublist they will know where to stop
- // walking up their ASR chain when building scroll metadata.
- if (forceNewLayerData) {
- mAsrStack.push_back(asr);
- }
- }
-
- { // scope the ScrollingLayersHelper
- ScrollingLayersHelper clip(item, aBuilder, aSc, mClipIdCache, AsyncPanZoomEnabled());
-
- // Note: this call to CreateWebRenderCommands can recurse back into
- // this function if the |item| is a wrapper for a sublist.
- if (!item->CreateWebRenderCommands(aBuilder, aResources, aSc, this,
- aDisplayListBuilder)) {
- PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder);
- }
- }
-
- if (apzEnabled && forceNewLayerData) {
- // Pop the thing we pushed before the recursion, so the topmost item on
- // the stack is enclosing display item's ASR (or the stack is empty)
- mAsrStack.pop_back();
- const ActiveScrolledRoot* stopAtAsr =
- mAsrStack.empty() ? nullptr : mAsrStack.back();
-
- int32_t descendants = mLayerScrollData.size() - layerCountBeforeRecursing;
-
- mLayerScrollData.emplace_back();
- mLayerScrollData.back().Initialize(mScrollData, item, descendants, stopAtAsr);
- }
- }
-
- // If we have any event region info left over we need to flush it before we
- // return. Again, at this point the layer data list must be non-empty, and
- // the most recently created layer data will have been created by an item
- // with matching ASRs.
- if (!eventRegions.IsEmpty()) {
- MOZ_ASSERT(apzEnabled);
- MOZ_ASSERT(!mLayerScrollData.empty());
- mLayerScrollData.back().AddEventRegions(eventRegions);
- }
-}
-
-Maybe<wr::ImageKey>
-WebRenderLayerManager::CreateImageKey(nsDisplayItem* aItem,
- ImageContainer* aContainer,
- mozilla::wr::DisplayListBuilder& aBuilder,
- mozilla::wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- gfx::IntSize& aSize)
-{
- RefPtr<WebRenderImageData> imageData = CreateOrRecycleWebRenderUserData<WebRenderImageData>(aItem);
- MOZ_ASSERT(imageData);
-
- if (aContainer->IsAsync()) {
- bool snap;
- nsRect bounds = aItem->GetBounds(nullptr, &snap);
- int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
- LayerRect rect = ViewAs<LayerPixel>(
- LayoutDeviceRect::FromAppUnits(bounds, appUnitsPerDevPixel),
- PixelCastJustification::WebRenderHasUnitResolution);
- LayerRect scBounds(0, 0, rect.width, rect.Height());
- MaybeIntSize scaleToSize;
- if (!aContainer->GetScaleHint().IsEmpty()) {
- scaleToSize = Some(aContainer->GetScaleHint());
- }
- // TODO!
- // We appear to be using the image bridge for a lot (most/all?) of
- // layers-free image handling and that breaks frame consistency.
- imageData->CreateAsyncImageWebRenderCommands(aBuilder,
- aContainer,
- aSc,
- rect,
- scBounds,
- gfx::Matrix4x4(),
- scaleToSize,
- wr::ImageRendering::Auto,
- wr::MixBlendMode::Normal,
- !aItem->BackfaceIsHidden());
- return Nothing();
- }
-
- AutoLockImage autoLock(aContainer);
- if (!autoLock.HasImage()) {
- return Nothing();
- }
- mozilla::layers::Image* image = autoLock.GetImage();
- aSize = image->GetSize();
-
- return imageData->UpdateImageKey(aContainer, aResources);
-}
-
-bool
-WebRenderLayerManager::PushImage(nsDisplayItem* aItem,
- ImageContainer* aContainer,
- mozilla::wr::DisplayListBuilder& aBuilder,
- mozilla::wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- const LayerRect& aRect)
-{
- gfx::IntSize size;
- Maybe<wr::ImageKey> key = CreateImageKey(aItem, aContainer,
- aBuilder, aResources,
- aSc, size);
- if (aContainer->IsAsync()) {
- // Async ImageContainer does not create ImageKey, instead it uses Pipeline.
- MOZ_ASSERT(key.isNothing());
- return true;
- }
- if (!key) {
- return false;
- }
-
- auto r = aSc.ToRelativeLayoutRect(aRect);
- SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
- aBuilder.PushImage(r, r, !aItem->BackfaceIsHidden(), wr::ToImageRendering(sampleFilter), key.value());
-
- return true;
-}
-
-static void
-PaintItemByDrawTarget(nsDisplayItem* aItem,
- DrawTarget* aDT,
- const LayerRect& aImageRect,
- const LayerPoint& aOffset,
- nsDisplayListBuilder* aDisplayListBuilder,
- RefPtr<BasicLayerManager>& aManager,
- WebRenderLayerManager* aWrManager,
- const gfx::Size& aScale)
-{
- MOZ_ASSERT(aDT);
-
- aDT->ClearRect(aImageRect.ToUnknownRect());
- RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT);
- MOZ_ASSERT(context);
-
- context->SetMatrix(context->CurrentMatrix().PreScale(aScale.width, aScale.height).PreTranslate(-aOffset.x, -aOffset.y));
-
- switch (aItem->GetType()) {
- case DisplayItemType::TYPE_MASK:
- static_cast<nsDisplayMask*>(aItem)->PaintMask(aDisplayListBuilder, context);
- break;
- case DisplayItemType::TYPE_FILTER:
- {
- if (aManager == nullptr) {
- aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
- }
-
- FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
- layerBuilder->Init(aDisplayListBuilder, aManager);
- layerBuilder->DidBeginRetainedLayerTransaction(aManager);
-
- aManager->BeginTransactionWithTarget(context);
-
- ContainerLayerParameters param;
- RefPtr<Layer> layer =
- static_cast<nsDisplayFilter*>(aItem)->BuildLayer(aDisplayListBuilder,
- aManager, param);
-
- if (layer) {
- UniquePtr<LayerProperties> props;
- props = Move(LayerProperties::CloneFrom(aManager->GetRoot()));
-
- aManager->SetRoot(layer);
- layerBuilder->WillEndTransaction();
-
- static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder,
- context, aManager);
- }
-
- if (aManager->InTransaction()) {
- aManager->AbortTransaction();
- }
- aManager->SetTarget(nullptr);
- break;
- }
- default:
- aItem->Paint(aDisplayListBuilder, context);
- break;
- }
-
- if (gfxPrefs::WebRenderHighlightPaintedLayers()) {
- aDT->SetTransform(Matrix());
- aDT->FillRect(Rect(0, 0, aImageRect.Width(), aImageRect.Height()), ColorPattern(Color(1.0, 0.0, 0.0, 0.5)));
- }
- if (aItem->Frame()->PresContext()->GetPaintFlashing()) {
- 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)));
- }
-}
-
-already_AddRefed<WebRenderFallbackData>
-WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder,
- LayerRect& aImageRect)
-{
- RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
-
- bool snap;
- nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
- nsRect clippedBounds = itemBounds;
-
- const DisplayItemClip& clip = aItem->GetClip();
- // Blob images will only draw the visible area of the blob so we don't need to clip
- // them here and can just rely on the webrender clipping.
- if (clip.HasClip() && !gfxPrefs::WebRenderBlobImages()) {
- clippedBounds = itemBounds.Intersect(clip.GetClipRect());
- }
-
- // nsDisplayItem::Paint() may refer the variables that come from ComputeVisibility().
- // So we should call ComputeVisibility() before painting. e.g.: nsDisplayBoxShadowInner
- // uses mVisibleRegion in Paint() and mVisibleRegion is computed in
- // nsDisplayBoxShadowInner::ComputeVisibility().
- nsRegion visibleRegion(clippedBounds);
- aItem->ComputeVisibility(aDisplayListBuilder, &visibleRegion);
-
- const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
- LayerRect bounds = ViewAs<LayerPixel>(
- LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel),
- PixelCastJustification::WebRenderHasUnitResolution);
-
- gfx::Size scale = aSc.GetInheritedScale();
- LayerIntSize paintSize = RoundedToInt(LayerSize(bounds.width * scale.width, bounds.height * scale.height));
- if (paintSize.width == 0 || paintSize.height == 0) {
- return nullptr;
- }
-
- bool needPaint = true;
- LayerIntPoint offset = RoundedToInt(bounds.TopLeft());
- aImageRect = LayerRect(offset, LayerSize(RoundedToInt(bounds.Size())));
- LayerRect paintRect = LayerRect(LayerPoint(0, 0), LayerSize(paintSize));
- nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
-
- // nsDisplayFilter is rendered via BasicLayerManager which means the invalidate
- // region is unknown until we traverse the displaylist contained by it.
- if (geometry && !fallbackData->IsInvalid() &&
- aItem->GetType() != DisplayItemType::TYPE_FILTER) {
- nsRect invalid;
- nsRegion invalidRegion;
-
- if (aItem->IsInvalid(invalid)) {
- invalidRegion.OrWith(clippedBounds);
- } else {
- nsPoint shift = itemBounds.TopLeft() - geometry->mBounds.TopLeft();
- geometry->MoveBy(shift);
- aItem->ComputeInvalidationRegion(aDisplayListBuilder, geometry, &invalidRegion);
-
- nsRect lastBounds = fallbackData->GetBounds();
- lastBounds.MoveBy(shift);
-
- if (!lastBounds.IsEqualInterior(clippedBounds)) {
- invalidRegion.OrWith(lastBounds);
- invalidRegion.OrWith(clippedBounds);
- }
- }
- needPaint = !invalidRegion.IsEmpty();
- }
-
- if (needPaint) {
- gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
- gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
- if (gfxPrefs::WebRenderBlobImages()) {
- bool snapped;
- bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
-
- RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
- RefPtr<gfx::DrawTarget> dummyDt =
- gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
- RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
- PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
- fallbackData->mBasicLayerManager, this, scale);
- recorder->Finish();
-
- Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
- wr::ImageKey key = WrBridge()->GetNextImageKey();
- wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
- aResources.AddBlobImage(key, descriptor, bytes);
- fallbackData->SetKey(key);
- } else {
- fallbackData->CreateImageClientIfNeeded();
- RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
- RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
-
- {
- UpdateImageHelper helper(imageContainer, imageClient, paintSize.ToUnknownSize(), format);
- {
- RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
- if (!dt) {
- return nullptr;
- }
- PaintItemByDrawTarget(aItem, dt, paintRect, offset,
- aDisplayListBuilder,
- fallbackData->mBasicLayerManager, this, scale);
- }
- if (!helper.UpdateImage()) {
- 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, aResources, true)) {
- 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();
-}
-
-Maybe<wr::WrImageMask>
-WebRenderLayerManager::BuildWrMaskImage(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder,
- const LayerRect& aBounds)
-{
- LayerRect imageRect;
- RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aResources,
- aSc, aDisplayListBuilder,
- imageRect);
- if (!fallbackData) {
- return Nothing();
- }
-
- wr::WrImageMask imageMask;
- imageMask.image = fallbackData->GetKey().value();
- imageMask.rect = aSc.ToRelativeLayoutRect(aBounds);
- imageMask.repeat = false;
- return Some(imageMask);
-}
-
-bool
-WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder)
-{
- LayerRect imageRect;
- RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aResources,
- aSc, aDisplayListBuilder,
- imageRect);
- if (!fallbackData) {
- return false;
- }
-
- wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect);
- SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
- aBuilder.PushImage(dest,
- dest,
- !aItem->BackfaceIsHidden(),
- wr::ToImageRendering(sampleFilter),
- fallbackData->GetKey().value());
- return true;
-}
-
-void
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
// This should never get called, all callers should use
// EndTransactionWithoutLayer instead.
MOZ_ASSERT(false);
}
@@ -726,62 +242,22 @@ WebRenderLayerManager::EndTransactionWit
return;
}
DiscardCompositorAnimations();
wr::LayoutSize contentSize { (float)size.width, (float)size.height };
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize);
wr::IpcResourceUpdateQueue resourceUpdates(WrBridge()->GetShmemAllocator());
- { // scoping for StackingContextHelper RAII
-
- StackingContextHelper sc;
- mParentCommands.Clear();
- mScrollData = WebRenderScrollData();
- MOZ_ASSERT(mLayerScrollData.empty());
- mLastCanvasDatas.Clear();
- mLastAsr = nullptr;
-
- CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder, sc, builder, resourceUpdates);
-
- builder.Finalize(contentSize, mBuiltDisplayList);
-
- // Make a "root" layer data that has everything else as descendants
- mLayerScrollData.emplace_back();
- mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
- if (aDisplayListBuilder->IsBuildingLayerEventRegions()) {
- nsIPresShell* shell = aDisplayListBuilder->RootReferenceFrame()->PresContext()->PresShell();
- if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(shell)) {
- mLayerScrollData.back().SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
- }
- }
- RefPtr<WebRenderLayerManager> self(this);
- auto callback = [self](FrameMetrics::ViewID aScrollId) -> bool {
- return self->mScrollData.HasMetadataFor(aScrollId);
- };
- if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
- aDisplayListBuilder, nullptr, ContainerLayerParameters(), callback)) {
- mLayerScrollData.back().AppendScrollMetadata(mScrollData, rootMetadata.ref());
- }
- // Append the WebRenderLayerScrollData items into WebRenderScrollData
- // in reverse order, from topmost to bottommost. This is in keeping with
- // the semantics of WebRenderScrollData.
- for (auto i = mLayerScrollData.crbegin(); i != mLayerScrollData.crend(); i++) {
- mScrollData.AddLayerData(*i);
- }
- mLayerScrollData.clear();
- mClipIdCache.clear();
-
- // Remove the user data those are not displayed on the screen and
- // also reset the data to unused for next transaction.
- RemoveUnusedAndResetWebRenderUserData();
- }
-
- builder.PushBuiltDisplayList(mBuiltDisplayList);
- WrBridge()->AddWebRenderParentCommands(mParentCommands);
+ mWebRenderCommandsBuilder.BuildWebRenderCommands(builder,
+ resourceUpdates,
+ aDisplayList,
+ aDisplayListBuilder,
+ mScrollData,
+ contentSize);
mWidget->AddWindowOverlayWebRenderCommands(WrBridge(), builder, resourceUpdates);
WrBridge()->ClearReadLocks();
// We can't finish this transaction so return. This usually
// happens in an empty transaction where we can't repaint a painted layer.
// In this case, leave the transaction open and let a full transaction happen.
if (mTransactionIncomplete) {
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -11,16 +11,17 @@
#include "gfxPrefs.h"
#include "Layers.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/APZTestData.h"
#include "mozilla/layers/FocusTarget.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TransactionIdAllocator.h"
+#include "mozilla/layers/WebRenderCommandsBuilder.h"
#include "mozilla/layers/WebRenderScrollData.h"
#include "mozilla/layers/WebRenderUserData.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "nsDisplayList.h"
class nsIWidget;
@@ -58,53 +59,16 @@ public:
WebRenderLayerManager* AsWebRenderLayerManager() override { return this; }
virtual CompositorBridgeChild* GetCompositorBridgeChild() override;
virtual int32_t GetMaxTextureSize() const override;
virtual bool BeginTransactionWithTarget(gfxContext* aTarget) override;
virtual bool BeginTransaction() override;
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) override;
- Maybe<wr::ImageKey> CreateImageKey(nsDisplayItem* aItem,
- ImageContainer* aContainer,
- mozilla::wr::DisplayListBuilder& aBuilder,
- mozilla::wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- gfx::IntSize& aSize);
- bool PushImage(nsDisplayItem* aItem,
- ImageContainer* aContainer,
- mozilla::wr::DisplayListBuilder& aBuilder,
- mozilla::wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- const LayerRect& aRect);
-
- already_AddRefed<WebRenderFallbackData>
- GenerateFallbackData(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResourceUpdates,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder,
- LayerRect& aImageRect);
-
- Maybe<wr::WrImageMask> BuildWrMaskImage(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder,
- const LayerRect& aBounds);
- bool PushItemAsImage(nsDisplayItem* aItem,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources,
- const StackingContextHelper& aSc,
- nsDisplayListBuilder* aDisplayListBuilder);
- void CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
- nsDisplayListBuilder* aDisplayListBuilder,
- const StackingContextHelper& aSc,
- wr::DisplayListBuilder& aBuilder,
- wr::IpcResourceUpdateQueue& aResources);
void EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
nsDisplayListBuilder* aDisplayListBuilder);
virtual void EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags = END_DEFAULT) override;
virtual LayersBackend GetBackendType() override { return LayersBackend::LAYERS_WR; }
virtual void GetBackendName(nsAString& name) override { name.AssignLiteral("WebRender"); }
@@ -179,102 +143,31 @@ public:
const std::string& aValue) {
MOZ_ASSERT(gfxPrefs::APZTestLoggingEnabled(), "don't call me");
mApzTestData.LogTestDataForPaint(mPaintSequenceNumber, aScrollId, aKey, aValue);
}
// See equivalent function in ClientLayerManager
const APZTestData& GetAPZTestData() const
{ return mApzTestData; }
- // Those are data that we kept between transactions. We used to cache some
- // data in the layer. But in layers free mode, we don't have layer which
- // means we need some other place to cached the data between transaction.
- // We store the data in frame's property.
- template<class T> already_AddRefed<T>
- CreateOrRecycleWebRenderUserData(nsDisplayItem* aItem, bool* aOutIsRecycled = nullptr)
- {
- MOZ_ASSERT(aItem);
- nsIFrame* frame = aItem->Frame();
- if (aOutIsRecycled) {
- *aOutIsRecycled = true;
- }
-
- nsIFrame::WebRenderUserDataTable* userDataTable =
- frame->GetProperty(nsIFrame::WebRenderUserDataProperty());
-
- if (!userDataTable) {
- userDataTable = new nsIFrame::WebRenderUserDataTable();
- frame->AddProperty(nsIFrame::WebRenderUserDataProperty(), userDataTable);
- }
-
- RefPtr<WebRenderUserData>& data = userDataTable->GetOrInsert(aItem->GetPerFrameKey());
- if (!data || (data->GetType() != T::Type()) || !data->IsDataValid(this)) {
- // To recreate a new user data, we should remove the data from the table first.
- if (data) {
- data->RemoveFromTable();
- }
- data = new T(this, aItem, &mWebRenderUserDatas);
- mWebRenderUserDatas.PutEntry(data);
- if (aOutIsRecycled) {
- *aOutIsRecycled = false;
- }
- }
-
- MOZ_ASSERT(data);
- MOZ_ASSERT(data->GetType() == T::Type());
-
- // Mark the data as being used. We will remove unused user data in the end of EndTransaction.
- data->SetUsed(true);
-
- if (T::Type() == WebRenderUserData::UserDataType::eCanvas) {
- mLastCanvasDatas.PutEntry(data->AsCanvasData());
- }
- RefPtr<T> res = static_cast<T*>(data.get());
- return res.forget();
- }
-
bool SetPendingScrollUpdateForNextTransaction(FrameMetrics::ViewID aScrollId,
const ScrollUpdateInfo& aUpdateInfo) override;
+ WebRenderCommandsBuilder& CommandBuilder() { return mWebRenderCommandsBuilder; }
+ WebRenderUserDataRefTable* GetWebRenderUserDataTable() { return mWebRenderCommandsBuilder.GetWebRenderUserDataTable(); }
+ WebRenderScrollData& GetScrollData() { return mScrollData; }
private:
/**
* Take a snapshot of the parent context, and copy
* it into mTarget.
*/
void MakeSnapshotIfRequired(LayoutDeviceIntSize aSize);
void ClearLayer(Layer* aLayer);
- void RemoveUnusedAndResetWebRenderUserData()
- {
- for (auto iter = mWebRenderUserDatas.Iter(); !iter.Done(); iter.Next()) {
- WebRenderUserData* data = iter.Get()->GetKey();
- if (!data->IsUsed()) {
- nsIFrame* frame = data->GetFrame();
-
- MOZ_ASSERT(frame->HasProperty(nsIFrame::WebRenderUserDataProperty()));
-
- nsIFrame::WebRenderUserDataTable* userDataTable =
- frame->GetProperty(nsIFrame::WebRenderUserDataProperty());
-
- MOZ_ASSERT(userDataTable->Count());
-
- userDataTable->Remove(data->GetDisplayItemKey());
-
- if (!userDataTable->Count()) {
- frame->RemoveProperty(nsIFrame::WebRenderUserDataProperty());
- }
- iter.Remove();
- continue;
- }
-
- data->SetUsed(false);
- }
- }
-
private:
nsIWidget* MOZ_NON_OWNING_REF mWidget;
nsTArray<wr::ImageKey> mImageKeysToDelete;
// TODO - This is needed because we have some code that creates image keys
// and enqueues them for deletion right away which is bad not only because
// of poor texture cache usage, but also because images end up deleted before
// they are used. This should hopfully be temporary.
nsTArray<wr::ImageKey> mImageKeysToDeleteLater;
@@ -288,48 +181,19 @@ private:
RefPtr<WebRenderBridgeChild> mWrChild;
RefPtr<TransactionIdAllocator> mTransactionIdAllocator;
uint64_t mLatestTransactionId;
nsTArray<DidCompositeObserver*> mDidCompositeObservers;
- // These fields are used to save a copy of the display list for
- // empty transactions in layers-free mode.
- wr::BuiltDisplayList mBuiltDisplayList;
- nsTArray<WebRenderParentCommand> mParentCommands;
-
// This holds the scroll data that we need to send to the compositor for
// APZ to do it's job
WebRenderScrollData mScrollData;
- // We use this as a temporary data structure while building the mScrollData
- // inside a layers-free transaction.
- std::vector<WebRenderLayerScrollData> mLayerScrollData;
- // We use this as a temporary data structure to track the current display
- // item's ASR as we recurse in CreateWebRenderCommandsFromDisplayList. We
- // need this so that WebRenderLayerScrollData items that deeper in the
- // tree don't duplicate scroll metadata that their ancestors already have.
- std::vector<const ActiveScrolledRoot*> mAsrStack;
- const ActiveScrolledRoot* mLastAsr;
-
-public:
- // Note: two DisplayItemClipChain* A and B might actually be "equal" (as per
- // DisplayItemClipChain::Equal(A, B)) even though they are not the same pointer
- // (A != B). In this hopefully-rare case, they will get separate entries
- // in this map when in fact we could collapse them. However, to collapse
- // them involves writing a custom hash function for the pointer type such that
- // A and B hash to the same things whenever DisplayItemClipChain::Equal(A, B)
- // is true, and that will incur a performance penalty for all the hashmap
- // operations, so is probably not worth it. With the current code we might
- // end up creating multiple clips in WR that are effectively identical but
- // have separate clip ids. Hopefully this won't happen very often.
- typedef std::unordered_map<const DisplayItemClipChain*, wr::WrClipId> ClipIdMap;
-private:
- ClipIdMap mClipIdCache;
bool mTransactionIncomplete;
bool mNeedsComposite;
bool mIsFirstPaint;
FocusTarget mFocusTarget;
// When we're doing a transaction in order to draw to a non-default
@@ -341,19 +205,15 @@ private:
// back to mTarget.
RefPtr<gfxContext> mTarget;
// See equivalent field in ClientLayerManager
uint32_t mPaintSequenceNumber;
// See equivalent field in ClientLayerManager
APZTestData mApzTestData;
- typedef nsTHashtable<nsRefPtrHashKey<WebRenderCanvasData>> CanvasDataSet;
- // Store of WebRenderCanvasData objects for use in empty transactions
- CanvasDataSet mLastCanvasDatas;
-
- WebRenderUserDataRefTable mWebRenderUserDatas;
+ WebRenderCommandsBuilder mWebRenderCommandsBuilder;
};
} // namespace layers
} // namespace mozilla
#endif /* GFX_WEBRENDERLAYERMANAGER_H */
--- a/gfx/layers/wr/WebRenderUserData.cpp
+++ b/gfx/layers/wr/WebRenderUserData.cpp
@@ -11,22 +11,21 @@
#include "mozilla/layers/WebRenderMessages.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "nsDisplayListInvalidation.h"
#include "WebRenderCanvasRenderer.h"
namespace mozilla {
namespace layers {
-WebRenderUserData::WebRenderUserData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable)
+WebRenderUserData::WebRenderUserData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
: mWRManager(aWRManager)
, mFrame(aItem->Frame())
, mDisplayItemKey(aItem->GetPerFrameKey())
- , mTable(aTable)
+ , mTable(aWRManager->GetWebRenderUserDataTable())
, mUsed(false)
{
}
WebRenderUserData::~WebRenderUserData()
{
}
@@ -43,19 +42,18 @@ WebRenderUserData::RemoveFromTable()
}
WebRenderBridgeChild*
WebRenderUserData::WrBridge() const
{
return mWRManager->WrBridge();
}
-WebRenderImageData::WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable)
- : WebRenderUserData(aWRManager, aItem, aTable)
+WebRenderImageData::WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
+ : WebRenderUserData(aWRManager, aItem)
{
}
WebRenderImageData::~WebRenderImageData()
{
if (mKey) {
mWRManager->AddImageKeyForDiscard(mKey.value());
}
@@ -185,19 +183,18 @@ WebRenderImageData::CreateImageClientIfN
void
WebRenderImageData::CreateExternalImageIfNeeded()
{
if (!mExternalImageId) {
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
}
-WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable)
- : WebRenderImageData(aWRManager, aItem, aTable)
+WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
+ : WebRenderImageData(aWRManager, aItem)
, mInvalid(false)
{
}
WebRenderFallbackData::~WebRenderFallbackData()
{
}
@@ -208,38 +205,36 @@ WebRenderFallbackData::GetGeometry()
}
void
WebRenderFallbackData::SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
{
mGeometry = aGeometry;
}
-WebRenderAnimationData::WebRenderAnimationData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable)
- : WebRenderUserData(aWRManager, aItem, aTable)
+WebRenderAnimationData::WebRenderAnimationData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
+ : WebRenderUserData(aWRManager, aItem)
, mAnimationInfo(aWRManager)
{
}
WebRenderAnimationData::~WebRenderAnimationData()
{
// It may be the case that nsDisplayItem that created this WebRenderUserData
// gets destroyed without getting a chance to discard the compositor animation
// id, so we should do it as part of cleanup here.
uint64_t animationId = mAnimationInfo.GetCompositorAnimationsId();
// animationId might be 0 if mAnimationInfo never held any active animations.
if (animationId) {
mWRManager->AddCompositorAnimationsIdForDiscard(animationId);
}
}
-WebRenderCanvasData::WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable)
- : WebRenderUserData(aWRManager, aItem, aTable)
+WebRenderCanvasData::WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
+ : WebRenderUserData(aWRManager, aItem)
{
}
WebRenderCanvasData::~WebRenderCanvasData()
{
}
WebRenderCanvasRendererAsync*
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -31,18 +31,17 @@ class WebRenderLayerManager;
class WebRenderUserData
{
public:
typedef nsTHashtable<nsRefPtrHashKey<WebRenderUserData> > WebRenderUserDataRefTable;
NS_INLINE_DECL_REFCOUNTING(WebRenderUserData)
- WebRenderUserData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable);
+ WebRenderUserData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
virtual WebRenderImageData* AsImageData() { return nullptr; }
virtual WebRenderFallbackData* AsFallbackData() { return nullptr; }
virtual WebRenderCanvasData* AsCanvasData() { return nullptr; }
enum class UserDataType {
eImage,
eFallback,
@@ -68,18 +67,17 @@ protected:
uint32_t mDisplayItemKey;
WebRenderUserDataRefTable* mTable;
bool mUsed;
};
class WebRenderImageData : public WebRenderUserData
{
public:
- explicit WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable);
+ explicit WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
virtual ~WebRenderImageData();
virtual WebRenderImageData* AsImageData() override { return this; }
virtual UserDataType GetType() override { return UserDataType::eImage; }
static UserDataType Type() { return UserDataType::eImage; }
Maybe<wr::ImageKey> GetKey() { return mKey; }
void SetKey(const wr::ImageKey& aKey) { mKey = Some(aKey); }
already_AddRefed<ImageClient> GetImageClient();
@@ -109,18 +107,17 @@ protected:
RefPtr<ImageClient> mImageClient;
Maybe<wr::PipelineId> mPipelineId;
RefPtr<ImageContainer> mContainer;
};
class WebRenderFallbackData : public WebRenderImageData
{
public:
- explicit WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable);
+ explicit WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
virtual ~WebRenderFallbackData();
virtual WebRenderFallbackData* AsFallbackData() override { return this; }
virtual UserDataType GetType() override { return UserDataType::eFallback; }
static UserDataType Type() { return UserDataType::eFallback; }
nsAutoPtr<nsDisplayItemGeometry> GetGeometry();
void SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry);
nsRect GetBounds() { return mBounds; }
@@ -133,33 +130,31 @@ protected:
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
nsRect mBounds;
bool mInvalid;
};
class WebRenderAnimationData : public WebRenderUserData
{
public:
- explicit WebRenderAnimationData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable);
+ explicit WebRenderAnimationData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
virtual ~WebRenderAnimationData();
virtual UserDataType GetType() override { return UserDataType::eAnimation; }
static UserDataType Type() { return UserDataType::eAnimation; }
AnimationInfo& GetAnimationInfo() { return mAnimationInfo; }
protected:
AnimationInfo mAnimationInfo;
};
class WebRenderCanvasData : public WebRenderUserData
{
public:
- explicit WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem,
- WebRenderUserDataRefTable* aTable);
+ explicit WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
virtual ~WebRenderCanvasData();
virtual WebRenderCanvasData* AsCanvasData() override { return this; }
virtual UserDataType GetType() override { return UserDataType::eCanvas; }
static UserDataType Type() { return UserDataType::eCanvas; }
WebRenderCanvasRendererAsync* GetCanvasRenderer();
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -12,16 +12,17 @@
#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/layers/LayersMessages.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/layers/WebRenderMessages.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Move.h"
#include "nsCOMPtr.h"
#include "nsFontMetrics.h"
#include "nsGkAtoms.h"
#include "nsGenericHTMLElement.h"
#include "nsAttrValueInlines.h"
#include "nsPresContext.h"
@@ -467,17 +468,17 @@ BulletRenderer::CreateWebRenderCommandsF
RefPtr<layers::ImageContainer> container =
mImage->GetImageContainer(aManager, flags);
if (!container) {
return;
}
gfx::IntSize size;
- Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aResources, aSc, size);
+ Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container, aBuilder, aResources, aSc, size);
if (key.isNothing()) {
return;
}
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(mDest, appUnitsPerDevPixel);
wr::LayoutRect dest = aSc.ToRelativeLayoutRect(destRect);
@@ -493,17 +494,17 @@ BulletRenderer::CreateWebRenderCommandsF
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
MOZ_ASSERT(IsPathType());
- if (!aManager->PushItemAsImage(aItem, aBuilder, aResources, aSc, aDisplayListBuilder)) {
+ if (!aManager->CommandBuilder().PushItemAsImage(aItem, aBuilder, aResources, aSc, aDisplayListBuilder)) {
NS_WARNING("Fail to create WebRender commands for Bullet path.");
}
}
void
BulletRenderer::CreateWebRenderCommandsForText(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -132,17 +132,17 @@ public:
HTMLCanvasElement* element = static_cast<HTMLCanvasElement*>(mFrame->GetContent());
switch(element->GetCurrentContextType()) {
case CanvasContextType::Canvas2D:
case CanvasContextType::WebGL1:
case CanvasContextType::WebGL2:
{
bool isRecycled;
RefPtr<WebRenderCanvasData> canvasData =
- aManager->CreateOrRecycleWebRenderUserData<WebRenderCanvasData>(this, &isRecycled);
+ aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderCanvasData>(this, &isRecycled);
WebRenderCanvasRendererAsync* data =
static_cast<WebRenderCanvasRendererAsync*>(canvasData->GetCanvasRenderer());
if (!isRecycled) {
nsHTMLCanvasFrame* canvasFrame = static_cast<nsHTMLCanvasFrame*>(mFrame);
if (!canvasFrame->InitializeCanvasRenderer(aDisplayListBuilder, data)) {
return true;
}
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1719,17 +1719,17 @@ nsDisplayImage::CreateWebRenderCommands(
return false;
}
const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
const LayoutDeviceRect destRect(
LayoutDeviceIntRect::FromAppUnits(GetDestRect(), factor));
const LayerRect dest = ViewAs<LayerPixel>(destRect, PixelCastJustification::WebRenderHasUnitResolution);
- return aManager->PushImage(this, container, aBuilder, aResources, aSc, dest);
+ return aManager->CommandBuilder().PushImage(this, container, aBuilder, aResources, aSc, dest);
}
DrawResult
nsImageFrame::PaintImage(gfxContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, imgIContainer* aImage,
uint32_t aFlags)
{
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -1440,17 +1440,17 @@ nsPluginFrame::CreateWebRenderCommands(n
RefPtr<LayerManager> lm = aDisplayListBuilder->GetWidgetLayerManager();
if (!mDidCompositeObserver || !mDidCompositeObserver->IsValid(lm)) {
mDidCompositeObserver = MakeUnique<PluginFrameDidCompositeObserver>(mInstanceOwner, lm);
}
lm->AddDidCompositeObserver(mDidCompositeObserver.get());
LayerRect dest(r.x, r.y, size.width, size.height);
- return aManager->PushImage(aItem, container, aBuilder, aResources, aSc, dest);
+ return aManager->CommandBuilder().PushImage(aItem, container, aBuilder, aResources, aSc, dest);
}
already_AddRefed<Layer>
nsPluginFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
nsDisplayItem* aItem,
const ContainerLayerParameters& aContainerParameters)
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -493,17 +493,17 @@ public:
VideoInfo::Rotation rotationDeg = element->RotationDegrees();
IntSize scaleHint(static_cast<int32_t>(destGFXRect.Width()),
static_cast<int32_t>(destGFXRect.Height()));
// scaleHint is set regardless of rotation, so swap w/h if needed.
SwapScaleWidthHeightForRotation(scaleHint, rotationDeg);
container->SetScaleHint(scaleHint);
LayerRect rect(destGFXRect.x, destGFXRect.y, destGFXRect.width, destGFXRect.height);
- return aManager->PushImage(this, container, aBuilder, aResources, aSc, rect);
+ return aManager->CommandBuilder().PushImage(this, container, aBuilder, aResources, aSc, rect);
}
// It would be great if we could override GetOpaqueRegion to return nonempty here,
// but it's probably not safe to do so in general. Video frames are
// updated asynchronously from decoder threads, and it's possible that
// we might have an opaque video frame when GetOpaqueRegion is called, but
// when we come to paint, the video frame is transparent or has gone
// away completely (e.g. because of a decoder error). The problem would
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5084,17 +5084,18 @@ nsDisplayBorder::CreateBorderImageWebRen
RefPtr<imgIContainer> img = mBorderImageRenderer->mImageRenderer.GetImage();
RefPtr<layers::ImageContainer> container = img->GetImageContainer(aManager, flags);
if (!container) {
return;
}
gfx::IntSize size;
- Maybe<wr::ImageKey> key = aManager->CreateImageKey(this, container, aBuilder, aResources, aSc, size);
+ Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(this, container, aBuilder,
+ aResources, aSc, size);
if (key.isNothing()) {
return;
}
aBuilder.PushBorderImage(dest,
clip,
!BackfaceIsHidden(),
wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
@@ -5912,21 +5913,21 @@ nsDisplayWrapList::SetReferenceFrame(con
bool
nsDisplayWrapList::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
- aManager->CreateWebRenderCommandsFromDisplayList(GetChildren(),
- aDisplayListBuilder,
- aSc,
- aBuilder,
- aResources);
+ aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(GetChildren(),
+ aDisplayListBuilder,
+ aSc,
+ aBuilder,
+ aResources);
return true;
}
static nsresult
WrapDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, nsDisplayWrapper* aWrapper) {
if (!aList->GetTop())
return NS_OK;
@@ -6247,17 +6248,17 @@ bool
nsDisplayOpacity::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
float* opacityForSC = &mOpacity;
- RefPtr<WebRenderAnimationData> animationData = aManager->CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
+ RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
AnimationInfo& animationInfo = animationData->GetAnimationInfo();
AddAnimationsForProperty(Frame(), aDisplayListBuilder,
this, eCSSProperty_opacity,
animationInfo, false);
animationInfo.StartPendingAnimations(aManager->GetAnimationReadyTime());
// Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
// are no active animations.
@@ -6285,21 +6286,21 @@ nsDisplayOpacity::CreateWebRenderCommand
&mList,
nullptr,
animationsId,
opacityForSC,
nullptr,
nullptr,
filters);
- aManager->CreateWebRenderCommandsFromDisplayList(&mList,
- aDisplayListBuilder,
- sc,
- aBuilder,
- aResources);
+ aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(&mList,
+ aDisplayListBuilder,
+ sc,
+ aBuilder,
+ aResources);
return true;
}
nsDisplayBlendMode::nsDisplayBlendMode(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
uint8_t aBlendMode,
const ActiveScrolledRoot* aActiveScrolledRoot,
uint32_t aIndex)
@@ -6567,17 +6568,17 @@ nsDisplayOwnLayer::CreateWebRenderComman
mThumbData.mDirection == ScrollDirection::NONE) {
return nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, aSc,
aManager, aDisplayListBuilder);
}
// APZ is enabled and this is a scroll thumb, so we need to create and
// set an animation id. That way APZ can move this scrollthumb around as
// needed.
- RefPtr<WebRenderAnimationData> animationData = aManager->CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
+ RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
AnimationInfo& animationInfo = animationData->GetAnimationInfo();
animationInfo.EnsureAnimationsId();
mWrAnimationId = animationInfo.GetCompositorAnimationsId();
StackingContextHelper sc(aSc, aBuilder, aDisplayListBuilder, this,
&mList, nullptr, mWrAnimationId, nullptr, nullptr);
nsDisplayWrapList::CreateWebRenderCommands(aBuilder, aResources, sc,
@@ -8015,17 +8016,17 @@ nsDisplayTransform::CreateWebRenderComma
gfx::Matrix4x4* transformForSC = &newTransformMatrix;
if (newTransformMatrix.IsIdentity()) {
// If the transform is an identity transform, strip it out so that WR
// doesn't turn this stacking context into a reference frame, as it
// affects positioning. Bug 1345577 tracks a better fix.
transformForSC = nullptr;
}
- RefPtr<WebRenderAnimationData> animationData = aManager->CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
+ RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
AnimationInfo& animationInfo = animationData->GetAnimationInfo();
AddAnimationsForProperty(Frame(), aDisplayListBuilder,
this, eCSSProperty_transform,
animationInfo, false);
animationInfo.StartPendingAnimations(aManager->GetAnimationReadyTime());
// Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
@@ -9163,18 +9164,19 @@ nsDisplayMask::CreateWebRenderCommands(m
nsDisplayListBuilder* aDisplayListBuilder)
{
bool snap;
float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
nsRect displayBound = GetBounds(aDisplayListBuilder, &snap);
LayerRect bounds = ViewAs<LayerPixel>(LayoutDeviceRect::FromAppUnits(displayBound, appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
- Maybe<wr::WrImageMask> mask = aManager->BuildWrMaskImage(this, aBuilder, aResources,
- aSc, aDisplayListBuilder, bounds);
+ Maybe<wr::WrImageMask> mask = aManager->CommandBuilder().BuildWrMaskImage(this, aBuilder, aResources,
+ aSc, aDisplayListBuilder,
+ bounds);
if (mask) {
wr::WrClipId clipId = aBuilder.DefineClip(
aSc.ToRelativeLayoutRect(bounds), nullptr, mask.ptr());
// Don't record this clip push in aBuilder's internal clip stack, because
// otherwise any nested ScrollingLayersHelper instances that are created
// will get confused about which clips are pushed.
aBuilder.PushClip(clipId, /*aMask*/ true);
}
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -9,16 +9,17 @@
#include "nsImageRenderer.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "gfxContext.h"
#include "gfxDrawable.h"
#include "ImageOps.h"
#include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
#include "nsContentUtils.h"
#include "nsCSSRendering.h"
#include "nsCSSRenderingGradients.h"
#include "nsIFrame.h"
#include "nsStyleStructInlines.h"
#include "nsSVGDisplayableFrame.h"
#include "SVGObserverUtils.h"
#include "nsSVGIntegrationUtils.h"
@@ -629,17 +630,18 @@ nsImageRenderer::BuildWebRenderDisplayIt
RefPtr<layers::ImageContainer> container =
mImageContainer->GetImageContainer(aManager, containerFlags);
if (!container) {
NS_WARNING("Failed to get image container");
return DrawResult::NOT_READY;
}
gfx::IntSize size;
- Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aResources, aSc, size);
+ Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container, aBuilder,
+ aResources, aSc, size);
if (key.isNothing()) {
return DrawResult::BAD_IMAGE;
}
const int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
aDest, appUnitsPerDevPixel);
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -444,19 +444,19 @@ nsImageBoxFrame::CreateWebRenderCommands
RefPtr<layers::ImageContainer> container =
imgCon->GetImageContainer(aManager, containerFlags);
if (!container) {
NS_WARNING("Failed to get image container");
return DrawResult::NOT_READY;
}
gfx::IntSize size;
- Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container,
- aBuilder, aResources,
- aSc, size);
+ Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container,
+ aBuilder, aResources,
+ aSc, size);
if (key.isNothing()) {
return DrawResult::BAD_IMAGE;
}
const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits(dest,
appUnitsPerDevPixel);
wr::LayoutRect fill = aSc.ToRelativeLayoutRect(fillRect);