Merge mozilla-central to autoland

This commit is contained in:
Carsten "Tomcat" Book 2017-04-25 11:53:39 +02:00
Родитель 0340ccd2e1 9155c12847
Коммит e7e00b58d2
26 изменённых файлов: 254 добавлений и 147 удалений

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

@ -30,7 +30,6 @@ XPIDL_MODULE = 'shellservice'
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'../../../other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp',
'nsWindowsShellService.cpp',
]
LOCAL_INCLUDES += [

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

@ -46,7 +46,7 @@ EXEC = exec
# ELOG prints out failed command when building silently (gmake -s). Pymake
# prints out failed commands anyway, so ELOG just makes things worse by
# forcing shell invocations.
ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
ifneq (,$(findstring -s, $(filter-out --%, $(MAKEFLAGS))))
ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
else
ELOG :=

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

@ -3049,13 +3049,20 @@ nsDOMWindowUtils::IsPartOfOpaqueLayer(nsIDOMElement* aElement, bool* aResult)
return NS_ERROR_FAILURE;
}
PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(frame);
if (!layer) {
return NS_ERROR_FAILURE;
ColorLayer* colorLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<ColorLayer>(frame);
if (colorLayer) {
auto color = colorLayer->GetColor();
*aResult = color.a == 1.0f;
return NS_OK;
}
*aResult = (layer->GetContentFlags() & Layer::CONTENT_OPAQUE);
return NS_OK;
PaintedLayer* paintedLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
if (paintedLayer) {
*aResult = paintedLayer->IsOpaque();
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@ -3078,7 +3085,7 @@ nsDOMWindowUtils::NumberOfAssignedPaintedLayers(nsIDOMElement** aElements,
return NS_ERROR_FAILURE;
}
PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(frame);
PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
if (!layer) {
return NS_ERROR_FAILURE;
}

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

@ -223,8 +223,8 @@ TouchEvent::PrefEnabled(nsIDocShell* aDocShell)
if (enabled && aDocShell) {
// APZ might be disabled on this particular widget, in which case
// TouchEvent support will also be disabled. Try to detect that.
nsPresContext* pc = nullptr;
aDocShell->GetPresContext(&pc);
RefPtr<nsPresContext> pc;
aDocShell->GetPresContext(getter_AddRefs(pc));
if (pc && pc->GetRootWidget()) {
enabled &= pc->GetRootWidget()->AsyncPanZoomEnabled();
}

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

@ -116,7 +116,8 @@ class LayersPacket;
#define MOZ_LAYER_DECL_NAME(n, e) \
virtual const char* Name() const override { return n; } \
virtual LayerType GetType() const override { return e; }
virtual LayerType GetType() const override { return e; } \
static LayerType Type() { return e; }
// Defined in LayerUserData.h; please include that file instead.
class LayerUserData;

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

@ -24,6 +24,7 @@ ZoneGroup::ZoneGroup(JSRuntime* runtime)
#endif
jitZoneGroup(this, nullptr),
debuggerList_(this),
numFinishedBuilders(0),
ionLazyLinkListSize_(0)
{}
@ -67,6 +68,11 @@ ZoneGroup::enter()
ownerContext_ = CooperatingContext(cx);
if (cx->generationalDisabled)
nursery().disable();
// Finish any Ion compilations in this zone group, in case compilation
// finished for some script in this group while no thread was in this
// group.
jit::AttachFinishedCompilations(this, nullptr);
}
enterCount++;
}
@ -100,6 +106,7 @@ ZoneGroup::ionLazyLinkListRemove(jit::IonBuilder* builder)
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
"Should only be mutated by the active thread.");
MOZ_ASSERT(this == builder->script()->zone()->group());
MOZ_ASSERT(ionLazyLinkListSize_ > 0);
builder->removeFrom(ionLazyLinkList());
@ -113,6 +120,7 @@ ZoneGroup::ionLazyLinkListAdd(jit::IonBuilder* builder)
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
"Should only be mutated by the active thread.");
MOZ_ASSERT(this == builder->script()->zone()->group());
ionLazyLinkList().insertFront(builder);
ionLazyLinkListSize_++;
}

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

@ -96,6 +96,11 @@ class ZoneGroup
public:
mozilla::LinkedList<js::Debugger>& debuggerList() { return debuggerList_.ref(); }
// Number of Ion compilations which were finished off thread and are
// waiting to be lazily linked. This is only set while holding the helper
// thread state lock, but may be read from at other times.
mozilla::Atomic<size_t> numFinishedBuilders;
private:
/* List of Ion compilation waiting to get linked. */
typedef mozilla::LinkedList<js::jit::IonBuilder> IonBuilderList;

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

@ -2049,14 +2049,16 @@ CompileBackEnd(MIRGenerator* mir)
return GenerateCode(mir, lir);
}
// Find a finished builder for the runtime.
// Find a builder which the current thread can finish.
static IonBuilder*
GetFinishedBuilder(JSContext* cx, GlobalHelperThreadState::IonBuilderVector& finished)
GetFinishedBuilder(ZoneGroup* group, GlobalHelperThreadState::IonBuilderVector& finished)
{
for (size_t i = 0; i < finished.length(); i++) {
IonBuilder* testBuilder = finished[i];
if (testBuilder->script()->runtimeFromAnyThread() == cx->runtime()) {
if (testBuilder->script()->runtimeFromAnyThread() == group->runtime &&
testBuilder->script()->zone()->group() == group) {
HelperThreadState().remove(finished, &i);
group->numFinishedBuilders--;
return testBuilder;
}
}
@ -2065,44 +2067,46 @@ GetFinishedBuilder(JSContext* cx, GlobalHelperThreadState::IonBuilderVector& fin
}
void
AttachFinishedCompilations(JSContext* cx)
AttachFinishedCompilations(ZoneGroup* group, JSContext* maybecx)
{
JitCompartment* ion = cx->compartment()->jitCompartment();
if (!ion)
MOZ_ASSERT_IF(maybecx, maybecx->zone()->group() == group);
if (!group->numFinishedBuilders)
return;
{
AutoLockHelperThreadState lock;
AutoLockHelperThreadState lock;
GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock);
GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(lock);
// Incorporate any off thread compilations for the runtime which have
// finished, failed or have been cancelled.
while (true) {
// Find a finished builder for the zone group.
IonBuilder* builder = GetFinishedBuilder(group, finished);
if (!builder)
break;
// Incorporate any off thread compilations for the runtime which have
// finished, failed or have been cancelled.
while (true) {
// Find a finished builder for the runtime.
IonBuilder* builder = GetFinishedBuilder(cx, finished);
if (!builder)
break;
JSScript* script = builder->script();
MOZ_ASSERT(script->hasBaselineScript());
script->baselineScript()->setPendingIonBuilder(group->runtime, script, builder);
group->ionLazyLinkListAdd(builder);
JSScript* script = builder->script();
MOZ_ASSERT(script->hasBaselineScript());
script->baselineScript()->setPendingIonBuilder(cx->runtime(), script, builder);
cx->zone()->group()->ionLazyLinkListAdd(builder);
// Don't keep more than 100 lazy link builders in a zone group.
// Link the oldest ones immediately.
while (cx->zone()->group()->ionLazyLinkListSize() > 100) {
jit::IonBuilder* builder = cx->zone()->group()->ionLazyLinkList().getLast();
RootedScript script(cx, builder->script());
// Don't keep more than 100 lazy link builders in a zone group.
// Link the oldest ones immediately. Only do this if we have a valid
// context to use (otherwise this method might have been called in the
// middle of a compartment change on the current thread's context).
if (maybecx) {
while (group->ionLazyLinkListSize() > 100) {
jit::IonBuilder* builder = group->ionLazyLinkList().getLast();
RootedScript script(maybecx, builder->script());
AutoUnlockHelperThreadState unlock(lock);
AutoCompartment ac(cx, script);
jit::LinkIonScript(cx, script);
AutoCompartment ac(maybecx, script);
jit::LinkIonScript(maybecx, script);
}
continue;
}
}
MOZ_ASSERT(!group->numFinishedBuilders);
}
static void

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

@ -159,7 +159,7 @@ LIRGraph* GenerateLIR(MIRGenerator* mir);
CodeGenerator* GenerateCode(MIRGenerator* mir, LIRGraph* lir);
CodeGenerator* CompileBackEnd(MIRGenerator* mir);
void AttachFinishedCompilations(JSContext* cx);
void AttachFinishedCompilations(ZoneGroup* group, JSContext* maybecx);
void FinishOffThreadBuilder(JSRuntime* runtime, IonBuilder* builder,
const AutoLockHelperThreadState& lock);

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

@ -121,6 +121,7 @@ FinishOffThreadIonCompile(jit::IonBuilder* builder, const AutoLockHelperThreadSt
AutoEnterOOMUnsafeRegion oomUnsafe;
if (!HelperThreadState().ionFinishedList(lock).append(builder))
oomUnsafe.crash("FinishOffThreadIonCompile");
builder->script()->zoneFromAnyThread()->group()->numFinishedBuilders++;
}
static JSRuntime*
@ -222,6 +223,7 @@ js::CancelOffThreadIonCompile(const CompilationSelector& selector, bool discardL
for (size_t i = 0; i < finished.length(); i++) {
jit::IonBuilder* builder = finished[i];
if (CompiledScriptMatches(selector, builder->script())) {
builder->script()->zone()->group()->numFinishedBuilders--;
jit::FinishOffThreadBuilder(nullptr, builder, lock);
HelperThreadState().remove(finished, &i);
}

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

@ -506,12 +506,13 @@ static bool
InvokeInterruptCallback(JSContext* cx)
{
MOZ_ASSERT(cx->requestDepth >= 1);
MOZ_ASSERT(!cx->compartment()->isAtomsCompartment());
cx->runtime()->gc.gcIfRequested();
// A worker thread may have requested an interrupt after finishing an Ion
// compilation.
jit::AttachFinishedCompilations(cx);
jit::AttachFinishedCompilations(cx->zone()->group(), cx);
// Important: Additional callbacks can occur inside the callback handler
// if it re-enters the JS engine. The embedding must ensure that the

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

@ -6786,6 +6786,7 @@ nsLayoutUtils::ComputeSizeForDrawingWithFallback(imgIContainer* aImage,
/* static */ DrawResult
nsLayoutUtils::DrawBackgroundImage(gfxContext& aContext,
nsIFrame* aForFrame,
nsPresContext* aPresContext,
imgIContainer* aImage,
const CSSIntSize& aImageSize,
@ -6802,7 +6803,8 @@ nsLayoutUtils::DrawBackgroundImage(gfxContext& aContext,
PROFILER_LABEL("layout", "nsLayoutUtils::DrawBackgroundImage",
js::ProfileEntry::Category::GRAPHICS);
const Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(aImageSize))));
Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(aImageSize))));
SVGImageContext::MaybeStoreContextPaint(svgContext, aForFrame, aImage);
/* Fast path when there is no need for image spacing */
if (aRepeatSize.width == aDest.width && aRepeatSize.height == aDest.height) {

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

@ -1774,9 +1774,10 @@ public:
* Draw a background image. The image's dimensions are as specified in aDest;
* the image itself is not consulted to determine a size.
* See https://wiki.mozilla.org/Gecko:Image_Snapping_and_Rendering
* @param aRenderingContext Where to draw the image, set up with an
* @param aContext The context to draw to, already set up with an
* appropriate scale and transform for drawing in
* app units.
* @param aForFrame The nsIFrame that we're drawing this image for.
* @param aImage The image.
* @param aImageSize The unscaled size of the image being drawn.
* (This might be the image's size if no scaling
@ -1798,6 +1799,7 @@ public:
* @param aExtendMode How to extend the image over the dest rect.
*/
static DrawResult DrawBackgroundImage(gfxContext& aContext,
nsIFrame* aForFrame,
nsPresContext* aPresContext,
imgIContainer* aImage,
const CSSIntSize& aImageSize,

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

@ -285,7 +285,14 @@ nsImageFrame::Init(nsIContent* aContent,
getter_AddRefs(currentRequest));
if (currentRequest) {
currentRequest->BoostPriority(imgIRequest::CATEGORY_FRAME_INIT);
uint32_t categoryToBoostPriority = imgIRequest::CATEGORY_FRAME_INIT;
// Increase load priority further if intrinsic size might be important for layout.
if (!HaveSpecifiedSize(StylePosition())) {
categoryToBoostPriority |= imgIRequest::CATEGORY_SIZE_QUERY;
}
currentRequest->BoostPriority(categoryToBoostPriority);
}
}
@ -1700,7 +1707,7 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt,
}
Maybe<SVGImageContext> svgContext;
SVGImageContext::MaybeInitAndStoreContextPaint(svgContext, this, aImage);
SVGImageContext::MaybeStoreContextPaint(svgContext, this, aImage);
DrawResult result =
nsLayoutUtils::DrawSingleImage(*aRenderingContext.ThebesContext(),

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

@ -301,6 +301,15 @@ FrameLayerBuilder::DisplayItemData::GetFrameListChanges()
return mFrameListChanges;
}
FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::DisplayItemData::AssertDisplayItemData(FrameLayerBuilder::DisplayItemData* aData)
{
MOZ_RELEASE_ASSERT(aData);
MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(aData));
MOZ_RELEASE_ASSERT(aData->mLayer);
return aData;
}
/**
* This is the userdata we associate with a layer manager.
*/
@ -1803,15 +1812,6 @@ FrameLayerBuilder::FlashPaint(gfxContext *aContext)
aContext->Paint();
}
static FrameLayerBuilder::DisplayItemData*
AssertDisplayItemData(FrameLayerBuilder::DisplayItemData* aData)
{
MOZ_RELEASE_ASSERT(aData);
MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(aData));
MOZ_RELEASE_ASSERT(aData->mLayer);
return aData;
}
FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
{
@ -1819,7 +1819,7 @@ FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
aFrame->Properties().Get(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
DisplayItemData* item = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
if (item->mDisplayItemKey == aKey &&
item->mLayer->Manager() == mRetainingManager) {
return item;
@ -2049,7 +2049,7 @@ FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
aItem->Frame()->Properties().Get(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
DisplayItemData* item = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
if (item->mDisplayItemKey == aItem->GetPerFrameKey() &&
item->mLayer->Manager() == aManager) {
return item;
@ -2066,7 +2066,7 @@ FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey
aFrame->Properties().Get(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
if (DisplayItemData::AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
return true;
}
}
@ -2084,7 +2084,7 @@ FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallb
}
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* data = AssertDisplayItemData(array->ElementAt(i));
DisplayItemData* data = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
if (data->mDisplayItemKey != nsDisplayItem::TYPE_ZERO) {
aCallback(aFrame, data);
}
@ -2152,7 +2152,7 @@ FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
}
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *data = AssertDisplayItemData(array->ElementAt(i));
DisplayItemData *data = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
if (data->mDisplayItemKey == aDisplayItemKey) {
return data->mLayer;
@ -2161,36 +2161,6 @@ FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
return nullptr;
}
/* static */ PaintedLayer*
FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
if (!array) {
return nullptr;
}
Layer* layer = nullptr;
for (DisplayItemData* data : *array) {
AssertDisplayItemData(data);
if (!data->mLayer->AsPaintedLayer()) {
continue;
}
if (layer && layer != data->mLayer) {
// More than one layer assigned, bail.
return nullptr;
}
layer = data->mLayer;
}
if (!layer) {
return nullptr;
}
return layer->AsPaintedLayer();
}
// Reset state that should not persist when a layer is recycled.
static void
ResetLayerStateForRecycling(Layer* aLayer) {
@ -5811,7 +5781,7 @@ FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
aFrame->Properties().Get(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
DisplayItemData::AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
}
}
}
@ -5828,7 +5798,7 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
aFrame->Properties().Get(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i));
DisplayItemData *element = DisplayItemData::AssertDisplayItemData(array->ElementAt(i));
if (!element->mParent->mLayerManager->IsWidgetLayerManager()) {
continue;
}
@ -5887,7 +5857,7 @@ FrameLayerBuilder::GetPaintedLayerScaleForFrame(nsIFrame* aFrame)
}
for (uint32_t i = 0; i < array->Length(); i++) {
Layer* layer = AssertDisplayItemData(array->ElementAt(i))->mLayer;
Layer* layer = DisplayItemData::AssertDisplayItemData(array->ElementAt(i))->mLayer;
ContainerLayer* container = layer->AsContainerLayer();
if (!container ||
!layer->Manager()->IsWidgetLayerManager()) {
@ -6327,7 +6297,7 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
// Find our display item data, if it exists, and return its geometry.
uint32_t itemPerFrameKey = aItem->GetPerFrameKey();
for (uint32_t i = 0; i < dataArray->Length(); i++) {
DisplayItemData* data = AssertDisplayItemData(dataArray->ElementAt(i));
DisplayItemData* data = DisplayItemData::AssertDisplayItemData(dataArray->ElementAt(i));
if (data->GetDisplayItemKey() == itemPerFrameKey) {
return data->GetGeometry();
}

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

@ -370,7 +370,36 @@ public:
* frame's display items (i.e. zero, or more than one).
* This function is for testing purposes and not performance sensitive.
*/
static PaintedLayer* GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame);
template<class T>
static T*
GetDebugSingleOldLayerForFrame(nsIFrame* aFrame)
{
const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty());
if (!array) {
return nullptr;
}
Layer* layer = nullptr;
for (DisplayItemData* data : *array) {
DisplayItemData::AssertDisplayItemData(data);
if (data->mLayer->GetType() != T::Type()) {
continue;
}
if (layer && layer != data->mLayer) {
// More than one layer assigned, bail.
return nullptr;
}
layer = data->mLayer;
}
if (!layer) {
return nullptr;
}
return static_cast<T*>(layer);
}
/**
* Destroy any stored LayerManagerDataProperty and the associated data for
@ -451,6 +480,8 @@ public:
void Invalidate() { mIsInvalid = true; }
void ClearAnimationCompositorState();
static DisplayItemData* AssertDisplayItemData(DisplayItemData* aData);
private:
DisplayItemData(LayerManagerData* aParent,
uint32_t aKey,

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

@ -513,7 +513,7 @@ nsImageRenderer::Draw(nsPresContext* aPresContext,
CSSIntSize imageSize(nsPresContext::AppUnitsToIntCSSPixels(mSize.width),
nsPresContext::AppUnitsToIntCSSPixels(mSize.height));
result =
nsLayoutUtils::DrawBackgroundImage(*ctx,
nsLayoutUtils::DrawBackgroundImage(*ctx, mForFrame,
aPresContext,
mImageContainer, imageSize,
samplingFilter,
@ -920,7 +920,7 @@ nsImageRenderer::DrawBorderImageComponent(nsPresContext* aPresContext,
nsRect tile = ComputeTile(fillRect, aHFill, aVFill, aUnitSize, repeatSize);
CSSIntSize imageSize(srcRect.width, srcRect.height);
return nsLayoutUtils::DrawBackgroundImage(*aRenderingContext.ThebesContext(),
aPresContext,
mForFrame, aPresContext,
subImage, imageSize, samplingFilter,
tile, fillRect, repeatSize,
tile.TopLeft(), aDirtyRect,

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

@ -0,0 +1,5 @@
<html>
<body>
<div style="width: 100px; height: 100px; border: 10px solid blue; box-sizing: border-box;"></div>
</body>
</html>

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

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Basic context-fill in background-image test</title>
<style>
div {
width: 100px;
height: 100px;
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect width='100%' height='100%' fill='context-fill red'/></svg>");
fill: blue;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

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

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Basic context-stroke in background-image test</title>
<style>
div {
width: 100px;
height: 100px;
background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect x='5' y='5' width='90' height='90' fill='none' stroke='context-stroke red' stroke-width='10'/></svg>");
stroke: blue;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

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

@ -55,6 +55,7 @@ fuzzy(1,2) fuzzy-if(azureSkia,1,40000) == canvas-drawImage-alpha-2.html canvas-d
== canvas-drawImage-transform-restored.html canvas-drawImage-transform-restored-ref.html
# Context paint tests (this feature is currently not part of any spec.)
# context-fill:
== context-fill-01.html blue100x100-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-fill-01.html lime100x100-ref.html
== context-fill-02.html transparent100x100-w-border-ref.html
@ -65,6 +66,8 @@ fuzzy-if(winWidget,1,10000) test-pref(svg.context-properties.content.enabled,tru
test-pref(svg.context-properties.content.enabled,true) == context-fill-05.html context-fill-or-stroke-05-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-fill-06.html lime100x100-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-fill-07.html context-fill-07-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-fill-bg-image-01.html blue100x100-ref.html
# context-stroke:
== context-stroke-01.html blue100x100-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-stroke-01.html lime100x100-ref.html
== context-stroke-02.html transparent100x100-w-border-ref.html
@ -75,6 +78,7 @@ fuzzy-if(winWidget,1,10000) test-pref(svg.context-properties.content.enabled,tru
test-pref(svg.context-properties.content.enabled,true) == context-stroke-05.html context-fill-or-stroke-05-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-stroke-06.html lime100x100-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-stroke-07.html context-stroke-07-ref.html
test-pref(svg.context-properties.content.enabled,true) == context-stroke-bg-image-01.html blue100x100-border-ref.html
# Simple <img> tests
== img-simple-1.html lime100x100-ref.html

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

@ -16,15 +16,13 @@
namespace mozilla {
/* static */ void
SVGImageContext::MaybeInitAndStoreContextPaint(Maybe<SVGImageContext>& aContext,
nsIFrame* aFromFrame,
imgIContainer* aImgContainer)
SVGImageContext::MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
nsIFrame* aFromFrame,
imgIContainer* aImgContainer)
{
static bool sEnabledForContent = false;
static bool sEnabledForContentCached = false;
MOZ_ASSERT(!aContext, "The emplace() call below with overwrite this object");
if (!sEnabledForContentCached) {
Preferences::AddBoolVarCache(&sEnabledForContent,
"svg.context-properties.content.enabled", false);
@ -62,7 +60,9 @@ SVGImageContext::MaybeInitAndStoreContextPaint(Maybe<SVGImageContext>& aContext,
}
if (haveContextPaint) {
aContext.emplace();
if (!aContext) {
aContext.emplace();
}
aContext->mContextPaint = contextPaint.forget();
}
}

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

@ -47,9 +47,9 @@ public:
, mPreserveAspectRatio(aPreserveAspectRatio)
{ }
static void MaybeInitAndStoreContextPaint(Maybe<SVGImageContext>& aContext,
nsIFrame* aFromFrame,
imgIContainer* aImgContainer);
static void MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
nsIFrame* aFromFrame,
imgIContainer* aImgContainer);
const Maybe<CSSIntSize>& GetViewportSize() const {
return mViewportSize;

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

@ -410,7 +410,7 @@ nsImageBoxFrame::PaintImage(nsRenderingContext& aRenderingContext,
}
Maybe<SVGImageContext> svgContext;
SVGImageContext::MaybeInitAndStoreContextPaint(svgContext, this, imgCon);
SVGImageContext::MaybeStoreContextPaint(svgContext, this, imgCon);
return nsLayoutUtils::DrawSingleImage(
*aRenderingContext.ThebesContext(),

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

@ -13,32 +13,47 @@ from ..taskgraph import TaskGraph
from ..task import Task
from mozunit import main
# an empty graph, for things that don't look at it
empty_graph = TaskGraph({}, Graph(set(), set()))
def unittest_task(n, tp):
def unittest_task(n, tp, bt='opt'):
return (n, Task('test', n, {
'unittest_try_name': n,
'test_platform': tp,
'test_platform': tp.split('/')[0],
'build_type': bt,
}, {}))
def talos_task(n, tp):
def talos_task(n, tp, bt='opt'):
return (n, Task('test', n, {
'talos_try_name': n,
'test_platform': tp,
'test_platform': tp.split('/')[0],
'build_type': bt,
}, {}))
tasks = {k: v for k, v in [
unittest_task('mochitest-browser-chrome', 'linux/opt'),
unittest_task('mochitest-browser-chrome-e10s', 'linux64/debug'),
unittest_task('mochitest-chrome', 'linux/this'),
unittest_task('mochitest-webgl', 'linux/that'),
unittest_task('mochitest-browser-chrome-e10s', 'linux64/opt'),
unittest_task('mochitest-chrome', 'linux/debug', 'debug'),
unittest_task('mochitest-webgl', 'linux/debug', 'debug'),
unittest_task('extra1', 'linux', 'debug/opt'),
unittest_task('extra2', 'win32/opt'),
unittest_task('crashtest-e10s', 'linux/other'),
unittest_task('gtest', 'linux64/asan'),
talos_task('dromaeojs', 'linux64/psan'),
unittest_task('extra3', 'linux/opt'),
unittest_task('extra4', 'linux64/debug', 'debug'),
unittest_task('extra5', 'linux/this'),
unittest_task('extra6', 'linux/that'),
unittest_task('extra7', 'linux/other'),
unittest_task('extra8', 'linux64/asan'),
talos_task('extra9', 'linux64/psan'),
]}
for r in RIDEALONG_BUILDS.values():
tasks.update({k: v for k, v in [
unittest_task(n + '-test', n) for n in r
]})
unittest_tasks = {k: v for k, v in tasks.iteritems()
if 'unittest_try_name' in v.attributes}
talos_tasks = {k: v for k, v in tasks.iteritems()
@ -50,7 +65,7 @@ class TestTryOptionSyntax(unittest.TestCase):
def test_empty_message(self):
"Given an empty message, it should return an empty value"
tos = TryOptionSyntax('', empty_graph)
tos = TryOptionSyntax('', graph_with_jobs)
self.assertEqual(tos.build_types, [])
self.assertEqual(tos.jobs, [])
self.assertEqual(tos.unittests, [])
@ -65,7 +80,7 @@ class TestTryOptionSyntax(unittest.TestCase):
def test_message_without_try(self):
"Given a non-try message, it should return an empty value"
tos = TryOptionSyntax('Bug 1234: frobnicte the foo', empty_graph)
tos = TryOptionSyntax('Bug 1234: frobnicte the foo', graph_with_jobs)
self.assertEqual(tos.build_types, [])
self.assertEqual(tos.jobs, [])
self.assertEqual(tos.unittests, [])
@ -80,74 +95,74 @@ class TestTryOptionSyntax(unittest.TestCase):
def test_unknown_args(self):
"unknown arguments are ignored"
tos = TryOptionSyntax('try: --doubledash -z extra', empty_graph)
tos = TryOptionSyntax('try: --doubledash -z extra', graph_with_jobs)
# equilvant to "try:"..
self.assertEqual(tos.build_types, [])
self.assertEqual(tos.jobs, None)
def test_b_do(self):
"-b do should produce both build_types"
tos = TryOptionSyntax('try: -b do', empty_graph)
tos = TryOptionSyntax('try: -b do', graph_with_jobs)
self.assertEqual(sorted(tos.build_types), ['debug', 'opt'])
def test_b_d(self):
"-b d should produce build_types=['debug']"
tos = TryOptionSyntax('try: -b d', empty_graph)
tos = TryOptionSyntax('try: -b d', graph_with_jobs)
self.assertEqual(sorted(tos.build_types), ['debug'])
def test_b_o(self):
"-b o should produce build_types=['opt']"
tos = TryOptionSyntax('try: -b o', empty_graph)
tos = TryOptionSyntax('try: -b o', graph_with_jobs)
self.assertEqual(sorted(tos.build_types), ['opt'])
def test_build_o(self):
"--build o should produce build_types=['opt']"
tos = TryOptionSyntax('try: --build o', empty_graph)
tos = TryOptionSyntax('try: --build o', graph_with_jobs)
self.assertEqual(sorted(tos.build_types), ['opt'])
def test_b_dx(self):
"-b dx should produce build_types=['debug'], silently ignoring the x"
tos = TryOptionSyntax('try: -b dx', empty_graph)
tos = TryOptionSyntax('try: -b dx', graph_with_jobs)
self.assertEqual(sorted(tos.build_types), ['debug'])
def test_j_job(self):
"-j somejob sets jobs=['somejob']"
tos = TryOptionSyntax('try: -j somejob', empty_graph)
tos = TryOptionSyntax('try: -j somejob', graph_with_jobs)
self.assertEqual(sorted(tos.jobs), ['somejob'])
def test_j_jobs(self):
"-j job1,job2 sets jobs=['job1', 'job2']"
tos = TryOptionSyntax('try: -j job1,job2', empty_graph)
tos = TryOptionSyntax('try: -j job1,job2', graph_with_jobs)
self.assertEqual(sorted(tos.jobs), ['job1', 'job2'])
def test_j_all(self):
"-j all sets jobs=None"
tos = TryOptionSyntax('try: -j all', empty_graph)
tos = TryOptionSyntax('try: -j all', graph_with_jobs)
self.assertEqual(tos.jobs, None)
def test_j_twice(self):
"-j job1 -j job2 sets jobs=job1, job2"
tos = TryOptionSyntax('try: -j job1 -j job2', empty_graph)
tos = TryOptionSyntax('try: -j job1 -j job2', graph_with_jobs)
self.assertEqual(sorted(tos.jobs), sorted(['job1', 'job2']))
def test_p_all(self):
"-p all sets platforms=None"
tos = TryOptionSyntax('try: -p all', empty_graph)
tos = TryOptionSyntax('try: -p all', graph_with_jobs)
self.assertEqual(tos.platforms, None)
def test_p_linux(self):
"-p linux sets platforms=['linux', 'linux-l10n']"
tos = TryOptionSyntax('try: -p linux', empty_graph)
tos = TryOptionSyntax('try: -p linux', graph_with_jobs)
self.assertEqual(tos.platforms, ['linux', 'linux-l10n'])
def test_p_linux_win32(self):
"-p linux,win32 sets platforms=['linux', 'linux-l10n', 'win32']"
tos = TryOptionSyntax('try: -p linux,win32', empty_graph)
tos = TryOptionSyntax('try: -p linux,win32', graph_with_jobs)
self.assertEqual(sorted(tos.platforms), ['linux', 'linux-l10n', 'win32'])
def test_p_expands_ridealongs(self):
"-p linux,linux64 includes the RIDEALONG_BUILDS"
tos = TryOptionSyntax('try: -p linux,linux64', empty_graph)
tos = TryOptionSyntax('try: -p linux,linux64', graph_with_jobs)
platforms = set(['linux'] + RIDEALONG_BUILDS['linux'])
platforms |= set(['linux64'] + RIDEALONG_BUILDS['linux64'])
self.assertEqual(sorted(tos.platforms), sorted(platforms))
@ -218,9 +233,10 @@ class TestTryOptionSyntax(unittest.TestCase):
def test_u_platforms_negated(self):
"-u gtest[-linux] selects all platforms but linux for gtest"
tos = TryOptionSyntax('try: -u gtest[-linux]', graph_with_jobs)
self.assertEqual(sorted(tos.unittests), sorted([
{'test': 'gtest', 'platforms': ['linux64']},
]))
all_platforms = set([x.attributes['test_platform'] for x in unittest_tasks.values()])
self.assertEqual(sorted(tos.unittests[0]['platforms']), sorted(
[x for x in all_platforms if x != 'linux']
))
def test_u_platforms_negated_pretty(self):
"-u gtest[Ubuntu,-x64] selects just linux for gtest"
@ -255,52 +271,52 @@ class TestTryOptionSyntax(unittest.TestCase):
def test_trigger_tests(self):
"--rebuild 10 sets trigger_tests"
tos = TryOptionSyntax('try: --rebuild 10', empty_graph)
tos = TryOptionSyntax('try: --rebuild 10', graph_with_jobs)
self.assertEqual(tos.trigger_tests, 10)
def test_talos_trigger_tests(self):
"--rebuild-talos 10 sets talos_trigger_tests"
tos = TryOptionSyntax('try: --rebuild-talos 10', empty_graph)
tos = TryOptionSyntax('try: --rebuild-talos 10', graph_with_jobs)
self.assertEqual(tos.talos_trigger_tests, 10)
def test_interactive(self):
"--interactive sets interactive"
tos = TryOptionSyntax('try: --interactive', empty_graph)
tos = TryOptionSyntax('try: --interactive', graph_with_jobs)
self.assertEqual(tos.interactive, True)
def test_all_email(self):
"--all-emails sets notifications"
tos = TryOptionSyntax('try: --all-emails', empty_graph)
tos = TryOptionSyntax('try: --all-emails', graph_with_jobs)
self.assertEqual(tos.notifications, 'all')
def test_fail_email(self):
"--failure-emails sets notifications"
tos = TryOptionSyntax('try: --failure-emails', empty_graph)
tos = TryOptionSyntax('try: --failure-emails', graph_with_jobs)
self.assertEqual(tos.notifications, 'failure')
def test_no_email(self):
"no email settings don't set notifications"
tos = TryOptionSyntax('try:', empty_graph)
tos = TryOptionSyntax('try:', graph_with_jobs)
self.assertEqual(tos.notifications, None)
def test_setenv(self):
"--setenv VAR=value adds a environment variables setting to env"
tos = TryOptionSyntax('try: --setenv VAR1=value1 --setenv VAR2=value2', empty_graph)
tos = TryOptionSyntax('try: --setenv VAR1=value1 --setenv VAR2=value2', graph_with_jobs)
self.assertEqual(tos.env, ['VAR1=value1', 'VAR2=value2'])
def test_profile(self):
"--geckoProfile sets profile to true"
tos = TryOptionSyntax('try: --geckoProfile', empty_graph)
tos = TryOptionSyntax('try: --geckoProfile', graph_with_jobs)
self.assertTrue(tos.profile)
def test_tag(self):
"--tag TAG sets tag to TAG value"
tos = TryOptionSyntax('try: --tag tagName', empty_graph)
tos = TryOptionSyntax('try: --tag tagName', graph_with_jobs)
self.assertEqual(tos.tag, 'tagName')
def test_no_retry(self):
"--no-retry sets no_retry to true"
tos = TryOptionSyntax('try: --no-retry', empty_graph)
tos = TryOptionSyntax('try: --no-retry', graph_with_jobs)
self.assertTrue(tos.no_retry)
if __name__ == '__main__':

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

@ -35,6 +35,9 @@ if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']:
EXPORTS += ['EventTracer.h']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
SOURCES += [
'../../other-licenses/nsis/Contrib/CityHash/cityhash/city.cpp',
]
UNIFIED_SOURCES += [
'nsNativeAppSupportWin.cpp',
]