--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -219,17 +219,17 @@ public:
, mText(text)
, mFontMetrics(fm)
, mPoint(point)
, mListStyleType(listStyleType)
{
MOZ_ASSERT(IsTextType());
}
- void
+ bool
CreateWebRenderCommands(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder);
DrawResult
@@ -264,37 +264,42 @@ public:
mListStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_OPEN &&
mListStyleType != NS_STYLE_LIST_STYLE_DISCLOSURE_CLOSED &&
!mText.IsEmpty();
}
bool
BuildGlyphForText(nsDisplayItem* aItem, bool disableSubpixelAA);
+ void
+ PaintTextToContext(nsIFrame* aFrame,
+ gfxContext* aCtx,
+ bool aDisableSubpixelAA);
+
bool
IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags);
private:
- void
+ bool
CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder);
- void
+ bool
CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder);
- void
+ bool
CreateWebRenderCommandsForText(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder);
private:
@@ -317,34 +322,34 @@ private:
nsPoint mPoint;
RefPtr<ScaledFont> mFont;
nsTArray<layers::GlyphArray> mGlyphs;
// Store the type of list-style-type.
int32_t mListStyleType;
};
-void
+bool
BulletRenderer::CreateWebRenderCommands(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
if (IsImageType()) {
- CreateWebRenderCommandsForImage(aItem, aBuilder, aResources,
+ return CreateWebRenderCommandsForImage(aItem, aBuilder, aResources,
aSc, aManager, aDisplayListBuilder);
} else if (IsPathType()) {
- CreateWebRenderCommandsForPath(aItem, aBuilder, aResources,
+ return CreateWebRenderCommandsForPath(aItem, aBuilder, aResources,
aSc, aManager, aDisplayListBuilder);
} else {
MOZ_ASSERT(IsTextType());
- CreateWebRenderCommandsForText(aItem, aBuilder, aResources, aSc,
- aManager, aDisplayListBuilder);
+ return CreateWebRenderCommandsForText(aItem, aBuilder, aResources, aSc,
+ aManager, aDisplayListBuilder);
}
}
DrawResult
BulletRenderer::Paint(gfxContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect, uint32_t aFlags,
bool aDisableSubpixelAA, nsIFrame* aFrame)
{
@@ -372,28 +377,17 @@ BulletRenderer::Paint(gfxContext& aRende
drawTarget->Fill(mPath, ColorPattern(ToDeviceColor(mColor)));
break;
default:
MOZ_CRASH("unreachable");
}
}
if (IsTextType()) {
- DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
- DrawTargetAutoDisableSubpixelAntialiasing
- disable(drawTarget, aDisableSubpixelAA);
-
- aRenderingContext.SetColor(Color::FromABGR(mColor));
-
- nsPresContext* presContext = aFrame->PresContext();
- if (!presContext->BidiEnabled() && HasRTLChars(mText)) {
- presContext->SetBidiEnabled();
- }
- nsLayoutUtils::DrawString(aFrame, *mFontMetrics, &aRenderingContext,
- mText.get(), mText.Length(), mPoint);
+ PaintTextToContext(aFrame, &aRenderingContext, aDisableSubpixelAA);
}
return DrawResult::SUCCESS;
}
bool
BulletRenderer::BuildGlyphForText(nsDisplayItem* aItem, bool disableSubpixelAA)
{
@@ -402,31 +396,17 @@ BulletRenderer::BuildGlyphForText(nsDisp
RefPtr<DrawTarget> screenTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
RefPtr<DrawTargetCapture> capture =
Factory::CreateCaptureDrawTarget(screenTarget->GetBackendType(),
IntSize(),
screenTarget->GetFormat());
RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(capture);
- {
- DrawTargetAutoDisableSubpixelAntialiasing
- disable(capture, disableSubpixelAA);
-
- captureCtx->SetColor(
- Color::FromABGR(mColor));
-
- nsPresContext* presContext = aItem->Frame()->PresContext();
- if (!presContext->BidiEnabled() && HasRTLChars(mText)) {
- presContext->SetBidiEnabled();
- }
-
- nsLayoutUtils::DrawString(aItem->Frame(), *mFontMetrics, captureCtx,
- mText.get(), mText.Length(), mPoint);
- }
+ PaintTextToContext(aItem->Frame(), captureCtx, disableSubpixelAA);
layers::GlyphArray* g = mGlyphs.AppendElement();
std::vector<Glyph> glyphs;
Color color;
if (!capture->ContainsOnlyColoredGlyphs(mFont, color, glyphs)) {
mFont = nullptr;
mGlyphs.Clear();
return false;
@@ -434,115 +414,131 @@ BulletRenderer::BuildGlyphForText(nsDisp
g->glyphs().SetLength(glyphs.size());
PodCopy(g->glyphs().Elements(), glyphs.data(), glyphs.size());
g->color() = color;
return true;
}
+void
+BulletRenderer::PaintTextToContext(nsIFrame* aFrame,
+ gfxContext* aCtx,
+ bool aDisableSubpixelAA)
+{
+ MOZ_ASSERT(IsTextType());
+
+ DrawTarget* drawTarget = aCtx->GetDrawTarget();
+ DrawTargetAutoDisableSubpixelAntialiasing
+ disable(drawTarget, aDisableSubpixelAA);
+
+ aCtx->SetColor(Color::FromABGR(mColor));
+
+ nsPresContext* presContext = aFrame->PresContext();
+ if (!presContext->BidiEnabled() && HasRTLChars(mText)) {
+ presContext->SetBidiEnabled();
+ }
+ nsLayoutUtils::DrawString(aFrame, *mFontMetrics, aCtx,
+ mText.get(), mText.Length(), mPoint);
+}
+
bool
BulletRenderer::IsImageContainerAvailable(layers::LayerManager* aManager, uint32_t aFlags)
{
MOZ_ASSERT(IsImageType());
return mImage->IsImageContainerAvailable(aManager, aFlags);
}
-void
+bool
BulletRenderer::CreateWebRenderCommandsForImage(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
- MOZ_ASSERT(IsImageType());
-
- if (!mImage) {
- return;
- }
+ MOZ_RELEASE_ASSERT(IsImageType());
+ MOZ_RELEASE_ASSERT(mImage);
uint32_t flags = aDisplayListBuilder->ShouldSyncDecodeImages() ?
imgIContainer::FLAG_SYNC_DECODE :
imgIContainer::FLAG_NONE;
+ // FIXME: is this check always redundant with the next one?
+ if (IsImageContainerAvailable(aManager, flags)) {
+ return false;
+ }
+
RefPtr<layers::ImageContainer> container =
mImage->GetImageContainer(aManager, flags);
if (!container) {
- return;
+ return false;
}
gfx::IntSize size;
Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container, aBuilder, aResources, aSc, size);
if (key.isNothing()) {
- return;
+ return true; // Nothing to do
}
const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(mDest, appUnitsPerDevPixel);
wr::LayoutRect dest = aSc.ToRelativeLayoutRect(destRect);
aBuilder.PushImage(dest,
dest,
!aItem->BackfaceIsHidden(),
wr::ImageRendering::Auto,
key.value());
+
+ return true;
}
-void
+bool
BulletRenderer::CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
MOZ_ASSERT(IsPathType());
if (!aManager->CommandBuilder().PushItemAsImage(aItem, aBuilder, aResources, aSc, aDisplayListBuilder)) {
NS_WARNING("Fail to create WebRender commands for Bullet path.");
+ return false;
}
+
+ return true;
}
-void
+bool
BulletRenderer::CreateWebRenderCommandsForText(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
MOZ_ASSERT(IsTextType());
- MOZ_ASSERT(mFont);
- MOZ_ASSERT(!mGlyphs.IsEmpty());
- const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
bool dummy;
- LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
- aItem->GetBounds(aDisplayListBuilder, &dummy), appUnitsPerDevPixel);
- wr::LayoutRect wrDestRect = aSc.ToRelativeLayoutRect(destRect);
-
- nsTArray<wr::GlyphInstance> wrGlyphs;
+ nsRect bounds = aItem->GetBounds(aDisplayListBuilder, &dummy);
- for (layers::GlyphArray& glyphArray : mGlyphs) {
- const auto& glyphs = glyphArray.glyphs();
- wrGlyphs.SetLength(glyphs.Length());
+ if (bounds.IsEmpty()) {
+ return true;
+ }
- for (size_t j = 0; j < glyphs.Length(); j++) {
- wrGlyphs[j].index = glyphs[j].mIndex;
- wrGlyphs[j].point = aSc.ToRelativeLayoutPoint(
- LayoutDevicePoint::FromUnknownPoint(glyphs[j].mPosition));
- }
+ RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget(aBuilder, aSc, aManager, aItem, bounds);
+ RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer);
+ PaintTextToContext(aItem->Frame(), captureCtx, aItem);
+ textDrawer->TerminateShadows();
- aManager->WrBridge()->PushGlyphs(aBuilder, wrGlyphs, mFont,
- wr::ToColorF(glyphArray.color().value()),
- aSc, wrDestRect, wrDestRect,
- !aItem->BackfaceIsHidden());
- }
+ return !textDrawer->HasUnsupportedFeatures();
}
class nsDisplayBullet final : public nsDisplayItem {
public:
nsDisplayBullet(nsDisplayListBuilder* aBuilder, nsBulletFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
{
MOZ_COUNT_CTOR(nsDisplayBullet);
@@ -673,27 +669,29 @@ nsDisplayBullet::BuildLayer(nsDisplayLis
bool
nsDisplayBullet::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
- ContainerLayerParameters parameter;
- if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
+ // FIXME: avoid needing to make this target if we're drawing text
+ // (non-trivial refactor of all this code)
+ RefPtr<gfxContext> screenRefCtx = gfxContext::CreateOrNull(
+ gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget().get());
+ Maybe<BulletRenderer> br = static_cast<nsBulletFrame*>(mFrame)->
+ CreateBulletRenderer(*screenRefCtx, ToReferenceFrame());
+
+ if (!br) {
return false;
}
- if (!mBulletRenderer)
- return false;
-
- mBulletRenderer->CreateWebRenderCommands(this, aBuilder, aResources, aSc,
- aManager, aDisplayListBuilder);
- return true;
+ return br->CreateWebRenderCommands(this, aBuilder, aResources, aSc,
+ aManager, aDisplayListBuilder);
}
void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx)
{
uint32_t flags = imgIContainer::FLAG_NONE;
if (aBuilder->ShouldSyncDecodeImages()) {
flags |= imgIContainer::FLAG_SYNC_DECODE;