Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Cosmin Sabou 2019-06-21 01:03:07 +03:00
Родитель 360ae4d7f5 52ccd7af68
Коммит 49014f945b
5913 изменённых файлов: 37166 добавлений и 13751 удалений

Просмотреть файл

@ -38,14 +38,18 @@ class FlexItemSizingOutline extends PureComponent {
);
}
renderFinalOutline(mainFinalSize, mainMaxSize, mainMinSize, isClamped) {
return (
dom.div({ className: "flex-outline-final" + (isClamped ? " clamped" : "") })
);
renderFinalOutline(isClamped) {
return dom.div({ className: "flex-outline-final" + (isClamped ? " clamped" : "") });
}
renderPoint(className, label = className) {
return dom.div({ className: `flex-outline-point ${className}`, "data-label": label });
return (
dom.div({
key: className,
className: `flex-outline-point ${className}`,
"data-label": label,
})
);
}
render() {
@ -145,7 +149,7 @@ class FlexItemSizingOutline extends PureComponent {
dom.div(
{
className: `flex-outline ${mainAxisDirection}` +
(mainDeltaSize > 0 ? " growing" : " shrinking"),
(mainDeltaSize > 0 ? " growing" : " shrinking"),
style: {
gridTemplateColumns,
},
@ -155,8 +159,7 @@ class FlexItemSizingOutline extends PureComponent {
showMax ? this.renderPoint("max") : null,
this.renderBasisOutline(mainBaseSize),
this.renderDeltaOutline(mainDeltaSize),
this.renderFinalOutline(mainFinalSize, mainMaxSize, mainMinSize,
clampState !== "unclamped")
this.renderFinalOutline(clampState !== "unclamped")
)
)
);

Просмотреть файл

@ -1005,10 +1005,6 @@ DOMInterfaces = {
'headerFile': 'mozilla/dom/SVGGradientElement.h',
},
'SVGRect': {
'nativeType': 'mozilla::dom::SVGIRect'
},
'SVGStringList': {
'nativeType': 'mozilla::DOMSVGStringList',
'headerFile': 'DOMSVGStringList.h',

Просмотреть файл

@ -7,8 +7,8 @@
#include "SVGAnimatedRect.h"
#include "mozilla/dom/SVGAnimatedRectBinding.h"
#include "mozilla/dom/SVGElement.h"
#include "mozilla/dom/SVGRect.h"
#include "SVGAnimatedViewBox.h"
#include "SVGIRect.h"
namespace mozilla {
namespace dom {
@ -26,11 +26,11 @@ SVGAnimatedRect::~SVGAnimatedRect() {
SVGAnimatedViewBox::sSVGAnimatedRectTearoffTable.RemoveTearoff(mVal);
}
already_AddRefed<SVGIRect> SVGAnimatedRect::GetBaseVal() {
already_AddRefed<SVGRect> SVGAnimatedRect::GetBaseVal() {
return mVal->ToDOMBaseVal(mSVGElement);
}
already_AddRefed<SVGIRect> SVGAnimatedRect::GetAnimVal() {
already_AddRefed<SVGRect> SVGAnimatedRect::GetAnimVal() {
return mVal->ToDOMAnimVal(mSVGElement);
}

Просмотреть файл

@ -9,15 +9,21 @@
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/SVGElement.h"
#include "mozilla/dom/SVGRectBinding.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsWrapperCache.h"
namespace mozilla {
class SVGAnimatedViewBox;
namespace dom {
class SVGRect;
// Despite the name of this class appearing to be generic,
// SVGAnimatedRect is only used for viewBox attributes.
class SVGAnimatedRect final : public nsWrapperCache {
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(SVGAnimatedRect)
@ -30,9 +36,9 @@ class SVGAnimatedRect final : public nsWrapperCache {
virtual JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
already_AddRefed<SVGIRect> GetBaseVal();
already_AddRefed<SVGRect> GetBaseVal();
already_AddRefed<SVGIRect> GetAnimVal();
already_AddRefed<SVGRect> GetAnimVal();
private:
virtual ~SVGAnimatedRect();

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/Move.h"
#include "mozilla/SMILValue.h"
#include "mozilla/SVGContentUtils.h"
#include "mozilla/dom/SVGRect.h"
#include "nsCharSeparatedTokenizer.h"
#include "SVGViewBoxSMILType.h"
#include "nsTextFormatter.h"
@ -61,32 +62,9 @@ nsresult SVGViewBox::FromString(const nsAString& aStr, SVGViewBox* aViewBox) {
return NS_OK;
}
/* Cycle collection macros for SVGAnimatedViewBox */
NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(SVGAnimatedViewBox::DOMBaseVal,
mSVGElement)
NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(SVGAnimatedViewBox::DOMAnimVal,
mSVGElement)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGAnimatedViewBox::DOMBaseVal)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGAnimatedViewBox::DOMBaseVal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGAnimatedViewBox::DOMAnimVal)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGAnimatedViewBox::DOMAnimVal)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAnimatedViewBox::DOMBaseVal)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAnimatedViewBox::DOMAnimVal)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
static SVGAttrTearoffTable<SVGAnimatedViewBox, SVGAnimatedViewBox::DOMBaseVal>
static SVGAttrTearoffTable<SVGAnimatedViewBox, SVGRect>
sBaseSVGViewBoxTearoffTable;
static SVGAttrTearoffTable<SVGAnimatedViewBox, SVGAnimatedViewBox::DOMAnimVal>
static SVGAttrTearoffTable<SVGAnimatedViewBox, SVGRect>
sAnimSVGViewBoxTearoffTable;
SVGAttrTearoffTable<SVGAnimatedViewBox, SVGAnimatedRect>
SVGAnimatedViewBox::sSVGAnimatedRectTearoffTable;
@ -206,70 +184,45 @@ already_AddRefed<SVGAnimatedRect> SVGAnimatedViewBox::ToSVGAnimatedRect(
return domAnimatedRect.forget();
}
already_AddRefed<SVGIRect> SVGAnimatedViewBox::ToDOMBaseVal(
already_AddRefed<SVGRect> SVGAnimatedViewBox::ToDOMBaseVal(
SVGElement* aSVGElement) {
if (!mHasBaseVal || mBaseVal.none) {
return nullptr;
}
RefPtr<DOMBaseVal> domBaseVal = sBaseSVGViewBoxTearoffTable.GetTearoff(this);
RefPtr<SVGRect> domBaseVal = sBaseSVGViewBoxTearoffTable.GetTearoff(this);
if (!domBaseVal) {
domBaseVal = new DOMBaseVal(this, aSVGElement);
domBaseVal = new SVGRect(this, aSVGElement, SVGRect::BaseValue);
sBaseSVGViewBoxTearoffTable.AddTearoff(this, domBaseVal);
}
return domBaseVal.forget();
}
SVGAnimatedViewBox::DOMBaseVal::~DOMBaseVal() {
sBaseSVGViewBoxTearoffTable.RemoveTearoff(mVal);
SVGRect::~SVGRect() {
if (mType == BaseValue) {
sBaseSVGViewBoxTearoffTable.RemoveTearoff(mVal);
} else if (mType == AnimValue) {
sAnimSVGViewBoxTearoffTable.RemoveTearoff(mVal);
}
}
already_AddRefed<SVGIRect> SVGAnimatedViewBox::ToDOMAnimVal(
already_AddRefed<SVGRect> SVGAnimatedViewBox::ToDOMAnimVal(
SVGElement* aSVGElement) {
if ((mAnimVal && mAnimVal->none) ||
(!mAnimVal && (!mHasBaseVal || mBaseVal.none))) {
return nullptr;
}
RefPtr<DOMAnimVal> domAnimVal = sAnimSVGViewBoxTearoffTable.GetTearoff(this);
RefPtr<SVGRect> domAnimVal = sAnimSVGViewBoxTearoffTable.GetTearoff(this);
if (!domAnimVal) {
domAnimVal = new DOMAnimVal(this, aSVGElement);
domAnimVal = new SVGRect(this, aSVGElement, SVGRect::AnimValue);
sAnimSVGViewBoxTearoffTable.AddTearoff(this, domAnimVal);
}
return domAnimVal.forget();
}
SVGAnimatedViewBox::DOMAnimVal::~DOMAnimVal() {
sAnimSVGViewBoxTearoffTable.RemoveTearoff(mVal);
}
void SVGAnimatedViewBox::DOMBaseVal::SetX(float aX, ErrorResult& aRv) {
SVGViewBox rect = mVal->GetBaseValue();
rect.x = aX;
mVal->SetBaseValue(rect, mSVGElement);
}
void SVGAnimatedViewBox::DOMBaseVal::SetY(float aY, ErrorResult& aRv) {
SVGViewBox rect = mVal->GetBaseValue();
rect.y = aY;
mVal->SetBaseValue(rect, mSVGElement);
}
void SVGAnimatedViewBox::DOMBaseVal::SetWidth(float aWidth, ErrorResult& aRv) {
SVGViewBox rect = mVal->GetBaseValue();
rect.width = aWidth;
mVal->SetBaseValue(rect, mSVGElement);
}
void SVGAnimatedViewBox::DOMBaseVal::SetHeight(float aHeight,
ErrorResult& aRv) {
SVGViewBox rect = mVal->GetBaseValue();
rect.height = aHeight;
mVal->SetBaseValue(rect, mSVGElement);
}
UniquePtr<SMILAttr> SVGAnimatedViewBox::ToSMILAttr(SVGElement* aSVGElement) {
return MakeUnique<SMILViewBox>(this, aSVGElement);
}

Просмотреть файл

@ -15,13 +15,13 @@
#include "mozilla/SMILAttr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/SVGAnimatedRect.h"
#include "mozilla/dom/SVGIRect.h"
namespace mozilla {
class SMILValue;
namespace dom {
class SVGRect;
class SVGAnimationElement;
class SVGElement;
} // namespace dom
@ -80,11 +80,9 @@ class SVGAnimatedViewBox {
already_AddRefed<mozilla::dom::SVGAnimatedRect> ToSVGAnimatedRect(
SVGElement* aSVGElement);
already_AddRefed<mozilla::dom::SVGIRect> ToDOMBaseVal(
SVGElement* aSVGElement);
already_AddRefed<dom::SVGRect> ToDOMBaseVal(SVGElement* aSVGElement);
already_AddRefed<mozilla::dom::SVGIRect> ToDOMAnimVal(
SVGElement* aSVGElement);
already_AddRefed<dom::SVGRect> ToDOMAnimVal(SVGElement* aSVGElement);
mozilla::UniquePtr<SMILAttr> ToSMILAttr(SVGElement* aSVGElement);
@ -94,89 +92,6 @@ class SVGAnimatedViewBox {
bool mHasBaseVal;
public:
struct DOMBaseVal final : public mozilla::dom::SVGIRect {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMBaseVal)
DOMBaseVal(SVGAnimatedViewBox* aVal, SVGElement* aSVGElement)
: mozilla::dom::SVGIRect(), mVal(aVal), mSVGElement(aSVGElement) {}
SVGAnimatedViewBox* mVal; // kept alive because it belongs to content
RefPtr<SVGElement> mSVGElement;
float X() const final { return mVal->GetBaseValue().x; }
float Y() const final { return mVal->GetBaseValue().y; }
float Width() const final { return mVal->GetBaseValue().width; }
float Height() const final { return mVal->GetBaseValue().height; }
void SetX(float aX, mozilla::ErrorResult& aRv) final;
void SetY(float aY, mozilla::ErrorResult& aRv) final;
void SetWidth(float aWidth, mozilla::ErrorResult& aRv) final;
void SetHeight(float aHeight, mozilla::ErrorResult& aRv) final;
virtual nsIContent* GetParentObject() const override { return mSVGElement; }
private:
virtual ~DOMBaseVal();
};
struct DOMAnimVal final : public mozilla::dom::SVGIRect {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMAnimVal)
DOMAnimVal(SVGAnimatedViewBox* aVal, SVGElement* aSVGElement)
: mozilla::dom::SVGIRect(), mVal(aVal), mSVGElement(aSVGElement) {}
SVGAnimatedViewBox* mVal; // kept alive because it belongs to content
RefPtr<SVGElement> mSVGElement;
// Script may have modified animation parameters or timeline -- DOM getters
// need to flush any resample requests to reflect these modifications.
float X() const final {
mSVGElement->FlushAnimations();
return mVal->GetAnimValue().x;
}
float Y() const final {
mSVGElement->FlushAnimations();
return mVal->GetAnimValue().y;
}
float Width() const final {
mSVGElement->FlushAnimations();
return mVal->GetAnimValue().width;
}
float Height() const final {
mSVGElement->FlushAnimations();
return mVal->GetAnimValue().height;
}
void SetX(float aX, mozilla::ErrorResult& aRv) final {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
void SetY(float aY, mozilla::ErrorResult& aRv) final {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
void SetWidth(float aWidth, mozilla::ErrorResult& aRv) final {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
void SetHeight(float aHeight, mozilla::ErrorResult& aRv) final {
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
}
virtual nsIContent* GetParentObject() const override { return mSVGElement; }
private:
virtual ~DOMAnimVal();
};
struct SMILViewBox : public SMILAttr {
public:
SMILViewBox(SVGAnimatedViewBox* aVal, SVGElement* aSVGElement)

Просмотреть файл

@ -1,52 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SVGIRect_h
#define mozilla_dom_SVGIRect_h
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/SVGRectBinding.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "nsWrapperCache.h"
class nsIContent;
namespace mozilla {
namespace dom {
class SVGIRect : public nsISupports, public nsWrapperCache {
public:
virtual ~SVGIRect() = default;
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override {
return SVGRect_Binding::Wrap(aCx, this, aGivenProto);
}
virtual nsIContent* GetParentObject() const = 0;
virtual float X() const = 0;
virtual void SetX(float aX, ErrorResult& aRv) = 0;
virtual float Y() const = 0;
virtual void SetY(float aY, ErrorResult& aRv) = 0;
virtual float Width() const = 0;
virtual void SetWidth(float aWidth, ErrorResult& aRv) = 0;
virtual float Height() const = 0;
virtual void SetHeight(float aHeight, ErrorResult& aRv) = 0;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGIRect_h

Просмотреть файл

@ -5,19 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGRect.h"
#include "SVGElement.h"
#include "mozilla/dom/SVGRectBinding.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "SVGAnimatedViewBox.h"
#include "nsWrapperCache.h"
using namespace mozilla::gfx;
namespace mozilla {
namespace dom {
//----------------------------------------------------------------------
// implementation:
SVGRect::SVGRect(nsIContent* aParent, float x, float y, float w, float h)
: SVGIRect(), mParent(aParent), mX(x), mY(y), mWidth(w), mHeight(h) {}
//----------------------------------------------------------------------
// nsISupports methods:
@ -31,23 +29,132 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGRect)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// implementation:
SVGRect::SVGRect(SVGSVGElement* aSVGElement)
: mVal(nullptr), mParent(aSVGElement), mType(CreatedValue) {
MOZ_ASSERT(mParent);
mRect = gfx::Rect(0, 0, 0, 0);
}
JSObject* SVGRect::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
MOZ_ASSERT(mParent);
return SVGRect_Binding::Wrap(aCx, this, aGivenProto);
}
float SVGRect::X() {
switch (mType) {
case AnimValue:
static_cast<SVGElement*>(mParent->AsElement())->FlushAnimations();
return mVal->GetAnimValue().x;
case BaseValue:
return mVal->GetBaseValue().x;
default:
return mRect.x;
}
}
float SVGRect::Y() {
switch (mType) {
case AnimValue:
static_cast<SVGElement*>(mParent->AsElement())->FlushAnimations();
return mVal->GetAnimValue().y;
case BaseValue:
return mVal->GetBaseValue().y;
default:
return mRect.y;
}
}
float SVGRect::Width() {
switch (mType) {
case AnimValue:
static_cast<SVGElement*>(mParent->AsElement())->FlushAnimations();
return mVal->GetAnimValue().width;
case BaseValue:
return mVal->GetBaseValue().width;
default:
return mRect.width;
}
}
float SVGRect::Height() {
switch (mType) {
case AnimValue:
static_cast<SVGElement*>(mParent->AsElement())->FlushAnimations();
return mVal->GetAnimValue().height;
case BaseValue:
return mVal->GetBaseValue().height;
default:
return mRect.height;
}
}
void SVGRect::SetX(float aX, ErrorResult& aRv) {
switch (mType) {
case AnimValue:
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
case BaseValue: {
SVGViewBox rect = mVal->GetBaseValue();
rect.x = aX;
mVal->SetBaseValue(rect, static_cast<SVGElement*>(mParent->AsElement()));
return;
}
default:
mRect.x = aX;
}
}
void SVGRect::SetY(float aY, ErrorResult& aRv) {
switch (mType) {
case AnimValue:
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
case BaseValue: {
SVGViewBox rect = mVal->GetBaseValue();
rect.y = aY;
mVal->SetBaseValue(rect, static_cast<SVGElement*>(mParent->AsElement()));
return;
}
default:
mRect.y = aY;
}
}
void SVGRect::SetWidth(float aWidth, ErrorResult& aRv) {
switch (mType) {
case AnimValue:
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
case BaseValue: {
SVGViewBox rect = mVal->GetBaseValue();
rect.width = aWidth;
mVal->SetBaseValue(rect, static_cast<SVGElement*>(mParent->AsElement()));
return;
}
default:
mRect.width = aWidth;
}
}
void SVGRect::SetHeight(float aHeight, ErrorResult& aRv) {
switch (mType) {
case AnimValue:
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
return;
case BaseValue: {
SVGViewBox rect = mVal->GetBaseValue();
rect.height = aHeight;
mVal->SetBaseValue(rect, static_cast<SVGElement*>(mParent->AsElement()));
return;
}
default:
mRect.height = aHeight;
}
}
} // namespace dom
} // namespace mozilla
////////////////////////////////////////////////////////////////////////
// Exported creation functions:
already_AddRefed<mozilla::dom::SVGRect> NS_NewSVGRect(nsIContent* aParent,
float aX, float aY,
float aWidth,
float aHeight) {
RefPtr<mozilla::dom::SVGRect> rect =
new mozilla::dom::SVGRect(aParent, aX, aY, aWidth, aHeight);
return rect.forget();
}
already_AddRefed<mozilla::dom::SVGRect> NS_NewSVGRect(nsIContent* aParent,
const Rect& aRect) {
return NS_NewSVGRect(aParent, aRect.x, aRect.y, aRect.width, aRect.height);
}

Просмотреть файл

@ -7,10 +7,8 @@
#ifndef mozilla_dom_SVGRect_h
#define mozilla_dom_SVGRect_h
#include "mozilla/dom/SVGIRect.h"
#include "mozilla/dom/SVGElement.h"
#include "mozilla/gfx/Rect.h"
#include "nsCOMPtr.h"
#include "SVGElement.h"
////////////////////////////////////////////////////////////////////////
// SVGRect class
@ -18,50 +16,71 @@
namespace mozilla {
namespace dom {
class SVGRect final : public SVGIRect {
class SVGSVGElement;
class SVGRect final : public nsISupports, public nsWrapperCache {
public:
explicit SVGRect(nsIContent* aParent, float x = 0.0f, float y = 0.0f,
float w = 0.0f, float h = 0.0f);
typedef enum { BaseValue, AnimValue, CreatedValue } RectType;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SVGRect)
// WebIDL
float X() const final { return mX; }
/**
* Generic ctor for objects that are created for an attribute.
*/
SVGRect(SVGAnimatedViewBox* aVal, SVGElement* aSVGElement, RectType aType)
: mVal(aVal), mParent(aSVGElement), mType(aType) {
MOZ_ASSERT(mParent);
MOZ_ASSERT(mType == BaseValue || mType == AnimValue);
}
void SetX(float aX, ErrorResult& aRv) final { mX = aX; }
/**
* Ctor for creating the objects returned by SVGSVGElement.createSVGRect(),
* which do not initially belong to an attribute.
*/
explicit SVGRect(SVGSVGElement* aSVGElement);
float Y() const final { return mY; }
/**
* Ctor for all other non-attribute usage i.e getBBox, getExtentOfChar etc.
*/
SVGRect(nsIContent* aParent, const gfx::Rect& aRect)
: mVal(nullptr), mRect(aRect), mParent(aParent), mType(CreatedValue) {
MOZ_ASSERT(mParent);
}
void SetY(float aY, ErrorResult& aRv) final { mY = aY; }
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
float Width() const final { return mWidth; }
float X();
float Y();
float Width();
float Height();
void SetWidth(float aWidth, ErrorResult& aRv) final { mWidth = aWidth; }
void SetX(float aX, mozilla::ErrorResult& aRv);
void SetY(float aY, mozilla::ErrorResult& aRv);
void SetWidth(float aWidth, mozilla::ErrorResult& aRv);
void SetHeight(float aHeight, mozilla::ErrorResult& aRv);
float Height() const final { return mHeight; }
nsIContent* GetParentObject() const {
MOZ_ASSERT(mParent);
return mParent;
}
void SetHeight(float aHeight, ErrorResult& aRv) final { mHeight = aHeight; }
private:
virtual ~SVGRect();
virtual nsIContent* GetParentObject() const override { return mParent; }
// If we're actually representing a viewBox rect then our value
// will come from that element's viewBox attribute's value.
SVGAnimatedViewBox* mVal; // kept alive because it belongs to content
gfx::Rect mRect;
protected:
~SVGRect() = default;
nsCOMPtr<nsIContent> mParent;
float mX, mY, mWidth, mHeight;
// If mType is AnimValue or BaseValue this will be an element that
// has a viewBox, otherwise it could be any nsIContent.
RefPtr<nsIContent> mParent;
const RectType mType;
};
} // namespace dom
} // namespace mozilla
already_AddRefed<mozilla::dom::SVGRect> NS_NewSVGRect(nsIContent* aParent,
float x = 0.0f,
float y = 0.0f,
float width = 0.0f,
float height = 0.0f);
already_AddRefed<mozilla::dom::SVGRect> NS_NewSVGRect(
nsIContent* aParent, const mozilla::gfx::Rect& rect);
#endif // mozilla_dom_SVGRect_h

Просмотреть файл

@ -270,8 +270,8 @@ already_AddRefed<SVGMatrix> SVGSVGElement::CreateSVGMatrix() {
return do_AddRef(new SVGMatrix());
}
already_AddRefed<SVGIRect> SVGSVGElement::CreateSVGRect() {
return NS_NewSVGRect(this);
already_AddRefed<SVGRect> SVGSVGElement::CreateSVGRect() {
return do_AddRef(new SVGRect(this));
}
already_AddRefed<DOMSVGTransform> SVGSVGElement::CreateSVGTransform() {

Просмотреть файл

@ -25,7 +25,7 @@ class DOMSVGAngle;
class DOMSVGLength;
class DOMSVGNumber;
class SVGMatrix;
class SVGIRect;
class SVGRect;
class SVGSVGElement;
// Stores svgView arguments of SVG fragment identifiers.
@ -137,7 +137,7 @@ class SVGSVGElement final : public SVGSVGElementBase {
already_AddRefed<DOMSVGAngle> CreateSVGAngle();
already_AddRefed<nsISVGPoint> CreateSVGPoint();
already_AddRefed<SVGMatrix> CreateSVGMatrix();
already_AddRefed<SVGIRect> CreateSVGRect();
already_AddRefed<SVGRect> CreateSVGRect();
already_AddRefed<DOMSVGTransform> CreateSVGTransform();
already_AddRefed<DOMSVGTransform> CreateSVGTransformFromMatrix(
SVGMatrix& matrix);

Просмотреть файл

@ -8,7 +8,7 @@
#include "mozilla/dom/SVGLengthBinding.h"
#include "mozilla/dom/SVGTextContentElementBinding.h"
#include "mozilla/dom/SVGIRect.h"
#include "mozilla/dom/SVGRect.h"
#include "nsBidiUtils.h"
#include "nsISVGPoint.h"
#include "nsTextFragment.h"
@ -163,7 +163,7 @@ already_AddRefed<nsISVGPoint> SVGTextContentElement::GetEndPositionOfChar(
return point.forget();
}
already_AddRefed<SVGIRect> SVGTextContentElement::GetExtentOfChar(
already_AddRefed<SVGRect> SVGTextContentElement::GetExtentOfChar(
uint32_t charnum, ErrorResult& rv) {
SVGTextFrame* textFrame = GetSVGTextFrame();
@ -172,7 +172,7 @@ already_AddRefed<SVGIRect> SVGTextContentElement::GetExtentOfChar(
return nullptr;
}
RefPtr<SVGIRect> rect;
RefPtr<SVGRect> rect;
rv = textFrame->GetExtentOfChar(this, charnum, getter_AddRefs(rect));
return rect.forget();
}

Просмотреть файл

@ -20,7 +20,7 @@ class nsISVGPoint;
namespace dom {
struct DOMPointInit;
class SVGIRect;
class SVGRect;
typedef SVGGraphicsElement SVGTextContentElementBase;
@ -46,7 +46,7 @@ class SVGTextContentElement : public SVGTextContentElementBase {
already_AddRefed<nsISVGPoint> GetEndPositionOfChar(uint32_t charnum,
ErrorResult& rv);
MOZ_CAN_RUN_SCRIPT
already_AddRefed<SVGIRect> GetExtentOfChar(uint32_t charnum, ErrorResult& rv);
already_AddRefed<SVGRect> GetExtentOfChar(uint32_t charnum, ErrorResult& rv);
MOZ_CAN_RUN_SCRIPT float GetRotationOfChar(uint32_t charnum, ErrorResult& rv);
MOZ_CAN_RUN_SCRIPT int32_t GetCharNumAtPosition(const DOMPointInit& aPoint);

Просмотреть файл

@ -156,7 +156,7 @@ SVGElement* SVGTransformableElement::GetFarthestViewportElement() {
return SVGContentUtils::GetOuterSVGElement(this);
}
already_AddRefed<SVGIRect> SVGTransformableElement::GetBBox(
already_AddRefed<SVGRect> SVGTransformableElement::GetBBox(
const SVGBoundingBoxOptions& aOptions, ErrorResult& rv) {
nsIFrame* frame = GetPrimaryFrame(FlushType::Layout);
@ -199,14 +199,14 @@ already_AddRefed<SVGIRect> SVGTransformableElement::GetBBox(
rec.x += float(text->GetPosition().x) / AppUnitsPerCSSPixel();
rec.y += float(text->GetPosition().y) / AppUnitsPerCSSPixel();
return NS_NewSVGRect(this, ToRect(rec));
return do_AddRef(new SVGRect(this, ToRect(rec)));
}
if (!NS_SVGNewGetBBoxEnabled()) {
return NS_NewSVGRect(
return do_AddRef(new SVGRect(
this, ToRect(nsSVGUtils::GetBBox(
frame, nsSVGUtils::eBBoxIncludeFillGeometry |
nsSVGUtils::eUseUserSpaceOfUseElement)));
nsSVGUtils::eUseUserSpaceOfUseElement))));
}
uint32_t flags = 0;
if (aOptions.mFill) {
@ -222,14 +222,15 @@ already_AddRefed<SVGIRect> SVGTransformableElement::GetBBox(
flags |= nsSVGUtils::eBBoxIncludeClipped;
}
if (flags == 0) {
return NS_NewSVGRect(this, 0, 0, 0, 0);
return do_AddRef(new SVGRect(this, gfx::Rect()));
}
if (flags == nsSVGUtils::eBBoxIncludeMarkers ||
flags == nsSVGUtils::eBBoxIncludeClipped) {
flags |= nsSVGUtils::eBBoxIncludeFill;
}
flags |= nsSVGUtils::eUseUserSpaceOfUseElement;
return NS_NewSVGRect(this, ToRect(nsSVGUtils::GetBBox(frame, flags)));
return do_AddRef(
new SVGRect(this, ToRect(nsSVGUtils::GetBBox(frame, flags))));
}
already_AddRefed<SVGMatrix> SVGTransformableElement::GetCTM() {

Просмотреть файл

@ -20,7 +20,7 @@ namespace dom {
class DOMSVGAnimatedTransformList;
class SVGGraphicsElement;
class SVGMatrix;
class SVGIRect;
class SVGRect;
struct SVGBoundingBoxOptions;
class SVGTransformableElement : public SVGElement {
@ -36,8 +36,8 @@ class SVGTransformableElement : public SVGElement {
SVGElement* GetNearestViewportElement();
SVGElement* GetFarthestViewportElement();
MOZ_CAN_RUN_SCRIPT
already_AddRefed<SVGIRect> GetBBox(const SVGBoundingBoxOptions& aOptions,
ErrorResult& rv);
already_AddRefed<SVGRect> GetBBox(const SVGBoundingBoxOptions& aOptions,
ErrorResult& rv);
already_AddRefed<SVGMatrix> GetCTM();
already_AddRefed<SVGMatrix> GetScreenCTM();
already_AddRefed<SVGMatrix> GetTransformToElement(

Просмотреть файл

@ -62,7 +62,6 @@ EXPORTS.mozilla.dom += [
'SVGGradientElement.h',
'SVGGraphicsElement.h',
'SVGImageElement.h',
'SVGIRect.h',
'SVGLineElement.h',
'SVGMarkerElement.h',
'SVGMaskElement.h',

Просмотреть файл

@ -210,9 +210,8 @@ void brush_vs(
#ifdef WR_FRAGMENT_SHADER
Fragment brush_fs() {
vec2 compute_repeated_uvs(float perspective_divisor) {
vec2 uv_size = vUvBounds.zw - vUvBounds.xy;
float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y);
#ifdef WR_FEATURE_ALPHA_PASS
// This prevents the uv on the top and left parts of the primitive that was inflated
@ -233,10 +232,21 @@ Fragment brush_fs() {
repeated_uv.y = vUvBounds.w;
}
#else
// Handle horizontal and vertical repetitions.
vec2 repeated_uv = mod(vUv * perspective_divisor, uv_size) + vUvBounds.xy;
#endif
return repeated_uv;
}
Fragment brush_fs() {
float perspective_divisor = mix(gl_FragCoord.w, 1.0, vLayerAndPerspective.y);
#ifdef WR_FEATURE_REPETITION
vec2 repeated_uv = compute_repeated_uvs(perspective_divisor);
#else
vec2 repeated_uv = vUv * perspective_divisor + vUvBounds.xy;
#endif
// Clamp the uvs to avoid sampling artifacts.
vec2 uv = clamp(repeated_uv, vUvSampleBounds.xy, vUvSampleBounds.zw);
@ -245,7 +255,11 @@ Fragment brush_fs() {
Fragment frag;
#ifdef WR_FEATURE_ALPHA_PASS
float alpha = init_transform_fs(vLocalPos);
#ifdef WR_FEATURE_ANTIALIASING
float alpha = init_transform_fs(vLocalPos);
#else
float alpha = 1.0;
#endif
texel.rgb = texel.rgb * vMaskSwizzle.x + texel.aaa * vMaskSwizzle.y;
vec4 alpha_mask = texel * alpha;

Просмотреть файл

@ -157,6 +157,7 @@ impl AlphaBatchList {
pub fn set_params_and_get_batch(
&mut self,
key: BatchKey,
features: BatchFeatures,
// The bounding box of everything at this Z plane. We expect potentially
// multiple primitive segments coming with the same `z_id`.
z_bounding_rect: &PictureRect,
@ -226,7 +227,10 @@ impl AlphaBatchList {
assert_eq!(self.item_rects[self.current_batch_index].last(), Some(z_bounding_rect));
}
&mut self.batches[self.current_batch_index].instances
let batch = &mut self.batches[self.current_batch_index];
batch.features |= features;
&mut batch.instances
}
}
@ -250,6 +254,7 @@ impl OpaqueBatchList {
pub fn set_params_and_get_batch(
&mut self,
key: BatchKey,
features: BatchFeatures,
// The bounding box of everything at the current Z, whatever it is. We expect potentially
// multiple primitive segments produced by a primitive, which we allow to check
// `current_batch_index` instead of iterating the batches.
@ -289,7 +294,10 @@ impl OpaqueBatchList {
self.current_batch_index = selected_batch_index.unwrap();
}
&mut self.batches[self.current_batch_index].instances
let batch = &mut self.batches[self.current_batch_index];
batch.features |= features;
&mut batch.instances
}
fn finalize(&mut self) {
@ -310,6 +318,25 @@ impl OpaqueBatchList {
pub struct PrimitiveBatch {
pub key: BatchKey,
pub instances: Vec<PrimitiveInstanceData>,
pub features: BatchFeatures,
}
bitflags! {
/// Features of the batch that, if not requested, may allow a fast-path.
///
/// Rather than breaking batches when primitives request different features,
/// we always request the minimum amount of features to satisfy all items in
/// the batch.
/// The goal is to let the renderer be optionally select more specialized
/// versions of a shader if the batch doesn't require code certain code paths.
/// Not all shaders necessarily implement all of these features.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
pub struct BatchFeatures: u8 {
const ALPHA_PASS = 1 << 0;
const ANTIALIASING = 1 << 1;
const REPETITION = 1 << 2;
}
}
impl PrimitiveBatch {
@ -317,6 +344,7 @@ impl PrimitiveBatch {
PrimitiveBatch {
key,
instances: Vec::new(),
features: BatchFeatures::empty(),
}
}
}
@ -454,24 +482,26 @@ impl AlphaBatchBuilder {
pub fn push_single_instance(
&mut self,
key: BatchKey,
features: BatchFeatures,
bounding_rect: &PictureRect,
z_id: ZBufferId,
instance: PrimitiveInstanceData,
) {
self.set_params_and_get_batch(key, bounding_rect, z_id)
self.set_params_and_get_batch(key, features, bounding_rect, z_id)
.push(instance);
}
pub fn set_params_and_get_batch(
&mut self,
key: BatchKey,
features: BatchFeatures,
bounding_rect: &PictureRect,
z_id: ZBufferId,
) -> &mut Vec<PrimitiveInstanceData> {
match key.blend_mode {
BlendMode::None => {
self.opaque_batch_list
.set_params_and_get_batch(key, bounding_rect)
.set_params_and_get_batch(key, features, bounding_rect)
}
BlendMode::Alpha |
BlendMode::PremultipliedAlpha |
@ -481,7 +511,7 @@ impl AlphaBatchBuilder {
BlendMode::SubpixelDualSource |
BlendMode::Advanced(_) => {
self.alpha_batch_list
.set_params_and_get_batch(key, bounding_rect, z_id)
.set_params_and_get_batch(key, features, bounding_rect, z_id)
}
}
}
@ -513,6 +543,7 @@ impl BatchBuilder {
fn add_brush_instance_to_batches(
&mut self,
batch_key: BatchKey,
features: BatchFeatures,
bounding_rect: &PictureRect,
z_id: ZBufferId,
segment_index: i32,
@ -539,6 +570,7 @@ impl BatchBuilder {
batcher.push_single_instance(
batch_key,
features,
bounding_rect,
z_id,
PrimitiveInstanceData::from(instance),
@ -562,6 +594,7 @@ impl BatchBuilder {
batcher.push_single_instance(
batch_key,
BatchFeatures::empty(),
bounding_rect,
z_id,
PrimitiveInstanceData::from(SplitCompositeInstance {
@ -654,6 +687,15 @@ impl BatchBuilder {
prim_common_data.prim_size,
);
let mut batch_features = BatchFeatures::empty();
if prim_common_data.may_need_repetition {
batch_features |= BatchFeatures::REPETITION;
}
if transform_kind != TransformedRectKind::AxisAligned {
batch_features |= BatchFeatures::ANTIALIASING;
}
let snap_offsets = prim_info.snap_offsets;
let prim_vis_mask = prim_info.visibility_mask;
@ -705,6 +747,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
batch_key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -781,6 +824,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -907,6 +951,7 @@ impl BatchBuilder {
let render_task_address = batcher.render_task_address;
let batch = batcher.alpha_batch_list.set_params_and_get_batch(
key,
BatchFeatures::empty(),
bounding_rect,
z_id,
);
@ -1001,6 +1046,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
batch_key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1177,6 +1223,7 @@ impl BatchBuilder {
&batch_params,
blend_mode,
blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -1213,6 +1260,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1284,6 +1332,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
shadow_key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1306,6 +1355,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
content_key,
batch_features,
bounding_rect,
z_id_content,
INVALID_SEGMENT_INDEX,
@ -1386,6 +1436,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1432,6 +1483,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1464,6 +1516,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1506,6 +1559,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -1575,6 +1629,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -1664,6 +1719,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -1726,6 +1782,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -1834,6 +1891,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -1939,6 +1997,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -1995,6 +2054,7 @@ impl BatchBuilder {
};
self.add_brush_instance_to_batches(
batch_key,
batch_features,
bounding_rect,
z_id,
i as i32,
@ -2072,6 +2132,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
batch_key,
batch_features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -2115,6 +2176,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -2201,6 +2263,7 @@ impl BatchBuilder {
&batch_params,
specified_blend_mode,
non_segmented_blend_mode,
batch_features,
prim_header_index,
bounding_rect,
transform_kind,
@ -2245,6 +2308,7 @@ impl BatchBuilder {
batch_kind: BrushBatchKind,
prim_header_index: PrimitiveHeaderIndex,
alpha_blend_mode: BlendMode,
features: BatchFeatures,
bounding_rect: &PictureRect,
transform_kind: TransformedRectKind,
render_tasks: &RenderTaskGraph,
@ -2281,6 +2345,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
batch_key,
features,
bounding_rect,
z_id,
segment_index,
@ -2301,6 +2366,7 @@ impl BatchBuilder {
params: &BrushBatchParameters,
alpha_blend_mode: BlendMode,
non_segmented_blend_mode: BlendMode,
features: BatchFeatures,
prim_header_index: PrimitiveHeaderIndex,
bounding_rect: &PictureRect,
transform_kind: TransformedRectKind,
@ -2327,6 +2393,7 @@ impl BatchBuilder {
params.batch_kind,
prim_header_index,
alpha_blend_mode,
features,
bounding_rect,
transform_kind,
render_tasks,
@ -2352,6 +2419,7 @@ impl BatchBuilder {
params.batch_kind,
prim_header_index,
alpha_blend_mode,
features,
bounding_rect,
transform_kind,
render_tasks,
@ -2377,6 +2445,7 @@ impl BatchBuilder {
).unwrap_or(OPAQUE_TASK_ADDRESS);
self.add_brush_instance_to_batches(
batch_key,
features,
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,
@ -2437,6 +2506,7 @@ impl BatchBuilder {
self.add_brush_instance_to_batches(
key,
BatchFeatures::empty(),
bounding_rect,
z_id,
INVALID_SEGMENT_INDEX,

Просмотреть файл

@ -5,7 +5,7 @@
use api::{BorderRadius, ClipMode, ColorF};
use api::{ImageRendering, RepeatMode};
use api::{PremultipliedColorF, PropertyBinding, Shadow, GradientStop};
use api::{BoxShadowClipMode, LineStyle, LineOrientation};
use api::{BoxShadowClipMode, LineStyle, LineOrientation, BorderStyle};
use api::{PrimitiveKeyKind};
use api::units::*;
use crate::border::{get_max_scale_for_border, build_border_instances};
@ -650,6 +650,7 @@ impl From<PrimitiveKeyKind> for PrimitiveTemplateKind {
#[derive(MallocSizeOf)]
pub struct PrimTemplateCommonData {
pub is_backface_visible: bool,
pub may_need_repetition: bool,
pub prim_size: LayoutSize,
pub opacity: PrimitiveOpacity,
/// The GPU cache handle for a primitive template. Since this structure
@ -663,6 +664,7 @@ impl PrimTemplateCommonData {
pub fn with_key_common(common: PrimKeyCommonData) -> Self {
PrimTemplateCommonData {
is_backface_visible: common.is_backface_visible,
may_need_repetition: true,
prim_size: common.prim_size.into(),
gpu_cache_handle: GpuCacheHandle::new(),
opacity: PrimitiveOpacity::translucent(),
@ -2334,6 +2336,7 @@ impl PrimitiveStore {
match image_properties {
Some(ImageProperties { tiling: None, .. }) => {
frame_state.resource_cache.request_image(
request,
frame_state.gpu_cache,
@ -2373,6 +2376,10 @@ impl PrimitiveStore {
let stride = image_data.stretch_size + image_data.tile_spacing;
// We are performing the decomposition on the CPU here, no need to
// have it in the shader.
common_data.may_need_repetition = false;
let repetitions = crate::image::repetitions(
&prim_rect,
&visible_rect,
@ -2819,6 +2826,8 @@ impl PrimitiveStore {
let prim_data = &mut data_stores.text_run[*data_handle];
let run = &mut self.text_runs[*run_index];
prim_data.common.may_need_repetition = false;
// The transform only makes sense for screen space rasterization
let relative_transform = frame_context
.clip_scroll_tree
@ -2851,6 +2860,8 @@ impl PrimitiveStore {
PrimitiveInstanceKind::Clear { data_handle, .. } => {
let prim_data = &mut data_stores.prim[*data_handle];
prim_data.common.may_need_repetition = false;
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
prim_data.update(frame_state);
@ -2860,7 +2871,27 @@ impl PrimitiveStore {
let common_data = &mut prim_data.common;
let border_data = &mut prim_data.kind;
// Update the template this instane references, which may refresh the GPU
let mut needs_repetition = false;
needs_repetition |= match border_data.border.top.style {
BorderStyle::Dotted | BorderStyle::Dashed => true,
_ => false,
};
needs_repetition |= match border_data.border.right.style {
BorderStyle::Dotted | BorderStyle::Dashed => true,
_ => false,
};
needs_repetition |= match border_data.border.bottom.style {
BorderStyle::Dotted | BorderStyle::Dashed => true,
_ => false,
};
needs_repetition |= match border_data.border.left.style {
BorderStyle::Dotted | BorderStyle::Dashed => true,
_ => false,
};
common_data.may_need_repetition = needs_repetition;
// Update the template this instance references, which may refresh the GPU
// cache with any shared template data.
border_data.update(common_data, frame_state);
@ -2930,6 +2961,8 @@ impl PrimitiveStore {
}
PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
let prim_data = &mut data_stores.image_border[*data_handle];
// TODO: get access to the ninepatch and to check whwther we need support
// for repetitions in the shader.
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
@ -2937,6 +2970,7 @@ impl PrimitiveStore {
}
PrimitiveInstanceKind::Rectangle { data_handle, segment_instance_index, opacity_binding_index, .. } => {
let prim_data = &mut data_stores.prim[*data_handle];
prim_data.common.may_need_repetition = false;
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
@ -2963,6 +2997,8 @@ impl PrimitiveStore {
PrimitiveInstanceKind::YuvImage { data_handle, segment_instance_index, .. } => {
let yuv_image_data = &mut data_stores.yuv_image[*data_handle];
yuv_image_data.common.may_need_repetition = false;
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
yuv_image_data.kind.update(&mut yuv_image_data.common, frame_state);
@ -2982,6 +3018,12 @@ impl PrimitiveStore {
let common_data = &mut prim_data.common;
let image_data = &mut prim_data.kind;
if image_data.stretch_size.width >= common_data.prim_size.width &&
image_data.stretch_size.height >= common_data.prim_size.height {
common_data.may_need_repetition = false;
}
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
image_data.update(common_data, frame_state);
@ -3012,6 +3054,12 @@ impl PrimitiveStore {
// cache with any shared template data.
prim_data.update(frame_state);
if prim_data.stretch_size.width >= prim_data.common.prim_size.width &&
prim_data.stretch_size.height >= prim_data.common.prim_size.height {
prim_data.common.may_need_repetition = false;
}
if prim_data.supports_caching {
let gradient_size = (prim_data.end_point - prim_data.start_point).to_size();
@ -3085,6 +3133,10 @@ impl PrimitiveStore {
}
if prim_data.tile_spacing != LayoutSize::zero() {
// We are performing the decomposition on the CPU here, no need to
// have it in the shader.
prim_data.common.may_need_repetition = false;
let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
let prim_rect = LayoutRect::new(
prim_instance.prim_origin,
@ -3134,6 +3186,14 @@ impl PrimitiveStore {
PrimitiveInstanceKind::RadialGradient { data_handle, ref mut visible_tiles_range, .. } => {
let prim_data = &mut data_stores.radial_grad[*data_handle];
if prim_data.stretch_size.width >= prim_data.common.prim_size.width &&
prim_data.stretch_size.height >= prim_data.common.prim_size.height {
// We are performing the decomposition on the CPU here, no need to
// have it in the shader.
prim_data.common.may_need_repetition = false;
}
// Update the template this instane references, which may refresh the GPU
// cache with any shared template data.
prim_data.update(frame_state);
@ -3152,6 +3212,8 @@ impl PrimitiveStore {
frame_context.clip_scroll_tree,
);
prim_data.common.may_need_repetition = false;
*visible_tiles_range = decompose_repeated_primitive(
&prim_info.combined_local_clip_rect,
&prim_rect,
@ -3185,9 +3247,12 @@ impl PrimitiveStore {
// TODO(gw): Consider whether it's worth doing segment building
// for gradient primitives.
}
PrimitiveInstanceKind::Picture { pic_index, segment_instance_index, .. } => {
PrimitiveInstanceKind::Picture { pic_index, segment_instance_index, data_handle, .. } => {
let pic = &mut self.pictures[pic_index.0];
let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
data_stores.picture[*data_handle].common.may_need_repetition = false;
if pic.prepare_for_render(
frame_context,
frame_state,

Просмотреть файл

@ -44,7 +44,7 @@ use api::channel;
use api::units::*;
pub use api::DebugFlags;
use api::channel::{MsgSender, PayloadReceiverHelperMethods};
use crate::batch::{AlphaBatchContainer, BatchKind, BatchTextures, BrushBatchKind, ClipBatchList};
use crate::batch::{AlphaBatchContainer, BatchKind, BatchFeatures, BatchTextures, BrushBatchKind, ClipBatchList};
#[cfg(any(feature = "capture", feature = "replay"))]
use crate::capture::{CaptureConfig, ExternalCaptureImage, PlainExternalImage};
use crate::debug_colors;
@ -3465,7 +3465,7 @@ impl Renderer {
}
self.shaders.borrow_mut()
.get(&batch.key, self.debug_flags)
.get(&batch.key, batch.features, self.debug_flags)
.bind(
&mut self.device, projection,
&mut self.renderer_errors,
@ -3514,7 +3514,7 @@ impl Renderer {
}
self.shaders.borrow_mut()
.get(&batch.key, self.debug_flags)
.get(&batch.key, batch.features | BatchFeatures::ALPHA_PASS, self.debug_flags)
.bind(
&mut self.device, projection,
&mut self.renderer_errors,

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use crate::batch::{BatchKey, BatchKind, BrushBatchKind};
use crate::batch::{BatchKey, BatchKind, BrushBatchKind, BatchFeatures};
use crate::device::{Device, Program, ShaderError};
use euclid::{Transform3D};
use crate::glyph_rasterizer::GlyphFormat;
@ -516,6 +516,7 @@ pub struct Shaders {
// Brush shaders
brush_solid: BrushShader,
brush_image: Vec<Option<BrushShader>>,
brush_fast_image: Vec<Option<BrushShader>>,
brush_blend: BrushShader,
brush_mix_blend: BrushShader,
brush_yuv_image: Vec<Option<BrushShader>>,
@ -740,26 +741,45 @@ impl Shaders {
// All image configuration.
let mut image_features = Vec::new();
let mut brush_image = Vec::new();
let mut brush_fast_image = Vec::new();
// PrimitiveShader is not clonable. Use push() to initialize the vec.
for _ in 0 .. IMAGE_BUFFER_KINDS.len() {
brush_image.push(None);
brush_fast_image.push(None);
}
for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() {
if IMAGE_BUFFER_KINDS[buffer_kind].has_platform_support(&gl_type) {
let feature_string = IMAGE_BUFFER_KINDS[buffer_kind].get_feature_string();
if feature_string != "" {
image_features.push(feature_string);
}
brush_image[buffer_kind] = Some(BrushShader::new(
"brush_image",
device,
&image_features,
options.precache_flags,
options.allow_advanced_blend_equation,
options.allow_dual_source_blending,
use_pixel_local_storage,
)?);
if !IMAGE_BUFFER_KINDS[buffer_kind].has_platform_support(&gl_type) {
continue;
}
let feature_string = IMAGE_BUFFER_KINDS[buffer_kind].get_feature_string();
if feature_string != "" {
image_features.push(feature_string);
}
brush_fast_image[buffer_kind] = Some(BrushShader::new(
"brush_image",
device,
&image_features,
options.precache_flags,
options.allow_advanced_blend_equation,
options.allow_dual_source_blending,
use_pixel_local_storage,
)?);
image_features.push("REPETITION");
image_features.push("ANTIALIASING");
brush_image[buffer_kind] = Some(BrushShader::new(
"brush_image",
device,
&image_features,
options.precache_flags,
options.allow_advanced_blend_equation,
options.allow_dual_source_blending,
use_pixel_local_storage,
)?);
image_features.clear();
}
@ -838,6 +858,7 @@ impl Shaders {
cs_scale_rgba8,
brush_solid,
brush_image,
brush_fast_image,
brush_blend,
brush_mix_blend,
brush_yuv_image,
@ -859,7 +880,7 @@ impl Shaders {
(buffer_kind as usize)
}
pub fn get(&mut self, key: &BatchKey, debug_flags: DebugFlags) -> &mut LazilyCompiledShader {
pub fn get(&mut self, key: &BatchKey, features: BatchFeatures, debug_flags: DebugFlags) -> &mut LazilyCompiledShader {
match key.kind {
BatchKind::SplitComposite => {
&mut self.ps_split_composite
@ -870,9 +891,18 @@ impl Shaders {
&mut self.brush_solid
}
BrushBatchKind::Image(image_buffer_kind) => {
self.brush_image[image_buffer_kind as usize]
.as_mut()
.expect("Unsupported image shader kind")
if features.contains(BatchFeatures::ANTIALIASING) ||
features.contains(BatchFeatures::REPETITION) ||
!features.contains(BatchFeatures::ALPHA_PASS) {
self.brush_image[image_buffer_kind as usize]
.as_mut()
.expect("Unsupported image shader kind")
} else {
self.brush_fast_image[image_buffer_kind as usize]
.as_mut()
.expect("Unsupported image shader kind")
}
}
BrushBatchKind::Blend => {
&mut self.brush_blend
@ -929,6 +959,11 @@ impl Shaders {
shader.deinit(device);
}
}
for shader in self.brush_fast_image {
if let Some(shader) = shader {
shader.deinit(device);
}
}
for shader in self.brush_yuv_image {
if let Some(shader) = shader {
shader.deinit(device);

Просмотреть файл

@ -4035,7 +4035,7 @@ nsresult SVGTextFrame::GetEndPositionOfChar(nsIContent* aContent,
* text content element.
*/
nsresult SVGTextFrame::GetExtentOfChar(nsIContent* aContent, uint32_t aCharNum,
SVGIRect** aResult) {
SVGRect** aResult) {
nsIFrame* kid = PrincipalChildList().FirstChild();
if (NS_SUBTREE_DIRTY(kid)) {
// We're never reflowed if we're under a non-SVG element that is
@ -4088,7 +4088,7 @@ nsresult SVGTextFrame::GetExtentOfChar(nsIContent* aContent, uint32_t aCharNum,
// Transform the glyph's rect into user space.
gfxRect r = m.TransformBounds(glyphRect);
RefPtr<SVGRect> rect = new SVGRect(aContent, r.x, r.y, r.width, r.height);
RefPtr<SVGRect> rect = new SVGRect(aContent, ToRect(r));
rect.forget(aResult);
return NS_OK;
}

Просмотреть файл

@ -35,7 +35,7 @@ class TextRenderedRunIterator;
namespace dom {
struct DOMPointInit;
class SVGIRect;
class SVGRect;
class SVGGeometryElement;
} // namespace dom
@ -247,7 +247,7 @@ class SVGTextFrame final : public nsSVGDisplayContainerFrame {
nsresult GetEndPositionOfChar(nsIContent* aContent, uint32_t aCharNum,
mozilla::nsISVGPoint** aResult);
nsresult GetExtentOfChar(nsIContent* aContent, uint32_t aCharNum,
mozilla::dom::SVGIRect** aResult);
mozilla::dom::SVGRect** aResult);
nsresult GetRotationOfChar(nsIContent* aContent, uint32_t aCharNum,
float* aResult);

Просмотреть файл

@ -567,6 +567,11 @@ bool DataChannelConnection::Init(const uint16_t aLocalPort,
}
}
// Update number of streams
mStreams.AppendElements(aNumStreams);
for (uint32_t i = 0; i < aNumStreams; ++i) {
mStreams[i] = nullptr;
}
memset(&initmsg, 0, sizeof(initmsg));
len = sizeof(initmsg);
if (usrsctp_getsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
@ -662,27 +667,20 @@ bool DataChannelConnection::ConnectToTransport(const std::string& aTransportId,
mLocalPort = localport;
mRemotePort = remoteport;
mState = CONNECTING;
mAllocateEven = Some(aClient);
// Could be faster. Probably doesn't matter.
while (auto channel = mChannels.Get(INVALID_STREAM)) {
mChannels.Remove(channel);
channel->mStream = FindFreeStream();
if (channel->mStream != INVALID_STREAM) {
mChannels.Insert(channel);
}
}
RUN_ON_THREAD(mSTS,
WrapRunnable(RefPtr<DataChannelConnection>(this),
&DataChannelConnection::SetSignals, aTransportId),
NS_DISPATCH_NORMAL);
RUN_ON_THREAD(
mSTS,
WrapRunnable(RefPtr<DataChannelConnection>(this),
&DataChannelConnection::SetSignals, aTransportId, aClient),
NS_DISPATCH_NORMAL);
return true;
}
void DataChannelConnection::SetSignals(const std::string& aTransportId) {
void DataChannelConnection::SetSignals(const std::string& aTransportId,
bool aClient) {
ASSERT_WEBRTC(IsSTSThread());
mTransportId = aTransportId;
mAllocateEven = aClient;
mTransportHandler->SignalPacketReceived.connect(
this, &DataChannelConnection::SctpDtlsInput);
// SignalStateChange() doesn't call you with the initial state
@ -1027,47 +1025,48 @@ bool DataChannelConnection::Connect(const char* addr, unsigned short port) {
#endif
DataChannel* DataChannelConnection::FindChannelByStream(uint16_t stream) {
return mChannels.Get(stream).get();
return mStreams.SafeElementAt(stream);
}
uint16_t DataChannelConnection::FindFreeStream() {
ASSERT_WEBRTC(NS_IsMainThread());
uint16_t i, limit;
uint32_t i, j, limit;
limit = MAX_NUM_STREAMS;
limit = mStreams.Length();
if (limit > MAX_NUM_STREAMS) limit = MAX_NUM_STREAMS;
MOZ_ASSERT(mAllocateEven.isSome());
for (i = (*mAllocateEven ? 0 : 1); i < limit; i += 2) {
if (mChannels.Get(i)) {
continue;
}
// Verify it's not still in the process of closing
size_t j;
for (j = 0; j < mStreamsResetting.Length(); ++j) {
if (mStreamsResetting[j] == i) {
break;
for (i = (mAllocateEven ? 0 : 1); i < limit; i += 2) {
if (!mStreams[i]) {
// Verify it's not still in the process of closing
for (j = 0; j < mStreamsResetting.Length(); ++j) {
if (mStreamsResetting[j] == i) {
break;
}
}
}
if (j == mStreamsResetting.Length()) {
return i;
if (j == mStreamsResetting.Length()) break;
}
}
return INVALID_STREAM;
if (i >= limit) {
return INVALID_STREAM;
}
return i;
}
uint32_t DataChannelConnection::UpdateCurrentStreamIndex() {
RefPtr<DataChannel> channel = mChannels.GetNextChannel(mCurrentStream);
if (!channel) {
if (mCurrentStream == mStreams.Length() - 1) {
mCurrentStream = 0;
} else {
mCurrentStream = channel->mStream;
++mCurrentStream;
}
return mCurrentStream;
}
uint32_t DataChannelConnection::GetCurrentStreamIndex() {
// Fix current stream index (in case #streams decreased)
if (mCurrentStream >= mStreams.Length()) {
mCurrentStream = 0;
}
return mCurrentStream;
}
@ -1077,8 +1076,8 @@ bool DataChannelConnection::RequestMoreStreams(int32_t aNeeded) {
uint32_t outStreamsNeeded;
socklen_t len;
if (aNeeded + mNegotiatedIdLimit > MAX_NUM_STREAMS) {
aNeeded = MAX_NUM_STREAMS - mNegotiatedIdLimit;
if (aNeeded + mStreams.Length() > MAX_NUM_STREAMS) {
aNeeded = MAX_NUM_STREAMS - mStreams.Length();
}
if (aNeeded <= 0) {
return false;
@ -1109,8 +1108,8 @@ bool DataChannelConnection::RequestMoreStreams(int32_t aNeeded) {
return false;
}
LOG(("Requested %u more streams", outStreamsNeeded));
// We add to mNegotiatedIdLimit when we get a SCTP_STREAM_CHANGE_EVENT and the
// values are larger than mNegotiatedIdLimit
// We add to mStreams when we get a SCTP_STREAM_CHANGE_EVENT and the
// values are larger than mStreams.Length()
return true;
}
@ -1218,7 +1217,6 @@ bool DataChannelConnection::SendDeferredMessages() {
// This may block while something is modifying channels, but should not block
// for IO
ASSERT_WEBRTC(!NS_IsMainThread());
mLock.AssertCurrentThreadOwns();
LOG(("SendDeferredMessages called, pending type: %d", mPendingType));
@ -1244,7 +1242,7 @@ bool DataChannelConnection::SendDeferredMessages() {
uint32_t i = GetCurrentStreamIndex();
uint32_t end = i;
do {
channel = mChannels.Get(i);
channel = mStreams[i];
// Should already be cleared if closing/closed
if (!channel || channel->mBufferedData.IsEmpty()) {
i = UpdateCurrentStreamIndex();
@ -1321,7 +1319,6 @@ void DataChannelConnection::HandleOpenRequestMessage(
uint32_t prValue;
uint16_t prPolicy;
ASSERT_WEBRTC(!NS_IsMainThread());
mLock.AssertCurrentThreadOwns();
const size_t requiredLength = (sizeof(*req) - 1) + ntohs(req->label_length) +
@ -1357,7 +1354,7 @@ void DataChannelConnection::HandleOpenRequestMessage(
bool ordered = !(req->channel_type & 0x80);
if ((channel = FindChannelByStream(stream))) {
if (!channel->mNegotiated) {
if (!(channel->mFlags & DATA_CHANNEL_FLAGS_EXTERNAL_NEGOTIATED)) {
LOG(
("ERROR: HandleOpenRequestMessage: channel for pre-existing stream "
"%u that was not externally negotiated. JS is lying to us, or "
@ -1378,9 +1375,9 @@ void DataChannelConnection::HandleOpenRequestMessage(
}
return;
}
if (stream >= mNegotiatedIdLimit) {
if (stream >= mStreams.Length()) {
LOG(("%s: stream %u out of bounds (%zu)", __FUNCTION__, stream,
mNegotiatedIdLimit));
mStreams.Length()));
return;
}
@ -1392,7 +1389,7 @@ void DataChannelConnection::HandleOpenRequestMessage(
channel =
new DataChannel(this, stream, DataChannel::OPEN, label, protocol,
prPolicy, prValue, ordered, false, nullptr, nullptr);
mChannels.Insert(channel);
mStreams[stream] = channel;
LOG(("%s: sending ON_CHANNEL_CREATED for %s/%s: %u", __FUNCTION__,
channel->mLabel.get(), channel->mProtocol.get(), stream));
@ -1564,7 +1561,8 @@ void DataChannelConnection::HandleDataMessage(const void* data, size_t length,
"closing",
data_length));
// Only unblock if unordered
if (!channel->mOrdered && (flags & MSG_EOR)) {
if ((channel->mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED) &&
(flags & MSG_EOR)) {
channel->mFlags &= ~DATA_CHANNEL_FLAGS_CLOSING_TOO_LARGE;
}
}
@ -1991,9 +1989,7 @@ void DataChannelConnection::ClearResets() {
if (channel) {
LOG(("Forgetting channel %u (%p) with pending reset", channel->mStream,
channel.get()));
// TODO: Do we _really_ want to remove this? Are we allowed to reuse the
// id?
mChannels.Remove(channel);
mStreams[channel->mStream] = nullptr;
}
}
mStreamsResetting.Clear();
@ -2075,10 +2071,11 @@ void DataChannelConnection::HandleStreamResetEvent(
// yet.
LOG(("Incoming: Channel %u closed", channel->mStream));
if (mChannels.Remove(channel)) {
if (mStreams[channel->mStream]) {
// Mark the stream for reset (the reset is sent below)
ResetOutgoingStream(channel->mStream);
}
mStreams[channel->mStream] = nullptr;
LOG(("Disconnected DataChannel %p from connection %p",
(void*)channel.get(), (void*)channel->mConnection.get()));
@ -2099,43 +2096,48 @@ void DataChannelConnection::HandleStreamResetEvent(
void DataChannelConnection::HandleStreamChangeEvent(
const struct sctp_stream_change_event* strchg) {
ASSERT_WEBRTC(!NS_IsMainThread());
uint16_t stream;
RefPtr<DataChannel> channel;
if (strchg->strchange_flags == SCTP_STREAM_CHANGE_DENIED) {
LOG(("*** Failed increasing number of streams from %zu (%u/%u)",
mNegotiatedIdLimit, strchg->strchange_instrms,
mStreams.Length(), strchg->strchange_instrms,
strchg->strchange_outstrms));
// XXX FIX! notify pending opens of failure
return;
}
if (strchg->strchange_instrms > mNegotiatedIdLimit) {
LOG(("Other side increased streams from %zu to %u", mNegotiatedIdLimit,
if (strchg->strchange_instrms > mStreams.Length()) {
LOG(("Other side increased streams from %zu to %u", mStreams.Length(),
strchg->strchange_instrms));
}
uint16_t old_limit = mNegotiatedIdLimit;
uint16_t new_limit =
std::max(strchg->strchange_outstrms, strchg->strchange_instrms);
if (new_limit > mNegotiatedIdLimit) {
if (strchg->strchange_outstrms > mStreams.Length() ||
strchg->strchange_instrms > mStreams.Length()) {
uint16_t old_len = mStreams.Length();
uint16_t new_len =
std::max(strchg->strchange_outstrms, strchg->strchange_instrms);
LOG(("Increasing number of streams from %u to %u - adding %u (in: %u)",
old_limit, new_limit, new_limit - old_limit,
strchg->strchange_instrms));
old_len, new_len, new_len - old_len, strchg->strchange_instrms));
// make sure both are the same length
mNegotiatedIdLimit = new_limit;
LOG(("New length = %zu (was %d)", mNegotiatedIdLimit, old_limit));
mStreams.AppendElements(new_len - old_len);
LOG(("New length = %zu (was %d)", mStreams.Length(), old_len));
for (size_t i = old_len; i < mStreams.Length(); ++i) {
mStreams[i] = nullptr;
}
// Re-process any channels waiting for streams.
// Linear search, but we don't increase channels often and
// the array would only get long in case of an app error normally
// Make sure we request enough streams if there's a big jump in streams
// Could make a more complex API for OpenXxxFinish() and avoid this loop
auto channels = mChannels.GetAll();
size_t num_needed =
channels.Length() ? (channels.LastElement()->mStream + 1) : 0;
MOZ_ASSERT(num_needed != INVALID_STREAM);
if (num_needed > new_limit) {
int32_t more_needed = num_needed - ((int32_t)mNegotiatedIdLimit) + 16;
LOG(("Not enough new streams, asking for %d more", more_needed));
size_t num_needed = mPending.GetSize();
LOG(("%zu of %d new streams already needed", num_needed,
new_len - old_len));
num_needed -= (new_len - old_len); // number we added
if (num_needed > 0) {
if (num_needed < 16) num_needed = 16;
LOG(("Not enough new streams, asking for %zu more", num_needed));
// TODO: parameter is an int32_t but we pass size_t
RequestMoreStreams(more_needed);
RequestMoreStreams(num_needed);
} else if (strchg->strchange_outstrms < strchg->strchange_instrms) {
LOG(("Requesting %d output streams to match partner",
strchg->strchange_instrms - strchg->strchange_outstrms));
@ -2147,14 +2149,41 @@ void DataChannelConnection::HandleStreamChangeEvent(
}
// else probably not a change in # of streams
if ((strchg->strchange_flags & SCTP_STREAM_CHANGE_DENIED) ||
(strchg->strchange_flags & SCTP_STREAM_CHANGE_FAILED)) {
// Other side denied our request. Need to AnnounceClosed some stuff.
for (auto& channel : mChannels.GetAll()) {
if (channel->mStream >= mNegotiatedIdLimit) {
for (uint32_t i = 0; i < mStreams.Length(); ++i) {
channel = mStreams[i];
if (!channel) continue;
if (channel->mStream == INVALID_STREAM) {
if ((strchg->strchange_flags & SCTP_STREAM_CHANGE_DENIED) ||
(strchg->strchange_flags & SCTP_STREAM_CHANGE_FAILED)) {
/* XXX: Signal to the other end. */
channel->AnnounceClosed();
// maybe fire onError (bug 843625)
} else {
stream = FindFreeStream();
if (stream != INVALID_STREAM) {
channel->mStream = stream;
mStreams[stream] = channel;
// Send open request
int error = SendOpenRequestMessage(
channel->mLabel, channel->mProtocol, channel->mStream,
!!(channel->mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED),
channel->mPrPolicy, channel->mPrValue);
if (error) {
LOG(("SendOpenRequest failed, error = %d", error));
// Close the channel, inform the user
mStreams[channel->mStream] = nullptr;
channel->AnnounceClosed();
// Don't need to reset; we didn't open it
} else {
channel->mFlags |= DATA_CHANNEL_FLAGS_READY;
channel->AnnounceOpen();
}
} else {
/* We will not find more ... */
break;
}
}
}
}
@ -2250,18 +2279,9 @@ already_AddRefed<DataChannel> DataChannelConnection::Open(
const nsACString& label, const nsACString& protocol, Type type,
bool inOrder, uint32_t prValue, DataChannelListener* aListener,
nsISupports* aContext, bool aExternalNegotiated, uint16_t aStream) {
ASSERT_WEBRTC(NS_IsMainThread());
if (!aExternalNegotiated) {
if (mAllocateEven.isSome()) {
aStream = FindFreeStream();
if (aStream == INVALID_STREAM) {
return nullptr;
}
} else {
// We do not yet know whether we are client or server, and an id has not
// been chosen for us. We will need to choose later.
aStream = INVALID_STREAM;
}
// aStream == INVALID_STREAM to have the protocol allocate
aStream = INVALID_STREAM;
}
uint16_t prPolicy = SCTP_PR_SCTP_NONE;
@ -2290,7 +2310,9 @@ already_AddRefed<DataChannel> DataChannelConnection::Open(
return nullptr;
}
if (aStream != INVALID_STREAM && mChannels.Get(aStream)) {
// Don't look past currently-negotiated streams
if (aStream != INVALID_STREAM && aStream < mStreams.Length() &&
mStreams[aStream]) {
LOG(("ERROR: external negotiation of already-open channel %u", aStream));
// XXX How do we indicate this up to the application? Probably the
// caller's job, but we may need to return an error code.
@ -2300,7 +2322,6 @@ already_AddRefed<DataChannel> DataChannelConnection::Open(
RefPtr<DataChannel> channel(new DataChannel(
this, aStream, DataChannel::CONNECTING, label, protocol, prPolicy,
prValue, inOrder, aExternalNegotiated, aListener, aContext));
mChannels.Insert(channel);
MutexAutoLock lock(mLock); // OpenFinish assumes this
return OpenFinish(channel.forget());
@ -2312,7 +2333,7 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
RefPtr<DataChannel> channel(aChannel); // takes the reference passed in
// Normally 1 reference if called from ::Open(), or 2 if called from
// ProcessQueuedOpens() unless the DOMDataChannel was gc'd
const uint16_t stream = channel->mStream;
uint16_t stream = channel->mStream;
bool queue = false;
mLock.AssertCurrentThreadOwns();
@ -2342,12 +2363,16 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
// either change the initial ask or possibly renegotiate after open.
if (mState == OPEN) {
MOZ_ASSERT(stream != INVALID_STREAM);
if (stream >= mNegotiatedIdLimit) {
if (stream == INVALID_STREAM) {
stream = FindFreeStream(); // may be INVALID_STREAM if we need more
}
if (stream == INVALID_STREAM || stream >= mStreams.Length()) {
// RequestMoreStreams() limits to MAX_NUM_STREAMS -- allocate extra
// streams to avoid going back immediately for more if the ask to N, N+1,
// etc
int32_t more_needed = stream - ((int32_t)mNegotiatedIdLimit) + 16;
int32_t more_needed = (stream == INVALID_STREAM)
? 16
: (stream - ((int32_t)mStreams.Length())) + 16;
if (!RequestMoreStreams(more_needed)) {
// Something bad happened... we're done
goto request_error_cleanup;
@ -2356,13 +2381,12 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
}
} else {
// not OPEN
if (stream != INVALID_STREAM && stream >= mNegotiatedIdLimit &&
if (stream != INVALID_STREAM && stream >= mStreams.Length() &&
mState == CLOSED) {
// Update number of streams for init message
struct sctp_initmsg initmsg;
socklen_t len = sizeof(initmsg);
uint16_t total_needed =
(stream < UINT16_MAX - 16) ? stream + 16 : UINT16_MAX;
int32_t total_needed = stream + 16;
memset(&initmsg, 0, sizeof(initmsg));
if (usrsctp_getsockopt(mMasterSocket, IPPROTO_SCTP, SCTP_INITMSG,
@ -2379,6 +2403,12 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
LOG(("*** failed setsockopt SCTP_INITMSG, errno %d", errno));
goto request_error_cleanup;
}
int32_t old_len = mStreams.Length();
mStreams.AppendElements(total_needed - old_len);
for (int32_t i = old_len; i < total_needed; ++i) {
mStreams[i] = nullptr;
}
}
// else if state is CONNECTING, we'll just re-negotiate when OpenFinish
// is called, if needed
@ -2396,24 +2426,28 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
}
MOZ_ASSERT(stream != INVALID_STREAM);
MOZ_ASSERT(stream < mNegotiatedIdLimit);
// just allocated (& OPEN), or externally negotiated
mStreams[stream] = channel; // holds a reference
channel->mStream = stream;
#ifdef TEST_QUEUED_DATA
// It's painful to write a test for this...
channel->AnnounceOpen();
channel->mFlags |= DATA_CHANNEL_FLAGS_READY;
SendDataMsgInternalOrBuffer(channel, "Help me!", 8,
DATA_CHANNEL_PPID_DOMSTRING);
#endif
if (!channel->mOrdered) {
if (channel->mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED) {
// Don't send unordered until this gets cleared
channel->mFlags |= DATA_CHANNEL_FLAGS_WAITING_ACK;
}
if (!channel->mNegotiated) {
int error = SendOpenRequestMessage(channel->mLabel, channel->mProtocol,
stream, !channel->mOrdered,
channel->mPrPolicy, channel->mPrValue);
if (!(channel->mFlags & DATA_CHANNEL_FLAGS_EXTERNAL_NEGOTIATED)) {
int error = SendOpenRequestMessage(
channel->mLabel, channel->mProtocol, stream,
!!(channel->mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED),
channel->mPrPolicy, channel->mPrValue);
if (error) {
LOG(("SendOpenRequest failed, error = %d", error));
if (channel->mFlags & DATA_CHANNEL_FLAGS_FINISH_OPEN) {
@ -2423,7 +2457,8 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
}
// If we haven't returned the channel yet, it will get destroyed when we
// exit this function.
mChannels.Remove(channel);
mStreams[stream] = nullptr;
channel->mStream = INVALID_STREAM;
// we'll be destroying the channel
return nullptr;
/* NOTREACHED */
@ -2431,6 +2466,7 @@ already_AddRefed<DataChannel> DataChannelConnection::OpenFinish(
}
// Either externally negotiated or we sent Open
channel->mFlags |= DATA_CHANNEL_FLAGS_READY;
// FIX? Move into DOMDataChannel? I don't think we can send it yet here
channel->AnnounceOpen();
@ -2614,12 +2650,12 @@ int DataChannelConnection::SendDataMsgInternalOrBuffer(DataChannel& channel,
info.sendv_sndinfo.snd_flags = SCTP_EOR;
info.sendv_sndinfo.snd_ppid = htonl(ppid);
MutexAutoLock lock(mLock); // Need to protect mFlags... :(
// Unordered?
// To avoid problems where an in-order OPEN is lost and an
// out-of-order data message "beats" it, require data to be in-order
// until we get an ACK.
if (!channel.mOrdered && !(channel.mFlags & DATA_CHANNEL_FLAGS_WAITING_ACK)) {
if ((channel.mFlags & DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED) &&
!(channel.mFlags & DATA_CHANNEL_FLAGS_WAITING_ACK)) {
info.sendv_sndinfo.snd_flags |= SCTP_UNORDERED;
}
@ -2632,6 +2668,7 @@ int DataChannelConnection::SendDataMsgInternalOrBuffer(DataChannel& channel,
// Create message instance and send
OutgoingMsg msg(info, data, len);
MutexAutoLock lock(mLock);
bool buffered;
size_t written = 0;
mDeferSend = true;
@ -2706,7 +2743,7 @@ class ReadBlobRunnable : public Runnable {
// Returns a POSIX error code.
int DataChannelConnection::SendBlob(uint16_t stream, nsIInputStream* aBlob) {
RefPtr<DataChannel> channel = mChannels.Get(stream);
DataChannel* channel = mStreams[stream];
if (NS_WARN_IF(!channel)) {
return EINVAL; // TODO: Find a better error code
}
@ -2792,6 +2829,15 @@ void DataChannelConnection::ReadBlob(
Dispatch(runnable.forget());
}
void DataChannelConnection::GetStreamIds(std::vector<uint16_t>* aStreamList) {
ASSERT_WEBRTC(NS_IsMainThread());
for (uint32_t i = 0; i < mStreams.Length(); ++i) {
if (mStreams[i]) {
aStreamList->push_back(mStreams[i]->mStream);
}
}
}
// Returns a POSIX error code.
int DataChannelConnection::SendDataMsgCommon(uint16_t stream,
const nsACString& aMsg,
@ -2799,7 +2845,7 @@ int DataChannelConnection::SendDataMsgCommon(uint16_t stream,
ASSERT_WEBRTC(NS_IsMainThread());
// We really could allow this from other threads, so long as we deal with
// asynchronosity issues with channels closing, in particular access to
// mChannels, and issues with the association closing (access to mSocket).
// mStreams, and issues with the association closing (access to mSocket).
const uint8_t* data = (const uint8_t*)aMsg.BeginReading();
uint32_t len = aMsg.Length();
@ -2808,11 +2854,12 @@ int DataChannelConnection::SendDataMsgCommon(uint16_t stream,
return EMSGSIZE;
}
#endif
DataChannel* channelPtr;
LOG(("Sending %sto stream %u: %u bytes", isBinary ? "binary " : "", stream,
len));
// XXX if we want more efficiency, translate flags once at open time
RefPtr<DataChannel> channelPtr = mChannels.Get(stream);
channelPtr = mStreams[stream];
if (NS_WARN_IF(!channelPtr)) {
return EINVAL; // TODO: Find a better error code
}
@ -2847,24 +2894,24 @@ void DataChannelConnection::CloseInt(DataChannel* aChannel) {
mLock.AssertCurrentThreadOwns();
LOG(("Connection %p/Channel %p: Closing stream %u",
channel->mConnection.get(), channel.get(), channel->mStream));
aChannel->mBufferedData.Clear();
if (mState == CLOSED) {
// If we're CLOSING, we might leave this in place until we can send a
// reset.
mChannels.Remove(channel);
}
// re-test since it may have closed before the lock was grabbed
if (aChannel->mReadyState == CLOSED || aChannel->mReadyState == CLOSING) {
LOG(("Channel already closing/closed (%u)", aChannel->mReadyState));
if (mState == CLOSED && channel->mStream != INVALID_STREAM) {
// called from CloseAll()
// we're not going to hang around waiting any more
mStreams[channel->mStream] = nullptr;
}
return;
}
aChannel->mBufferedData.Clear();
if (channel->mStream != INVALID_STREAM) {
ResetOutgoingStream(channel->mStream);
if (mState != CLOSED) {
// Individual channel is being closed, send reset now.
if (mState == CLOSED) { // called from CloseAll()
// Let resets accumulate then send all at once in CloseAll()
// we're not going to hang around waiting
mStreams[channel->mStream] = nullptr;
} else {
SendOutgoingStreamReset();
}
}
@ -2890,8 +2937,12 @@ void DataChannelConnection::CloseAll() {
// Close current channels
// If there are runnables, they hold a strong ref and keep the channel
// and/or connection alive (even if in a CLOSED state)
for (auto& channel : mChannels.GetAll()) {
channel->Close();
bool closed_some = false;
for (uint32_t i = 0; i < mStreams.Length(); ++i) {
if (mStreams[i]) {
mStreams[i]->Close();
closed_some = true;
}
}
// Clean up any pending opens for channels
@ -2901,78 +2952,14 @@ void DataChannelConnection::CloseAll() {
LOG(("closing pending channel %p, stream %u", channel.get(),
channel->mStream));
channel->Close(); // also releases the ref on each iteration
closed_some = true;
}
// It's more efficient to let the Resets queue in shutdown and then
// SendOutgoingStreamReset() here.
MutexAutoLock lock(mLock);
SendOutgoingStreamReset();
}
bool DataChannelConnection::Channels::IdComparator::Equals(
const RefPtr<DataChannel>& aChannel, uint16_t aId) const {
return aChannel->mStream == aId;
}
bool DataChannelConnection::Channels::IdComparator::LessThan(
const RefPtr<DataChannel>& aChannel, uint16_t aId) const {
return aChannel->mStream < aId;
}
bool DataChannelConnection::Channels::IdComparator::Equals(
const RefPtr<DataChannel>& a1, const RefPtr<DataChannel>& a2) const {
return Equals(a1, a2->mStream);
}
bool DataChannelConnection::Channels::IdComparator::LessThan(
const RefPtr<DataChannel>& a1, const RefPtr<DataChannel>& a2) const {
return LessThan(a1, a2->mStream);
}
void DataChannelConnection::Channels::Insert(
const RefPtr<DataChannel>& aChannel) {
LOG(("Inserting channel %u : %p", aChannel->mStream, aChannel.get()));
MutexAutoLock lock(mMutex);
if (aChannel->mStream != INVALID_STREAM) {
MOZ_ASSERT(!mChannels.ContainsSorted(aChannel, IdComparator()));
if (closed_some) {
MutexAutoLock lock(mLock);
SendOutgoingStreamReset();
}
MOZ_ASSERT(!mChannels.Contains(aChannel));
mChannels.InsertElementSorted(aChannel, IdComparator());
}
bool DataChannelConnection::Channels::Remove(
const RefPtr<DataChannel>& aChannel) {
LOG(("Removing channel %u : %p", aChannel->mStream, aChannel.get()));
MutexAutoLock lock(mMutex);
if (aChannel->mStream == INVALID_STREAM) {
return mChannels.RemoveElement(aChannel);
}
return mChannels.RemoveElementSorted(aChannel, IdComparator());
}
RefPtr<DataChannel> DataChannelConnection::Channels::Get(uint16_t aId) const {
MutexAutoLock lock(mMutex);
auto index = mChannels.BinaryIndexOf(aId, IdComparator());
if (index == ChannelArray::NoIndex) {
return nullptr;
}
return mChannels[index];
}
RefPtr<DataChannel> DataChannelConnection::Channels::GetNextChannel(
uint16_t aCurrentId) const {
MutexAutoLock lock(mMutex);
if (mChannels.IsEmpty()) {
return nullptr;
}
auto index = mChannels.IndexOfFirstElementGt(aCurrentId, IdComparator());
if (index == mChannels.Length()) {
index = 0;
}
return mChannels[index];
}
DataChannel::~DataChannel() {
@ -2999,6 +2986,8 @@ void DataChannel::StreamClosedLocked() {
LOG(("Destroying Data channel %u", mStream));
MOZ_ASSERT_IF(mStream != INVALID_STREAM,
!mConnection->FindChannelByStream(mStream));
// Spec doesn't say to mess with the stream id...
mStream = INVALID_STREAM;
AnnounceClosed();
// We leave mConnection live until the DOM releases us, to avoid races
}

Просмотреть файл

@ -164,7 +164,7 @@ class DataChannelConnection final : public net::NeckoTargetHolder
void TransportStateChange(const std::string& aTransportId,
TransportLayer::State aState);
void CompleteConnect();
void SetSignals(const std::string& aTransportId);
void SetSignals(const std::string& aTransportId, bool aClient);
#endif
typedef enum {
@ -216,6 +216,8 @@ class DataChannelConnection final : public net::NeckoTargetHolder
void ReadBlob(already_AddRefed<DataChannelConnection> aThis, uint16_t aStream,
nsIInputStream* aBlob);
void GetStreamIds(std::vector<uint16_t>* aStreamList);
bool SendDeferredMessages();
protected:
@ -308,47 +310,16 @@ class DataChannelConnection final : public net::NeckoTargetHolder
}
#endif
class Channels {
public:
Channels() : mMutex("DataChannelConnection::Channels::mMutex") {}
void Insert(const RefPtr<DataChannel>& aChannel);
bool Remove(const RefPtr<DataChannel>& aChannel);
RefPtr<DataChannel> Get(uint16_t aId) const;
typedef AutoTArray<RefPtr<DataChannel>, 16> ChannelArray;
ChannelArray GetAll() const {
MutexAutoLock lock(mMutex);
return mChannels;
}
RefPtr<DataChannel> GetNextChannel(uint16_t aCurrentId) const;
private:
struct IdComparator {
bool Equals(const RefPtr<DataChannel>& aChannel, uint16_t aId) const;
bool LessThan(const RefPtr<DataChannel>& aChannel, uint16_t aId) const;
bool Equals(const RefPtr<DataChannel>& a1,
const RefPtr<DataChannel>& a2) const;
bool LessThan(const RefPtr<DataChannel>& a1,
const RefPtr<DataChannel>& a2) const;
};
mutable Mutex mMutex;
ChannelArray mChannels;
};
bool mSendInterleaved = false;
bool mMaxMessageSizeSet = false;
uint64_t mMaxMessageSize = 0;
// Main thread only
Maybe<bool> mAllocateEven;
bool mAllocateEven = false;
// Data:
// NOTE: while this container will auto-expand, increases in the number of
// NOTE: while this array will auto-expand, increases in the number of
// channels available from the stack must be negotiated!
// Accessed from both main and sts, API is threadsafe
Channels mChannels;
// STS only
AutoTArray<RefPtr<DataChannel>, 16> mStreams;
uint32_t mCurrentStream = 0;
nsDeque mPending; // Holds addref'ed DataChannel's -- careful!
// STS and main
size_t mNegotiatedIdLimit = 0; // GUARDED_BY(mConnection->mLock)
uint8_t mPendingType = PENDING_NONE;
// holds data that's come in before a channel is open
nsTArray<nsAutoPtr<QueuedDataMessage>> mQueuedData;
@ -356,8 +327,8 @@ class DataChannelConnection final : public net::NeckoTargetHolder
nsTArray<nsAutoPtr<BufferedOutgoingMsg>>
mBufferedControl; // GUARDED_BY(mConnection->mLock)
// Streams pending reset. Accessed from main and STS.
AutoTArray<uint16_t, 4> mStreamsResetting; // GUARDED_BY(mConnection->mLock)
// Streams pending reset
AutoTArray<uint16_t, 4> mStreamsResetting;
// accessed from STS thread
struct socket* mMasterSocket = nullptr;
// cloned from mMasterSocket on successful Connect on STS thread
@ -414,10 +385,17 @@ class DataChannel {
mNegotiated(negotiated),
mOrdered(ordered),
mFlags(0),
mId(0),
mIsRecvBinary(false),
mBufferedThreshold(0), // default from spec
mBufferedAmount(0),
mMainThreadEventTarget(connection->GetNeckoTarget()) {
if (!ordered) {
mFlags |= DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED;
}
if (negotiated) {
mFlags |= DATA_CHANNEL_FLAGS_EXTERNAL_NEGOTIATED;
}
NS_ASSERTION(mConnection, "NULL connection");
}
@ -515,10 +493,10 @@ class DataChannel {
uint16_t mStream;
uint16_t mPrPolicy;
uint32_t mPrValue;
// Accessed on main and STS
const bool mNegotiated;
const bool mOrdered;
uint32_t mFlags;
uint32_t mId;
bool mIsRecvBinary;
size_t mBufferedThreshold;
// Read/written on main only. Decremented via message-passing, because the

Просмотреть файл

@ -36,7 +36,10 @@
#define DATA_CHANNEL_MAX_BINARY_FRAGMENT 0x4000
#define DATA_CHANNEL_FLAGS_READY 0x00000001
#define DATA_CHANNEL_FLAGS_OUT_OF_ORDER_ALLOWED 0x00000002
#define DATA_CHANNEL_FLAGS_FINISH_OPEN 0x00000004
#define DATA_CHANNEL_FLAGS_EXTERNAL_NEGOTIATED 0x00000008
#define DATA_CHANNEL_FLAGS_WAITING_ACK 0x00000010
#define DATA_CHANNEL_FLAGS_CLOSING_TOO_LARGE 0x00000020

Просмотреть файл

@ -121,16 +121,22 @@ TestPassed = [
{'regex': re.compile('''(TEST-INFO|TEST-KNOWN-FAIL|TEST-PASS|INFO \| )'''), 'level': INFO},
]
HarnessErrorList = [
BaseHarnessErrorList = [
{'substr': 'TEST-UNEXPECTED', 'level': ERROR, },
{'substr': 'PROCESS-CRASH', 'level': ERROR, },
{'substr': 'A content process crashed', 'level': ERROR, },
{'regex': re.compile('''ERROR: (Address|Leak)Sanitizer'''), 'level': ERROR, },
{'regex': re.compile('''thread '([^']+)' panicked'''), 'level': ERROR, },
{'substr': 'pure virtual method called', 'level': ERROR, },
{'substr': 'Pure virtual function called!', 'level': ERROR, },
]
HarnessErrorList = BaseHarnessErrorList + [
{'substr': 'A content process crashed', 'level': ERROR, },
]
# wpt can have expected crashes so we can't always turn treeherder orange in those cases
WptHarnessErrorList = BaseHarnessErrorList
LogcatErrorList = [
{'substr': 'Fatal signal 11 (SIGSEGV)', 'level': ERROR,
'explanation': 'This usually indicates the B2G process has crashed'},

Просмотреть файл

@ -26,7 +26,7 @@ from mozharness.mozilla.testing.codecoverage import (
CodeCoverageMixin,
code_coverage_config_options
)
from mozharness.mozilla.testing.errors import HarnessErrorList
from mozharness.mozilla.testing.errors import WptHarnessErrorList
from mozharness.mozilla.structuredlog import StructuredOutputParser
from mozharness.base.log import INFO
@ -342,7 +342,7 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
parser = StructuredOutputParser(config=self.config,
log_obj=self.log_obj,
log_compact=True,
error_list=BaseErrorList + HarnessErrorList,
error_list=BaseErrorList + WptHarnessErrorList,
allow_crashes=True)
env = {'MINIDUMP_SAVE_PATH': dirs['abs_blob_upload_dir']}

Просмотреть файл

@ -1,4 +0,0 @@
[2d.drawImage.zerocanvas.html]
[Canvas test: 2d.drawImage.zerocanvas]
expected: FAIL

Просмотреть файл

@ -1,2 +1,2 @@
leak-threshold: [default:102400]
lsan-allowed: [Alloc, Create, MakeUnique, PLDHashTable::Add, Realloc, SetPropertyAsInterface, WeakPtr, already_AddRefed, mozilla::SupportsWeakPtr, mozilla::WeakPtr, mozilla::dom::BrowsingContext::Create, mozilla::dom::ContentParent::CreateBrowser, mozilla::dom::BrowserParent::GetLoadContext, mozilla::extensions::ChannelWrapper::ChannelWrapper, mozilla::net::CacheFile::OnFileOpened, mozilla::net::CacheFileHandles::NewHandle, mozilla::net::nsHttpTransaction::ParseHead, mozilla::net::nsStandardURL::TemplatedMutator, nsLocalFile::Clone, nsNodeSupportsWeakRefTearoff::GetWeakReference, nsSegmentedBuffer::AppendNewSegment]
leak-threshold: [default:102400]

Просмотреть файл

@ -0,0 +1,5 @@
[2d.shadow.enable.blur.html]
[Shadows are drawn if shadowBlur is set]
expected:
if not e10s: FAIL

Просмотреть файл

@ -0,0 +1,5 @@
[2d.shadow.enable.x.html]
[Shadows are drawn if shadowOffsetX is set]
expected:
if not e10s: FAIL

Просмотреть файл

@ -0,0 +1,5 @@
[2d.shadow.enable.y.html]
[Shadows are drawn if shadowOffsetY is set]
expected:
if not e10s: FAIL

Просмотреть файл

@ -1,7 +0,0 @@
[bigint_value.htm]
[Values]
expected: FAIL
[IndexedDB: BigInt keys and values]
expected: FAIL

Просмотреть файл

@ -1,39 +0,0 @@
[pbkdf2.https.any.html?1001-2000]
[pbkdf2.https.any.html?3001-4000]
[pbkdf2.https.any.html?1-1000]
[pbkdf2.https.any.html?5001-6000]
[pbkdf2.https.any.html?7001-8000]
[pbkdf2.https.any.html?2001-3000]
[pbkdf2.https.any.html?8001-last]
[pbkdf2.https.any.html?4001-5000]
[Derived key of type name: AES-CBC length: 128 using long password, empty salt, SHA-384, with 100000 iterations]
expected:
if not debug and (os == "linux") and (bits == "32"): TIMEOUT
[pbkdf2.https.any.html?6001-7000]
[pbkdf2.https.any.worker.html?2001-3000]
[pbkdf2.https.any.worker.html?1-1000]
[pbkdf2.https.any.worker.html?1001-2000]
[pbkdf2.https.any.worker.html?3001-4000]
[pbkdf2.https.any.worker.html?8001-last]
[pbkdf2.https.any.worker.html?4001-5000]
[pbkdf2.https.any.worker.html?7001-8000]
[pbkdf2.https.any.worker.html?6001-7000]
[pbkdf2.https.any.worker.html?5001-6000]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_AES-CBC.https.any.html]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_AES-CTR.https.any.html]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_AES-GCM.https.any.html]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_AES-KW.https.any.html]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_ECDH.https.any.html]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_ECDSA.https.any.html]

Просмотреть файл

@ -5,3 +5,5 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_HMAC.https.any.html]

Просмотреть файл

@ -125,3 +125,35 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_RSA-OAEP.https.any.html?11-20]
[successes_RSA-OAEP.https.any.html?141-150]
[successes_RSA-OAEP.https.any.html?131-140]
[successes_RSA-OAEP.https.any.html?1-10]
[successes_RSA-OAEP.https.any.html?61-70]
[successes_RSA-OAEP.https.any.html?21-30]
[successes_RSA-OAEP.https.any.html?31-40]
[successes_RSA-OAEP.https.any.html?151-last]
[successes_RSA-OAEP.https.any.html?71-80]
[successes_RSA-OAEP.https.any.html?81-90]
[successes_RSA-OAEP.https.any.html?101-110]
[successes_RSA-OAEP.https.any.html?41-50]
[successes_RSA-OAEP.https.any.html?91-100]
[successes_RSA-OAEP.https.any.html?111-120]
[successes_RSA-OAEP.https.any.html?51-60]
[successes_RSA-OAEP.https.any.html?121-130]

Просмотреть файл

@ -29,3 +29,11 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_RSA-PSS.https.any.html?1-10]
[successes_RSA-PSS.https.any.html?21-30]
[successes_RSA-PSS.https.any.html?11-20]
[successes_RSA-PSS.https.any.html?31-last]

Просмотреть файл

@ -29,3 +29,11 @@
[WebCryptoAPI: generateKey() Successful Calls]
expected: FAIL
[successes_RSASSA-PKCS1-v1_5.https.any.html?21-30]
[successes_RSASSA-PKCS1-v1_5.https.any.html?1-10]
[successes_RSASSA-PKCS1-v1_5.https.any.html?11-20]
[successes_RSASSA-PKCS1-v1_5.https.any.html?31-last]

Просмотреть файл

@ -1,19 +0,0 @@
[exceptions.html]
[Object.getOwnPropertyDescriptor(exception, "name")]
expected: FAIL
[typeof exception.message === "string"]
expected: FAIL
[Object.getOwnPropertyDescriptor(exception, "code")]
expected: FAIL
[In iframe: Object.getOwnPropertyDescriptor(exception, "name")]
expected: FAIL
[In iframe: typeof exception.message === "string"]
expected: FAIL
[In iframe: Object.getOwnPropertyDescriptor(exception, "code")]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[Accelerometer_insecure_context.html]
[Accelerometer Test: insecure context]
expected: FAIL

Просмотреть файл

@ -0,0 +1 @@
leak-threshold: [default:2969600]

Просмотреть файл

@ -1,7 +0,0 @@
[AmbientLightSensor_insecure_context.html]
[throw a 'SecurityError' when construct AmbientLightSensor in an insecure context]
expected: FAIL
[AmbientLightSensor Test: insecure context]
expected: FAIL

Просмотреть файл

@ -0,0 +1,2 @@
[worklet-animation-get-timing-on-worklet-thread.https.html]
expected: TIMEOUT

Просмотреть файл

@ -0,0 +1 @@
leak-threshold: [default:51200]

Просмотреть файл

@ -1,12 +0,0 @@
[idlharness.any.html]
[Navigator interface: operation sendBacon(USVString, BodyInit)]
expected: FAIL
[Navigator interface: navigator must inherit property "sendBacon(USVString, BodyInit)" with the proper type]
expected: FAIL
[Navigator interface: calling sendBacon(USVString, BodyInit) on navigator with too few arguments must throw TypeError]
expected: FAIL
[idlharness.any.worker.html]

Просмотреть файл

@ -0,0 +1,4 @@
[buffer-is-detached.https.html]
[writeValue() fails when passed a detached buffer]
expected: FAIL

Просмотреть файл

@ -0,0 +1,4 @@
[buffer-is-detached.https.html]
[writeValue() fails when passed a detached buffer]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[idl-NavigatorBluetooth.html]
[navigator.bluetooth IDL test]
expected: FAIL

Просмотреть файл

@ -0,0 +1,7 @@
[accept_ch_feature_policy.tentative.sub.https.html]
[Accept-CH header test]
expected: FAIL
[Cross-Origin Accept-CH header test]
expected: FAIL

Просмотреть файл

@ -0,0 +1,4 @@
[accept_ch_no_feature_policy.tentative.sub.https.html]
[Accept-CH header test]
expected: FAIL

Просмотреть файл

@ -4,14 +4,12 @@
[Window interface: attribute orientation]
expected:
if (os == "android") and not e10s: PASS
if (os == "android") and e10s: PASS
if os == "android": PASS
FAIL
[Window interface: window must inherit property "orientation" with the proper type]
expected:
if (os == "android") and not e10s: PASS
if (os == "android") and e10s: PASS
if os == "android": PASS
FAIL
[HTMLBodyElement interface: attribute onorientationchange]
@ -19,13 +17,14 @@
[Window interface: window must inherit property "onorientationchange" with the proper type]
expected:
if (os == "android") and not e10s: PASS
if (os == "android") and e10s: PASS
if os == "android": PASS
FAIL
[Window interface: attribute onorientationchange]
expected:
if (os == "android") and not e10s: PASS
if (os == "android") and e10s: PASS
if os == "android": PASS
FAIL
[idlharness]
expected: FAIL

Просмотреть файл

@ -1,8 +0,0 @@
[connect-src-beacon-blocked.sub.html]
type: testharness
[sendBeacon should not throw.]
expected: FAIL
[redirect case]
expected: TIMEOUT

Просмотреть файл

@ -1,5 +0,0 @@
[connect-src-websocket-blocked.sub.html]
type: testharness
[WebSocket should fire error event.]
expected: FAIL

Просмотреть файл

@ -1,7 +0,0 @@
[connect-src-xmlhttprequest-blocked.sub.html]
[XHR should fire onerror.]
expected: TIMEOUT
[XHR should fire onerror after a redirect.]
expected: FAIL

Просмотреть файл

@ -1,6 +1,8 @@
[subsumption_algorithm-host_sources-ports.html]
[Specified ports must match.]
expected: FAIL
expected:
if webrender and debug and (os == "linux"): FAIL
FAIL
[Returned CSP should be subsumed if the port is specified but is not default for a more secure scheme.]
expected: FAIL

Просмотреть файл

@ -1,5 +0,0 @@
[form-action-src-blocked.sub.html]
type: testharness
[form-action-src-blocked]
expected: FAIL

Просмотреть файл

@ -1,5 +0,0 @@
[form-action-src-get-blocked.sub.html]
type: testharness
[form-action-src-allowed]
expected: FAIL

Просмотреть файл

@ -1,5 +0,0 @@
[form-action-src-javascript-blocked.sub.html]
type: testharness
[form-action-src-javascript-blocked]
expected: FAIL

Просмотреть файл

@ -1,6 +1,5 @@
[dedicated-inheritance.html]
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1556907
expected: ERROR
[Same-origin 'fetch()' in http:?pipe=sub|header(Content-Security-Policy,connect-src%20%27none%27)]
expected: FAIL

Просмотреть файл

@ -1,6 +1,6 @@
[child-navigates-parent-blocked.sub.html]
disabled:
if os == "android" and not e10s: https://bugzilla.mozilla.org/show_bug.cgi?id=1511193
if (os == "android") and not e10s: https://bugzilla.mozilla.org/show_bug.cgi?id=1511193
[Violation report status OK.]
expected: FAIL

Просмотреть файл

@ -0,0 +1,4 @@
[cookies-without-samesite-must-be-secure.https.tentative.html]
[SameSite=None cookies are rejected unless the Secure attribute is set.]
expected: FAIL

Просмотреть файл

@ -8,3 +8,23 @@
[Cross-site redirecting to subdomain fetches are strictly same-site]
expected: FAIL
[fetch.html?samesite-by-default-cookies.tentative]
[Subdomain redirecting to cross-site fetches are cross-site]
expected: FAIL
[Same-host redirecting to cross-site fetches are cross-site]
expected: FAIL
[Cross-site redirecting to same-host fetches are strictly same-site]
expected: FAIL
[Cross-site redirecting to subdomain fetches are strictly same-site]
expected: FAIL
[Cross-site redirecting to cross-site fetches are cross-site]
expected: FAIL
[Cross-site fetches are cross-site]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[form-get-blank-reload.html]
[Untitled]
expected: FAIL

Просмотреть файл

@ -8,3 +8,11 @@
[Cross-site redirecting to subdomain top-level form GETs are strictly same-site]
expected: FAIL
[form-get-blank.html?samesite-by-default-cookies.tentative]
[Cross-site redirecting to subdomain top-level form GETs are strictly same-site]
expected: FAIL
[Cross-site redirecting to same-host top-level form GETs are strictly same-site]
expected: FAIL

Просмотреть файл

@ -1,7 +1,6 @@
[form-post-blank-reload.html]
expected:
if (os == "android") and not e10s: TIMEOUT
if (os == "android") and e10s: TIMEOUT
if os == "android": TIMEOUT
ERROR
[Untitled]
expected:
@ -9,20 +8,25 @@
FAIL
[Reloaded same-host top-level form POSTs are strictly same-site]
expected:
if (os == "android") and not e10s: TIMEOUT
if debug and not e10s and (os == "linux"): TIMEOUT
if (os == "android") and e10s: TIMEOUT
expected: TIMEOUT
[Reloaded subdomain top-level form POSTs are strictly same-site]
expected:
if (os == "android") and not e10s: NOTRUN
if debug and not e10s and (os == "linux"): NOTRUN
if (os == "android") and e10s: NOTRUN
expected: NOTRUN
[Reloaded cross-site top-level form POSTs are not same-site]
expected:
if (os == "android") and not e10s: NOTRUN
if debug and not e10s and (os == "linux"): NOTRUN
if (os == "android") and e10s: NOTRUN
expected: NOTRUN
[form-post-blank-reload.html?samesite-by-default-cookies.tentative]
expected:
if os == "android": TIMEOUT
ERROR
[Reloaded same-host top-level form POSTs are strictly same-site]
expected: TIMEOUT
[Reloaded subdomain top-level form POSTs are strictly same-site]
expected: NOTRUN
[Reloaded cross-site top-level form POSTs are not same-site]
expected: NOTRUN

Просмотреть файл

@ -8,3 +8,23 @@
[Cross-site redirecting to subdomain top-level form POSTs are strictly same-site]
expected: FAIL
[form-post-blank.html?samesite-by-default-cookies.tentative]
[Cross-site redirecting to same-host top-level form POSTs are strictly same-site]
expected: FAIL
[Cross-site top-level form POSTs are cross-site]
expected: FAIL
[Same-host redirecting to cross-site top-level form POSTs are cross-site]
expected: FAIL
[Cross-site redirecting to subdomain top-level form POSTs are strictly same-site]
expected: FAIL
[Cross-site redirecting to cross-site top-level form POSTs are cross-site]
expected: FAIL
[Subdomain redirecting to cross-site top-level form POSTs are cross-site]
expected: FAIL

Просмотреть файл

@ -2,3 +2,8 @@
[Untitled]
expected: FAIL
[iframe-reload.html?samesite-by-default-cookies.tentative]
[Reloaded cross-site fetches are cross-site]
expected: FAIL

Просмотреть файл

@ -8,3 +8,23 @@
[Cross-site redirecting to subdomain fetches are strictly same-site]
expected: FAIL
[iframe.html?samesite-by-default-cookies.tentative]
[Subdomain redirecting to cross-site fetches are cross-site]
expected: FAIL
[Same-host redirecting to cross-site fetches are cross-site]
expected: FAIL
[Cross-site redirecting to same-host fetches are strictly same-site]
expected: FAIL
[Cross-site redirecting to subdomain fetches are strictly same-site]
expected: FAIL
[Cross-site redirecting to cross-site fetches are cross-site]
expected: FAIL
[Cross-site fetches are cross-site]
expected: FAIL

Просмотреть файл

@ -8,3 +8,23 @@
[Cross-site redirecting to subdomain images are strictly same-site]
expected: FAIL
[img.html?samesite-by-default-cookies.tentative]
[Cross-site redirecting to cross-site images are cross-site]
expected: FAIL
[Subdomain redirecting to cross-site images are cross-site]
expected: FAIL
[Cross-site images are cross-site]
expected: FAIL
[Same-host redirecting to cross-site images are cross-site]
expected: FAIL
[Cross-site redirecting to same-host images are strictly same-site]
expected: FAIL
[Cross-site redirecting to subdomain images are strictly same-site]
expected: FAIL

Просмотреть файл

@ -0,0 +1,6 @@
[setcookie-lax.html?samesite-by-default-cookies.tentative]
[Cross-site window shouldn't be able to set `SameSite=Lax` or `SameSite=Strict` cookies.]
expected: FAIL
[setcookie-lax.html]

Просмотреть файл

@ -1,7 +0,0 @@
[window-open-reload.html]
[Untitled]
expected: FAIL
[Reloaded ross-site auxiliary navigations are laxly same-site]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[window-open.html]
[Untitled]
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[preflight-failure.htm]
[Should throw error if preflight respond with 100]
expected: TIMEOUT

Просмотреть файл

@ -0,0 +1,3 @@
[c44-ln-box-001.xht]
expected:
if (os == "android") and debug: FAIL

Просмотреть файл

@ -0,0 +1,2 @@
[adjoining-float-nested-forced-clearance-002.html]
expected: FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-011.xht]
expected:
if os == "win": FAIL
if os == "linux": PASS
if os == "mac": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-012.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-013.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-014.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-015.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-016.xht]
expected:
if os == "win": FAIL
if os == "linux": PASS
if os == "mac": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-029.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-030.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-031.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-032.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-042.xht]
expected:
if os == "win": FAIL
if os == "mac": PASS
if os == "linux": PASS
FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[font-043.xht]
expected:
if os == "win": FAIL
if os == "linux": PASS
if os == "mac": PASS
FAIL

Просмотреть файл

@ -0,0 +1,2 @@
[margin-collapse-through-percentage-height-block.html]
expected: FAIL

Просмотреть файл

@ -0,0 +1,2 @@
[margin-collapse-through-percentage-padding.html]
expected: FAIL

Просмотреть файл

@ -2,3 +2,5 @@
disabled:
if os == "linux": https://bugzilla.mozilla.org/show_bug.cgi?id=1383229
if os == "win": https://bugzilla.mozilla.org/show_bug.cgi?id=1383229
expected:
if not e10s: FAIL

Просмотреть файл

@ -0,0 +1,3 @@
[text-indent-007.xht]
expected:
if os == "android": FAIL

Просмотреть файл

@ -0,0 +1,3 @@
[text-indent-008.xht]
expected:
if os == "android": FAIL

Просмотреть файл

@ -0,0 +1,3 @@
[text-indent-019.xht]
expected:
if os == "android": FAIL

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше