mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1343979 - Add webrender support for ButtonBorderBackground. r=ethlin
This commit is contained in:
parent
b17625cf2c
commit
2289ed06ba
@ -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',
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -43,6 +43,8 @@ UNIFIED_SOURCES += [
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'../../editor/txmgr',
|
||||
'../base',
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -79,6 +79,7 @@ class nsCSSBorderRenderer final
|
||||
|
||||
friend class nsDisplayBorder;
|
||||
friend class nsDisplayOutline;
|
||||
friend class nsDisplayButtonBorder;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user