Merge inbound to mozilla-central. a=merge

This commit is contained in:
Bogdan Tara 2018-09-07 00:55:00 +03:00
Родитель 57e533640d a17cd1805a
Коммит df9ab52a72
10 изменённых файлов: 188 добавлений и 101 удалений

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

@ -112,6 +112,7 @@ struct BlobItemData
Matrix mMatrix; // updated to track the current transform to device space
Matrix4x4Flagged mTransform; // only used with nsDisplayTransform items to detect transform changes
float mOpacity; // only used with nsDisplayOpacity items to detect change to opacity
RefPtr<BasicLayerManager> mLayerManager;
IntRect mImageRect;
LayerIntPoint mGroupOffset;
@ -449,7 +450,7 @@ struct DIGroup
GP("mRect %d %d %d %d\n", aData->mRect.x, aData->mRect.y, aData->mRect.width, aData->mRect.height);
InvalidateRect(aData->mRect);
aData->mInvalid = true;
} else if (/*aData->mIsInvalid || XXX: handle image load invalidation */ (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
} else if (aData->mInvalid || /* XXX: handle image load invalidation */ (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
MOZ_RELEASE_ASSERT(imageRect.IsEqualEdges(aData->mImageRect));
MOZ_RELEASE_ASSERT(mLayerBounds.TopLeft() == aData->mGroupOffset);
UniquePtr<nsDisplayItemGeometry> geometry(aItem->AllocateGeometry(aBuilder));
@ -806,6 +807,32 @@ struct DIGroup
}
};
// If we have an item we need to make sure it matches the current group
// otherwise it means the item switched groups and we need to invalidate
// it and recreate the data.
static BlobItemData*
GetBlobItemDataForGroup(nsDisplayItem* aItem, DIGroup* aGroup)
{
BlobItemData* data = GetBlobItemData(aItem);
if (data) {
MOZ_RELEASE_ASSERT(data->mGroup->mDisplayItems.Contains(data));
if (data->mGroup != aGroup) {
GP("group don't match %p %p\n", data->mGroup, aGroup);
data->ClearFrame();
// the item is for another group
// it should be cleared out as being unused at the end of this paint
data = nullptr;
}
}
if (!data) {
GP("Allocating blob data\n");
data = new BlobItemData(aGroup, aItem);
aGroup->mDisplayItems.PutEntry(data);
}
data->mUsed = true;
return data;
}
void
Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect& aItemBounds,
nsDisplayList* aChildren, gfxContext* aContext,
@ -872,26 +899,32 @@ Grouper::PaintContainerItem(DIGroup* aGroup, nsDisplayItem* aItem, const IntRect
GP("Paint Mask\n");
// We don't currently support doing invalidation inside nsDisplayMask
// for now just paint it as a single item
gfx::Size scale(1, 1);
RefPtr<BasicLayerManager> blm = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
PaintByLayer(aItem, mDisplayListBuilder, blm, aContext, scale, [&]() {
static_cast<nsDisplayMask*>(aItem)->PaintAsLayer(mDisplayListBuilder,
aContext, blm);
});
aContext->GetDrawTarget()->FlushItem(aItemBounds);
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
if (data->mLayerManager->GetRoot()) {
data->mLayerManager->BeginTransaction();
static_cast<nsDisplayMask*>(aItem)->PaintAsLayer(mDisplayListBuilder,
aContext, data->mLayerManager);
if (data->mLayerManager->InTransaction()) {
data->mLayerManager->AbortTransaction();
}
aContext->GetDrawTarget()->FlushItem(aItemBounds);
}
break;
}
case DisplayItemType::TYPE_FILTER: {
GP("Paint Filter\n");
// We don't currently support doing invalidation inside nsDisplayFilter
// for now just paint it as a single item
RefPtr<BasicLayerManager> blm = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
gfx::Size scale(1, 1);
PaintByLayer(aItem, mDisplayListBuilder, blm, aContext, scale, [&]() {
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(mDisplayListBuilder,
aContext, blm);
});
aContext->GetDrawTarget()->FlushItem(aItemBounds);
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
if (data->mLayerManager->GetRoot()) {
data->mLayerManager->BeginTransaction();
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(mDisplayListBuilder,
aContext, data->mLayerManager);
if (data->mLayerManager->InTransaction()) {
data->mLayerManager->AbortTransaction();
}
aContext->GetDrawTarget()->FlushItem(aItemBounds);
}
break;
}
@ -965,32 +998,6 @@ IsItemProbablyActive(nsDisplayItem* aItem, nsDisplayListBuilder* aDisplayListBui
}
}
// If we have an item we need to make sure it matches the current group
// otherwise it means the item switched groups and we need to invalidate
// it and recreate the data.
static BlobItemData*
GetBlobItemDataForGroup(nsDisplayItem* aItem, DIGroup* aGroup)
{
BlobItemData* data = GetBlobItemData(aItem);
if (data) {
MOZ_RELEASE_ASSERT(data->mGroup->mDisplayItems.Contains(data));
if (data->mGroup != aGroup) {
GP("group don't match %p %p\n", data->mGroup, aGroup);
data->ClearFrame();
// the item is for another group
// it should be cleared out as being unused at the end of this paint
data = nullptr;
}
}
if (!data) {
GP("Allocating blob data\n");
data = new BlobItemData(aGroup, aItem);
aGroup->mDisplayItems.PutEntry(data);
}
data->mUsed = true;
return data;
}
// This does a pass over the display lists and will join the display items
// into groups as well as paint them
void
@ -1076,6 +1083,10 @@ Grouper::ConstructGroupInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
}
}
bool BuildLayer(nsDisplayItem* aItem, BlobItemData* aData,
nsDisplayListBuilder* aDisplayListBuilder,
const gfx::Size& aScale);
void
Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
wr::DisplayListBuilder& aBuilder,
@ -1084,8 +1095,15 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
const StackingContextHelper& aSc)
{
nsDisplayList* children = aItem->GetChildren();
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
if (aItem->GetType() == DisplayItemType::TYPE_TRANSFORM) {
if (aItem->GetType() == DisplayItemType::TYPE_FILTER ||
aItem->GetType() == DisplayItemType::TYPE_MASK) {
gfx::Size scale(1, 1);
// If ComputeDifferences finds any change, we invalidate the entire container item.
// This is needed because blob merging requires the entire item to be within the invalid region.
data->mInvalid = BuildLayer(aItem, data, mDisplayListBuilder, scale);
} else if (aItem->GetType() == DisplayItemType::TYPE_TRANSFORM) {
nsDisplayTransform* transformItem = static_cast<nsDisplayTransform*>(aItem);
const Matrix4x4Flagged& t = transformItem->GetTransform();
Matrix t2d;
@ -1101,12 +1119,13 @@ Grouper::ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
mTransform = m;
} else if (children) {
sIndent++;
ConstructGroupInsideInactive(aCommandBuilder, aBuilder, aResources, aGroup, children, aSc);
sIndent--;
}
GP("Including %s of %d\n", aItem->Name(), aGroup->mDisplayItems.Count());
BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
aGroup->ComputeGeometryChange(aItem, data, mTransform, mDisplayListBuilder); // we compute the geometry change here because we have the transform around still
}
@ -1556,6 +1575,50 @@ WebRenderCommandBuilder::PushImage(nsDisplayItem* aItem,
return true;
}
bool
BuildLayer(nsDisplayItem* aItem,
BlobItemData* aData,
nsDisplayListBuilder* aDisplayListBuilder,
const gfx::Size& aScale)
{
if (!aData->mLayerManager) {
aData->mLayerManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
}
RefPtr<BasicLayerManager> blm = aData->mLayerManager;
UniquePtr<LayerProperties> props;
if (blm->GetRoot()) {
props = LayerProperties::CloneFrom(blm->GetRoot());
}
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
layerBuilder->Init(aDisplayListBuilder, blm, nullptr, true);
layerBuilder->DidBeginRetainedLayerTransaction(blm);
blm->BeginTransaction();
bool isInvalidated = false;
ContainerLayerParameters param(aScale.width, aScale.height);
RefPtr<Layer> root = aItem->BuildLayer(aDisplayListBuilder, blm, param);
if (root) {
blm->SetRoot(root);
layerBuilder->WillEndTransaction();
// Check if there is any invalidation region.
nsIntRegion invalid;
if (props) {
props->ComputeDifferences(root, invalid, nullptr);
if (!invalid.IsEmpty()) {
isInvalidated = true;
}
} else {
isInvalidated = true;
}
}
blm->AbortTransaction();
return isInvalidated;
}
static bool
PaintByLayer(nsDisplayItem* aItem,
nsDisplayListBuilder* aDisplayListBuilder,

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

@ -239,6 +239,8 @@ DeleteBlobFont(WrFontInstanceKey aKey)
}
}
} // extern
static RefPtr<UnscaledFont>
GetUnscaledFont(Translator* aTranslator, WrFontKey aKey)
{
@ -455,6 +457,11 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
return ret;
}
} // namespace
} // namespace
extern "C" {
bool wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
uint32_t width, uint32_t height,
mozilla::wr::ImageFormat aFormat,
@ -474,6 +481,3 @@ bool wr_moz2d_render_cb(const mozilla::wr::ByteSlice blob,
} // extern
} // namespace
} // namespace

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

