--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -7,16 +7,18 @@
#include "nsBulletFrame.h"
#include "gfx2DGlue.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/layers/LayersMessages.h"
+#include "mozilla/layers/WebRenderDisplayItemLayer.h"
+#include "mozilla/layers/WebRenderMessages.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"
@@ -223,16 +225,21 @@ public:
}
already_AddRefed<layers::Layer>
BuildLayer(nsDisplayListBuilder* aBuilder,
layers::LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters,
nsDisplayItem* aItem);
+ void
+ CreateWebRenderCommands(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer);
+
DrawResult
Paint(nsRenderingContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, uint32_t aFlags,
bool aDisableSubpixelAA, nsIFrame* aFrame);
bool
IsImageType() const
{
@@ -260,16 +267,19 @@ public:
mListStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN &&
mListStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
!mText.IsEmpty();
}
bool
BuildGlyphForText(nsDisplayItem* aItem, bool disableSubpixelAA);
+ bool
+ IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags);
+
private:
already_AddRefed<layers::Layer>
BuildLayerForImage(layers::Layer* aOldLayer,
nsDisplayListBuilder* aBuilder,
layers::LayerManager* aManager,
nsDisplayItem* aItem);
already_AddRefed<layers::Layer>
@@ -279,16 +289,31 @@ private:
nsDisplayItem* aItem);
already_AddRefed<layers::Layer>
BuildLayerForText(layers::Layer* aOldLayer,
nsDisplayListBuilder* aBuilder,
layers::LayerManager* aManager,
nsDisplayItem* aItem);
+ void
+ CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer);
+
+ void
+ CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer);
+
+ void
+ CreateWebRenderCommandsForText(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer);
+
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.
nscolor mColor;
@@ -299,16 +324,17 @@ private:
// mText, mFontMertrics, mPoint, mFont and mGlyphs are for other
// list-style-type which can be drawed by text.
nsString mText;
RefPtr<nsFontMetrics> mFontMetrics;
nsPoint mPoint;
RefPtr<ScaledFont> mFont;
nsTArray<layers::GlyphArray> mGlyphs;
+ WebRenderGlyphHelper mGlyphHelper;
// Store the type of list-style-type.
int32_t mListStyleType;
};
already_AddRefed<layers::Layer>
BulletRenderer::BuildLayer(nsDisplayListBuilder* aBuilder,
layers::LayerManager* aManager,
@@ -332,16 +358,31 @@ BulletRenderer::BuildLayer(nsDisplayList
if (layer) {
layer->SetBaseTransform(gfx::Matrix4x4::Translation(offset.x, offset.y, 0));
}
return layer.forget();
}
+void
+BulletRenderer::CreateWebRenderCommands(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer)
+{
+ if (IsImageType()) {
+ CreateWebRenderCommandsForImage(aItem, aCommands, aLayer);
+ } else if (IsPathType()) {
+ CreateWebRenderCommandsForPath(aItem, aCommands, aLayer);
+ } else {
+ MOZ_ASSERT(IsTextType());
+ CreateWebRenderCommandsForText(aItem, aCommands, aLayer);
+ }
+}
+
DrawResult
BulletRenderer::Paint(nsRenderingContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, uint32_t aFlags,
bool aDisableSubpixelAA, nsIFrame* aFrame)
{
if (IsImageType()) {
SamplingFilter filter = nsLayoutUtils::GetSamplingFilterForFrame(aFrame);
return nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(),
@@ -405,16 +446,17 @@ BulletRenderer::BuildGlyphForText(nsDisp
ctx.ThebesContext()->SetColor(
Color::FromABGR(mColor));
nsPresContext* presContext = aItem->Frame()->PresContext();
if (!presContext->BidiEnabled() && HasRTLChars(mText)) {
presContext->SetBidiEnabled();
}
+
nsLayoutUtils::DrawString(aItem->Frame(), *mFontMetrics, &ctx,
mText.get(), mText.Length(), mPoint);
}
layers::GlyphArray* g = mGlyphs.AppendElement();
std::vector<Glyph> glyphs;
Color color;
if (!capture->ContainsOnlyColoredGlyphs(mFont, color, glyphs)) {
@@ -425,16 +467,24 @@ BulletRenderer::BuildGlyphForText(nsDisp
g->glyphs().SetLength(glyphs.size());
PodCopy(g->glyphs().Elements(), glyphs.data(), glyphs.size());
g->color() = color;
return true;
}
+bool
+BulletRenderer::IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags)
+{
+ MOZ_ASSERT(IsImageType());
+
+ return mImage->IsImageContainerAvailable(aManager, aFlags);
+}
+
already_AddRefed<layers::Layer>
BulletRenderer::BuildLayerForImage(layers::Layer* aOldLayer,
nsDisplayListBuilder* aBuilder,
layers::LayerManager* aManager,
nsDisplayItem* aItem)
{
MOZ_ASSERT(IsImageType());
@@ -511,16 +561,87 @@ BulletRenderer::BuildLayerForText(layers
auto A2D = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
bool dummy;
const LayoutDeviceIntRect destBounds =
LayoutDeviceIntRect::FromAppUnitsToOutside(aItem->GetBounds(aBuilder, &dummy), A2D);
layer->SetBounds(IntRect(destBounds.x, destBounds.y, destBounds.width, destBounds.height));
return layer.forget();
}
+void
+BulletRenderer::CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer)
+{
+ MOZ_ASSERT(IsImageType());
+
+ if (!mImage) {
+ return;
+ }
+
+ layers::WebRenderDisplayItemLayer* layer = static_cast<layers::WebRenderDisplayItemLayer*>(aLayer);
+ nsDisplayListBuilder* builder = layer->GetDisplayListBuilder();
+ uint32_t flags = builder->ShouldSyncDecodeImages() ?
+ imgIContainer::FLAG_SYNC_DECODE :
+ imgIContainer::FLAG_NONE;
+
+ RefPtr<layers::ImageContainer> container =
+ mImage->GetImageContainer(aLayer->WrManager(), flags);
+ if (!container) {
+ return;
+ }
+
+ uint64_t externalImageId = layer->SendImageContainer(container);
+
+ const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
+ Rect destRect =
+ NSRectToRect(mDest, appUnitsPerDevPixel);
+ Rect destRectTransformed = aLayer->RelativeToParent(destRect);
+ IntRect dest = RoundedToInt(destRectTransformed);
+
+ aCommands.AppendElement(layers::OpDPPushExternalImageId(
+ LayerIntRegion(),
+ wr::ToWrRect(dest),
+ wr::ToWrRect(dest),
+ Nothing(),
+ WrImageRendering::Auto,
+ externalImageId));
+}
+
+void
+BulletRenderer::CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer)
+{
+ MOZ_ASSERT(IsPathType());
+ // Not supported yet.
+ MOZ_CRASH("unreachable");
+}
+
+void
+BulletRenderer::CreateWebRenderCommandsForText(nsDisplayItem* aItem,
+ nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer)
+{
+ 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;
+ Rect destRect =
+ NSRectToRect(aItem->GetBounds(builder, &dummy), appUnitsPerDevPixel);
+ Rect destRectTransformed = aLayer->RelativeToParent(destRect);
+
+ mGlyphHelper.BuildWebRenderCommands(aCommands, mGlyphs, mFont, aLayer->GetOffsetToParent(),
+ destRectTransformed, destRectTransformed);
+}
+
class nsDisplayBullet final : public nsDisplayItem {
public:
nsDisplayBullet(nsDisplayListBuilder* aBuilder, nsBulletFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
, mDisableSubpixelAA(false)
{
MOZ_COUNT_CTOR(nsDisplayBullet);
}
@@ -540,16 +661,19 @@ 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 CreateWebRenderCommands(nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer) override;
+
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames) override {
aOutFrames->AppendElement(mFrame);
}
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) override;
NS_DISPLAY_DECL_NAME("Bullet", TYPE_BULLET)
@@ -617,16 +741,26 @@ nsDisplayBullet::GetLayerState(nsDisplay
return LAYER_NONE;
}
// Only support image and text type.
if (!br->IsImageType() && !br->IsTextType()) {
return LAYER_NONE;
}
+ if (br->IsImageType()) {
+ uint32_t flags = aBuilder->ShouldSyncDecodeImages()
+ ? imgIContainer::FLAG_SYNC_DECODE
+ : imgIContainer::FLAG_NONE;
+
+ if (!br->IsImageContainerAvailable(aManager, flags)) {
+ return LAYER_NONE;
+ }
+ }
+
if (br->IsTextType()) {
if (!br->BuildGlyphForText(this, mDisableSubpixelAA)) {
return LAYER_NONE;
}
}
mBulletRenderer = br;
return LAYER_ACTIVE;
@@ -636,17 +770,28 @@ already_AddRefed<layers::Layer>
nsDisplayBullet::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
if (!mBulletRenderer) {
return nullptr;
}
- return mBulletRenderer->BuildLayer(aBuilder, aManager, aContainerParameters, this);
+ /* return mBulletRenderer->BuildLayer(aBuilder, aManager, aContainerParameters, this); */
+ return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
+}
+
+void
+nsDisplayBullet::CreateWebRenderCommands(nsTArray<layers::WebRenderCommand>& aCommands,
+ layers::WebRenderDisplayItemLayer* aLayer)
+{
+ if (!mBulletRenderer)
+ return;
+
+ mBulletRenderer->CreateWebRenderCommands(this, aCommands, aLayer);
}
void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
uint32_t flags = imgIContainer::FLAG_NONE;
if (aBuilder->ShouldSyncDecodeImages()) {
flags |= imgIContainer::FLAG_SYNC_DECODE;