mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-25 01:01:52 +00:00
merge mozilla-inbound to mozilla-central. r=merge a=merge
MozReview-Commit-ID: oIdBL7fmlE
This commit is contained in:
commit
831f2ed98f
@ -7215,20 +7215,6 @@ EventTarget::IsOnCurrentThreadInfallible()
|
||||
|
||||
BEGIN_WORKERS_NAMESPACE
|
||||
|
||||
WorkerCrossThreadDispatcher*
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker)
|
||||
{
|
||||
if (!aWorker.isObject()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aWorker.toObject());
|
||||
WorkerPrivate* w = nullptr;
|
||||
UNWRAP_OBJECT(Worker, &obj, w);
|
||||
MOZ_ASSERT(w);
|
||||
return w->GetCrossThreadDispatcher();
|
||||
}
|
||||
|
||||
// Force instantiation.
|
||||
template class WorkerPrivateParent<WorkerPrivate>;
|
||||
|
||||
|
@ -366,9 +366,6 @@ public:
|
||||
PostTask(WorkerTask* aTask);
|
||||
};
|
||||
|
||||
WorkerCrossThreadDispatcher*
|
||||
GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker);
|
||||
|
||||
// Random unique constant to facilitate JSPrincipal debugging
|
||||
const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace gfx {
|
||||
|
||||
using namespace std;
|
||||
|
||||
DrawEventRecorderPrivate::DrawEventRecorderPrivate()
|
||||
DrawEventRecorderPrivate::DrawEventRecorderPrivate() : mExternalFonts(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -79,11 +79,42 @@ DrawEventRecorderMemory::DrawEventRecorderMemory()
|
||||
WriteHeader(mOutputStream);
|
||||
}
|
||||
|
||||
DrawEventRecorderMemory::DrawEventRecorderMemory(const SerializeResourcesFn &aFn) :
|
||||
mSerializeCallback(aFn)
|
||||
{
|
||||
mExternalFonts = true;
|
||||
WriteHeader(mOutputStream);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawEventRecorderMemory::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DrawEventRecorderMemory::FlushItem(IntRect aRect)
|
||||
{
|
||||
DetatchResources();
|
||||
WriteElement(mIndex, mOutputStream.mLength);
|
||||
mSerializeCallback(mOutputStream, mUnscaledFonts);
|
||||
WriteElement(mIndex, mOutputStream.mLength);
|
||||
ClearResources();
|
||||
}
|
||||
|
||||
void
|
||||
DrawEventRecorderMemory::Finish()
|
||||
{
|
||||
size_t indexOffset = mOutputStream.mLength;
|
||||
// write out the index
|
||||
mOutputStream.write(mIndex.mData, mIndex.mLength);
|
||||
mIndex = MemStream();
|
||||
// write out the offset of the Index to the end of the output stream
|
||||
WriteElement(mOutputStream, indexOffset);
|
||||
ClearResources();
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
DrawEventRecorderMemory::RecordingSize()
|
||||
{
|
||||
@ -94,6 +125,7 @@ void
|
||||
DrawEventRecorderMemory::WipeRecording()
|
||||
{
|
||||
mOutputStream = MemStream();
|
||||
mIndex = MemStream();
|
||||
|
||||
WriteHeader(mOutputStream);
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <fstream>
|
||||
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
@ -25,7 +27,9 @@ public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate)
|
||||
DrawEventRecorderPrivate();
|
||||
virtual ~DrawEventRecorderPrivate() { }
|
||||
virtual void Finish() {
|
||||
virtual void Finish() { ClearResources(); }
|
||||
virtual void FlushItem(IntRect) { }
|
||||
void DetatchResources() {
|
||||
// The iteration is a bit awkward here because our iterator will
|
||||
// be invalidated by the removal
|
||||
for (auto font = mStoredFonts.begin(); font != mStoredFonts.end(); ) {
|
||||
@ -36,7 +40,15 @@ public:
|
||||
auto oldSurface = surface++;
|
||||
(*oldSurface)->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
|
||||
}
|
||||
mStoredFonts.clear();
|
||||
mStoredSurfaces.clear();
|
||||
}
|
||||
|
||||
void ClearResources() {
|
||||
mUnscaledFonts.clear();
|
||||
mStoredObjects.clear();
|
||||
mStoredFontData.clear();
|
||||
mUnscaledFontMap.clear();
|
||||
}
|
||||
|
||||
template<class S>
|
||||
@ -85,6 +97,22 @@ public:
|
||||
return mStoredFontData.find(aFontDataKey) != mStoredFontData.end();
|
||||
}
|
||||
|
||||
// Returns the index of the UnscaledFont
|
||||
size_t GetUnscaledFontIndex(UnscaledFont *aFont) {
|
||||
auto i = mUnscaledFontMap.find(aFont);
|
||||
size_t index;
|
||||
if (i == mUnscaledFontMap.end()) {
|
||||
mUnscaledFonts.push_back(aFont);
|
||||
index = mUnscaledFonts.size() - 1;
|
||||
mUnscaledFontMap.insert({{aFont, index}});
|
||||
} else {
|
||||
index = i->second;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
bool WantsExternalFonts() { return mExternalFonts; }
|
||||
|
||||
protected:
|
||||
virtual void Flush() = 0;
|
||||
|
||||
@ -92,6 +120,9 @@ protected:
|
||||
std::unordered_set<uint64_t> mStoredFontData;
|
||||
std::unordered_set<ScaledFont*> mStoredFonts;
|
||||
std::unordered_set<SourceSurface*> mStoredSurfaces;
|
||||
std::vector<RefPtr<UnscaledFont>> mUnscaledFonts;
|
||||
std::unordered_map<UnscaledFont*, size_t> mUnscaledFontMap;
|
||||
bool mExternalFonts;
|
||||
};
|
||||
|
||||
class DrawEventRecorderFile : public DrawEventRecorderPrivate
|
||||
@ -128,6 +159,8 @@ private:
|
||||
std::ofstream mOutputStream;
|
||||
};
|
||||
|
||||
typedef std::function<void(MemStream &aStream, std::vector<RefPtr<UnscaledFont>> &aUnscaledFonts)> SerializeResourcesFn;
|
||||
|
||||
// WARNING: This should not be used in its existing state because
|
||||
// it is likely to OOM because of large continguous allocations.
|
||||
class DrawEventRecorderMemory final : public DrawEventRecorderPrivate
|
||||
@ -139,6 +172,7 @@ public:
|
||||
* Constructs a DrawEventRecorder that stores the recording in memory.
|
||||
*/
|
||||
DrawEventRecorderMemory();
|
||||
explicit DrawEventRecorderMemory(const SerializeResourcesFn &aSerialize);
|
||||
|
||||
void RecordEvent(const RecordedEvent &aEvent) override;
|
||||
|
||||
@ -153,9 +187,19 @@ public:
|
||||
* and processed in chunks, releasing memory as it goes.
|
||||
*/
|
||||
void WipeRecording();
|
||||
void Finish() override;
|
||||
void FlushItem(IntRect) override;
|
||||
|
||||
MemStream mOutputStream;
|
||||
/* The index stream is of the form:
|
||||
* ItemIndex { size_t dataEnd; size_t extraDataEnd; }
|
||||
* It gets concatenated to the end of mOutputStream in Finish()
|
||||
* The last size_t in the stream is offset of the begining of the
|
||||
* index.
|
||||
*/
|
||||
MemStream mIndex;
|
||||
private:
|
||||
SerializeResourcesFn mSerializeCallback;
|
||||
~DrawEventRecorderMemory() {};
|
||||
|
||||
void Flush() override;
|
||||
|
@ -332,32 +332,34 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
|
||||
UserDataKey* userDataKey = reinterpret_cast<UserDataKey*>(mRecorder.get());
|
||||
if (!aFont->GetUserData(userDataKey)) {
|
||||
UnscaledFont* unscaledFont = aFont->GetUnscaledFont();
|
||||
if (!mRecorder->HasStoredObject(unscaledFont)) {
|
||||
RecordedFontData fontData(unscaledFont);
|
||||
RecordedFontDetails fontDetails;
|
||||
if (fontData.GetFontDetails(fontDetails)) {
|
||||
// Try to serialise the whole font, just in case this is a web font that
|
||||
// is not present on the system.
|
||||
if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
|
||||
mRecorder->RecordEvent(fontData);
|
||||
mRecorder->AddStoredFontData(fontDetails.fontDataKey);
|
||||
}
|
||||
mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, fontDetails));
|
||||
} else {
|
||||
// If that fails, record just the font description and try to load it from
|
||||
// the system on the other side.
|
||||
RecordedFontDescriptor fontDesc(unscaledFont);
|
||||
if (fontDesc.IsValid()) {
|
||||
mRecorder->RecordEvent(fontDesc);
|
||||
} else {
|
||||
gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
|
||||
}
|
||||
if (mRecorder->WantsExternalFonts()) {
|
||||
size_t index = mRecorder->GetUnscaledFontIndex(unscaledFont);
|
||||
mRecorder->RecordEvent(RecordedScaledFontCreationByIndex(aFont, index));
|
||||
} else {
|
||||
if (!mRecorder->HasStoredObject(unscaledFont)) {
|
||||
RecordedFontData fontData(unscaledFont);
|
||||
RecordedFontDetails fontDetails;
|
||||
if (fontData.GetFontDetails(fontDetails)) {
|
||||
// Try to serialise the whole font, just in case this is a web font that
|
||||
// is not present on the system.
|
||||
if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) {
|
||||
mRecorder->RecordEvent(fontData);
|
||||
mRecorder->AddStoredFontData(fontDetails.fontDataKey);
|
||||
}
|
||||
mRecorder->RecordEvent(RecordedUnscaledFontCreation(unscaledFont, fontDetails));
|
||||
} else {
|
||||
// If that fails, record just the font description and try to load it from
|
||||
// the system on the other side.
|
||||
RecordedFontDescriptor fontDesc(unscaledFont);
|
||||
if (fontDesc.IsValid()) {
|
||||
mRecorder->RecordEvent(fontDesc);
|
||||
} else {
|
||||
gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
|
||||
}
|
||||
}
|
||||
mRecorder->AddStoredObject(unscaledFont);
|
||||
}
|
||||
mRecorder->AddStoredObject(unscaledFont);
|
||||
}
|
||||
|
||||
mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, unscaledFont));
|
||||
|
||||
RecordingFontUserData *userData = new RecordingFontUserData;
|
||||
userData->refPtr = aFont;
|
||||
userData->recorder = mRecorder;
|
||||
|
@ -52,6 +52,7 @@ InlineTranslator::TranslateRecording(char *aData, size_t aLen)
|
||||
};
|
||||
MemReader reader(aData, aLen);
|
||||
|
||||
|
||||
uint32_t magicInt;
|
||||
ReadElement(reader, magicInt);
|
||||
if (magicInt != mozilla::gfx::kMagicInt) {
|
||||
|
@ -76,13 +76,19 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
UnscaledFont* LookupUnscaledFont(ReferencePtr aRefPtr) final
|
||||
UnscaledFont* LookupUnscaledFont(ReferencePtr aRefPtr) override final
|
||||
{
|
||||
UnscaledFont* result = mUnscaledFonts.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual UnscaledFont* LookupUnscaledFontByIndex(size_t index) override final
|
||||
{
|
||||
UnscaledFont* result = mUnscaledFontTable[index];
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeFontResource* LookupNativeFontResource(uint64_t aKey) final
|
||||
{
|
||||
NativeFontResource* result = mNativeFontResources.GetWeak(aKey);
|
||||
@ -122,6 +128,7 @@ public:
|
||||
|
||||
void AddUnscaledFont(ReferencePtr aRefPtr, UnscaledFont *aUnscaledFont) final
|
||||
{
|
||||
mUnscaledFontTable.push_back(aUnscaledFont);
|
||||
mUnscaledFonts.Put(aRefPtr, aUnscaledFont);
|
||||
}
|
||||
|
||||
@ -179,6 +186,7 @@ private:
|
||||
RefPtr<DrawTarget> mBaseDT;
|
||||
void* mFontContext;
|
||||
|
||||
std::vector<RefPtr<UnscaledFont>> mUnscaledFontTable;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, DrawTarget> mDrawTargets;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, Path> mPaths;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, SourceSurface> mSourceSurfaces;
|
||||
|
@ -88,6 +88,8 @@ RecordedEvent::GetEventName(EventType aType)
|
||||
return "Snapshot";
|
||||
case SCALEDFONTCREATION:
|
||||
return "ScaledFontCreation";
|
||||
case SCALEDFONTCREATIONBYINDEX:
|
||||
return "ScaledFontCreationByIndex";
|
||||
case SCALEDFONTDESTRUCTION:
|
||||
return "ScaledFontDestruction";
|
||||
case MASKSURFACE:
|
||||
@ -115,6 +117,40 @@ RecordedEvent::GetEventName(EventType aType)
|
||||
}
|
||||
}
|
||||
|
||||
template<class S>
|
||||
void RecordedEvent::RecordUnscaledFontImpl(UnscaledFont *aUnscaledFont, S& aOutput) {
|
||||
RecordedFontData fontData(aUnscaledFont);
|
||||
RecordedFontDetails fontDetails;
|
||||
if (fontData.GetFontDetails(fontDetails)) {
|
||||
// Try to serialise the whole font, just in case this is a web font that
|
||||
// is not present on the system.
|
||||
WriteElement(aOutput, fontData.mType);
|
||||
fontData.RecordToStream(aOutput);
|
||||
|
||||
auto r = RecordedUnscaledFontCreation(aUnscaledFont, fontDetails);
|
||||
WriteElement(aOutput, r.mType);
|
||||
r.RecordToStream(aOutput);
|
||||
} else {
|
||||
// If that fails, record just the font description and try to load it from
|
||||
// the system on the other side.
|
||||
RecordedFontDescriptor fontDesc(aUnscaledFont);
|
||||
if (fontDesc.IsValid()) {
|
||||
WriteElement(aOutput, fontDesc.RecordedEvent::mType);
|
||||
fontDesc.RecordToStream(aOutput);
|
||||
} else {
|
||||
gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise UnscaledFont";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RecordedEvent::RecordUnscaledFont(UnscaledFont *aUnscaledFont, std::ostream *aOutput) {
|
||||
RecordUnscaledFontImpl(aUnscaledFont, *aOutput);
|
||||
}
|
||||
|
||||
void RecordedEvent::RecordUnscaledFont(UnscaledFont *aUnscaledFont, MemStream &aOutput) {
|
||||
RecordUnscaledFontImpl(aUnscaledFont, aOutput);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
Translator::CreateDrawTarget(ReferencePtr aRefPtr, const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
|
@ -89,6 +89,7 @@ public:
|
||||
virtual GradientStops *LookupGradientStops(ReferencePtr aRefPtr) = 0;
|
||||
virtual ScaledFont *LookupScaledFont(ReferencePtr aRefPtr) = 0;
|
||||
virtual UnscaledFont* LookupUnscaledFont(ReferencePtr aRefPtr) = 0;
|
||||
virtual UnscaledFont* LookupUnscaledFontByIndex(size_t aIndex) { return nullptr; }
|
||||
virtual NativeFontResource *LookupNativeFontResource(uint64_t aKey) = 0;
|
||||
virtual void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) = 0;
|
||||
virtual void RemoveDrawTarget(ReferencePtr aRefPtr) = 0;
|
||||
@ -241,6 +242,7 @@ public:
|
||||
GRADIENTSTOPSDESTRUCTION,
|
||||
SNAPSHOT,
|
||||
SCALEDFONTCREATION,
|
||||
SCALEDFONTCREATIONBYINDEX,
|
||||
SCALEDFONTDESTRUCTION,
|
||||
MASKSURFACE,
|
||||
FILTERNODECREATION,
|
||||
@ -311,6 +313,10 @@ protected:
|
||||
friend class DrawEventRecorderPrivate;
|
||||
friend class DrawEventRecorderFile;
|
||||
friend class DrawEventRecorderMemory;
|
||||
static void RecordUnscaledFont(UnscaledFont *aUnscaledFont, std::ostream *aOutput);
|
||||
static void RecordUnscaledFont(UnscaledFont *aUnscaledFont, MemStream &aOutput);
|
||||
template<class S>
|
||||
static void RecordUnscaledFontImpl(UnscaledFont *aUnscaledFont, S &aOutput);
|
||||
|
||||
MOZ_IMPLICIT RecordedEvent(int32_t aType) : mType(aType)
|
||||
{}
|
||||
|
@ -22,6 +22,7 @@ namespace gfx {
|
||||
template<class Derived>
|
||||
class RecordedEventDerived : public RecordedEvent {
|
||||
using RecordedEvent::RecordedEvent;
|
||||
public:
|
||||
void RecordToStream(std::ostream &aStream) const {
|
||||
static_cast<const Derived*>(this)->Record(aStream);
|
||||
}
|
||||
@ -1068,6 +1069,49 @@ private:
|
||||
MOZ_IMPLICIT RecordedScaledFontCreation(S &aStream);
|
||||
};
|
||||
|
||||
class RecordedScaledFontCreationByIndex : public RecordedEventDerived<RecordedScaledFontCreationByIndex> {
|
||||
public:
|
||||
|
||||
static void FontInstanceDataProc(const uint8_t* aData, uint32_t aSize,
|
||||
const FontVariation* aVariations, uint32_t aNumVariations,
|
||||
void* aBaton)
|
||||
{
|
||||
auto recordedScaledFontCreation = static_cast<RecordedScaledFontCreation*>(aBaton);
|
||||
recordedScaledFontCreation->SetFontInstanceData(aData, aSize, aVariations, aNumVariations);
|
||||
}
|
||||
|
||||
RecordedScaledFontCreationByIndex(ScaledFont* aScaledFont, size_t aUnscaledFontIndex)
|
||||
: RecordedEventDerived(SCALEDFONTCREATIONBYINDEX)
|
||||
, mRefPtr(aScaledFont)
|
||||
, mUnscaledFontIndex(aUnscaledFontIndex)
|
||||
, mGlyphSize(aScaledFont->GetSize())
|
||||
{
|
||||
aScaledFont->GetFontInstanceData(FontInstanceDataProc, this);
|
||||
}
|
||||
|
||||
virtual bool PlayEvent(Translator *aTranslator) const;
|
||||
|
||||
template<class S> void Record(S &aStream) const;
|
||||
virtual void OutputSimpleEventInfo(std::stringstream &aStringStream) const;
|
||||
|
||||
virtual std::string GetName() const { return "ScaledFont Creation"; }
|
||||
virtual ReferencePtr GetObjectRef() const { return mRefPtr; }
|
||||
|
||||
void SetFontInstanceData(const uint8_t *aData, uint32_t aSize);
|
||||
|
||||
private:
|
||||
friend class RecordedEvent;
|
||||
|
||||
ReferencePtr mRefPtr;
|
||||
size_t mUnscaledFontIndex;
|
||||
Float mGlyphSize;
|
||||
std::vector<uint8_t> mInstanceData;
|
||||
std::vector<FontVariation> mVariations;
|
||||
|
||||
template<class S>
|
||||
MOZ_IMPLICIT RecordedScaledFontCreationByIndex(S &aStream);
|
||||
};
|
||||
|
||||
class RecordedScaledFontDestruction : public RecordedEventDerived<RecordedScaledFontDestruction> {
|
||||
public:
|
||||
MOZ_IMPLICIT RecordedScaledFontDestruction(ReferencePtr aRefPtr)
|
||||
@ -2954,6 +2998,68 @@ RecordedScaledFontCreation::RecordedScaledFontCreation(S &aStream)
|
||||
aStream.read((char*)mVariations.data(), sizeof(FontVariation) * numVariations);
|
||||
}
|
||||
|
||||
inline bool
|
||||
RecordedScaledFontCreationByIndex::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
UnscaledFont* unscaledFont = aTranslator->LookupUnscaledFontByIndex(mUnscaledFontIndex);
|
||||
if (!unscaledFont) {
|
||||
gfxDevCrash(LogReason::UnscaledFontNotFound) <<
|
||||
"UnscaledFont lookup failed for key |" << hexa(mUnscaledFontIndex) << "|.";
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<ScaledFont> scaledFont =
|
||||
unscaledFont->CreateScaledFont(mGlyphSize,
|
||||
mInstanceData.data(), mInstanceData.size(),
|
||||
mVariations.data(), mVariations.size());
|
||||
|
||||
aTranslator->AddScaledFont(mRefPtr, scaledFont);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class S>
|
||||
void
|
||||
RecordedScaledFontCreationByIndex::Record(S &aStream) const
|
||||
{
|
||||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mUnscaledFontIndex);
|
||||
WriteElement(aStream, mGlyphSize);
|
||||
WriteElement(aStream, (size_t)mInstanceData.size());
|
||||
aStream.write((char*)mInstanceData.data(), mInstanceData.size());
|
||||
WriteElement(aStream, (size_t)mVariations.size());
|
||||
aStream.write((char*)mVariations.data(), sizeof(FontVariation) * mVariations.size());
|
||||
}
|
||||
|
||||
inline void
|
||||
RecordedScaledFontCreationByIndex::OutputSimpleEventInfo(std::stringstream &aStringStream) const
|
||||
{
|
||||
aStringStream << "[" << mRefPtr << "] ScaledFont Created By Index";
|
||||
}
|
||||
|
||||
inline void
|
||||
RecordedScaledFontCreationByIndex::SetFontInstanceData(const uint8_t *aData, uint32_t aSize)
|
||||
{
|
||||
mInstanceData.assign(aData, aData + aSize);
|
||||
}
|
||||
|
||||
template<class S>
|
||||
RecordedScaledFontCreationByIndex::RecordedScaledFontCreationByIndex(S &aStream)
|
||||
: RecordedEventDerived(SCALEDFONTCREATIONBYINDEX)
|
||||
{
|
||||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mUnscaledFontIndex);
|
||||
ReadElement(aStream, mGlyphSize);
|
||||
|
||||
size_t size;
|
||||
ReadElement(aStream, size);
|
||||
mInstanceData.resize(size);
|
||||
aStream.read((char*)mInstanceData.data(), size);
|
||||
size_t numVariations;
|
||||
ReadElement(aStream, numVariations);
|
||||
mVariations.resize(numVariations);
|
||||
aStream.read((char*)mVariations.data(), sizeof(FontVariation) * numVariations);
|
||||
}
|
||||
|
||||
inline bool
|
||||
RecordedScaledFontDestruction::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
@ -3169,6 +3275,7 @@ RecordedFilterNodeSetInput::OutputSimpleEventInfo(std::stringstream &aStringStre
|
||||
f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
|
||||
f(SNAPSHOT, RecordedSnapshot); \
|
||||
f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
|
||||
f(SCALEDFONTCREATIONBYINDEX, RecordedScaledFontCreationByIndex); \
|
||||
f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
|
||||
f(MASKSURFACE, RecordedMaskSurface); \
|
||||
f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
|
||||
|
@ -81,8 +81,9 @@ BufferRecycleBin::GetBuffer(uint32_t aSize)
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
if (mRecycledBuffers.IsEmpty() || mRecycledBufferSize != aSize)
|
||||
return MakeUnique<uint8_t[]>(aSize);
|
||||
if (mRecycledBuffers.IsEmpty() || mRecycledBufferSize != aSize) {
|
||||
return UniquePtr<uint8_t[]>(new (fallible) uint8_t[aSize]);
|
||||
}
|
||||
|
||||
uint32_t last = mRecycledBuffers.Length() - 1;
|
||||
UniquePtr<uint8_t[]> result = Move(mRecycledBuffers[last]);
|
||||
|
@ -294,19 +294,12 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
|
||||
return instanceKey;
|
||||
}
|
||||
|
||||
RefPtr<gfx::UnscaledFont> unscaled = aScaledFont->GetUnscaledFont();
|
||||
MOZ_ASSERT(unscaled);
|
||||
|
||||
wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
|
||||
|
||||
wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0};
|
||||
if (!mFontKeys.Get(unscaled, &fontKey)) {
|
||||
FontFileDataSink sink = { &fontKey, this, &resources };
|
||||
if (!unscaled->GetFontFileData(WriteFontFileData, &sink)) {
|
||||
return instanceKey;
|
||||
}
|
||||
|
||||
mFontKeys.Put(unscaled, fontKey);
|
||||
wr::FontKey fontKey = GetFontKeyForUnscaledFont(aScaledFont->GetUnscaledFont());
|
||||
wr::FontKey nullKey = { wr::IdNamespace { 0 }, 0};
|
||||
if (fontKey == nullKey) {
|
||||
return instanceKey;
|
||||
}
|
||||
|
||||
instanceKey = GetNextFontInstanceKey();
|
||||
@ -324,6 +317,27 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
|
||||
mFontInstanceKeys.Put(aScaledFont, instanceKey);
|
||||
|
||||
return instanceKey;
|
||||
|
||||
}
|
||||
|
||||
wr::FontKey
|
||||
WebRenderBridgeChild::GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaled)
|
||||
{
|
||||
MOZ_ASSERT(!mDestroyed);
|
||||
|
||||
wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0};
|
||||
if (!mFontKeys.Get(aUnscaled, &fontKey)) {
|
||||
wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
|
||||
FontFileDataSink sink = { &fontKey, this, &resources };
|
||||
if (!aUnscaled->GetFontFileData(WriteFontFileData, &sink)) {
|
||||
return fontKey;
|
||||
}
|
||||
UpdateResources(resources);
|
||||
|
||||
mFontKeys.Put(aUnscaled, fontKey);
|
||||
}
|
||||
|
||||
return fontKey;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -136,6 +136,7 @@ public:
|
||||
const wr::GlyphOptions* aGlyphOptions = nullptr);
|
||||
|
||||
wr::FontInstanceKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
|
||||
wr::FontKey GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaledFont);
|
||||
|
||||
void RemoveExpiredFontKeys();
|
||||
void ClearReadLocks();
|
||||
|
@ -782,6 +782,7 @@ WebRenderBridgeParent::RecvAddPipelineIdForCompositable(const wr::PipelineId& aP
|
||||
}
|
||||
|
||||
wrHost->SetWrBridge(this);
|
||||
wrHost->EnableUseAsyncImagePipeline();
|
||||
mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost);
|
||||
mAsyncImageManager->AddAsyncImagePipeline(aPipelineId, wrHost);
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
void WebRenderCommandBuilder::Destroy()
|
||||
{
|
||||
mLastCanvasDatas.Clear();
|
||||
@ -500,12 +502,20 @@ WebRenderCommandBuilder::GenerateFallbackData(nsDisplayItem* aItem,
|
||||
bool snapped;
|
||||
bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
|
||||
|
||||
RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
|
||||
RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>([&] (MemStream &aStream, std::vector<RefPtr<UnscaledFont>> &aUnscaledFonts) {
|
||||
size_t count = aUnscaledFonts.size();
|
||||
aStream.write((const char*)&count, sizeof(count));
|
||||
for (auto unscaled : aUnscaledFonts) {
|
||||
wr::FontKey key = mManager->WrBridge()->GetFontKeyForUnscaledFont(unscaled);
|
||||
aStream.write((const char*)&key, sizeof(key));
|
||||
}
|
||||
});
|
||||
RefPtr<gfx::DrawTarget> dummyDt =
|
||||
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
|
||||
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
|
||||
PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
|
||||
fallbackData->mBasicLayerManager, mManager, scale);
|
||||
recorder->FlushItem(IntRect());
|
||||
recorder->Finish();
|
||||
|
||||
Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
|
||||
|
@ -29,6 +29,7 @@ WebRenderImageHost::WebRenderImageHost(const TextureInfo& aTextureInfo)
|
||||
, ImageComposite()
|
||||
, mWrBridge(nullptr)
|
||||
, mWrBridgeBindings(0)
|
||||
, mUseAsyncImagePipeline(false)
|
||||
{}
|
||||
|
||||
WebRenderImageHost::~WebRenderImageHost()
|
||||
@ -188,7 +189,7 @@ WebRenderImageHost::SetCurrentTextureHost(TextureHost* aTexture)
|
||||
}
|
||||
|
||||
if (mWrBridge &&
|
||||
!mAsyncRef &&
|
||||
!mUseAsyncImagePipeline &&
|
||||
!!mCurrentTextureHost &&
|
||||
mCurrentTextureHost != aTexture &&
|
||||
mCurrentTextureHost->AsWebRenderTextureHost()) {
|
||||
|
@ -73,6 +73,11 @@ public:
|
||||
|
||||
void ClearWrBridge();
|
||||
|
||||
void EnableUseAsyncImagePipeline()
|
||||
{
|
||||
mUseAsyncImagePipeline = true;
|
||||
}
|
||||
|
||||
TextureHost* GetCurrentTextureHost() { return mCurrentTextureHost; }
|
||||
|
||||
protected:
|
||||
@ -84,6 +89,7 @@ protected:
|
||||
WebRenderBridgeParent* MOZ_NON_OWNING_REF mWrBridge;
|
||||
|
||||
uint32_t mWrBridgeBindings;
|
||||
bool mUseAsyncImagePipeline;
|
||||
|
||||
CompositableTextureHostRef mCurrentTextureHost;
|
||||
};
|
||||
|
@ -13,18 +13,102 @@
|
||||
#include "webrender_ffi.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef MOZ_ENABLE_FREETYPE
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#endif
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<mozilla::wr::FontKey>{
|
||||
public :
|
||||
size_t operator()(const mozilla::wr::FontKey &key ) const
|
||||
{
|
||||
return hash<size_t>()(mozilla::wr::AsUint64(key));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
namespace wr {
|
||||
|
||||
#ifdef MOZ_ENABLE_FREETYPE
|
||||
static MOZ_THREAD_LOCAL(FT_Library) sFTLibrary;
|
||||
#endif
|
||||
|
||||
struct FontTemplate {
|
||||
void *mData;
|
||||
size_t mSize;
|
||||
int mIndex;
|
||||
const VecU8 *mVec;
|
||||
RefPtr<UnscaledFont> mUnscaledFont;
|
||||
};
|
||||
|
||||
// we need to do special things for linux so that we have fonts per backend
|
||||
std::unordered_map<FontKey, FontTemplate> sFontDataTable;
|
||||
|
||||
extern "C" {
|
||||
void
|
||||
AddFontData(wr::FontKey aKey, void *aData, size_t aSize, int aIndex, ArcVecU8 *aVec) {
|
||||
auto i = sFontDataTable.find(aKey);
|
||||
if (i == sFontDataTable.end()) {
|
||||
FontTemplate font;
|
||||
font.mData = aData;
|
||||
font.mSize = aSize;
|
||||
font.mIndex = aIndex;
|
||||
font.mVec = wr_add_ref_arc(aVec);
|
||||
sFontDataTable[aKey] = font;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DeleteFontData(wr::FontKey aKey) {
|
||||
auto i = sFontDataTable.find(aKey);
|
||||
if (i != sFontDataTable.end()) {
|
||||
sFontDataTable.erase(i);
|
||||
wr_dec_ref_arc(i->second.mVec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<UnscaledFont>
|
||||
GetUnscaledFont(Translator *aTranslator, wr::FontKey key) {
|
||||
MOZ_ASSERT(sFontDataTable.find(key) != sFontDataTable.end());
|
||||
auto &data = sFontDataTable[key];
|
||||
if (data.mUnscaledFont) {
|
||||
return data.mUnscaledFont;
|
||||
}
|
||||
FontType type =
|
||||
#ifdef XP_MACOSX
|
||||
FontType::MAC;
|
||||
#elif XP_WIN
|
||||
FontType::DWRITE;
|
||||
#elif ANDROID
|
||||
FontType::FREETYPE;
|
||||
#else
|
||||
FontType::FONTCONFIG;
|
||||
#endif
|
||||
// makes a copy of the data
|
||||
RefPtr<NativeFontResource> fontResource = Factory::CreateNativeFontResource((uint8_t*)data.mData, data.mSize,
|
||||
aTranslator->GetReferenceDrawTarget()->GetBackendType(),
|
||||
type,
|
||||
aTranslator->GetFontContext());
|
||||
RefPtr<UnscaledFont> unscaledFont;
|
||||
if (fontResource) {
|
||||
// Instance data is only needed for GDI fonts which webrender does not
|
||||
// support.
|
||||
unscaledFont = fontResource->CreateUnscaledFont(data.mIndex, nullptr, 0);
|
||||
}
|
||||
data.mUnscaledFont = unscaledFont;
|
||||
return unscaledFont;
|
||||
}
|
||||
|
||||
static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
|
||||
gfx::IntSize aSize,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
@ -86,9 +170,43 @@ static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
|
||||
dt = gfx::Factory::CreateTiledDrawTarget(tileset);
|
||||
}
|
||||
|
||||
gfx::InlineTranslator translator(dt, fontContext);
|
||||
struct Reader {
|
||||
const uint8_t *buf;
|
||||
size_t len;
|
||||
size_t pos;
|
||||
|
||||
auto ret = translator.TranslateRecording((char*)aBlob.begin().get(), aBlob.length());
|
||||
Reader(const uint8_t *buf, size_t len) : buf(buf), len(len), pos(0) {}
|
||||
|
||||
size_t ReadSize() {
|
||||
size_t ret;
|
||||
MOZ_RELEASE_ASSERT(pos + sizeof(ret) <= len);
|
||||
memcpy(&ret, buf + pos, sizeof(ret));
|
||||
pos += sizeof(ret);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
//XXX: Make safe
|
||||
size_t indexOffset = *(size_t*)(aBlob.end().get()-sizeof(size_t));
|
||||
Reader reader(aBlob.begin().get()+indexOffset, aBlob.length()-sizeof(size_t)-indexOffset);
|
||||
|
||||
bool ret;
|
||||
size_t offset = 0;
|
||||
while (reader.pos < reader.len) {
|
||||
size_t end = reader.ReadSize();
|
||||
size_t extra_end = reader.ReadSize();
|
||||
|
||||
gfx::InlineTranslator translator(dt, fontContext);
|
||||
|
||||
size_t count = *(size_t*)(aBlob.begin().get() + end);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
wr::FontKey key = *(wr::FontKey*)(aBlob.begin() + end + sizeof(count) + sizeof(wr::FontKey)*i).get();
|
||||
RefPtr<UnscaledFont> font = GetUnscaledFont(&translator, key);
|
||||
translator.AddUnscaledFont(0, font);
|
||||
}
|
||||
Range<const uint8_t> blob(aBlob.begin() + offset, aBlob.begin() + end);
|
||||
ret = translator.TranslateRecording((char*)blob.begin().get(), blob.length());
|
||||
offset = extra_end;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int i = 0;
|
||||
|
@ -38,7 +38,7 @@ type WrPipelineId = PipelineId;
|
||||
/// cbindgen:field-names=[mNamespace, mHandle]
|
||||
type WrImageKey = ImageKey;
|
||||
/// cbindgen:field-names=[mNamespace, mHandle]
|
||||
type WrFontKey = FontKey;
|
||||
pub type WrFontKey = FontKey;
|
||||
/// cbindgen:field-names=[mNamespace, mHandle]
|
||||
type WrFontInstanceKey = FontInstanceKey;
|
||||
/// cbindgen:field-names=[mNamespace, mHandle]
|
||||
|
@ -1,8 +1,10 @@
|
||||
#![allow(improper_ctypes)] // this is needed so that rustc doesn't complain about passing the &Arc<Vec> to an extern function
|
||||
use webrender_api::*;
|
||||
use bindings::{ByteSlice, MutByteSlice, wr_moz2d_render_cb};
|
||||
use rayon::ThreadPool;
|
||||
|
||||
use std::collections::hash_map::{HashMap, Entry};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||
use std::sync::Arc;
|
||||
@ -26,6 +28,48 @@ fn option_to_nullable<T>(option: &Option<T>) -> *const T {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_usize(slice: &[u8]) -> usize {
|
||||
convert_from_bytes(slice)
|
||||
}
|
||||
|
||||
fn convert_from_bytes<T>(slice: &[u8]) -> T {
|
||||
assert!(mem::size_of::<T>() <= slice.len());
|
||||
let mut ret: T;
|
||||
unsafe {
|
||||
ret = mem::uninitialized();
|
||||
ptr::copy_nonoverlapping(slice.as_ptr(),
|
||||
&mut ret as *mut T as *mut u8,
|
||||
mem::size_of::<T>());
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
struct BufReader<'a>
|
||||
{
|
||||
buf: &'a[u8],
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl<'a> BufReader<'a> {
|
||||
fn new(buf: &'a[u8]) -> BufReader<'a> {
|
||||
BufReader{ buf: buf, pos: 0 }
|
||||
}
|
||||
|
||||
fn read<T>(&mut self) -> T {
|
||||
let ret = convert_from_bytes(&self.buf[self.pos..]);
|
||||
self.pos += mem::size_of::<T>();
|
||||
ret
|
||||
}
|
||||
|
||||
fn read_font_key(&mut self) -> FontKey {
|
||||
self.read()
|
||||
}
|
||||
|
||||
fn read_usize(&mut self) -> usize {
|
||||
self.read()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlobImageRenderer for Moz2dImageRenderer {
|
||||
fn add(&mut self, key: ImageKey, data: BlobImageData, tiling: Option<TileSize>) {
|
||||
self.blob_commands.insert(key, (Arc::new(data), tiling));
|
||||
@ -41,7 +85,7 @@ impl BlobImageRenderer for Moz2dImageRenderer {
|
||||
}
|
||||
|
||||
fn request(&mut self,
|
||||
_resources: &BlobImageResources,
|
||||
resources: &BlobImageResources,
|
||||
request: BlobImageRequest,
|
||||
descriptor: &BlobImageDescriptor,
|
||||
_dirty_rect: Option<DeviceUintRect>) {
|
||||
@ -61,6 +105,29 @@ impl BlobImageRenderer for Moz2dImageRenderer {
|
||||
let commands = Arc::clone(&blob.0);
|
||||
|
||||
|
||||
fn process_fonts(mut extra_data: BufReader, resources: &BlobImageResources) {
|
||||
let font_count = extra_data.read_usize();
|
||||
for _ in 0..font_count {
|
||||
let key = extra_data.read_font_key();
|
||||
let template = resources.get_font_data(key);
|
||||
if let &FontTemplate::Raw(ref data, ref index) = template {
|
||||
unsafe { AddFontData(key, data.as_ptr(), data.len(), *index, data); }
|
||||
}
|
||||
resources.get_font_data(key);
|
||||
}
|
||||
}
|
||||
let index_offset_pos = commands.len()-mem::size_of::<usize>();
|
||||
|
||||
let index_offset = to_usize(&commands[index_offset_pos..]);
|
||||
{
|
||||
let mut index = BufReader::new(&commands[index_offset..index_offset_pos]);
|
||||
while index.pos < index.buf.len() {
|
||||
let end = index.read_usize();
|
||||
let extra_end = index.read_usize();
|
||||
process_fonts(BufReader::new(&commands[end..extra_end]), resources);
|
||||
}
|
||||
}
|
||||
|
||||
self.workers.spawn(move || {
|
||||
let buf_size = (descriptor.width
|
||||
* descriptor.height
|
||||
@ -120,14 +187,21 @@ impl BlobImageRenderer for Moz2dImageRenderer {
|
||||
// If we break out of the loop above it means the channel closed unexpectedly.
|
||||
Err(BlobImageError::Other("Channel closed".into()))
|
||||
}
|
||||
|
||||
fn delete_font(&mut self, _font: FontKey) {
|
||||
fn delete_font(&mut self, font: FontKey) {
|
||||
unsafe { DeleteFontData(font); }
|
||||
}
|
||||
|
||||
fn delete_font_instance(&mut self, _key: FontInstanceKey) {
|
||||
}
|
||||
}
|
||||
|
||||
use bindings::WrFontKey;
|
||||
extern "C" {
|
||||
#[allow(improper_ctypes)]
|
||||
fn AddFontData(key: WrFontKey, data: *const u8, size: usize, index: u32, vec: &Arc<Vec<u8>>);
|
||||
fn DeleteFontData(key: WrFontKey);
|
||||
}
|
||||
|
||||
impl Moz2dImageRenderer {
|
||||
pub fn new(workers: Arc<ThreadPool>) -> Self {
|
||||
let (tx, rx) = channel();
|
||||
|
@ -39,7 +39,7 @@ if CONFIG['OS_TARGET'] == 'Darwin' and (CONFIG['MOZ_REPLACE_MALLOC'] or
|
||||
Library('memory')
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Android' and CONFIG['CC_TYPE'] == 'clang':
|
||||
CFLAGS += [
|
||||
CXXFLAGS += [
|
||||
'-Wno-tautological-pointer-compare',
|
||||
]
|
||||
|
||||
|
@ -257,6 +257,9 @@ static const DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
// Bug 1407337, crashes with OpenSC < 0.16.0
|
||||
{ "onepin-opensc-pkcs11.dll", MAKE_VERSION(0, 15, 0xffff, 0xffff) },
|
||||
|
||||
// Avecto Privilege Guard causes crashes, bug 1385542
|
||||
{ "pghook.dll", ALL_VERSIONS },
|
||||
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
|
@ -331,6 +331,25 @@ void *
|
||||
SystemElf::GetSymbolPtr(const char *symbol) const
|
||||
{
|
||||
void *sym = dlsym(dlhandle, symbol);
|
||||
// Various bits of Gecko use isnanf, which gcc is happy to compile into
|
||||
// inlined code using floating-point comparisons. clang, on the other hand,
|
||||
// does not use inline code and generates full calls to isnanf.
|
||||
//
|
||||
// libm.so on Android defines isnanf as weak. dlsym always returns null for
|
||||
// weak symbols. Which means that we'll never be able to resolve the symbol
|
||||
// that clang generates here. However, said weak symbol for isnanf is just
|
||||
// an alias for __isnanf, which is the real definition. So if we're asked
|
||||
// for isnanf and we can't find it, try looking for __isnanf instead. The
|
||||
// actual system linker uses alternate resolution interfaces and therefore
|
||||
// does not encounter this issue.
|
||||
//
|
||||
// See also https://bugs.chromium.org/p/chromium/issues/detail?id=376828,
|
||||
// from which this comment and this fix are adapted.
|
||||
if (!sym &&
|
||||
!strcmp(symbol, "isnanf") &&
|
||||
!strcmp(GetName(), "libm.so")) {
|
||||
sym = dlsym(dlhandle, "__isnanf");
|
||||
}
|
||||
DEBUG_LOG("dlsym(%p [\"%s\"], \"%s\") = %p", dlhandle, GetPath(), symbol, sym);
|
||||
ElfLoader::Singleton.lastError = dlerror();
|
||||
return sym;
|
||||
|
@ -3624,6 +3624,10 @@ HttpChannelChild::OverrideWithSynthesizedResponse(nsAutoPtr<nsHttpResponseHead>&
|
||||
|
||||
if (nsHttpChannel::WillRedirect(mResponseHead)) {
|
||||
mShouldInterceptSubsequentRedirect = true;
|
||||
if (mInterceptListener) {
|
||||
mInterceptListener->Cleanup();
|
||||
mInterceptListener = nullptr;
|
||||
}
|
||||
// Continue with the original cross-process request
|
||||
rv = ContinueAsyncOpen();
|
||||
return;
|
||||
|
@ -38,7 +38,7 @@ mochitest:
|
||||
android.*: 20
|
||||
linux.*/debug: 16
|
||||
linux64-asan/opt: 10
|
||||
linux64-*cov/opt: 10
|
||||
linux64-.*cov/opt: 10
|
||||
default: 5
|
||||
e10s:
|
||||
by-test-platform:
|
||||
@ -48,7 +48,6 @@ mochitest:
|
||||
max-run-time:
|
||||
by-test-platform:
|
||||
android-4.3-arm7-api-16/debug: 7200
|
||||
linux64-jsdcov/opt: 10800
|
||||
default: 5400
|
||||
allow-software-gl-layers: false
|
||||
tier:
|
||||
@ -96,7 +95,6 @@ mochitest-browser-chrome:
|
||||
by-test-platform:
|
||||
linux.*/debug: 16
|
||||
linux64-asan/opt: 16
|
||||
linux64-jsdcov/opt: 35
|
||||
default: 7
|
||||
e10s:
|
||||
by-test-platform:
|
||||
|
@ -1,16 +1,5 @@
|
||||
[redirected-response.https.html]
|
||||
type: testharness
|
||||
disabled:
|
||||
if debug and os == "win": https://bugzilla.mozilla.org/show_bug.cgi?id=1411528
|
||||
expected:
|
||||
if debug and not stylo and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH
|
||||
if debug and not stylo and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH
|
||||
if debug and stylo and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): CRASH
|
||||
if debug and stylo and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86_64") and (bits == 64): CRASH
|
||||
if debug and stylo and e10s and (os == "linux") and (version == "Ubuntu 16.04") and (processor == "x86") and (bits == 32): CRASH
|
||||
if debug and not stylo and e10s and (os == "win") and (version == "10.0.15063") and (processor == "x86_64") and (bits == 64): CRASH
|
||||
if debug and stylo and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): CRASH
|
||||
if debug and not stylo and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): CRASH
|
||||
[mode: "follow", no mode change]
|
||||
expected: FAIL
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user