@ -107,29 +107,29 @@ BinASTParserBase::~BinASTParserBase()
// ------------- Toplevel constructions
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parse(const Vector<uint8_t>& data)
BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const Vector<uint8_t>& data)
{
return parse(data.begin(), data.length());
return parse(globalsc, data.begin(), data.length());
}
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parse(const uint8_t* start, const size_t length)
BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const uint8_t* start, const size_t length)
{
auto result = parseAux(start, length);
auto result = parseAux(globalsc, start, length);
poison(); // Make sure that the parser is never used again accidentally.
return result;
}
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length)
BinASTParser<Tok>::parseAux(GlobalSharedContext* globalsc,
const uint8_t* start, const size_t length)
{
MOZ_ASSERT(globalsc);
tokenizer_.emplace(cx_, start, length);
Directives directives(options().strictOption);
GlobalSharedContext globalsc(cx_, ScopeKind::Global,
directives, options().extraWarningsOption);
BinParseContext globalpc(cx_, this, &globalsc, /* newDirectives = */ nullptr);
BinParseContext globalpc(cx_, this, globalsc, /* newDirectives = */ nullptr);
if (!globalpc.init())
return cx_->alreadyReportedError();
@ -146,7 +146,7 @@ BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length)
parseContext_);
if (!bindings)
return cx_->alreadyReportedError();
globalsc.bindings = *bindings;
globalsc->bindings = *bindings;
return result; // Magic conversion to Ok.
}

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

@ -124,11 +124,13 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
*
* In case of error, the parser reports the JS error.
*/
JS::Result<ParseNode*> parse(const uint8_t* start, const size_t length);
JS::Result<ParseNode*> parse(const Vector<uint8_t>& data);
JS::Result<ParseNode*> parse(GlobalSharedContext* globalsc,
const uint8_t* start, const size_t length);
JS::Result<ParseNode*> parse(GlobalSharedContext* globalsc, const Vector<uint8_t>& data);
private:
MOZ_MUST_USE JS::Result<ParseNode*> parseAux(const uint8_t* start, const size_t length);
MOZ_MUST_USE JS::Result<ParseNode*> parseAux(GlobalSharedContext* globalsc,
const uint8_t* start, const size_t length);
// --- Raise errors.
//

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

@ -641,16 +641,17 @@ frontend::CompileGlobalBinASTScript(JSContext* cx, LifoAlloc& alloc, const ReadO
if (!script)
return nullptr;
Directives directives(options.strictOption);
GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, options.extraWarningsOption);
frontend::BinASTParser<BinTokenReaderMultipart> parser(cx, alloc, usedNames, options);
auto parsed = parser.parse(src, len);
auto parsed = parser.parse(&globalsc, src, len);
if (parsed.isErr())
return nullptr;
Directives dir(false);
GlobalSharedContext sc(cx, ScopeKind::Global, dir, false);
BytecodeEmitter bce(nullptr, &parser, &sc, script, nullptr, 0);
BytecodeEmitter bce(nullptr, &parser, &globalsc, script, nullptr, 0);
if (!bce.init())
return nullptr;

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

