Bug 1343979 - Add webrender support for ButtonBorderBackground. r=ethlin

This commit is contained in:
Mason Chang 2017-03-08 08:31:46 -08:00
parent b17625cf2c
commit 2289ed06ba
10 changed files with 194 additions and 38 deletions

View File

@ -207,6 +207,7 @@ EXPORTS.mozilla.layers += [
'SourceSurfaceVolatileData.h',
'TextureWrapperImage.h',
'TransactionIdAllocator.h',
'wr/WebRenderBorderLayer.h',
'wr/WebRenderBridgeChild.h',
'wr/WebRenderBridgeParent.h',
'wr/WebRenderCompositableHolder.h',

View File

@ -17,6 +17,36 @@ namespace layers {
using namespace mozilla::gfx;
/* static */void
WebRenderBorderLayer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
BorderColors& aColors,
BorderCorners& aCorners,
BorderWidths& aWidths,
BorderStyles& aBorderStyles,
Rect aRect,
Rect aClipRect,
Rect aRelBounds,
Rect aOverflow)
{
aBuilder.PushStackingContext(wr::ToWrRect(aRelBounds),
wr::ToWrRect(aOverflow),
nullptr,
1.0f,
aLayer->GetLayer()->GetTransform(),
WrMixBlendMode::Normal);
aBuilder.PushBorder(wr::ToWrRect(aRect), wr::ToWrRect(aClipRect),
wr::ToWrBorderSide(aWidths[0], aColors[0], aBorderStyles[0]),
wr::ToWrBorderSide(aWidths[1], aColors[1], aBorderStyles[1]),
wr::ToWrBorderSide(aWidths[2], aColors[2], aBorderStyles[2]),
wr::ToWrBorderSide(aWidths[3], aColors[3], aBorderStyles[3]),
wr::ToWrBorderRadius(aCorners[0], aCorners[1],
aCorners[3], aCorners[2]));
aBuilder.PopStackingContext();
}
void
WebRenderBorderLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
{

View File

@ -21,6 +21,18 @@ public:
MOZ_COUNT_CTOR(WebRenderBorderLayer);
}
static void
CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
BorderColors& aColors,
BorderCorners& aCorners,
BorderWidths& aWidths,
BorderStyles& aBorderStyles,
gfx::Rect aRect,
gfx::Rect aClipRect,
gfx::Rect aRelBounds,
gfx::Rect aOverflow);
protected:
virtual ~WebRenderBorderLayer()
{

View File

@ -465,7 +465,8 @@ private:
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.boxshadow-inset-layers", LayersAllowInsetBoxShadow, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.outline-layers", LayersAllowOutlineLayers, bool, false);
DECL_GFX_PREF(Skip, "layers.allow-d3d9-fallback", LayersAllowD3D9Fallback, bool, false);
DECL_GFX_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, bool, false);
DECL_GFX_PREF(Once, "layers.allow-d3d9-fallback", LayersAllowD3D9Fallback, bool, false);
DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);

View File

@ -43,6 +43,8 @@ UNIFIED_SOURCES += [
FINAL_LIBRARY = 'xul'
include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [
'../../editor/txmgr',
'../base',

View File

@ -15,6 +15,11 @@
#include "nsFrame.h"
#include "mozilla/EventStates.h"
#include "mozilla/dom/Element.h"
#include "Layers.h"
#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "mozilla/layers/WebRenderDisplayItemLayer.h"
#include "mozilla/layers/WebRenderBorderLayer.h"
#define ACTIVE "active"
#define HOVER "hover"
@ -22,6 +27,7 @@
using namespace mozilla;
using namespace mozilla::image;
using namespace mozilla::layers;
nsButtonFrameRenderer::nsButtonFrameRenderer()
{
@ -73,7 +79,7 @@ class nsDisplayButtonBoxShadowOuter : public nsDisplayItem {
public:
nsDisplayButtonBoxShadowOuter(nsDisplayListBuilder* aBuilder,
nsButtonFrameRenderer* aRenderer)
: nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) {
: nsDisplayItem(aBuilder, aRenderer->GetFrame()) {
MOZ_COUNT_CTOR(nsDisplayButtonBoxShadowOuter);
}
#ifdef NS_BUILD_REFCNT_LOGGING
@ -87,8 +93,6 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER)
private:
nsButtonFrameRenderer* mBFR;
};
nsRect
@ -102,11 +106,8 @@ nsDisplayButtonBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) {
nsRect frameRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
nsRect buttonRect;
mBFR->GetButtonRect(frameRect, buttonRect);
nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame,
buttonRect, mVisibleRect);
frameRect, mVisibleRect);
}
class nsDisplayButtonBorder : public nsDisplayItem {
@ -134,6 +135,15 @@ public:
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer) override;
NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
private:
nsButtonFrameRenderer* mBFR;
@ -145,6 +155,101 @@ nsDisplayButtonBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
LayerState
nsDisplayButtonBorder::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters)
{
if (gfxPrefs::LayersAllowDisplayButtonBorder()) {
return LAYER_ACTIVE;
}
return LAYER_NONE;
}
already_AddRefed<Layer>
nsDisplayButtonBorder::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
void
nsDisplayButtonBorder::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
nsTArray<WebRenderParentCommand>& aCommands,
WebRenderDisplayItemLayer* aLayer)
{
// This is really a combination of paint box shadow inner +
// paint border.
nsRect buttonRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
nsRect dirtyRect = mVisibleRect;
// TODO: Figure out what to do with sync decode images
/*
PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
? PaintBorderFlags::SYNC_DECODE_IMAGES
: PaintBorderFlags();
*/
nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(aBuilder,
aLayer,
mFrame,
buttonRect);
nsPoint offset = ToReferenceFrame();
Maybe<nsCSSBorderRenderer> br =
nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
nullptr,
mFrame,
nsRect(),
nsRect(offset, mFrame->GetSize()),
mFrame->StyleContext(),
mFrame->GetSkipSides());
if (!br) {
NS_WARNING("Could not create border renderer during nsDisplayButtonBorder");
return;
}
BorderColors colors;
BorderCorners corners;
BorderWidths widths;
BorderStyles borderStyles;
NS_FOR_CSS_SIDES(i) {
colors[i] = gfx::ToDeviceColor(br->mBorderColors[i]);
widths[i] = br->mBorderWidths[i];
borderStyles[i] = br->mBorderStyles[i];
}
NS_FOR_CSS_FULL_CORNERS(corner) {
corners[corner] = LayerSize(br->mBorderRadii[corner].width,
br->mBorderRadii[corner].height);
}
gfx::Rect relBounds = aLayer->VisibleBoundsRelativeToParent();
gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
gfx::Rect gfxDirtyRect = aLayer->RelativeToParent(NSRectToRect(dirtyRect, appUnitsPerDevPixel));
// The bounds rect starts from 0 here because the stacking context
// is created with the proper relative bounds.
LayerIntRect bounds = aLayer->GetVisibleRegion().GetBounds();
gfx::Rect boundsRect(0, 0, bounds.width, bounds.height);
WebRenderBorderLayer::CreateWebRenderCommands(aBuilder,
aLayer,
colors,
corners,
widths,
borderStyles,
boundsRect,
gfxDirtyRect,
relBounds,
overflow);
}
void
nsDisplayButtonBorder::ComputeInvalidationRegion(
nsDisplayListBuilder* aBuilder,
@ -163,8 +268,9 @@ nsDisplayButtonBorder::ComputeInvalidationRegion(
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void nsDisplayButtonBorder::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
void
nsDisplayButtonBorder::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
NS_ASSERTION(mFrame, "No frame?");
nsPresContext* pc = mFrame->PresContext();
@ -259,8 +365,7 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
nsDisplayButtonBoxShadowOuter(aBuilder, this));
}
nsRect buttonRect;
GetButtonRect(mFrame->GetRectRelativeToSelf(), buttonRect);
nsRect buttonRect = mFrame->GetRectRelativeToSelf();
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
aBuilder, mFrame, buttonRect, aBackground);
@ -280,7 +385,7 @@ nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
void
nsButtonFrameRenderer::GetButtonInnerFocusRect(const nsRect& aRect, nsRect& aResult)
{
GetButtonRect(aRect, aResult);
aResult = aRect;
aResult.Deflate(mFrame->GetUsedBorderAndPadding());
nsMargin innerFocusPadding(0,0,0,0);
@ -329,9 +434,7 @@ nsButtonFrameRenderer::PaintBorder(
const nsRect& aRect)
{
// get the button rect this is inside the focus and outline rects
nsRect buttonRect;
GetButtonRect(aRect, buttonRect);
nsRect buttonRect = aRect;
nsStyleContext* context = mFrame->StyleContext();
PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
@ -348,14 +451,6 @@ nsButtonFrameRenderer::PaintBorder(
return result;
}
void
nsButtonFrameRenderer::GetButtonRect(const nsRect& aRect, nsRect& r)
{
r = aRect;
}
/**
* Call this when styles change
*/

View File

@ -56,7 +56,6 @@ public:
bool isActive();
bool isDisabled();
void GetButtonRect(const nsRect& aRect, nsRect& aResult);
void GetButtonInnerFocusRect(const nsRect& aRect, nsRect& aResult);
nsStyleContext* GetStyleContext(int32_t aIndex) const;

View File

@ -79,6 +79,7 @@ class nsCSSBorderRenderer final
friend class nsDisplayBorder;
friend class nsDisplayOutline;
friend class nsDisplayButtonBorder;
public:

View File

@ -4989,24 +4989,23 @@ nsDisplayBoxShadowInner::BuildLayer(nsDisplayListBuilder* aBuilder,
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
void
nsDisplayBoxShadowInner::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
nsTArray<WebRenderParentCommand>& aParentCommands,
WebRenderDisplayItemLayer* aLayer)
/* static */ void
nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
WebRenderDisplayItemLayer* aLayer,
nsIFrame* aFrame,
const nsRect aBorderRect)
{
if (!nsCSSRendering::CanPaintBoxShadowInner(mFrame)) {
if (!nsCSSRendering::CanPaintBoxShadowInner(aFrame)) {
return;
}
int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
nsPoint offset = ToReferenceFrame();
nsRect borderRect = nsRect(offset, mFrame->GetSize());
int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
AutoTArray<nsRect,10> rects;
nsRegion visible = aLayer->GetVisibleRegion().ToAppUnits(appUnitsPerDevPixel);
ComputeDisjointRectangles(visible, &rects);
nsCSSShadowArray* shadows = mFrame->StyleEffects()->mBoxShadow;
nsCSSShadowArray* shadows = aFrame->StyleEffects()->mBoxShadow;
for (uint32_t i = 0; i < rects.Length(); ++i) {
Rect clipRect = NSRectToRect(rects[i], appUnitsPerDevPixel);
@ -5018,14 +5017,14 @@ nsDisplayBoxShadowInner::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilde
}
nsRect shadowRect =
nsCSSRendering::GetBoxShadowInnerPaddingRect(mFrame, borderRect);
nsCSSRendering::GetBoxShadowInnerPaddingRect(aFrame, aBorderRect);
RectCornerRadii innerRadii;
nsCSSRendering::GetShadowInnerRadii(mFrame, borderRect, innerRadii);
nsCSSRendering::GetShadowInnerRadii(aFrame, aBorderRect, innerRadii);
// Now translate everything to device pixels.
Rect deviceBoxRect = NSRectToRect(shadowRect, appUnitsPerDevPixel);
Rect deviceClipRect = aLayer->RelativeToParent(clipRect);
Color shadowColor = nsCSSRendering::GetShadowColor(shadowItem, mFrame, 1.0);
Color shadowColor = nsCSSRendering::GetShadowColor(shadowItem, aFrame, 1.0);
Point shadowOffset;
shadowOffset.x = (shadowItem->mXOffset / appUnitsPerDevPixel);
@ -5045,11 +5044,23 @@ nsDisplayBoxShadowInner::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilde
blurRadius,
spreadRadius,
borderRadius,
WrBoxShadowClipMode::Inset);
WrBoxShadowClipMode::Inset
);
}
}
}
void
nsDisplayBoxShadowInner::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
nsTArray<WebRenderParentCommand>& aCommands,
WebRenderDisplayItemLayer* aLayer)
{
nsPoint offset = ToReferenceFrame();
nsRect borderRect = nsRect(offset, mFrame->GetSize());
nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(aBuilder, aLayer, mFrame, borderRect);
}
bool
nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {

View File

@ -3440,6 +3440,10 @@ public:
}
}
static void CreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
WebRenderDisplayItemLayer* aLayer,
nsIFrame* aFrame,
const nsRect aBorderRect);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;