Bug 1400382 - Implement CreateWebRenderCommands for nsDisplayTextOverflow. r?jrmuizel
MozReview-Commit-ID: EQtFvLQCT2U
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -119,16 +119,17 @@
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "RegionBuilder.h"
#include "SVGSVGElement.h"
#include "DisplayItemClip.h"
#include "mozilla/layers/WebRenderLayerManager.h"
#include "prenv.h"
+#include "TextDrawTarget.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
#endif
#include "GeckoProfiler.h"
#include "nsAnimationManager.h"
#include "nsTransitionManager.h"
@@ -6062,28 +6063,47 @@ nsLayoutUtils::PaintTextShadow(const nsI
shadowDetails->mYOffset);
nscoord blurRadius = std::max(shadowDetails->mRadius, 0);
nsRect shadowRect(aTextRect);
shadowRect.MoveBy(shadowOffset);
nsPresContext* presCtx = aFrame->PresContext();
nsContextBoxBlur contextBoxBlur;
+
+ nscolor shadowColor;
+ if (shadowDetails->mHasColor)
+ shadowColor = shadowDetails->mColor;
+ else
+ shadowColor = aForegroundColor;
+
+ // Webrender just needs the shadow details
+ if (auto* textDrawer = aContext->GetTextDrawer()) {
+ wr::TextShadow wrShadow;
+
+ wrShadow.offset = {
+ presCtx->AppUnitsToFloatDevPixels(shadowDetails->mXOffset),
+ presCtx->AppUnitsToFloatDevPixels(shadowDetails->mYOffset)
+ };
+
+ wrShadow.blur_radius = presCtx->AppUnitsToFloatDevPixels(shadowDetails->mRadius);
+ wrShadow.color = wr::ToColorF(ToDeviceColor(shadowColor));
+
+ textDrawer->AppendShadow(wrShadow);
+ return;
+ }
+
gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, 0, blurRadius,
presCtx->AppUnitsPerDevPixel(),
aDestCtx, aDirtyRect, nullptr,
nsContextBoxBlur::DISABLE_HARDWARE_ACCELERATION_BLUR);
if (!shadowContext)
continue;
- nscolor shadowColor;
- if (shadowDetails->mHasColor)
- shadowColor = shadowDetails->mColor;
- else
- shadowColor = aForegroundColor;
+
aDestCtx->Save();
aDestCtx->NewPath();
aDestCtx->SetColor(Color::FromABGR(shadowColor));
// The callback will draw whatever we want to blur as a shadow.
aCallback(shadowContext, shadowOffset, shadowColor, aCallbackData);
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -19,16 +19,17 @@
#include "nsLayoutUtils.h"
#include "nsPresContext.h"
#include "nsRect.h"
#include "nsTextFrame.h"
#include "nsIFrameInlines.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Likely.h"
#include "nsISelection.h"
+#include "TextDrawTarget.h"
namespace mozilla {
namespace css {
class LazyReferenceRenderingDrawTargetGetterFromFrame final :
public gfxFontGroup::LazyReferenceDrawTargetGetter {
public:
typedef mozilla::gfx::DrawTarget DrawTarget;
@@ -203,16 +204,23 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) override;
virtual uint32_t GetPerFrameKey() const override {
return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey();
}
void PaintTextToContext(gfxContext* aCtx,
nsPoint aOffsetFromRect);
+
+ virtual bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override;
+
NS_DISPLAY_DECL_NAME("TextOverflow", TYPE_TEXT_OVERFLOW)
private:
nsRect mRect; // in reference frame coordinates
const nsStyleTextOverflowSide* mStyle;
nscoord mAscent; // baseline for the marker text in mRect
uint32_t mIndex;
};
@@ -273,16 +281,53 @@ nsDisplayTextOverflowMarker::PaintTextTo
} else {
RefPtr<nsFontMetrics> fm =
nsLayoutUtils::GetInflatedFontMetricsForFrame(mFrame);
nsLayoutUtils::DrawString(mFrame, *fm, aCtx, mStyle->mString.get(),
mStyle->mString.Length(), pt);
}
}
+bool
+nsDisplayTextOverflowMarker::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder)
+{
+ if (!aManager->IsLayersFreeTransaction() ||
+ !gfxPrefs::LayersAllowTextLayers() ||
+ !CanUseAdvancedLayer(aDisplayListBuilder->GetWidgetLayerManager())) {
+ return false;
+ }
+
+ bool snap;
+ nsRect bounds = GetBounds(aDisplayListBuilder, &snap);
+ if (bounds.IsEmpty()) {
+ return true;
+ }
+
+ // Run the rendering algorithm to capture the glyphs and shadows
+ RefPtr<TextDrawTarget> textDrawer = new TextDrawTarget();
+ RefPtr<gfxContext> captureCtx = gfxContext::CreateOrNull(textDrawer);
+ // TextOverflowMarker only draws glyphs
+ textDrawer->StartDrawing(TextDrawTarget::Phase::eGlyphs);
+ Paint(aDisplayListBuilder, captureCtx);
+
+ if (!textDrawer->CanSerializeFonts()) {
+ return false;
+ }
+
+ textDrawer->CreateWebRenderCommands(aBuilder, aSc, aManager, this, bounds);
+
+
+ return true;
+}
+
+
TextOverflow::TextOverflow(nsDisplayListBuilder* aBuilder,
nsIFrame* aBlockFrame)
: mContentArea(aBlockFrame->GetWritingMode(),
aBlockFrame->GetContentRectRelativeToSelf(),
aBlockFrame->GetSize())
, mBuilder(aBuilder)
, mBlock(aBlockFrame)
, mScrollableFrame(nsLayoutUtils::GetScrollableFrameFor(aBlockFrame))