--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -625,21 +625,22 @@ void
BufferTextureHost::PushExternalImage(wr::DisplayListBuilder& aBuilder,
const wr::LayoutRect& aBounds,
const wr::LayoutRect& aClip,
wr::ImageRendering aFilter,
Range<const wr::ImageKey>& aImageKeys)
{
if (GetFormat() != gfx::SurfaceFormat::YUV) {
MOZ_ASSERT(aImageKeys.length() == 1);
- aBuilder.PushImage(aBounds, aClip, aFilter, aImageKeys[0]);
+ aBuilder.PushImage(aBounds, aClip, true, aFilter, aImageKeys[0]);
} else {
MOZ_ASSERT(aImageKeys.length() == 3);
aBuilder.PushYCbCrPlanarImage(aBounds,
aClip,
+ true,
aImageKeys[0],
aImageKeys[1],
aImageKeys[2],
wr::WrYuvColorSpace::Rec601,
aFilter);
}
}
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -231,34 +231,36 @@ MacIOSurfaceTextureHostOGL::PushExternal
{
switch (GetFormat()) {
case gfx::SurfaceFormat::R8G8B8X8:
case gfx::SurfaceFormat::R8G8B8A8:
case gfx::SurfaceFormat::B8G8R8A8:
case gfx::SurfaceFormat::B8G8R8X8: {
MOZ_ASSERT(aImageKeys.length() == 1);
MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
- aBuilder.PushImage(aBounds, aClip, aFilter, aImageKeys[0]);
+ aBuilder.PushImage(aBounds, aClip, true, aFilter, aImageKeys[0]);
break;
}
case gfx::SurfaceFormat::YUV422: {
MOZ_ASSERT(aImageKeys.length() == 1);
MOZ_ASSERT(mSurface->GetPlaneCount() == 0);
aBuilder.PushYCbCrInterleavedImage(aBounds,
aClip,
+ true,
aImageKeys[0],
wr::WrYuvColorSpace::Rec601,
aFilter);
break;
}
case gfx::SurfaceFormat::NV12: {
MOZ_ASSERT(aImageKeys.length() == 2);
MOZ_ASSERT(mSurface->GetPlaneCount() == 2);
aBuilder.PushNV12Image(aBounds,
aClip,
+ true,
aImageKeys[0],
aImageKeys[1],
wr::WrYuvColorSpace::Rec601,
aFilter);
break;
}
default: {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -286,17 +286,18 @@ AsyncImagePipelineManager::ApplyAsyncIma
float opacity = 1.0f;
builder.PushStackingContext(wr::ToLayoutRect(pipeline->mScBounds),
0,
&opacity,
pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform,
wr::TransformStyle::Flat,
nullptr,
pipeline->mMixBlendMode,
- nsTArray<wr::WrFilterOp>());
+ nsTArray<wr::WrFilterOp>(),
+ true);
LayerRect rect(0, 0, pipeline->mCurrentTexture->GetSize().width, pipeline->mCurrentTexture->GetSize().height);
if (pipeline->mScaleToSize.isSome()) {
rect = LayerRect(0, 0, pipeline->mScaleToSize.value().width, pipeline->mScaleToSize.value().height);
}
if (useExternalImage) {
MOZ_ASSERT(pipeline->mCurrentTexture->AsWebRenderTextureHost());
@@ -306,16 +307,17 @@ AsyncImagePipelineManager::ApplyAsyncIma
wr::ToLayoutRect(rect),
pipeline->mFilter,
range_keys);
HoldExternalImage(pipelineId, epoch, pipeline->mCurrentTexture->AsWebRenderTextureHost());
} else {
MOZ_ASSERT(keys.Length() == 1);
builder.PushImage(wr::ToLayoutRect(rect),
wr::ToLayoutRect(rect),
+ true,
pipeline->mFilter,
keys[0]);
}
builder.PopStackingContext();
}
wr::BuiltDisplayList dl;
wr::LayoutSize builderContentSize;
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -30,17 +30,18 @@ StackingContextHelper::StackingContextHe
mTransform = aTransform.valueOr(layer->GetTransform());
float opacity = 1.0f;
mBuilder->PushStackingContext(scBounds, 0, &opacity,
mTransform.IsIdentity() ? nullptr : &mTransform,
wr::TransformStyle::Flat,
nullptr,
wr::ToMixBlendMode(layer->GetMixBlendMode()),
- aFilters);
+ aFilters,
+ true);
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
uint64_t aAnimationsId,
float* aOpacityPtr,
@@ -55,47 +56,50 @@ StackingContextHelper::StackingContextHe
mBuilder->PushStackingContext(scBounds,
aAnimationsId,
aOpacityPtr,
aTransformPtr,
wr::TransformStyle::Flat,
nullptr,
wr::ToMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()),
- aFilters);
+ aFilters,
+ true);
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
wr::DisplayListBuilder& aBuilder,
nsDisplayListBuilder* aDisplayListBuilder,
nsDisplayItem* aItem,
nsDisplayList* aDisplayList,
gfx::Matrix4x4Typed<LayerPixel, LayerPixel>* aBoundTransform,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
gfx::Matrix4x4* aPerspectivePtr,
const nsTArray<wr::WrFilterOp>& aFilters,
- const gfx::CompositionOp& aMixBlendMode)
+ const gfx::CompositionOp& aMixBlendMode,
+ bool aBackfaceVisible)
: mBuilder(&aBuilder)
{
bool is2d = !aTransformPtr || (aTransformPtr->Is2D() && !aPerspectivePtr);
if (aTransformPtr) {
mTransform = *aTransformPtr;
}
mBuilder->PushStackingContext(wr::LayoutRect(),
aAnimationsId,
aOpacityPtr,
aTransformPtr,
is2d ? wr::TransformStyle::Flat : wr::TransformStyle::Preserve3D,
aPerspectivePtr,
wr::ToMixBlendMode(aMixBlendMode),
- aFilters);
+ aFilters,
+ aBackfaceVisible);
}
StackingContextHelper::~StackingContextHelper()
{
if (mBuilder) {
mBuilder->PopStackingContext();
}
}
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -53,17 +53,18 @@ public:
nsDisplayItem* aItem,
nsDisplayList* aDisplayList,
gfx::Matrix4x4Typed<LayerPixel, LayerPixel>* aBoundTransform,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr,
gfx::Matrix4x4* aPerspectivePtr = nullptr,
const nsTArray<wr::WrFilterOp>& aFilters = nsTArray<wr::WrFilterOp>(),
- const gfx::CompositionOp& aMixBlendMode = gfx::CompositionOp::OP_OVER);
+ const gfx::CompositionOp& aMixBlendMode = gfx::CompositionOp::OP_OVER,
+ bool aBackfaceVisible = true);
// This version of the constructor should only be used at the root level
// of the tree, so that we have a StackingContextHelper to pass down into
// the RenderLayer traversal, but don't actually want it to push a stacking
// context on the display list builder.
StackingContextHelper();
// Pops the stacking context, if one was pushed during the constructor.
~StackingContextHelper();
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -236,17 +236,17 @@ WriteFontFileData(const uint8_t* aData,
memcpy(data->mFontBuffer.mData, aData, aLength);
data->mFontIndex = aIndex;
}
void
WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<gfx::Glyph>& aGlyphs,
gfx::ScaledFont* aFont, const gfx::Color& aColor, const StackingContextHelper& aSc,
- const LayerRect& aBounds, const LayerRect& aClip)
+ const LayerRect& aBounds, const LayerRect& aClip, bool aBackfaceVisible)
{
MOZ_ASSERT(aFont);
MOZ_ASSERT(!aGlyphs.IsEmpty());
wr::WrFontInstanceKey key = GetFontKeyForScaledFont(aFont);
MOZ_ASSERT(key.mNamespace.mHandle && key.mHandle);
nsTArray<wr::GlyphInstance> wr_glyph_instances;
@@ -255,16 +255,17 @@ WebRenderBridgeChild::PushGlyphs(wr::Dis
for (size_t j = 0; j < aGlyphs.Length(); j++) {
wr_glyph_instances[j].index = aGlyphs[j].mIndex;
wr_glyph_instances[j].point = aSc.ToRelativeLayoutPoint(
LayerPoint::FromUnknownPoint(aGlyphs[j].mPosition));
}
aBuilder.PushText(aSc.ToRelativeLayoutRect(aBounds),
aSc.ToRelativeLayoutRect(aClip),
+ aBackfaceVisible,
aColor,
key,
Range<const wr::GlyphInstance>(wr_glyph_instances.Elements(), wr_glyph_instances.Length()));
}
wr::FontInstanceKey
WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
{
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -111,17 +111,18 @@ public:
wr::WrImageKey GetNextImageKey()
{
return wr::WrImageKey{ GetNamespace(), GetNextResourceId() };
}
void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<gfx::Glyph>& aGlyphs,
gfx::ScaledFont* aFont, const gfx::Color& aColor,
const StackingContextHelper& aSc,
- const LayerRect& aBounds, const LayerRect& aClip);
+ const LayerRect& aBounds, const LayerRect& aClip,
+ bool aBackfaceVisible);
wr::FontInstanceKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
void RemoveExpiredFontKeys();
void ClearReadLocks();
void BeginClearCachedResources();
void EndClearCachedResources();
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -64,17 +64,17 @@ WebRenderCanvasLayer::RenderLayer(wr::Di
Stringify(filter).c_str());
}
wr::WrImageKey key = GenerateImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(canvasRenderer->GetExternalImageId().value(), key));
WrManager()->AddImageKeyForDiscard(key);
wr::LayoutRect r = sc.ToRelativeLayoutRect(rect);
- aBuilder.PushImage(r, r, filter, key);
+ aBuilder.PushImage(r, r, true, filter, key);
}
void
WebRenderCanvasLayer::ClearCachedResources()
{
mCanvasRenderer->ClearCachedResources();
}
--- a/gfx/layers/wr/WebRenderColorLayer.cpp
+++ b/gfx/layers/wr/WebRenderColorLayer.cpp
@@ -25,13 +25,13 @@ WebRenderColorLayer::RenderLayer(wr::Dis
{
ScrollingLayersHelper scroller(this, aBuilder, aSc);
StackingContextHelper sc(aSc, aBuilder, this);
LayerRect rect = Bounds();
DumpLayerInfo("ColorLayer", rect);
wr::LayoutRect r = sc.ToRelativeLayoutRect(rect);
- aBuilder.PushRect(r, r, wr::ToColorF(mColor));
+ aBuilder.PushRect(r, r, true, wr::ToColorF(mColor));
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderContainerLayer.cpp
+++ b/gfx/layers/wr/WebRenderContainerLayer.cpp
@@ -135,13 +135,13 @@ WebRenderRefLayer::RenderLayer(wr::Displ
// The conversion from ParentLayerPixel to LayerPixel below is a result of
// changing the reference layer from "this layer" to the "the layer that
// created aSc".
LayerRect rect = ViewAs<LayerPixel>(bounds,
PixelCastJustification::MovingDownToChildren);
DumpLayerInfo("RefLayer", rect);
wr::LayoutRect r = aSc.ToRelativeLayoutRect(rect);
- aBuilder.PushIFrame(r, wr::AsPipelineId(mId));
+ aBuilder.PushIFrame(r, true, wr::AsPipelineId(mId));
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -164,17 +164,17 @@ WebRenderImageLayer::RenderLayer(wr::Dis
// where it will be done when we build the display list for the iframe.
// That happens in AsyncImagePipelineManager.
LayerRect rect = ViewAs<LayerPixel>(bounds,
PixelCastJustification::MovingDownToChildren);
DumpLayerInfo("Image Layer async", rect);
wr::LayoutRect r = aSc.ToRelativeLayoutRect(rect);
- aBuilder.PushIFrame(r, mPipelineId.ref());
+ aBuilder.PushIFrame(r, true, mPipelineId.ref());
gfx::Matrix4x4 scTransform = GetTransform();
// Translate is applied as part of PushIFrame()
scTransform.PostTranslate(-rect.x, -rect.y, 0);
// Adjust transform as to apply origin
LayerPoint scOrigin = Bounds().TopLeft();
scTransform.PreTranslate(-scOrigin.x, -scOrigin.y, 0);
@@ -228,17 +228,17 @@ WebRenderImageLayer::RenderLayer(wr::Dis
DumpLayerInfo("Image Layer", rect);
if (gfxPrefs::LayersDump()) {
printf_stderr("ImageLayer %p texture-filter=%s \n",
GetLayer(),
Stringify(filter).c_str());
}
wr::LayoutRect r = sc.ToRelativeLayoutRect(rect);
- aBuilder.PushImage(r, r, filter, mKey.value());
+ aBuilder.PushImage(r, r, true, filter, mKey.value());
}
Maybe<wr::WrImageMask>
WebRenderImageLayer::RenderMaskLayer(const StackingContextHelper& aSc,
const gfx::Matrix4x4& aTransform)
{
if (!mContainer) {
return Nothing();
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -251,21 +251,16 @@ WebRenderLayerManager::CreateWebRenderCo
nsDisplayList* itemSameCoordinateSystemChildren
= item->GetSameCoordinateSystemChildren();
if (item->ShouldFlattenAway(aDisplayListBuilder)) {
aDisplayList->AppendToBottom(itemSameCoordinateSystemChildren);
item->Destroy(aDisplayListBuilder);
continue;
}
- if (item->BackfaceIsHidden() && aSc.IsBackfaceVisible()) {
- item->Destroy(aDisplayListBuilder);
- continue;
- }
-
savedItems.AppendToTop(item);
bool forceNewLayerData = false;
size_t layerCountBeforeRecursing = mLayerScrollData.size();
if (apzEnabled) {
// For some types of display items we want to force a new
// WebRenderLayerScrollData object, to ensure we preserve the APZ-relevant
// data that is in the display item.
@@ -411,17 +406,18 @@ WebRenderLayerManager::CreateImageKey(ns
imageData->CreateAsyncImageWebRenderCommands(aBuilder,
aContainer,
aSc,
rect,
scBounds,
gfx::Matrix4x4(),
scaleToSize,
wr::ImageRendering::Auto,
- wr::MixBlendMode::Normal);
+ wr::MixBlendMode::Normal,
+ !aItem->BackfaceIsHidden());
return Nothing();
}
AutoLockImage autoLock(aContainer);
if (!autoLock.HasImage()) {
return Nothing();
}
mozilla::layers::Image* image = autoLock.GetImage();
@@ -445,17 +441,17 @@ WebRenderLayerManager::PushImage(nsDispl
return true;
}
if (!key) {
return false;
}
auto r = aSc.ToRelativeLayoutRect(aRect);
SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
- aBuilder.PushImage(r, r, wr::ToImageRendering(sampleFilter), key.value());
+ aBuilder.PushImage(r, r, !aItem->BackfaceIsHidden(), wr::ToImageRendering(sampleFilter), key.value());
return true;
}
static void
PaintItemByDrawTarget(nsDisplayItem* aItem,
DrawTarget* aDT,
const LayerRect& aImageRect,
@@ -671,16 +667,17 @@ WebRenderLayerManager::PushItemAsImage(n
if (!fallbackData) {
return false;
}
wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect + offset);
SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
aBuilder.PushImage(dest,
dest,
+ !aItem->BackfaceIsHidden(),
wr::ToImageRendering(sampleFilter),
fallbackData->GetKey().value());
return true;
}
void
WebRenderLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -99,17 +99,17 @@ WebRenderPaintedLayer::CreateWebRenderDi
LayerRect rect = Bounds();
DumpLayerInfo("PaintedLayer", rect);
wr::WrImageKey key = GenerateImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
WrManager()->AddImageKeyForDiscard(key);
wr::LayoutRect r = sc.ToRelativeLayoutRect(rect);
- aBuilder.PushImage(r, r, wr::ImageRendering::Auto, key);
+ aBuilder.PushImage(r, r, true, wr::ImageRendering::Auto, key);
}
void
WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc)
{
if (!SetupExternalImages()) {
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
@@ -88,13 +88,14 @@ WebRenderPaintedLayerBlob::RenderLayer(w
ScrollingLayersHelper scroller(this, aBuilder, aSc);
StackingContextHelper sc(aSc, aBuilder, this);
LayerRect rect = Bounds();
DumpLayerInfo("PaintedLayer", rect);
aBuilder.PushImage(sc.ToRelativeLayoutRect(LayerRect(mImageBounds)),
sc.ToRelativeLayoutRect(rect),
+ true,
wr::ImageRendering::Auto, mImageKey.value());
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderTextLayer.cpp
+++ b/gfx/layers/wr/WebRenderTextLayer.cpp
@@ -38,14 +38,14 @@ WebRenderTextLayer::RenderLayer(wr::Disp
// we apply it here. The glyphs that we push to WR should already be
// taking the transform into account.
GetTransform().TransformBounds(IntRectToRect(mBounds))
);
DumpLayerInfo("TextLayer", rect);
for (GlyphArray& glyphs : mGlyphs) {
WrBridge()->PushGlyphs(aBuilder, glyphs.glyphs(), mFont,
- glyphs.color().value(), aSc, rect, rect);
+ glyphs.color().value(), aSc, rect, rect, true);
}
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderUserData.cpp
+++ b/gfx/layers/wr/WebRenderUserData.cpp
@@ -114,17 +114,18 @@ void
WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
ImageContainer* aContainer,
const StackingContextHelper& aSc,
const LayerRect& aBounds,
const LayerRect& aSCBounds,
const gfx::Matrix4x4& aSCTransform,
const gfx::MaybeIntSize& aScaleToSize,
const wr::ImageRendering& aFilter,
- const wr::MixBlendMode& aMixBlendMode)
+ const wr::MixBlendMode& aMixBlendMode,
+ bool aIsBackfaceVisible)
{
MOZ_ASSERT(aContainer->IsAsync());
if (!mPipelineId) {
// Alloc async image pipeline id.
mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
WrBridge()->AddPipelineIdForAsyncCompositable(mPipelineId.ref(),
aContainer->GetAsyncContainerHandle());
}
@@ -135,17 +136,17 @@ WebRenderImageData::CreateAsyncImageWebR
//
// 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 AsyncImagePipelineManager.
wr::LayoutRect r = aSc.ToRelativeLayoutRect(aBounds);
- aBuilder.PushIFrame(r, mPipelineId.ref());
+ aBuilder.PushIFrame(r, aIsBackfaceVisible, mPipelineId.ref());
WrBridge()->AddWebRenderParentCommand(OpUpdateAsyncImagePipeline(mPipelineId.value(),
aSCBounds,
aSCTransform,
aScaleToSize,
aFilter,
aMixBlendMode));
}
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -72,17 +72,18 @@ public:
void CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
ImageContainer* aContainer,
const StackingContextHelper& aSc,
const LayerRect& aBounds,
const LayerRect& aSCBounds,
const gfx::Matrix4x4& aSCTransform,
const gfx::MaybeIntSize& aScaleToSize,
const wr::ImageRendering& aFilter,
- const wr::MixBlendMode& aMixBlendMode);
+ const wr::MixBlendMode& aMixBlendMode,
+ bool aIsBackfaceVisible);
void CreateImageClientIfNeeded();
protected:
void CreateExternalImageIfNeeded();
wr::MaybeExternalImageId mExternalImageId;
Maybe<wr::ImageKey> mKey;
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -248,16 +248,17 @@ nsDisplayButtonBoxShadowOuter::CreateWeb
mozilla::gfx::Point shadowOffset;
shadowOffset.x = (shadow->mXOffset / appUnitsPerDevPixel);
shadowOffset.y = (shadow->mYOffset / appUnitsPerDevPixel);
float spreadRadius = float(shadow->mSpread) / float(appUnitsPerDevPixel);
aBuilder.PushBoxShadow(deviceBoxRect,
deviceClipRect,
+ !BackfaceIsHidden(),
deviceBoxRect,
wr::ToLayoutVector2D(shadowOffset),
wr::ToColorF(shadowColor),
blurRadius,
spreadRadius,
borderRadius,
wr::BoxShadowClipMode::Outset);
}
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -485,16 +485,17 @@ BulletRenderer::CreateWebRenderCommandsF
}
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());
}
void
BulletRenderer::CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
wr::DisplayListBuilder& aBuilder,
wr::IpcResourceUpdateQueue& aResources,
@@ -527,17 +528,17 @@ BulletRenderer::CreateWebRenderCommandsF
LayerRect destRect = ViewAs<LayerPixel>(
LayoutDeviceRect::FromAppUnits(
aItem->GetBounds(aDisplayListBuilder, &dummy), appUnitsPerDevPixel),
PixelCastJustification::WebRenderHasUnitResolution);
for (layers::GlyphArray& glyphs : mGlyphs) {
aManager->WrBridge()->PushGlyphs(aBuilder, glyphs.glyphs(), mFont,
glyphs.color().value(),
- aSc, destRect, destRect);
+ aSc, destRect, destRect, !aItem->BackfaceIsHidden());
}
}
class nsDisplayBullet final : public nsDisplayItem {
public:
nsDisplayBullet(nsDisplayListBuilder* aBuilder, nsBulletFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
{
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -326,16 +326,17 @@ nsDisplayCanvasBackgroundColor::CreateWe
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits(
bgClipRect, appUnitsPerDevPixel);
wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(rect);
aBuilder.PushRect(transformedRect,
transformedRect,
+ !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)));
return true;
}
#ifdef MOZ_DUMP_PAINTING
void
nsDisplayCanvasBackgroundColor::WriteDebugInfo(std::stringstream& aStream)
{
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -171,17 +171,17 @@ public:
// 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.
wr::LayoutRect r = aSc.ToRelativeLayoutRect(bounds);
- aBuilder.PushIFrame(r, data->GetPipelineId().ref());
+ aBuilder.PushIFrame(r, !BackfaceIsHidden(), data->GetPipelineId().ref());
gfx::Matrix4x4 scTransform;
if (data->NeedsYFlip()) {
scTransform = scTransform.PreTranslate(0, data->GetSize().height, 0).PreScale(1, -1, 1);
}
gfxRect destGFXRect = mFrame->PresContext()->AppUnitsToGfxUnits(dest);
scTransform.PreScale(destGFXRect.Width() / canvasSizeInPx.width,
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -5199,53 +5199,55 @@ nsDisplayText::CreateWebRenderCommands(m
layoutClipRect = LayoutDeviceRect::FromAppUnits(
GetClip().GetClipRect(), appUnitsPerDevPixel);
}
LayerRect boundsRect = LayerRect::FromUnknownRect(layoutBoundsRect.ToUnknownRect());
LayerRect clipRect = LayerRect::FromUnknownRect(layoutClipRect.ToUnknownRect());
wr::LayoutRect wrClipRect = aSc.ToRelativeLayoutRect(clipRect); // wr::ToLayoutRect(clipRect);
wr::LayoutRect wrBoundsRect = aSc.ToRelativeLayoutRect(boundsRect); //wr::ToLayoutRect(boundsRect);
+ bool backfaceVisible = !BackfaceIsHidden();
// Drawing order: selections, shadows,
// underline, overline, [grouped in one array]
// text, emphasisText, [grouped in one array]
// lineThrough
for (auto& part : mTextDrawer->GetParts()) {
if (part.selection) {
auto selection = part.selection.value();
- aBuilder.PushRect(selection.rect, wrClipRect, selection.color);
+ aBuilder.PushRect(selection.rect, wrClipRect, backfaceVisible, selection.color);
}
}
for (auto& part : mTextDrawer->GetParts()) {
// WR takes the shadows in CSS-order (reverse of rendering order),
// because the drawing of a shadow actually occurs when it's popped.
for (const wr::TextShadow& shadow : part.shadows) {
- aBuilder.PushTextShadow(wrBoundsRect, wrClipRect, shadow);
+ aBuilder.PushTextShadow(wrBoundsRect, wrClipRect, backfaceVisible, shadow);
}
for (const wr::Line& decoration : part.beforeDecorations) {
- aBuilder.PushLine(wrClipRect, decoration);
+ aBuilder.PushLine(wrClipRect, backfaceVisible, decoration);
}
for (const mozilla::layout::TextRunFragment& text : part.text) {
// mOpacity is set after we do our analysis, so we need to apply it here.
// mOpacity is only non-trivial when we have "pure" text, so we don't
// ever need to apply it to shadows or decorations.
auto color = text.color;
color.a *= mOpacity;
aManager->WrBridge()->PushGlyphs(aBuilder, text.glyphs, text.font,
- color, aSc, boundsRect, clipRect);
+ color, aSc, boundsRect, clipRect,
+ backfaceVisible);
}
for (const wr::Line& decoration : part.afterDecorations) {
- aBuilder.PushLine(wrClipRect, decoration);
+ aBuilder.PushLine(wrClipRect, backfaceVisible, decoration);
}
for (size_t i = 0; i < part.shadows.Length(); ++i) {
aBuilder.PopTextShadow();
}
}
return true;
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -393,16 +393,17 @@ nsDisplayRemote::CreateWebRenderCommands
mOffset = mozilla::layout::GetContentRectLayerOffset(mFrame, aDisplayListBuilder);
mozilla::LayoutDeviceRect visible = mozilla::LayoutDeviceRect::FromAppUnits(
GetVisibleRect(), mFrame->PresContext()->AppUnitsPerDevPixel());
visible += mOffset;
aBuilder.PushIFrame(aSc.ToRelativeLayoutRect(visible),
+ !BackfaceIsHidden(),
mozilla::wr::AsPipelineId(GetRemoteLayersId()));
return true;
}
bool
nsDisplayRemote::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData)
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -783,17 +783,18 @@ ConstructBorderRenderer(nsPresContext* a
aDrawTarget,
dirtyRect,
joinedBorderAreaPx,
borderStyles,
borderWidths,
bgRadii,
borderColors,
compositeColors,
- bgColor);
+ bgColor,
+ !aForFrame->BackfaceIsHidden());
}
DrawResult
nsCSSRendering::PaintBorderWithStyleBorder(nsPresContext* aPresContext,
gfxContext& aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
@@ -1062,17 +1063,18 @@ nsCSSRendering::CreateBorderRendererForO
dt,
dirtyRect,
oRect,
outlineStyles,
outlineWidths,
outlineRadii,
outlineColors,
nullptr,
- bgColor);
+ bgColor,
+ !aForFrame->BackfaceIsHidden());
return Some(br);
}
void
nsCSSRendering::PaintOutline(nsPresContext* aPresContext,
gfxContext& aRenderingContext,
nsIFrame* aForFrame,
@@ -1124,27 +1126,31 @@ nsCSSRendering::PaintFocus(nsPresContext
nscolor focusColors[4] = { aColor, aColor, aColor, aColor };
// Because this renders a dotted border, the background color
// should not be used. Therefore, we provide a value that will
// be blatantly wrong if it ever does get used. (If this becomes
// something that CSS can style, this function will then have access
// to a style context and can use the same logic that PaintBorder
// and PaintOutline do.)
+ //
+ // WebRender layers-free mode don't use PaintFocus function. Just assign
+ // the backface-visibility to true for this case.
nsCSSBorderRenderer br(aPresContext,
nullptr,
aDrawTarget,
focusRect,
focusRect,
focusStyles,
focusWidths,
focusRadii,
focusColors,
nullptr,
- NS_RGB(255, 0, 0));
+ NS_RGB(255, 0, 0),
+ true);
br.DrawBorders();
PrintAsStringNewline();
}
// Thebes Border Rendering Code End
//----------------------------------------------------------------------
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -174,24 +174,26 @@ nsCSSBorderRenderer::nsCSSBorderRenderer
DrawTarget* aDrawTarget,
const Rect& aDirtyRect,
Rect& aOuterRect,
const uint8_t* aBorderStyles,
const Float* aBorderWidths,
RectCornerRadii& aBorderRadii,
const nscolor* aBorderColors,
nsBorderColors* const* aCompositeColors,
- nscolor aBackgroundColor)
+ nscolor aBackgroundColor,
+ bool aBackfaceIsVisible)
: mPresContext(aPresContext),
mDocument(aDocument),
mDrawTarget(aDrawTarget),
mDirtyRect(aDirtyRect),
mOuterRect(aOuterRect),
mBorderRadii(aBorderRadii),
- mBackgroundColor(aBackgroundColor)
+ mBackgroundColor(aBackgroundColor),
+ mBackfaceIsVisible(aBackfaceIsVisible)
{
PodCopy(mBorderStyles, aBorderStyles, 4);
PodCopy(mBorderWidths, aBorderWidths, 4);
PodCopy(mBorderColors, aBorderColors, 4);
if (aCompositeColors) {
PodCopy(mCompositeColors, aCompositeColors, 4);
} else {
static nsBorderColors * const noColors[4] = { nullptr };
@@ -3623,16 +3625,17 @@ nsCSSBorderRenderer::CreateWebRenderComm
wr::BorderRadius borderRadius = wr::ToBorderRadius(LayerSize(mBorderRadii[0].width, mBorderRadii[0].height),
LayerSize(mBorderRadii[1].width, mBorderRadii[1].height),
LayerSize(mBorderRadii[3].width, mBorderRadii[3].height),
LayerSize(mBorderRadii[2].width, mBorderRadii[2].height));
Range<const wr::BorderSide> wrsides(side, 4);
aBuilder.PushBorder(transformedRect,
transformedRect,
+ mBackfaceIsVisible,
wr::ToBorderWidths(mBorderWidths[0], mBorderWidths[1], mBorderWidths[2], mBorderWidths[3]),
wrsides,
borderRadius);
}
/* static */Maybe<nsCSSBorderImageRenderer>
nsCSSBorderImageRenderer::CreateBorderImageRenderer(nsPresContext* aPresContext,
nsIFrame* aForFrame,
--- a/layout/painting/nsCSSRenderingBorders.h
+++ b/layout/painting/nsCSSRenderingBorders.h
@@ -96,17 +96,18 @@ public:
DrawTarget* aDrawTarget,
const Rect& aDirtyRect,
Rect& aOuterRect,
const uint8_t* aBorderStyles,
const Float* aBorderWidths,
RectCornerRadii& aBorderRadii,
const nscolor* aBorderColors,
nsBorderColors* const* aCompositeColors,
- nscolor aBackgroundColor);
+ nscolor aBackgroundColor,
+ bool aBackfaceIsVisible);
// draw the entire border
void DrawBorders();
bool CanCreateWebRenderCommands();
void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const mozilla::layers::StackingContextHelper& aSc);
@@ -157,16 +158,17 @@ private:
nscolor mBackgroundColor;
// calculated values
bool mAllBordersSameStyle;
bool mAllBordersSameWidth;
bool mOneUnitBorder;
bool mNoBorderRadius;
bool mAvoidStroke;
+ bool mBackfaceIsVisible;
// For all the sides in the bitmask, would they be rendered
// in an identical color and style?
bool AreBorderSideFinalStylesSame(uint8_t aSides);
// For the given style, is the given corner a solid color?
bool IsSolidCornerStyle(uint8_t aStyle, mozilla::Corner aCorner);
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -1026,16 +1026,17 @@ nsCSSGradientRenderer::BuildWebRenderPar
void
nsCSSGradientRenderer::BuildWebRenderDisplayItems(wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
layers::WebRenderDisplayItemLayer* aLayer,
const nsRect& aDest,
const nsRect& aFillArea,
const nsSize& aRepeatSize,
const CSSIntRect& aSrc,
+ bool aIsBackfaceVisible,
float aOpacity)
{
if (aDest.IsEmpty() || aFillArea.IsEmpty()) {
return;
}
wr::ExtendMode extendMode;
nsTArray<wr::GradientStop> stops;
@@ -1080,29 +1081,31 @@ nsCSSGradientRenderer::BuildWebRenderDis
if (mGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
lineEnd.x = (lineEnd.x - srcTransform.x) * srcTransform.width;
lineEnd.y = (lineEnd.y - srcTransform.y) * srcTransform.height;
aBuilder.PushLinearGradient(
wrGradientBounds,
wrClipBounds,
+ aIsBackfaceVisible,
mozilla::wr::ToLayoutPoint(lineStart),
mozilla::wr::ToLayoutPoint(lineEnd),
stops,
extendMode,
mozilla::wr::ToLayoutSize(layerFirstTileSize),
mozilla::wr::ToLayoutSize(tileSpacing));
} else {
gradientRadius.width *= srcTransform.width;
gradientRadius.height *= srcTransform.height;
aBuilder.PushRadialGradient(
wrGradientBounds,
wrClipBounds,
+ aIsBackfaceVisible,
mozilla::wr::ToLayoutPoint(lineStart),
mozilla::wr::ToLayoutSize(gradientRadius),
stops,
extendMode,
mozilla::wr::ToLayoutSize(layerFirstTileSize),
mozilla::wr::ToLayoutSize(tileSpacing));
}
}
--- a/layout/painting/nsCSSRenderingGradients.h
+++ b/layout/painting/nsCSSRenderingGradients.h
@@ -82,16 +82,17 @@ public:
*/
void BuildWebRenderDisplayItems(wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc,
layers::WebRenderDisplayItemLayer* aLayer,
const nsRect& aDest,
const nsRect& aFill,
const nsSize& aRepeatSize,
const mozilla::CSSIntRect& aSrc,
+ bool aIsBackfaceVisible,
float aOpacity = 1.0);
private:
nsCSSGradientRenderer() {}
nsPresContext* mPresContext;
nsStyleGradient* mGradient;
nsTArray<ColorStop> mStops;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2942,16 +2942,17 @@ nsDisplaySolidColor::CreateWebRenderComm
}
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
mVisibleRect, mFrame->PresContext()->AppUnitsPerDevPixel());
wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(bounds);
aBuilder.PushRect(transformedRect,
transformedRect,
+ !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)));
return true;
}
nsRect
nsDisplaySolidColorRegion::GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) const
@@ -2994,16 +2995,17 @@ nsDisplaySolidColorRegion::CreateWebRend
{
for (auto iter = mRegion.RectIter(); !iter.Done(); iter.Next()) {
nsRect rect = iter.Get();
LayoutDeviceRect layerRects = LayoutDeviceRect::FromAppUnits(
rect, mFrame->PresContext()->AppUnitsPerDevPixel());
wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(layerRects);
aBuilder.PushRect(transformedRect,
transformedRect,
+ !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)));
}
return true;
}
static void
RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
@@ -4265,16 +4267,17 @@ nsDisplayBackgroundColor::CreateWebRende
}
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
mBackgroundRect, mFrame->PresContext()->AppUnitsPerDevPixel());
wr::LayoutRect transformedRect = aSc.ToRelativeLayoutRect(bounds);
aBuilder.PushRect(transformedRect,
transformedRect,
+ !BackfaceIsHidden(),
wr::ToColorF(ToDeviceColor(mColor)));
return true;
}
void
nsDisplayBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx)
@@ -4786,21 +4789,23 @@ nsDisplayCaret::CreateWebRenderCommands(
hookRect + ToReferenceFrame(), appUnitsPerDevPixel);
wr::LayoutRect caret = aSc.ToRelativeLayoutRect(devCaretRect);
wr::LayoutRect hook = aSc.ToRelativeLayoutRect(devHookRect);
// Note, WR will pixel snap anything that is layout aligned.
aBuilder.PushRect(caret,
caret,
+ !BackfaceIsHidden(),
wr::ToColorF(color));
if (!devHookRect.IsEmpty()) {
aBuilder.PushRect(hook,
hook,
+ !BackfaceIsHidden(),
wr::ToColorF(color));
}
return true;
}
LayerState
nsDisplayCaret::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -5090,16 +5095,17 @@ nsDisplayBorder::CreateBorderImageWebRen
gfx::IntSize size;
Maybe<wr::ImageKey> key = aManager->CreateImageKey(this, container, aBuilder, aSc, size);
if (key.isNothing()) {
return;
}
aBuilder.PushBorderImage(dest,
clip,
+ !BackfaceIsHidden(),
wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
key.value(),
wr::ToNinePatchDescriptor(
(float)(mBorderImageRenderer->mImageSize.width) / appUnitsPerDevPixel,
(float)(mBorderImageRenderer->mImageSize.height) / appUnitsPerDevPixel,
wr::ToSideOffsets2D_u32(slice[0], slice[1], slice[2], slice[3])),
wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]),
wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeHorizontal),
@@ -5123,25 +5129,27 @@ nsDisplayBorder::CreateBorderImageWebRen
if (gradientData->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
LayerPoint startPoint = LayerPoint(dest.origin.x, dest.origin.y);
startPoint = startPoint + ViewAs<LayerPixel>(lineStart, PixelCastJustification::WebRenderHasUnitResolution);
LayerPoint endPoint = LayerPoint(dest.origin.x, dest.origin.y);
endPoint = endPoint + ViewAs<LayerPixel>(lineEnd, PixelCastJustification::WebRenderHasUnitResolution);
aBuilder.PushBorderGradient(dest,
clip,
+ !BackfaceIsHidden(),
wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
wr::ToLayoutPoint(startPoint),
wr::ToLayoutPoint(endPoint),
stops,
extendMode,
wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]));
} else {
aBuilder.PushBorderRadialGradient(dest,
clip,
+ !BackfaceIsHidden(),
wr::ToBorderWidths(widths[0], widths[1], widths[2], widths[3]),
wr::ToLayoutPoint(lineStart),
wr::ToLayoutSize(gradientRadius),
stops,
extendMode,
wr::ToSideOffsets2D_f32(outset[0], outset[1], outset[2], outset[3]));
}
break;
@@ -5455,16 +5463,17 @@ nsDisplayBoxShadowOuter::CreateWebRender
// TODO: support non-uniform border radius.
float borderRadius = hasBorderRadius ? borderRadii.TopLeft().width
: 0.0;
float spreadRadius = float(shadow->mSpread) / float(appUnitsPerDevPixel);
aBuilder.PushBoxShadow(deviceBoxRect,
deviceClipRect,
+ !BackfaceIsHidden(),
deviceBoxRect,
wr::ToLayoutVector2D(shadowOffset),
wr::ToColorF(shadowColor),
blurRadius,
spreadRadius,
borderRadius,
wr::BoxShadowClipMode::Outset);
}
@@ -5627,16 +5636,17 @@ nsDisplayBoxShadowInner::CreateInsetBoxS
float blurRadius = float(shadowItem->mRadius) / float(appUnitsPerDevPixel);
// TODO: WR doesn't support non-uniform border radii
float borderRadius = innerRadii.TopLeft().width;
// NOTE: Any spread radius > 0 will render nothing. WR Bug.
float spreadRadius = float(shadowItem->mSpread) / float(appUnitsPerDevPixel);
aBuilder.PushBoxShadow(wr::ToLayoutRect(deviceBoxRect),
deviceClipRect,
+ !aFrame->BackfaceIsHidden(),
wr::ToLayoutRect(deviceBoxRect),
wr::ToLayoutVector2D(shadowOffset),
wr::ToColorF(shadowColor),
blurRadius,
spreadRadius,
borderRadius,
wr::BoxShadowClipMode::Inset
);
@@ -7948,17 +7958,19 @@ nsDisplayTransform::CreateWebRenderComma
aDisplayListBuilder,
this,
mStoredList.GetChildren(),
&boundTransform,
animationsId,
nullptr,
transformForSC,
nullptr,
- filters);
+ filters,
+ gfx::CompositionOp::OP_OVER,
+ !BackfaceIsHidden());
return mStoredList.CreateWebRenderCommands(aBuilder, aResources, sc, aParentCommands,
aManager, aDisplayListBuilder);
}
bool
nsDisplayTransform::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData)
@@ -8554,17 +8566,19 @@ nsDisplayPerspective::CreateWebRenderCom
aDisplayListBuilder,
this,
mList.GetChildren(),
nullptr,
0,
nullptr,
&transformForSC,
&perspectiveMatrix,
- filters);
+ filters,
+ gfx::CompositionOp::OP_OVER,
+ !BackfaceIsHidden());
return mList.CreateWebRenderCommands(aBuilder, aResources, sc, aParentCommands,
aManager, aDisplayListBuilder);
}
int32_t
nsDisplayPerspective::ZIndex() const
{
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -610,17 +610,18 @@ nsImageRenderer::BuildWebRenderDisplayIt
}
switch (mType) {
case eStyleImageType_Gradient:
{
nsCSSGradientRenderer renderer =
nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
- renderer.BuildWebRenderDisplayItems(aBuilder, aSc, aLayer, aDest, aFill, aRepeatSize, aSrc, aOpacity);
+ renderer.BuildWebRenderDisplayItems(aBuilder, aSc, aLayer, aDest, aFill,
+ aRepeatSize, aSrc, !aItem->BackfaceIsHidden(), aOpacity);
break;
}
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) {
@@ -654,17 +655,17 @@ nsImageRenderer::BuildWebRenderDisplayIt
wr::LayoutRect fill = aSc.ToRelativeLayoutRect(fillRect);
wr::LayoutRect clip = aSc.ToRelativeLayoutRect(
LayoutDeviceRect::FromAppUnits(aFill, appUnitsPerDevPixel));
LayoutDeviceSize gapSize = LayoutDeviceSize::FromAppUnits(
aRepeatSize - aDest.Size(), appUnitsPerDevPixel);
SamplingFilter samplingFilter = nsLayoutUtils::GetSamplingFilterForFrame(mForFrame);
- aBuilder.PushImage(fill, clip,
+ aBuilder.PushImage(fill, clip, !aItem->BackfaceIsHidden(),
wr::ToLayoutSize(destRect.Size()), wr::ToLayoutSize(gapSize),
wr::ToImageRendering(samplingFilter), key.value());
break;
}
default:
break;
}
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -6497,16 +6497,17 @@ struct BCBorderParameters
nscolor mBorderColor;
nscolor mBGColor;
nsRect mBorderRect;
int32_t mAppUnitsPerDevPixel;
mozilla::Side mStartBevelSide;
nscoord mStartBevelOffset;
mozilla::Side mEndBevelSide;
nscoord mEndBevelOffset;
+ bool mBackfaceIsVisible;
};
struct BCBlockDirSeg
{
BCBlockDirSeg();
void Start(BCPaintBorderIterator& aIter,
BCBorderOwner aBorderOwner,
@@ -7330,16 +7331,17 @@ BCBlockDirSeg::BuildBorderParameters(BCP
aIter.IsDamageAreaIEndMost() ? eLogicalSideIEnd : eLogicalSideIStart;
int32_t relColIndex = aIter.GetRelativeColIndex();
nsTableColFrame* col = mCol; if (!col) ABORT1(Nothing());
nsTableCellFrame* cell = mFirstCell; // ???
nsIFrame* owner = nullptr;
result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID;
result.mBorderColor = 0xFFFFFFFF;
result.mBGColor = aIter.mTableBgColor;
+ result.mBackfaceIsVisible = true;
// All the tables frames have the same presContext, so we just use any one
// that exists here:
nsPresContext* presContext = aIter.mTable->PresContext();
result.mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
switch (mOwner) {
case eTableOwner:
@@ -7386,16 +7388,17 @@ BCBlockDirSeg::BuildBorderParameters(BCP
cell = mAjaCell;
MOZ_FALLTHROUGH;
case eCellOwner:
owner = cell;
break;
}
if (owner) {
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle, &result.mBorderColor);
+ result.mBackfaceIsVisible = !owner->BackfaceIsHidden();
}
BCPixelSize smallHalf, largeHalf;
DivideBCBorderSize(mWidth, smallHalf, largeHalf);
LogicalRect segRect(aIter.mTableWM,
mOffsetI - presContext->DevPixelsToAppUnits(largeHalf),
mOffsetB,
presContext->DevPixelsToAppUnits(mWidth), mLength);
nscoord bEndBevelOffset = (mIsBEndBevel) ?
@@ -7487,16 +7490,17 @@ BCBlockDirSeg::CreateWebRenderCommands(B
// each side to width of rect is fine.
wr::BorderWidths borderWidths = wr::ToBorderWidths(transformedRect.size.width,
transformedRect.size.width,
transformedRect.size.width,
transformedRect.size.width);
Range<const wr::BorderSide> wrsides(wrSide, 4);
aBuilder.PushBorder(transformedRect,
transformedRect,
+ param->mBackfaceIsVisible,
borderWidths,
wrsides,
borderRadii);
}
/**
* Advance the start point of a segment
*/
@@ -7599,16 +7603,17 @@ BCInlineDirSeg::BuildBorderParameters(BC
// get the border style, color and paint the segment
LogicalSide side =
aIter.IsDamageAreaBEndMost() ? eLogicalSideBEnd : eLogicalSideBStart;
nsIFrame* rg = aIter.mRg; if (!rg) ABORT1(Nothing());
nsIFrame* row = aIter.mRow; if (!row) ABORT1(Nothing());
nsIFrame* cell = mFirstCell;
nsIFrame* col;
nsIFrame* owner = nullptr;
+ result.mBackfaceIsVisible = true;
// All the tables frames have the same presContext, so we just use any one
// that exists here:
nsPresContext* presContext = aIter.mTable->PresContext();
result.mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
result.mBorderStyle = NS_STYLE_BORDER_STYLE_SOLID;
result.mBorderColor = 0xFFFFFFFF;
@@ -7657,16 +7662,17 @@ BCInlineDirSeg::BuildBorderParameters(BC
cell = mAjaCell;
MOZ_FALLTHROUGH;
case eCellOwner:
owner = cell;
break;
}
if (owner) {
::GetPaintStyleInfo(owner, aIter.mTableWM, side, &result.mBorderStyle, &result.mBorderColor);
+ result.mBackfaceIsVisible = !owner->BackfaceIsHidden();
}
BCPixelSize smallHalf, largeHalf;
DivideBCBorderSize(mWidth, smallHalf, largeHalf);
LogicalRect segRect(aIter.mTableWM, mOffsetI,
mOffsetB - presContext->DevPixelsToAppUnits(largeHalf),
mLength,
presContext->DevPixelsToAppUnits(mWidth));
@@ -7746,16 +7752,17 @@ BCInlineDirSeg::CreateWebRenderCommands(
// each side to height of rect is fine.
wr::BorderWidths borderWidths = wr::ToBorderWidths(transformedRect.size.height,
transformedRect.size.height,
transformedRect.size.height,
transformedRect.size.height);
Range<const wr::BorderSide> wrsides(wrSide, 4);
aBuilder.PushBorder(transformedRect,
transformedRect,
+ param->mBackfaceIsVisible,
borderWidths,
wrsides,
borderRadii);
}
/**
* Advance the start point of a segment
*/
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -453,17 +453,17 @@ nsImageBoxFrame::CreateWebRenderCommands
}
const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits(dest,
appUnitsPerDevPixel);
wr::LayoutRect fill = aSc.ToRelativeLayoutRect(fillRect);
LayoutDeviceSize gapSize(0, 0);
SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
- aBuilder.PushImage(fill, fill,
+ aBuilder.PushImage(fill, fill, !BackfaceIsHidden(),
wr::ToLayoutSize(fillRect.Size()), wr::ToLayoutSize(gapSize),
wr::ToImageRendering(sampleFilter), key.value());
return DrawResult::SUCCESS;
}
nsRect
nsImageBoxFrame::GetDestRect(const nsPoint& aOffset, Maybe<nsPoint>& aAnchorPoint)
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2117,17 +2117,17 @@ nsChildView::AddWindowOverlayWebRenderCo
if (needUpdate) {
wr::ImageDescriptor descriptor(size, stride, format);
aResources.UpdateImageBuffer(*mTitlebarImageKey, descriptor, buffer);
}
wr::LayoutRect rect = wr::ToLayoutRect(mTitlebarRect);
aBuilder.PushImage(wr::LayoutRect{ rect.origin, { float(size.width), float(size.height) } },
- rect, wr::ImageRendering::Auto, *mTitlebarImageKey);
+ rect, true, wr::ImageRendering::Auto, *mTitlebarImageKey);
}
}
void
nsChildView::CleanupWebRenderWindowOverlay(layers::WebRenderBridgeChild* aWrBridge,
wr::IpcResourceUpdateQueue& aResources)
{
if (mTitlebarImageKey) {