--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -245,16 +245,18 @@ WebRenderLayerManager::EndTransactionWit
WrSize contentSize { (float)size.width, (float)size.height };
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize);
if (aDisplayList && aDisplayListBuilder) {
StackingContextHelper sc;
mParentCommands.Clear();
CreateWebRenderCommandsFromDisplayList(this, aDisplayList, aDisplayListBuilder, sc, builder);
builder.Finalize(contentSize, mBuiltDisplayList);
+
+ mLastItemData.SwapElements(mItemData);
} else {
}
builder.PushBuiltDisplayList(mBuiltDisplayList);
WrBridge()->AddWebRenderParentCommands(mParentCommands);
@@ -292,16 +294,198 @@ WebRenderLayerManager::EndTransactionWit
mNeedsComposite = false;
// this may result in Layers being deleted, which results in
// PLayer::Send__delete__() and DeallocShmem()
mKeepAlive.Clear();
}
void
+WebRenderLayerManager::SendAnimationData(WMAnimationData* aAnimationData,
+ OptionalOpacity aOpacity,
+ OptionalTransform aTransform)
+{
+ aAnimationData->ResolveStartTime(mAnimationReadyTime);
+ OpAddCompositorAnimations
+ anim(CompositorAnimations(aAnimationData->GetAnimations(),
+ aAnimationData->GetCompositorAnimationsId()),
+ aTransform,
+ aOpacity);
+ WrBridge()->AddWebRenderParentCommand(anim);
+}
+
+Maybe<wr::ImageKey>
+WebRenderLayerManager::CreateImageKey(nsDisplayItem* aItem,
+ ImageContainer* aContainer,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ gfx::IntSize& aSize)
+{
+ RefPtr<WMImageData> imageData = CreateOrRecycleWMData<WMImageData>(aItem);
+ MOZ_ASSERT(imageData);
+
+ imageData->mContainer = aContainer;
+
+ if (aContainer->IsAsync()) {
+ imageData->mImageClientTypeContainer = CompositableType::IMAGE_BRIDGE;
+ } else {
+ AutoLockImage autoLock(aContainer);
+ imageData->mImageClientTypeContainer = autoLock.HasImage()
+ ? CompositableType::IMAGE : CompositableType::UNKNOWN;
+ }
+
+ if (imageData->mImageClientTypeContainer == CompositableType::IMAGE && !imageData->mImageClient) {
+ imageData->mImageClient = ImageClient::CreateImageClient(CompositableType::IMAGE,
+ WrBridge(),
+ TextureFlags::DEFAULT);
+ if (!imageData->mImageClient) {
+ return Nothing();
+ }
+ imageData->mImageClient->Connect();
+ }
+
+ if (imageData->mImageClientTypeContainer == CompositableType::IMAGE_BRIDGE && imageData->mPipelineId.isNothing()) {
+ MOZ_ASSERT(!imageData->mImageClient);
+ // Alloc async image pipeline id.
+ imageData->mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
+ WrBridge()->AddPipelineIdForAsyncCompositable(imageData->mPipelineId.ref(),
+ aContainer->GetAsyncContainerHandle());
+ } else if (imageData->mImageClientTypeContainer == CompositableType::IMAGE && imageData->mExternalImageId.isNothing()) {
+ MOZ_ASSERT(imageData->mImageClient);
+ imageData->mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(imageData->mImageClient));
+ MOZ_ASSERT(imageData->mExternalImageId.isSome());
+ }
+
+ if (imageData->mImageClientTypeContainer == CompositableType::IMAGE_BRIDGE) {
+ MOZ_ASSERT(!imageData->mImageClient);
+ MOZ_ASSERT(imageData->mExternalImageId.isNothing());
+
+ // Push IFrame for async image pipeline.
+ // XXX Remove this once partial display list update is supported.
+
+ //ScrollingLayersHelper scroller(this, aBuilder, aSc);
+
+ //ParentLayerRect bounds = GetLocalTransformTyped().TransformBounds(Bounds());
+
+ // We don't push a stacking context for this async image pipeline here.
+ // Instead, we do it inside the iframe that hosts the image. As a result,
+ // a bunch of the calculations normally done as part of that stacking
+ // context need to be done manually and pushed over to the parent side,
+ // where it will be done when we build the display list for the iframe.
+ // That happens in WebRenderCompositableHolder.
+
+ bool snap;
+ nsRect bounds = aItem->GetBounds(nullptr, &snap);
+ int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+ LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits(
+ bounds, appUnitsPerDevPixel);
+
+ aBuilder.PushIFrame(aSc.ToRelativeWrRect(rect), aSc.ToRelativeWrRect(rect), imageData->mPipelineId.ref());
+ gfx::Matrix4x4 scTransform;
+ LayerRect scBounds(0, 0, rect.width, rect.height);
+ MaybeIntSize scaleToSize;
+ //if (mScaleMode != ScaleMode::SCALE_NONE) {
+ // NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
+ // "No other scalemodes than stretch and none supported yet.");
+ // scaleToSize = Some(mScaleToSize);
+ //}
+ //LayerRect scBounds = BoundsForStackingContext();
+ wr::ImageRendering filter = wr::ImageRendering::Auto; //wr::ToImageRendering(mSamplingFilter);
+ wr::MixBlendMode mixBlendMode = wr::MixBlendMode::Normal; //wr::ToWrMixBlendMode(GetMixBlendMode());
+
+ WrBridge()->AddWebRenderParentCommand(OpUpdateAsyncImagePipeline(imageData->mPipelineId.value(),
+ scBounds,
+ scTransform,
+ scaleToSize,
+ filter,
+ mixBlendMode));
+ return Nothing();
+ }
+
+ MOZ_ASSERT(imageData->mImageClientTypeContainer == CompositableType::IMAGE);
+ MOZ_ASSERT(imageData->mImageClient->AsImageClientSingle());
+
+ AutoLockImage autoLock(aContainer);
+ mozilla::layers::Image* image = autoLock.GetImage();
+ if (!image) {
+ return Nothing();
+ }
+ aSize = image->GetSize();
+ ImageClientSingle* imageClient = imageData->mImageClient->AsImageClientSingle();
+ MOZ_ASSERT(imageClient);
+ MOZ_ASSERT(aContainer);
+ uint32_t oldCounter = imageClient->GetLastUpdateGenerationCounter();
+
+ bool ret = imageClient->UpdateImage(aContainer, /* unused */0);
+ if (!ret || imageClient->IsEmpty()) {
+ // Delete old key
+ if (imageData->mKey.isSome()) {
+ AddImageKeyForDiscard(imageData->mKey.value());
+ imageData->mKey = Nothing();
+ }
+ return Nothing();
+ }
+
+ // Reuse old key if generation is not updated.
+ if (oldCounter == imageClient->GetLastUpdateGenerationCounter() && imageData->mKey.isSome()) {
+ return imageData->mKey;
+ }
+
+ // Delete old key, we are generating a new key.
+ if (imageData->mKey.isSome()) {
+ AddImageKeyForDiscard(imageData->mKey.value());
+ imageData->mKey = Nothing();
+ }
+
+ WrImageKey key;
+ key.mNamespace = WrBridge()->GetNamespace();
+ key.mHandle = WrBridge()->GetNextResourceId();
+ WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(imageData->mExternalImageId.value(), key));
+ imageData->mKey = Some(key);
+
+ return imageData->mKey;
+}
+
+bool
+WebRenderLayerManager::PushImage(nsDisplayItem* aItem,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ ImageContainer* aContainer,
+ const LayerRect& aRect)
+{
+ gfx::IntSize size;
+ Maybe<wr::ImageKey> key = CreateImageKey(aItem, aContainer, aBuilder, aSc, size);
+ if (!key) {
+ return false;
+ }
+
+ #if 0
+ if (mScaleMode != ScaleMode::SCALE_NONE) {
+ NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
+ "No other scalemodes than stretch and none supported yet.");
+ rect = LayerRect(0, 0, mScaleToSize.width, mScaleToSize.height);
+ }
+ #endif
+
+ #if 0
+ LayoutDeviceRect clipRect(0, 0, size.width, size.height);
+ if (aItem->GetClip().HasClip()) {
+ int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+ clipRect = LayoutDeviceRect::FromAppUnits(
+ aItem->GetClip().GetClipRect(), appUnitsPerDevPixel);
+ }
+ #endif
+
+ wr::ImageRendering filter = wr::ImageRendering::Auto;
+ aBuilder.PushImage(aSc.ToRelativeWrRect(aRect), aSc.ToRelativeWrRect(aRect), filter, key.value());
+
+ return true;
+}
+
+void
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
DiscardImages();
WrBridge()->RemoveExpiredFontKeys();
EndTransactionInternal(aCallback, aCallbackData, aFlags);
}
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -6,27 +6,106 @@
#ifndef GFX_WEBRENDERLAYERMANAGER_H
#define GFX_WEBRENDERLAYERMANAGER_H
#include "Layers.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/APZTestData.h"
#include "mozilla/layers/TransactionIdAllocator.h"
#include "mozilla/webrender/WebRenderTypes.h"
+#include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/layers/AnimationHelper.h"
+#include "mozilla/layers/ImageClient.h"
+#include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/webrender/WebRenderAPI.h"
+#include "nsDisplayList.h"
class nsIWidget;
+class nsDisplayList;
namespace mozilla {
namespace layers {
class CompositorBridgeChild;
class KnowsCompositor;
class PCompositorBridgeChild;
class WebRenderBridgeChild;
+typedef Pair<nsIFrame*, uint32_t> FrameDisplayItemKey;
+
+class FrameDisplayItemKeyHashEntry : public PLDHashEntryHdr
+{
+public:
+ typedef FrameDisplayItemKey KeyType;
+ typedef const FrameDisplayItemKey* KeyTypePointer;
+
+ explicit FrameDisplayItemKeyHashEntry(KeyTypePointer aKey)
+ : mKey(*aKey) { }
+ explicit FrameDisplayItemKeyHashEntry(const FrameDisplayItemKeyHashEntry& aCopy) = default;
+
+ ~FrameDisplayItemKeyHashEntry() = default;
+
+ KeyType GetKey() const { return mKey; }
+ bool KeyEquals(KeyTypePointer aKey) const
+ {
+ return mKey.first() == aKey->first() && mKey.second() == aKey->second();
+ }
+
+ static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
+ static PLDHashNumber HashKey(KeyTypePointer aKey)
+ {
+ if (!aKey)
+ return 0;
+
+ return HashGeneric(aKey->first(), aKey->second());
+ }
+
+ enum { ALLOW_MEMMOVE = true };
+
+ FrameDisplayItemKey mKey;
+};
+
+class WMImageData;
+
+class WMData
+{
+public:
+ NS_INLINE_DECL_REFCOUNTING(WMData)
+
+ virtual WMAnimationData* AsAnimationData() { return nullptr; }
+ virtual WMImageData* AsImageData() { return nullptr; }
+ virtual WMCanvasData* AsCanvasData() { return nullptr; }
+
+ enum class TYPE {
+ ANIMATION,
+ IMAGE,
+ CANVAS
+ };
+
+ virtual TYPE GetType() = 0;
+
+protected:
+ virtual ~WMData() {}
+};
+
+class WMImageData : public WMData
+{
+public:
+ virtual WMImageData* AsImageData() override { return this; }
+ virtual TYPE GetType() override { return TYPE::IMAGE; }
+ static TYPE Type() { return TYPE::IMAGE; }
+
+ wr::MaybeExternalImageId mExternalImageId;
+ Maybe<wr::ImageKey> mKey;
+ RefPtr<ImageClient> mImageClient;
+ CompositableType mImageClientTypeContainer;
+ Maybe<wr::PipelineId> mPipelineId;
+ RefPtr<ImageContainer> mContainer;
+};
+
class WebRenderLayerManager final : public LayerManager
{
typedef nsTArray<RefPtr<Layer> > LayerRefArray;
public:
explicit WebRenderLayerManager(nsIWidget* aWidget);
void Initialize(PCompositorBridgeChild* aCBChild, wr::PipelineId aLayersId, TextureFactoryIdentifier* aTextureFactoryIdentifier);
@@ -40,23 +119,35 @@ 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,
+ const StackingContextHelper& aSc,
+ gfx::IntSize& aSize);
+ bool PushImage(nsDisplayItem* aItem,
+ mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ ImageContainer* aContainer,
+ const LayerRect& aRect);
+
static void CreateWebRenderCommandsFromDisplayList(WebRenderLayerManager* aManager,
nsDisplayList* aDisplayList,
nsDisplayListBuilder* aDisplayListBuilder,
StackingContextHelper& aSc,
wr::DisplayListBuilder& aBuilder);
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"); }
virtual const char* Name() const override { return "WebRender"; }
@@ -152,16 +243,18 @@ private:
void MakeSnapshotIfRequired(LayoutDeviceIntSize aSize);
void ClearLayer(Layer* aLayer);
bool EndTransactionInternal(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags);
+ nsDataHashtable<FrameDisplayItemKeyHashEntry, RefPtr<WMData>> mItemData;
+ nsDataHashtable<FrameDisplayItemKeyHashEntry, RefPtr<WMData>> mLastItemData;
wr::BuiltDisplayList mBuiltDisplayList;
nsTArray<WebRenderParentCommand> mParentCommands;
private:
nsIWidget* MOZ_NON_OWNING_REF mWidget;
std::vector<wr::ImageKey> mImageKeys;
nsTArray<uint64_t> mDiscardedCompositorAnimationsIds;
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -76,16 +76,25 @@
#include "nsBlockFrame.h"
#include "nsStyleStructInlines.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Link.h"
#include "SVGImageContext.h"
+#include "mozilla/layers/ImageClient.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
+#include "mozilla/layers/WebRenderBridgeChild.h"
+#include "mozilla/webrender/WebRenderAPI.h"
+#include "mozilla/layers/ScrollingLayersHelper.h"
+#include "mozilla/layers/StackingContextHelper.h"
+#include "mozilla/layers/CompositorBridgeChild.h"
+#include "ImageContainer.h"
+
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::gfx;
using namespace mozilla::image;
using namespace mozilla::layers;
// sizes (pixels) for image icon, padding and border frame
#define ICON_SIZE (16)
@@ -1680,16 +1689,46 @@ nsDisplayImage::BuildLayer(nsDisplayList
if (!layer)
return nullptr;
}
layer->SetContainer(container);
ConfigureLayer(layer, aParameters);
return layer.forget();
}
+bool
+nsDisplayImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ if (!CanOptimizeToImageLayer(aManager, aDisplayListBuilder)) {
+ return false;
+ }
+
+ uint32_t flags = imgIContainer::FLAG_ASYNC_NOTIFY;
+ if (aDisplayListBuilder->ShouldSyncDecodeImages()) {
+ flags |= imgIContainer::FLAG_SYNC_DECODE;
+ }
+
+ RefPtr<ImageContainer> container =
+ mImage->GetImageContainer(aManager, flags);
+ if (!container) {
+ 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, aBuilder, aSc, container, dest);
+}
+
DrawResult
nsImageFrame::PaintImage(gfxContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, imgIContainer* aImage,
uint32_t aFlags)
{
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
// Render the image into our content area (the area inside
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -455,16 +455,20 @@ public:
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
-
- NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
+ NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
private:
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<imgIContainer> mPrevImage;
};
#endif /* nsImageFrame_h___ */
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -1991,17 +1991,19 @@ nsCSSRendering::CanBuildWebRenderDisplay
return false;
}
DrawResult
nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(const PaintBGParams& aParams,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
- mozilla::layers::WebRenderDisplayItemLayer* aLayer)
+ mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem)
{
NS_PRECONDITION(aParams.frame,
"Frame is expected to be provided to BuildWebRenderDisplayItemsForStyleImageLayer");
nsStyleContext *sc;
if (!FindBackground(aParams.frame, &sc)) {
// We don't want to bail out if moz-appearance is set on a root
// node. If it has a parent content node, bail because it's not
@@ -2014,18 +2016,18 @@ nsCSSRendering::BuildWebRenderDisplayIte
nsIContent* content = aParams.frame->GetContent();
if (!content || content->GetParent()) {
return DrawResult::SUCCESS;
}
sc = aParams.frame->StyleContext();
}
-
- return BuildWebRenderDisplayItemsForStyleImageLayerWithSC(aParams, aBuilder, aSc, aParentCommands, aLayer,
+ return BuildWebRenderDisplayItemsForStyleImageLayerWithSC(aParams, aBuilder, aSc, aParentCommands,
+ aLayer, aManager, aItem,
sc, *aParams.frame->StyleBorder());
}
static bool
IsOpaqueBorderEdge(const nsStyleBorder& aBorder, mozilla::Side aSide)
{
if (aBorder.GetComputedBorder().Side(aSide) == 0)
return true;
@@ -2738,25 +2740,21 @@ nsCSSRendering::PaintStyleImageLayerWith
}
DrawResult
nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayerWithSC(const PaintBGParams& aParams,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem,
nsStyleContext *aBackgroundSC,
const nsStyleBorder& aBorder)
{
- MOZ_ASSERT(CanBuildWebRenderDisplayItemsForStyleImageLayer(aLayer->WrManager(),
- aParams.presCtx,
- aParams.frame,
- aBackgroundSC->StyleBackground(),
- aParams.layer));
-
MOZ_ASSERT(!(aParams.paintFlags & PAINTBG_MASK_IMAGE));
nscoord appUnitsPerPixel = aParams.presCtx.AppUnitsPerDevPixel();
ImageLayerClipState clipState;
clipState.mBGClipArea = *aParams.bgClipRect;
clipState.mCustomClip = true;
clipState.mHasRoundedCorners = false;
@@ -2783,17 +2781,18 @@ nsCSSRendering::BuildWebRenderDisplayIte
DrawResult result = DrawResult::SUCCESS;
nsBackgroundLayerState state =
PrepareImageLayer(&aParams.presCtx, aParams.frame,
aParams.paintFlags, paintBorderArea,
clipState.mBGClipArea, layer, nullptr);
result &= state.mImageRenderer.PrepareResult();
if (!state.mFillArea.IsEmpty()) {
return state.mImageRenderer.BuildWebRenderDisplayItemsForLayer(&aParams.presCtx,
- aBuilder, aSc, aParentCommands, aLayer,
+ aBuilder, aSc, aParentCommands,
+ aLayer, aManager, aItem,
state.mDestArea, state.mFillArea,
state.mAnchor + paintBorderArea.TopLeft(),
clipState.mDirtyRectInAppUnits,
state.mRepeatSize, aParams.opacity);
}
return result;
}
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -498,23 +498,27 @@ struct nsCSSRendering {
nsPresContext& aPresCtx,
nsIFrame *aFrame,
const nsStyleBackground* aBackgroundStyle,
int32_t aLayer);
static DrawResult BuildWebRenderDisplayItemsForStyleImageLayer(const PaintBGParams& aParams,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
- mozilla::layers::WebRenderDisplayItemLayer* aLayer);
+ mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem);
static DrawResult BuildWebRenderDisplayItemsForStyleImageLayerWithSC(const PaintBGParams& aParams,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<mozilla::layers::WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem,
nsStyleContext *mBackgroundSC,
const nsStyleBorder& aBorder);
/**
* Returns the rectangle covered by the given background layer image, taking
* into account background positioning, sizing, and repetition, but not
* clipping.
*/
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -3524,31 +3524,63 @@ nsDisplayBackgroundImage::CanBuildWebRen
return mBackgroundStyle->mImage.mLayers[mLayer].mClip != StyleGeometryBox::Text &&
nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer(aManager,
*StyleFrame()->PresContext(),
StyleFrame(),
mBackgroundStyle,
mLayer);
}
+bool
+nsDisplayBackgroundImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ if (!CanBuildWebRenderDisplayItems(aManager)) {
+ return false;
+ }
+
+ mImageFlags = aDisplayListBuilder->GetBackgroundPaintFlags();
+ CheckForBorderItem(this, mImageFlags);
+ nsCSSRendering::PaintBGParams params =
+ nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
+ mVisibleRect, mBackgroundRect,
+ StyleFrame(), mImageFlags, mLayer,
+ CompositionOp::OP_OVER);
+ params.bgClipRect = &mBounds;
+ DrawResult result =
+ nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params, aBuilder, aSc, aParentCommands, nullptr, aManager, this);
+ nsDisplayBackgroundGeometry::UpdateDrawResult(this, result);
+
+ return true;
+}
+
void
nsDisplayBackgroundImage::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer)
{
nsCSSRendering::PaintBGParams params =
nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
mVisibleRect, mBackgroundRect,
StyleFrame(), mImageFlags, mLayer,
CompositionOp::OP_OVER);
params.bgClipRect = &mBounds;
DrawResult result =
- nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params, aBuilder, aSc, aParentCommands, aLayer);
+ nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(params,
+ aBuilder,
+ aSc,
+ aParentCommands,
+ aLayer,
+ aLayer->WrManager(),
+ this);
nsDisplayBackgroundGeometry::UpdateDrawResult(this, result);
}
void
nsDisplayBackgroundImage::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect,
HitTestState* aState,
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3124,17 +3124,21 @@ public:
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
const StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer) override;
-
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
/**
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -17,16 +17,17 @@
#include "nsContentUtils.h"
#include "nsCSSRendering.h"
#include "nsCSSRenderingGradients.h"
#include "nsIFrame.h"
#include "nsStyleStructInlines.h"
#include "nsSVGDisplayableFrame.h"
#include "nsSVGEffects.h"
#include "nsSVGIntegrationUtils.h"
+#include "ImageContainer.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
using namespace mozilla::layers;
nsSize
CSSSizeOrRatio::ComputeConcreteSize() const
@@ -585,16 +586,18 @@ nsImageRenderer::Draw(nsPresContext*
}
DrawResult
nsImageRenderer::BuildWebRenderDisplayItems(nsPresContext* aPresContext,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem,
const nsRect& aDirtyRect,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsSize& aRepeatSize,
const CSSIntRect& aSrc,
float aOpacity)
{
@@ -619,23 +622,27 @@ nsImageRenderer::BuildWebRenderDisplayIt
case eStyleImageType_Image:
{
// XXX(aosmond): We will support downscale-on-decode in bug 1368776. Until
// then, don't pass FLAG_HIGH_QUALITY_SCALING.
uint32_t containerFlags = imgIContainer::FLAG_NONE;
if (mFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
}
- RefPtr<layers::ImageContainer> container = mImageContainer->GetImageContainer(aLayer->WrManager(),
+ RefPtr<layers::ImageContainer> container = mImageContainer->GetImageContainer(aManager,
containerFlags);
+ container = mImageContainer->GetImageContainer(aManager, containerFlags);
if (!container) {
NS_WARNING("Failed to get image container");
return DrawResult::NOT_READY;
}
- Maybe<wr::ImageKey> key = aLayer->SendImageContainer(container, aParentCommands);
+
+ gfx::IntSize size;
+ Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aSc, size);
+
if (key.isNothing()) {
return DrawResult::BAD_IMAGE;
}
const int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
aDest, appUnitsPerDevPixel);
@@ -725,33 +732,35 @@ nsImageRenderer::DrawLayer(nsPresContext
}
DrawResult
nsImageRenderer::BuildWebRenderDisplayItemsForLayer(nsPresContext* aPresContext,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsRect& aDirty,
const nsSize& aRepeatSize,
float aOpacity)
{
if (!IsReady()) {
NS_NOTREACHED("Ensure PrepareImage() has returned true before calling me");
return mPrepareResult;
}
if (aDest.IsEmpty() || aFill.IsEmpty() ||
mSize.width <= 0 || mSize.height <= 0) {
return DrawResult::SUCCESS;
}
-
- return BuildWebRenderDisplayItems(aPresContext, aBuilder, aSc, aParentCommands, aLayer,
+ return BuildWebRenderDisplayItems(aPresContext, aBuilder, aSc, aParentCommands,
+ aLayer, aManager, aItem,
aDirty, aDest, aFill, aAnchor, aRepeatSize,
CSSIntRect(0, 0,
nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
nsPresContext::AppUnitsToIntCSSPixels(mSize.height)),
aOpacity);
}
/**
--- a/layout/painting/nsImageRenderer.h
+++ b/layout/painting/nsImageRenderer.h
@@ -12,16 +12,17 @@
class gfxDrawable;
namespace mozilla {
namespace layers {
class StackingContextHelper;
class WebRenderParentCommand;
class WebRenderDisplayItemLayer;
+class WebRenderLayerManager;
} // namespace layers
namespace wr {
class DisplayListBuilder;
} // namespace wr
// A CSSSizeOrRatio represents a (possibly partially specified) size for use
// in computing image sizes. Either or both of the width and height might be
@@ -207,16 +208,18 @@ public:
* {background|mask}-specific arguments.
* @see nsLayoutUtils::DrawImage() for parameters.
*/
DrawResult BuildWebRenderDisplayItemsForLayer(nsPresContext* aPresContext,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsRect& aDirty,
const nsSize& aRepeatSize,
float aOpacity);
/**
@@ -292,16 +295,18 @@ private:
*
* @see nsLayoutUtils::DrawImage() for other parameters.
*/
DrawResult BuildWebRenderDisplayItems(nsPresContext* aPresContext,
mozilla::wr::DisplayListBuilder& aBuilder,
const mozilla::layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
mozilla::layers::WebRenderDisplayItemLayer* aLayer,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayItem* aItem,
const nsRect& aDirtyRect,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsSize& aRepeatSize,
const mozilla::CSSIntRect& aSrc,
float aOpacity = 1.0);