--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -3,16 +3,17 @@
* 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 "WebRenderLayerManager.h"
#include "gfxPrefs.h"
#include "GeckoProfiler.h"
#include "LayersLogging.h"
+#include "mozilla/gfx/DrawEventRecorder.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "WebRenderCanvasLayer.h"
#include "WebRenderColorLayer.h"
#include "WebRenderContainerLayer.h"
#include "WebRenderImageLayer.h"
@@ -298,16 +299,62 @@ WebRenderLayerManager::PushImage(nsDispl
wr::ImageRendering filter = wr::ImageRendering::Auto;
auto r = aSc.ToRelativeWrRect(aRect);
aBuilder.PushImage(r, r, filter, key.value());
return true;
}
+bool
+WebRenderLayerManager::PushItemAsBlobImage(nsDisplayItem* aItem,
+ wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+
+ bool snap;
+ LayerRect bounds = ViewAs<LayerPixel>(
+ LayoutDeviceRect::FromAppUnits(aItem->GetBounds(aDisplayListBuilder, &snap), appUnitsPerDevPixel),
+ PixelCastJustification::WebRenderHasUnitResolution);
+ LayerIntSize imageSize = RoundedToInt(bounds.Size());
+ LayerRect imageRect;
+ imageRect.SizeTo(LayerSize(imageSize));
+
+ RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
+ RefPtr<gfx::DrawTarget> dummyDt =
+ gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8X8);
+ RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
+ LayerPoint offset = ViewAs<LayerPixel>(
+ LayoutDevicePoint::FromAppUnits(aItem->ToReferenceFrame(), appUnitsPerDevPixel),
+ PixelCastJustification::WebRenderHasUnitResolution);
+
+ {
+ dt->ClearRect(imageRect.ToUnknownRect());
+ RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt, offset.ToUnknownPoint());
+ MOZ_ASSERT(context);
+
+ aItem->Paint(aDisplayListBuilder, context);
+ }
+
+ wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
+
+ WrRect dest = aSc.ToRelativeWrRect(imageRect + offset);
+ WrImageKey key = WrBridge()->GetNextImageKey();
+ WrBridge()->SendAddBlobImage(key, imageSize.ToUnknownSize(), imageSize.width * 4, dt->GetFormat(), bytes);
+ AddImageKeyForDiscard(key);
+
+ aBuilder.PushImage(dest,
+ dest,
+ wr::ImageRendering::Auto,
+ key);
+ return true;
+}
+
void
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
mEndTransactionWithoutLayers = false;
DiscardImages();
WrBridge()->RemoveExpiredFontKeys();
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -222,17 +222,18 @@ public:
MOZ_ASSERT(IsTextType());
}
void
CreateWebRenderCommands(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer);
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder);
DrawResult
Paint(gfxContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, uint32_t aFlags,
bool aDisableSubpixelAA, nsIFrame* aFrame);
bool
IsImageType() const
@@ -270,30 +271,33 @@ public:
IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags);
private:
void
CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer);
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder);
void
CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer);
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder);
void
CreateWebRenderCommandsForText(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
- layers::WebRenderDisplayItemLayer* aLayer);
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder);
private:
// mImage and mDest are the properties for list-style-image.
// mImage is the image content and mDest is the image position.
RefPtr<imgIContainer> mImage;
nsRect mDest;
// mColor indicate the color of list-style. Both text and path type would use this memeber.
@@ -315,25 +319,29 @@ private:
int32_t mListStyleType;
};
void
BulletRenderer::CreateWebRenderCommands(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer)
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
{
if (IsImageType()) {
- CreateWebRenderCommandsForImage(aItem, aBuilder, aSc, aParentCommands, aLayer);
+ CreateWebRenderCommandsForImage(aItem, aBuilder, aSc, aParentCommands,
+ aManager, aDisplayListBuilder);
} else if (IsPathType()) {
- CreateWebRenderCommandsForPath(aItem, aBuilder, aSc, aParentCommands, aLayer);
+ CreateWebRenderCommandsForPath(aItem, aBuilder, aSc, aParentCommands,
+ aManager, aDisplayListBuilder);
} else {
MOZ_ASSERT(IsTextType());
- CreateWebRenderCommandsForText(aItem, aBuilder, aSc, aLayer);
+ CreateWebRenderCommandsForText(aItem, aBuilder, aSc,
+ aManager, aDisplayListBuilder);
}
}
DrawResult
BulletRenderer::Paint(gfxContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, uint32_t aFlags,
bool aDisableSubpixelAA, nsIFrame* aFrame)
{
@@ -432,37 +440,37 @@ BulletRenderer::IsImageContainerAvailabl
return mImage->IsImageContainerAvailable(aManager, aFlags);
}
void
BulletRenderer::CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer)
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
{
MOZ_ASSERT(IsImageType());
if (!mImage) {
return;
}
- layers::WebRenderDisplayItemLayer* layer = static_cast<layers::WebRenderDisplayItemLayer*>(aLayer);
- nsDisplayListBuilder* builder = layer->GetDisplayListBuilder();
- uint32_t flags = builder->ShouldSyncDecodeImages() ?
+ uint32_t flags = aDisplayListBuilder->ShouldSyncDecodeImages() ?
imgIContainer::FLAG_SYNC_DECODE :
imgIContainer::FLAG_NONE;
RefPtr<layers::ImageContainer> container =
- mImage->GetImageContainer(aLayer->WrManager(), flags);
+ mImage->GetImageContainer(aManager, flags);
if (!container) {
return;
}
- Maybe<wr::ImageKey> key = layer->SendImageContainer(container, aParentCommands);
+ gfx::IntSize size;
+ Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aSc, size);
if (key.isNothing()) {
return;
}
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(mDest, appUnitsPerDevPixel);
WrRect dest = aSc.ToRelativeWrRectRounded(destRect);
@@ -472,46 +480,45 @@ BulletRenderer::CreateWebRenderCommandsF
key.value());
}
void
BulletRenderer::CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer)
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
{
MOZ_ASSERT(IsPathType());
- MOZ_ASSERT(aLayer->GetDisplayItem() == aItem);
- if (!aLayer->PushItemAsBlobImage(aBuilder, aSc)) {
+ if (!aManager->PushItemAsBlobImage(aItem, aBuilder, aSc, aDisplayListBuilder)) {
NS_WARNING("Fail to create WebRender commands for Bullet path.");
}
}
void
BulletRenderer::CreateWebRenderCommandsForText(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
- layers::WebRenderDisplayItemLayer* aLayer)
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
{
MOZ_ASSERT(IsTextType());
MOZ_ASSERT(mFont);
MOZ_ASSERT(!mGlyphs.IsEmpty());
- layers::WebRenderDisplayItemLayer* layer = static_cast<layers::WebRenderDisplayItemLayer*>(aLayer);
- nsDisplayListBuilder* builder = layer->GetDisplayListBuilder();
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
bool dummy;
LayerRect destRect = ViewAs<LayerPixel>(
LayoutDeviceRect::FromAppUnits(
- aItem->GetBounds(builder, &dummy), appUnitsPerDevPixel),
+ aItem->GetBounds(aDisplayListBuilder, &dummy), appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
- layer->WrBridge()->PushGlyphs(aBuilder, mGlyphs, mFont, aSc, destRect, destRect);
+ aManager->WrBridge()->PushGlyphs(aBuilder, mGlyphs, mFont, aSc, destRect, destRect);
}
class nsDisplayBullet final : public nsDisplayItem {
public:
nsDisplayBullet(nsDisplayListBuilder* aBuilder, nsBulletFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
, mDisableSubpixelAA(false)
{
@@ -533,20 +540,21 @@ public:
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
- virtual void CreateWebRenderCommand(mozilla::wr::DisplayListBuilder& aBuilder,
- const StackingContextHelper& aSc,
- nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::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 {
aOutFrames->AppendElement(mFrame);
}
virtual void Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) override;
@@ -641,26 +649,36 @@ nsDisplayBullet::BuildLayer(nsDisplayLis
{
if (!mBulletRenderer) {
return nullptr;
}
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
-void
-nsDisplayBullet::CreateWebRenderCommand(wr::DisplayListBuilder& aBuilder,
- const StackingContextHelper& aSc,
- nsTArray<layers::WebRenderParentCommand>& aParentCommands,
- layers::WebRenderDisplayItemLayer* aLayer)
+bool
+nsDisplayBullet::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc,
+ nsTArray<layers::WebRenderParentCommand>& aParentCommands,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
{
+ if (aManager->IsLayersFreeTransaction()) {
+ ContainerLayerParameters parameter;
+ if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
+ return false;
+ }
+ }
+
if (!mBulletRenderer)
- return;
+ return false;
- mBulletRenderer->CreateWebRenderCommands(this, aBuilder, aSc, aParentCommands, aLayer);
+ mBulletRenderer->CreateWebRenderCommands(this, aBuilder, aSc, aParentCommands,
+ aManager, aDisplayListBuilder);
+ return true;
}
void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx)
{
uint32_t flags = imgIContainer::FLAG_NONE;
if (aBuilder->ShouldSyncDecodeImages()) {
flags |= imgIContainer::FLAG_SYNC_DECODE;