@ -36,6 +36,8 @@ testBinASTReaderInit(int *argc, char ***argv) {
static int
testBinASTReaderFuzz(const uint8_t* buf, size_t size) {
using namespace js::frontend;
auto gcGuard = mozilla::MakeScopeExit([&] {
JS::PrepareForFullGC(gCx);
JS::NonIncrementalGC(gCx, GC_NORMAL, JS::gcreason::API);
@ -53,12 +55,16 @@ testBinASTReaderFuzz(const uint8_t* buf, size_t size) {
return 0;
}
js::frontend::UsedNameTracker binUsedNames(gCx);
UsedNameTracker binUsedNames(gCx);
js::frontend::BinASTParser<js::frontend::BinTokenReaderTester> reader(gCx, gCx->tempLifoAlloc(), binUsedNames, options);
Directives directives(false);
GlobalSharedContext globalsc(gCx, ScopeKind::Global, directives, false);
BinASTParser<js::frontend::BinTokenReaderTester> reader(gCx, gCx->tempLifoAlloc(),
binUsedNames, options);
// Will be deallocated once `reader` goes out of scope.
auto binParsed = reader.parse(binSource);
auto binParsed = reader.parse(&globalsc, binSource);
RootedValue binExn(gCx);
if (binParsed.isErr()) {
js::GetAndClearException(gCx, &binExn);

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

@ -202,11 +202,14 @@ runTestFromPath(JSContext* cx, const char* path)
CompileOptions binOptions(cx);
binOptions.setFileAndLine(binPath.begin(), 0);
js::frontend::UsedNameTracker binUsedNames(cx);
frontend::UsedNameTracker binUsedNames(cx);
js::frontend::BinASTParser<Tok> binParser(cx, allocScope.alloc(), binUsedNames, binOptions);
frontend::Directives directives(false);
frontend::GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, false);
auto binParsed = binParser.parse(binSource); // Will be deallocated once `reader` goes out of scope.
frontend::BinASTParser<Tok> binParser(cx, allocScope.alloc(), binUsedNames, binOptions);
auto binParsed = binParser.parse(&globalsc, binSource); // Will be deallocated once `reader` goes out of scope.
RootedValue binExn(cx);
if (binParsed.isErr()) {
// Save exception for more detailed error message, if necessary.

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

@ -4697,11 +4697,39 @@ GetModuleObject(JSContext* cx, unsigned argc, Value* vp)
#if defined(JS_BUILD_BINAST)
using js::frontend::BinASTParser;
using js::frontend::Directives;
using js::frontend::GlobalSharedContext;
using js::frontend::ParseNode;
using js::frontend::UsedNameTracker;
template <typename Tok>
static bool
ParseBinASTData(JSContext* cx, uint8_t* buf_data, uint32_t buf_length,
GlobalSharedContext* globalsc, UsedNameTracker& usedNames,
const JS::ReadOnlyCompileOptions& options)
{
MOZ_ASSERT(globalsc);
// Note: We need to keep `reader` alive as long as we can use `parsed`.
BinASTParser<Tok> reader(cx, cx->tempLifoAlloc(), usedNames, options);
JS::Result<ParseNode*> parsed = reader.parse(globalsc, buf_data, buf_length);
if (parsed.isErr())
return false;
#ifdef DEBUG
Fprinter out(stderr);
DumpParseTree(parsed.unwrap(), out);
#endif
return true;
}
static bool
BinParse(JSContext* cx, unsigned argc, Value* vp)
{
using namespace js::frontend;
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() < 1) {
@ -4782,35 +4810,13 @@ BinParse(JSContext* cx, unsigned argc, Value* vp)
UsedNameTracker usedNames(cx);
JS::Result<ParseNode*> parsed(nullptr);
if (useMultipart) {
// Note: We need to keep `reader` alive as long as we can use `parsed`.
BinASTParser<BinTokenReaderMultipart> reader(cx, cx->tempLifoAlloc(), usedNames, options);
Directives directives(false);
GlobalSharedContext globalsc(cx, ScopeKind::Global, directives, false);
parsed = reader.parse(buf_data, buf_length);
if (parsed.isErr())
return false;
#ifdef DEBUG
Fprinter out(stderr);
DumpParseTree(parsed.unwrap(), out);
#endif
} else {
// Note: We need to keep `reader` alive as long as we can use `parsed`.
BinASTParser<BinTokenReaderTester> reader(cx, cx->tempLifoAlloc(), usedNames, options);
parsed = reader.parse(buf_data, buf_length);
if (parsed.isErr())
return false;
#ifdef DEBUG
Fprinter out(stderr);
DumpParseTree(parsed.unwrap(), out);
#endif
}
auto parseFunc = useMultipart ? ParseBinASTData<frontend::BinTokenReaderMultipart>
: ParseBinASTData<frontend::BinTokenReaderTester>;
if (!parseFunc(cx, buf_data, buf_length, &globalsc, usedNames, options))
return false;
args.rval().setUndefined();
return true;

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

@ -172,7 +172,7 @@ def check_nsmodules(target, binary):
raise Skip()
symbols = []
if buildconfig.substs.get('_MSC_VER'):
for line in get_output('dumpbin', '-exports', binary):
for line in get_output('dumpbin.exe', '-exports', binary):
data = line.split(None, 3)
if data and len(data) == 4 and data[0].isdigit() and \
ishex(data[1]) and ishex(data[2]):

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

@ -425,7 +425,9 @@ class Linkable(ContextDerived):
# The '$' check is here as a special temporary rule, allowing the
# inherited use of make variables, most notably in TK_LIBS.
if not lib.startswith('$') and not lib.startswith('-'):
if self.config.substs.get('GNU_CC'):
type_var = 'HOST_CC_TYPE' if self.KIND == 'host' else 'CC_TYPE'
compiler_type = self.config.substs.get(type_var)
if compiler_type in ('gcc', 'clang'):
lib = '-l%s' % lib
else:
lib = '%s%s%s' % (