зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 3a8a36e50541 (bug 1555356) for reftest failures at pattern-big-image.html. CLOSED TREE
This commit is contained in:
Родитель
728d4108db
Коммит
73ca873fdb
|
@ -14,7 +14,6 @@
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "mozilla/gfx/Logging.h"
|
#include "mozilla/gfx/Logging.h"
|
||||||
#include "mozilla/gfx/Types.h"
|
#include "mozilla/gfx/Types.h"
|
||||||
#include "mozilla/layout/SVGGeometryFrame.h"
|
|
||||||
#include "mozilla/layers/AnimationHelper.h"
|
#include "mozilla/layers/AnimationHelper.h"
|
||||||
#include "mozilla/layers/ClipManager.h"
|
#include "mozilla/layers/ClipManager.h"
|
||||||
#include "mozilla/layers/ImageClient.h"
|
#include "mozilla/layers/ImageClient.h"
|
||||||
|
@ -1102,22 +1101,14 @@ class WebRenderGroupData : public WebRenderUserData {
|
||||||
DIGroup mFollowingGroup;
|
DIGroup mFollowingGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool IsItemProbablyActive(
|
static bool IsItemProbablyActive(nsDisplayItem* aItem,
|
||||||
nsDisplayItem* aItem, mozilla::wr::DisplayListBuilder& aBuilder,
|
nsDisplayListBuilder* aDisplayListBuilder,
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
bool aParentActive = true);
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder, bool aParentActive = true);
|
|
||||||
|
|
||||||
static bool HasActiveChildren(const nsDisplayList& aList,
|
static bool HasActiveChildren(const nsDisplayList& aList,
|
||||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||||
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
|
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
|
||||||
if (IsItemProbablyActive(i, aBuilder, aResources, aSc, aManager,
|
if (IsItemProbablyActive(i, aDisplayListBuilder, false)) {
|
||||||
aDisplayListBuilder, false)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1131,12 +1122,9 @@ static bool HasActiveChildren(const nsDisplayList& aList,
|
||||||
//
|
//
|
||||||
// We can't easily use GetLayerState because it wants a bunch of layers related
|
// We can't easily use GetLayerState because it wants a bunch of layers related
|
||||||
// information.
|
// information.
|
||||||
static bool IsItemProbablyActive(
|
static bool IsItemProbablyActive(nsDisplayItem* aItem,
|
||||||
nsDisplayItem* aItem, mozilla::wr::DisplayListBuilder& aBuilder,
|
nsDisplayListBuilder* aDisplayListBuilder,
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
bool aParentActive) {
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder, bool aParentActive) {
|
|
||||||
switch (aItem->GetType()) {
|
switch (aItem->GetType()) {
|
||||||
case DisplayItemType::TYPE_TRANSFORM: {
|
case DisplayItemType::TYPE_TRANSFORM: {
|
||||||
nsDisplayTransform* transformItem =
|
nsDisplayTransform* transformItem =
|
||||||
|
@ -1147,41 +1135,33 @@ static bool IsItemProbablyActive(
|
||||||
GP("active: %d\n", transformItem->MayBeAnimated(aDisplayListBuilder));
|
GP("active: %d\n", transformItem->MayBeAnimated(aDisplayListBuilder));
|
||||||
return transformItem->MayBeAnimated(aDisplayListBuilder, false) ||
|
return transformItem->MayBeAnimated(aDisplayListBuilder, false) ||
|
||||||
!is2D ||
|
!is2D ||
|
||||||
HasActiveChildren(*transformItem->GetChildren(), aBuilder,
|
HasActiveChildren(*transformItem->GetChildren(),
|
||||||
aResources, aSc, aManager, aDisplayListBuilder);
|
aDisplayListBuilder);
|
||||||
}
|
}
|
||||||
case DisplayItemType::TYPE_OPACITY: {
|
case DisplayItemType::TYPE_OPACITY: {
|
||||||
nsDisplayOpacity* opacityItem = static_cast<nsDisplayOpacity*>(aItem);
|
nsDisplayOpacity* opacityItem = static_cast<nsDisplayOpacity*>(aItem);
|
||||||
bool active = opacityItem->NeedsActiveLayer(aDisplayListBuilder,
|
bool active = opacityItem->NeedsActiveLayer(aDisplayListBuilder,
|
||||||
opacityItem->Frame(), false);
|
opacityItem->Frame(), false);
|
||||||
GP("active: %d\n", active);
|
GP("active: %d\n", active);
|
||||||
return active ||
|
return active || HasActiveChildren(*opacityItem->GetChildren(),
|
||||||
HasActiveChildren(*opacityItem->GetChildren(), aBuilder,
|
aDisplayListBuilder);
|
||||||
aResources, aSc, aManager, aDisplayListBuilder);
|
|
||||||
}
|
}
|
||||||
case DisplayItemType::TYPE_FOREIGN_OBJECT: {
|
case DisplayItemType::TYPE_FOREIGN_OBJECT: {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case DisplayItemType::TYPE_SVG_GEOMETRY: {
|
|
||||||
auto* svgItem = static_cast<nsDisplaySVGGeometry*>(aItem);
|
|
||||||
return svgItem->ShouldBeActive(aBuilder, aResources, aSc, aManager,
|
|
||||||
aDisplayListBuilder);
|
|
||||||
}
|
|
||||||
case DisplayItemType::TYPE_BLEND_MODE: {
|
case DisplayItemType::TYPE_BLEND_MODE: {
|
||||||
/* BLEND_MODE needs to be active if it might have a previous sibling
|
/* BLEND_MODE needs to be active if it might have a previous sibling
|
||||||
* that is active. We use the activeness of the parent as a rough
|
* that is active. We use the activeness of the parent as a rough
|
||||||
* proxy for this situation. */
|
* proxy for this situation. */
|
||||||
return aParentActive ||
|
return aParentActive ||
|
||||||
HasActiveChildren(*aItem->GetChildren(), aBuilder, aResources, aSc,
|
HasActiveChildren(*aItem->GetChildren(), aDisplayListBuilder);
|
||||||
aManager, aDisplayListBuilder);
|
|
||||||
}
|
}
|
||||||
case DisplayItemType::TYPE_WRAP_LIST:
|
case DisplayItemType::TYPE_WRAP_LIST:
|
||||||
case DisplayItemType::TYPE_CONTAINER:
|
case DisplayItemType::TYPE_CONTAINER:
|
||||||
case DisplayItemType::TYPE_MASK:
|
case DisplayItemType::TYPE_MASK:
|
||||||
case DisplayItemType::TYPE_PERSPECTIVE: {
|
case DisplayItemType::TYPE_PERSPECTIVE: {
|
||||||
if (aItem->GetChildren()) {
|
if (aItem->GetChildren()) {
|
||||||
return HasActiveChildren(*aItem->GetChildren(), aBuilder, aResources,
|
return HasActiveChildren(*aItem->GetChildren(), aDisplayListBuilder);
|
||||||
aSc, aManager, aDisplayListBuilder);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1207,12 +1187,8 @@ void Grouper::ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
|
||||||
|
|
||||||
nsDisplayItem* item = aList->GetBottom();
|
nsDisplayItem* item = aList->GetBottom();
|
||||||
nsDisplayItem* startOfCurrentGroup = item;
|
nsDisplayItem* startOfCurrentGroup = item;
|
||||||
RenderRootStateManager* manager =
|
|
||||||
aCommandBuilder->mManager->GetRenderRootStateManager(
|
|
||||||
aBuilder.GetRenderRoot());
|
|
||||||
while (item) {
|
while (item) {
|
||||||
if (IsItemProbablyActive(item, aBuilder, aResources, aSc, manager,
|
if (IsItemProbablyActive(item, mDisplayListBuilder)) {
|
||||||
mDisplayListBuilder)) {
|
|
||||||
// We're going to be starting a new group.
|
// We're going to be starting a new group.
|
||||||
RefPtr<WebRenderGroupData> groupData =
|
RefPtr<WebRenderGroupData> groupData =
|
||||||
aCommandBuilder->CreateOrRecycleWebRenderUserData<WebRenderGroupData>(
|
aCommandBuilder->CreateOrRecycleWebRenderUserData<WebRenderGroupData>(
|
||||||
|
@ -1275,6 +1251,9 @@ void Grouper::ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
|
||||||
sIndent++;
|
sIndent++;
|
||||||
// Note: this call to CreateWebRenderCommands can recurse back into
|
// Note: this call to CreateWebRenderCommands can recurse back into
|
||||||
// this function.
|
// this function.
|
||||||
|
RenderRootStateManager* manager =
|
||||||
|
aCommandBuilder->mManager->GetRenderRootStateManager(
|
||||||
|
aBuilder.GetRenderRoot());
|
||||||
bool createdWRCommands = item->CreateWebRenderCommands(
|
bool createdWRCommands = item->CreateWebRenderCommands(
|
||||||
aBuilder, aResources, aSc, manager, mDisplayListBuilder);
|
aBuilder, aResources, aSc, manager, mDisplayListBuilder);
|
||||||
sIndent--;
|
sIndent--;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
== image-filter-01.svg image-filter-01-ref.svg
|
== image-filter-01.svg image-filter-01-ref.svg
|
||||||
== image-load-01.svg ../pass.svg
|
== image-load-01.svg ../pass.svg
|
||||||
fuzzy-if(Android&&!browserIsRemote,0-4,0-32) == image-opacity-01.svg image-opacity-01-ref.svg # Bug 779514 for Android
|
fuzzy-if(Android&&!browserIsRemote,0-4,0-32) == image-opacity-01.svg image-opacity-01-ref.svg # Bug 779514 for Android
|
||||||
fuzzy-if(Android,0-4,0-34) fuzzy-if(webrender,0-1,0-64) == image-opacity-02.svg image-opacity-02-ref.svg # Bug 776039 for Android
|
fuzzy-if(Android,0-4,0-34) == image-opacity-02.svg image-opacity-02-ref.svg # Bug 776039 for Android
|
||||||
== image-rotate-01.svg image-rotate-01-ref.svg
|
== image-rotate-01.svg image-rotate-01-ref.svg
|
||||||
== image-rotate-02a.svg image-rotate-02-ref.svg
|
== image-rotate-02a.svg image-rotate-02-ref.svg
|
||||||
== image-rotate-02b.svg image-rotate-02-ref.svg
|
== image-rotate-02b.svg image-rotate-02-ref.svg
|
||||||
|
|
|
@ -63,7 +63,7 @@ fuzzy(0-11,0-7155) == blur-inside-clipPath.svg blur-inside-clipPath-ref.svg
|
||||||
== clip-01.svg pass.svg
|
== clip-01.svg pass.svg
|
||||||
== clip-02a.svg clip-02-ref.svg
|
== clip-02a.svg clip-02-ref.svg
|
||||||
== clip-02b.svg clip-02-ref.svg
|
== clip-02b.svg clip-02-ref.svg
|
||||||
fuzzy-if(webrender,0-1,0-10000) == clip-surface-clone-01.svg clip-surface-clone-01-ref.svg
|
== clip-surface-clone-01.svg clip-surface-clone-01-ref.svg
|
||||||
== clip-use-element-01.svg pass.svg
|
== clip-use-element-01.svg pass.svg
|
||||||
== clip-use-element-02.svg pass.svg
|
== clip-use-element-02.svg pass.svg
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ fuzzy-if(skiaContent,0-1,0-400) == path-06.svg path-06-ref.svg
|
||||||
== pathLength-02.svg pass.svg
|
== pathLength-02.svg pass.svg
|
||||||
|
|
||||||
== pattern-basic-01.svg pass.svg
|
== pattern-basic-01.svg pass.svg
|
||||||
fuzzy(0-1,0-5) fuzzy-if(webrender,0-2,0-59) == pattern-big-image.html pattern-big-image-ref.html
|
fuzzy(0-1,0-5) == pattern-big-image.html pattern-big-image-ref.html
|
||||||
== pattern-css-transform.html pattern-css-transform-ref.html
|
== pattern-css-transform.html pattern-css-transform-ref.html
|
||||||
== pattern-invalid-01.svg pattern-invalid-01-ref.svg
|
== pattern-invalid-01.svg pattern-invalid-01-ref.svg
|
||||||
fuzzy-if(skiaContent,0-1,0-5) == pattern-live-01a.svg pattern-live-01-ref.svg
|
fuzzy-if(skiaContent,0-1,0-5) == pattern-live-01a.svg pattern-live-01-ref.svg
|
||||||
|
|
|
@ -53,6 +53,39 @@ NS_QUERYFRAME_HEAD(SVGGeometryFrame)
|
||||||
NS_QUERYFRAME_ENTRY(SVGGeometryFrame)
|
NS_QUERYFRAME_ENTRY(SVGGeometryFrame)
|
||||||
NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
|
NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Display list item:
|
||||||
|
|
||||||
|
class nsDisplaySVGGeometry final : public nsPaintedDisplayItem {
|
||||||
|
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||||
|
|
||||||
|
public:
|
||||||
|
nsDisplaySVGGeometry(nsDisplayListBuilder* aBuilder, SVGGeometryFrame* aFrame)
|
||||||
|
: nsPaintedDisplayItem(aBuilder, aFrame) {
|
||||||
|
MOZ_COUNT_CTOR(nsDisplaySVGGeometry);
|
||||||
|
MOZ_ASSERT(aFrame, "Must have a frame!");
|
||||||
|
}
|
||||||
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
virtual ~nsDisplaySVGGeometry() { MOZ_COUNT_DTOR(nsDisplaySVGGeometry); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_DISPLAY_DECL_NAME("nsDisplaySVGGeometry", TYPE_SVG_GEOMETRY)
|
||||||
|
|
||||||
|
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||||
|
HitTestState* aState,
|
||||||
|
nsTArray<nsIFrame*>* aOutFrames) override;
|
||||||
|
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
||||||
|
|
||||||
|
nsDisplayItemGeometry* AllocateGeometry(
|
||||||
|
nsDisplayListBuilder* aBuilder) override {
|
||||||
|
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||||
|
const nsDisplayItemGeometry* aGeometry,
|
||||||
|
nsRegion* aInvalidRegion) const override;
|
||||||
|
};
|
||||||
|
|
||||||
void nsDisplaySVGGeometry::HitTest(nsDisplayListBuilder* aBuilder,
|
void nsDisplaySVGGeometry::HitTest(nsDisplayListBuilder* aBuilder,
|
||||||
const nsRect& aRect, HitTestState* aState,
|
const nsRect& aRect, HitTestState* aState,
|
||||||
nsTArray<nsIFrame*>* aOutFrames) {
|
nsTArray<nsIFrame*>* aOutFrames) {
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "gfxMatrix.h"
|
#include "gfxMatrix.h"
|
||||||
#include "gfxRect.h"
|
#include "gfxRect.h"
|
||||||
#include "nsDisplayList.h"
|
|
||||||
#include "nsFrame.h"
|
#include "nsFrame.h"
|
||||||
#include "nsSVGDisplayableFrame.h"
|
#include "nsSVGDisplayableFrame.h"
|
||||||
#include "nsLiteralString.h"
|
#include "nsLiteralString.h"
|
||||||
|
@ -20,13 +19,13 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class SVGGeometryFrame;
|
class SVGGeometryFrame;
|
||||||
class SVGMarkerObserver;
|
class SVGMarkerObserver;
|
||||||
class nsDisplaySVGGeometry;
|
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
class DrawTarget;
|
class DrawTarget;
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
class gfxContext;
|
class gfxContext;
|
||||||
|
class nsDisplaySVGGeometry;
|
||||||
class nsAtom;
|
class nsAtom;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
class nsSVGMarkerFrame;
|
class nsSVGMarkerFrame;
|
||||||
|
@ -48,7 +47,7 @@ class SVGGeometryFrame : public nsFrame, public nsSVGDisplayableFrame {
|
||||||
friend nsIFrame* ::NS_NewSVGGeometryFrame(mozilla::PresShell* aPresShell,
|
friend nsIFrame* ::NS_NewSVGGeometryFrame(mozilla::PresShell* aPresShell,
|
||||||
ComputedStyle* aStyle);
|
ComputedStyle* aStyle);
|
||||||
|
|
||||||
friend class nsDisplaySVGGeometry;
|
friend class ::nsDisplaySVGGeometry;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SVGGeometryFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
|
SVGGeometryFrame(ComputedStyle* aStyle, nsPresContext* aPresContext,
|
||||||
|
@ -119,16 +118,6 @@ class SVGGeometryFrame : public nsFrame, public nsSVGDisplayableFrame {
|
||||||
void Render(gfxContext* aContext, uint32_t aRenderComponents,
|
void Render(gfxContext* aContext, uint32_t aRenderComponents,
|
||||||
const gfxMatrix& aTransform, imgDrawingParams& aImgParams);
|
const gfxMatrix& aTransform, imgDrawingParams& aImgParams);
|
||||||
|
|
||||||
virtual bool CreateWebRenderCommands(
|
|
||||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder, nsDisplaySVGGeometry* aItem,
|
|
||||||
bool aDryRun) {
|
|
||||||
MOZ_RELEASE_ASSERT(aDryRun, "You shouldn't be calling this directly");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param aMatrix The transform that must be multiplied onto aContext to
|
* @param aMatrix The transform that must be multiplied onto aContext to
|
||||||
* establish this frame's SVG user space.
|
* establish this frame's SVG user space.
|
||||||
|
@ -136,72 +125,6 @@ class SVGGeometryFrame : public nsFrame, public nsSVGDisplayableFrame {
|
||||||
void PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform,
|
void PaintMarkers(gfxContext& aContext, const gfxMatrix& aTransform,
|
||||||
imgDrawingParams& aImgParams);
|
imgDrawingParams& aImgParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// Display list item:
|
|
||||||
|
|
||||||
class nsDisplaySVGGeometry final : public nsPaintedDisplayItem {
|
|
||||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
|
||||||
|
|
||||||
public:
|
|
||||||
nsDisplaySVGGeometry(nsDisplayListBuilder* aBuilder, SVGGeometryFrame* aFrame)
|
|
||||||
: nsPaintedDisplayItem(aBuilder, aFrame) {
|
|
||||||
MOZ_COUNT_CTOR(nsDisplaySVGGeometry);
|
|
||||||
MOZ_ASSERT(aFrame, "Must have a frame!");
|
|
||||||
}
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
virtual ~nsDisplaySVGGeometry() { MOZ_COUNT_DTOR(nsDisplaySVGGeometry); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NS_DISPLAY_DECL_NAME("nsDisplaySVGGeometry", TYPE_SVG_GEOMETRY)
|
|
||||||
|
|
||||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|
||||||
HitTestState* aState,
|
|
||||||
nsTArray<nsIFrame*>* aOutFrames) override;
|
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
|
||||||
|
|
||||||
nsDisplayItemGeometry* AllocateGeometry(
|
|
||||||
nsDisplayListBuilder* aBuilder) override {
|
|
||||||
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
|
||||||
const nsDisplayItemGeometry* aGeometry,
|
|
||||||
nsRegion* aInvalidRegion) const override;
|
|
||||||
|
|
||||||
// Whether this part of the SVG should be natively handled by webrender,
|
|
||||||
// potentially becoming an "active layer" inside a blob image.
|
|
||||||
bool ShouldBeActive(mozilla::wr::DisplayListBuilder& aBuilder,
|
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
|
||||||
// We delegate this question to the parent frame to take advantage of
|
|
||||||
// the SVGGeometryFrame inheritance hierarchy which provides actual
|
|
||||||
// implementation details. The dryRun flag prevents serious side-effects.
|
|
||||||
auto* frame = static_cast<SVGGeometryFrame*>(mFrame);
|
|
||||||
return frame->CreateWebRenderCommands(aBuilder, aResources, aSc, aManager,
|
|
||||||
aDisplayListBuilder, this,
|
|
||||||
/*aDryRun=*/true);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool CreateWebRenderCommands(
|
|
||||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder) override {
|
|
||||||
// We delegate this question to the parent frame to take advantage of
|
|
||||||
// the SVGGeometryFrame inheritance hierarchy which provides actual
|
|
||||||
// implementation details.
|
|
||||||
auto* frame = static_cast<SVGGeometryFrame*>(mFrame);
|
|
||||||
bool result = frame->CreateWebRenderCommands(aBuilder, aResources, aSc,
|
|
||||||
aManager, aDisplayListBuilder,
|
|
||||||
this, /*aDryRun=*/false);
|
|
||||||
MOZ_ASSERT(result, "ShouldBeActive inconsistent with CreateWRCommands?");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // __SVGGEOMETRYFRAME_H__
|
#endif // __SVGGEOMETRYFRAME_H__
|
||||||
|
|
|
@ -17,7 +17,6 @@ if CONFIG['ENABLE_TESTS']:
|
||||||
|
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'nsFilterInstance.h',
|
'nsFilterInstance.h',
|
||||||
'nsSVGDisplayableFrame.h',
|
|
||||||
'nsSVGFilterInstance.h',
|
'nsSVGFilterInstance.h',
|
||||||
'nsSVGForeignObjectFrame.h',
|
'nsSVGForeignObjectFrame.h',
|
||||||
'nsSVGImageFrame.h',
|
'nsSVGImageFrame.h',
|
||||||
|
@ -32,10 +31,6 @@ EXPORTS.mozilla += [
|
||||||
'SVGContextPaint.h',
|
'SVGContextPaint.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
EXPORTS.mozilla.layout += [
|
|
||||||
'SVGGeometryFrame.h',
|
|
||||||
]
|
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'nsCSSClipPathInstance.cpp',
|
'nsCSSClipPathInstance.cpp',
|
||||||
'nsCSSFilterInstance.cpp',
|
'nsCSSFilterInstance.cpp',
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxPlatform.h"
|
#include "gfxPlatform.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "mozilla/layers/RenderRootStateManager.h"
|
|
||||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
|
||||||
#include "imgIContainer.h"
|
#include "imgIContainer.h"
|
||||||
#include "nsContainerFrame.h"
|
#include "nsContainerFrame.h"
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
|
@ -33,7 +31,6 @@ using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
using namespace mozilla::image;
|
using namespace mozilla::image;
|
||||||
using namespace mozilla::dom::SVGPreserveAspectRatio_Binding;
|
|
||||||
namespace SVGT = SVGGeometryProperty::Tags;
|
namespace SVGT = SVGGeometryProperty::Tags;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
@ -385,233 +382,6 @@ void nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsSVGImageFrame::CreateWebRenderCommands(
|
|
||||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder, nsDisplaySVGGeometry* aItem,
|
|
||||||
bool aDryRun) {
|
|
||||||
if (!StyleVisibility()->IsVisible()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float opacity = 1.0f;
|
|
||||||
if (nsSVGUtils::CanOptimizeOpacity(this)) {
|
|
||||||
opacity = StyleEffects()->mOpacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opacity != 1.0f) {
|
|
||||||
// FIXME: not implemented, might be trivial
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
|
||||||
// FIXME: not implemented
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to setup the image
|
|
||||||
if (!mImageContainer) {
|
|
||||||
nsCOMPtr<imgIRequest> currentRequest;
|
|
||||||
nsCOMPtr<nsIImageLoadingContent> imageLoader =
|
|
||||||
do_QueryInterface(GetContent());
|
|
||||||
if (imageLoader) {
|
|
||||||
imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
|
||||||
getter_AddRefs(currentRequest));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentRequest) {
|
|
||||||
currentRequest->GetImage(getter_AddRefs(mImageContainer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mImageContainer) {
|
|
||||||
// nothing to draw (yet)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t flags = imgIContainer::FLAG_ASYNC_NOTIFY;
|
|
||||||
if (aDisplayListBuilder->ShouldSyncDecodeImages()) {
|
|
||||||
flags |= imgIContainer::FLAG_SYNC_DECODE;
|
|
||||||
}
|
|
||||||
if (aDisplayListBuilder->IsPaintingToWindow()) {
|
|
||||||
flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute bounds of the image
|
|
||||||
nscoord appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
|
|
||||||
int32_t appUnitsPerCSSPixel = AppUnitsPerCSSPixel();
|
|
||||||
|
|
||||||
float x, y, width, height;
|
|
||||||
SVGImageElement* imgElem = static_cast<SVGImageElement*>(GetContent());
|
|
||||||
SVGGeometryProperty::ResolveAll<SVGT::X, SVGT::Y, SVGT::Width, SVGT::Height>(
|
|
||||||
imgElem, &x, &y, &width, &height);
|
|
||||||
NS_ASSERTION(width > 0 && height > 0,
|
|
||||||
"Should only be painting things with valid width/height");
|
|
||||||
|
|
||||||
auto toReferenceFrame = aItem->ToReferenceFrame();
|
|
||||||
auto appRect = nsLayoutUtils::RoundGfxRectToAppRect(Rect(0, 0, width, height),
|
|
||||||
appUnitsPerCSSPixel);
|
|
||||||
appRect += toReferenceFrame;
|
|
||||||
auto destRect = LayoutDeviceRect::FromAppUnits(appRect, appUnitsPerDevPx);
|
|
||||||
auto clipRect = destRect;
|
|
||||||
|
|
||||||
if (StyleDisplay()->IsScrollableOverflow()) {
|
|
||||||
// Apply potential non-trivial clip
|
|
||||||
auto cssClip = nsSVGUtils::GetClipRectForFrame(this, 0, 0, width, height);
|
|
||||||
auto appClip =
|
|
||||||
nsLayoutUtils::RoundGfxRectToAppRect(cssClip, appUnitsPerCSSPixel);
|
|
||||||
appClip += toReferenceFrame;
|
|
||||||
clipRect = LayoutDeviceRect::FromAppUnits(appClip, appUnitsPerDevPx);
|
|
||||||
|
|
||||||
// Apply preserveAspectRatio
|
|
||||||
if (mImageContainer->GetType() == imgIContainer::TYPE_RASTER) {
|
|
||||||
int32_t nativeWidth, nativeHeight;
|
|
||||||
if (NS_FAILED(mImageContainer->GetWidth(&nativeWidth)) ||
|
|
||||||
NS_FAILED(mImageContainer->GetHeight(&nativeHeight)) ||
|
|
||||||
nativeWidth == 0 || nativeHeight == 0) {
|
|
||||||
// Image has no size; nothing to draw
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto preserveAspectRatio = imgElem->mPreserveAspectRatio.GetAnimValue();
|
|
||||||
uint16_t align = preserveAspectRatio.GetAlign();
|
|
||||||
uint16_t meetOrSlice = preserveAspectRatio.GetMeetOrSlice();
|
|
||||||
|
|
||||||
// default to the defaults
|
|
||||||
if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN) {
|
|
||||||
align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
|
|
||||||
}
|
|
||||||
if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN) {
|
|
||||||
meetOrSlice = SVG_MEETORSLICE_MEET;
|
|
||||||
}
|
|
||||||
|
|
||||||
// aspect > 1 is horizontal
|
|
||||||
// aspect < 1 is vertical
|
|
||||||
float nativeAspect = ((float)nativeWidth) / ((float)nativeHeight);
|
|
||||||
float viewAspect = width / height;
|
|
||||||
|
|
||||||
// "Meet" is "fit image to view"; "Slice" is "cover view with image".
|
|
||||||
//
|
|
||||||
// Whether we meet or slice, one side of the destRect will always be
|
|
||||||
// perfectly spanned by our image. The only questions to answer are
|
|
||||||
// "which side won't span perfectly" and "should that side be grown
|
|
||||||
// or shrunk".
|
|
||||||
//
|
|
||||||
// Because we fit our image to the destRect, this all just reduces to:
|
|
||||||
// "if meet, shrink to fit. if slice, grow to fit."
|
|
||||||
if (align != SVG_PRESERVEASPECTRATIO_NONE && nativeAspect != viewAspect) {
|
|
||||||
// Slightly redundant bools, but they make the conditions clearer
|
|
||||||
bool tooTall = nativeAspect > viewAspect;
|
|
||||||
bool tooWide = nativeAspect < viewAspect;
|
|
||||||
if ((meetOrSlice == SVG_MEETORSLICE_MEET && tooTall) ||
|
|
||||||
(meetOrSlice == SVG_MEETORSLICE_SLICE && tooWide)) {
|
|
||||||
// Adjust height and realign y
|
|
||||||
auto oldHeight = destRect.height;
|
|
||||||
destRect.height = destRect.width / nativeAspect;
|
|
||||||
auto heightChange = oldHeight - destRect.height;
|
|
||||||
switch (align) {
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMINYMIN:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMIDYMIN:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMAXYMIN:
|
|
||||||
// align to top (no-op)
|
|
||||||
break;
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMINYMID:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMIDYMID:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMAXYMID:
|
|
||||||
// align to center
|
|
||||||
destRect.y += heightChange / 2.0f;
|
|
||||||
break;
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMINYMAX:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMIDYMAX:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMAXYMAX:
|
|
||||||
// align to bottom
|
|
||||||
destRect.y += heightChange;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT_UNREACHABLE("Unknown value for align");
|
|
||||||
}
|
|
||||||
} else if ((meetOrSlice == SVG_MEETORSLICE_MEET && tooWide) ||
|
|
||||||
(meetOrSlice == SVG_MEETORSLICE_SLICE && tooTall)) {
|
|
||||||
// Adjust width and realign x
|
|
||||||
auto oldWidth = destRect.width;
|
|
||||||
destRect.width = destRect.height * nativeAspect;
|
|
||||||
auto widthChange = oldWidth - destRect.width;
|
|
||||||
switch (align) {
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMINYMIN:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMINYMID:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMINYMAX:
|
|
||||||
// align to left (no-op)
|
|
||||||
break;
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMIDYMIN:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMIDYMID:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMIDYMAX:
|
|
||||||
// align to center
|
|
||||||
destRect.x += widthChange / 2.0f;
|
|
||||||
break;
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMAXYMIN:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMAXYMID:
|
|
||||||
case SVG_PRESERVEASPECTRATIO_XMAXYMAX:
|
|
||||||
// align to right
|
|
||||||
destRect.x += widthChange;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_ASSERT_UNREACHABLE("Unknown value for align");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Maybe<SVGImageContext> svgContext;
|
|
||||||
if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
|
|
||||||
// Forward preserveAspectRatio to inner SVGs
|
|
||||||
svgContext.emplace(Some(CSSIntSize::Truncate(width, height)),
|
|
||||||
Some(imgElem->mPreserveAspectRatio.GetAnimValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntSize decodeSize = nsLayoutUtils::ComputeImageContainerDrawingParameters(
|
|
||||||
mImageContainer, this, destRect, aSc, flags, svgContext);
|
|
||||||
|
|
||||||
RefPtr<layers::ImageContainer> container;
|
|
||||||
ImgDrawResult drawResult = mImageContainer->GetImageContainerAtSize(
|
|
||||||
aManager->LayerManager(), decodeSize, svgContext, flags,
|
|
||||||
getter_AddRefs(container));
|
|
||||||
|
|
||||||
// While we got a container, it may not contain a fully decoded surface. If
|
|
||||||
// that is the case, and we have an image we were previously displaying which
|
|
||||||
// has a fully decoded surface, then we should prefer the previous image.
|
|
||||||
switch (drawResult) {
|
|
||||||
case ImgDrawResult::NOT_READY:
|
|
||||||
case ImgDrawResult::INCOMPLETE:
|
|
||||||
case ImgDrawResult::TEMPORARY_ERROR:
|
|
||||||
// nothing to draw (yet)
|
|
||||||
return true;
|
|
||||||
case ImgDrawResult::NOT_SUPPORTED:
|
|
||||||
// things we haven't implemented for WR yet
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
// image is ready to draw
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't do any actual mutations to state if we're doing a dry run
|
|
||||||
// (used to decide if we're making this into an active layer)
|
|
||||||
if (!aDryRun) {
|
|
||||||
// If the image container is empty, we don't want to fallback. Any other
|
|
||||||
// failure will be due to resource constraints and fallback is unlikely to
|
|
||||||
// help us. Hence we can ignore the return value from PushImage.
|
|
||||||
if (container) {
|
|
||||||
aManager->CommandBuilder().PushImage(aItem, container, aBuilder,
|
|
||||||
aResources, aSc, destRect, clipRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(aItem, drawResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame* nsSVGImageFrame::GetFrameForPoint(const gfxPoint& aPoint) {
|
nsIFrame* nsSVGImageFrame::GetFrameForPoint(const gfxPoint& aPoint) {
|
||||||
if (!(GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) && !GetHitTestFlags()) {
|
if (!(GetStateBits() & NS_STATE_SVG_CLIPPATH_CHILD) && !GetHitTestFlags()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -50,14 +50,6 @@ class nsSVGImageFrame final : public mozilla::SVGGeometryFrame,
|
||||||
friend nsIFrame* NS_NewSVGImageFrame(mozilla::PresShell* aPresShell,
|
friend nsIFrame* NS_NewSVGImageFrame(mozilla::PresShell* aPresShell,
|
||||||
ComputedStyle* aStyle);
|
ComputedStyle* aStyle);
|
||||||
|
|
||||||
virtual bool CreateWebRenderCommands(
|
|
||||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
|
||||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
|
||||||
const mozilla::layers::StackingContextHelper& aSc,
|
|
||||||
mozilla::layers::RenderRootStateManager* aManager,
|
|
||||||
nsDisplayListBuilder* aDisplayListBuilder,
|
|
||||||
mozilla::nsDisplaySVGGeometry* aItem, bool aDryRun) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit nsSVGImageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
explicit nsSVGImageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext)
|
||||||
: SVGGeometryFrame(aStyle, aPresContext, kClassID),
|
: SVGGeometryFrame(aStyle, aPresContext, kClassID),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче