merge mozilla-inbound to mozilla-central. r=merge a=merge
merge mozilla-inbound to mozilla-central. r=merge a=merge
MozReview-Commit-ID: oIdBL7fmlE
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -7210,26 +7210,12 @@ EventTarget::IsOnCurrentThreadInfallible
return false;
}
return mWorkerPrivate->IsOnCurrentThread();
}
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>;
END_WORKERS_NAMESPACE
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -361,19 +361,16 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerCrossThreadDispatcher)
// Generically useful function for running a bit of C++ code on the worker
// thread.
bool
PostTask(WorkerTask* aTask);
};
-WorkerCrossThreadDispatcher*
-GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker);
-
// Random unique constant to facilitate JSPrincipal debugging
const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
bool
IsWorkerGlobal(JSObject* global);
bool
IsDebuggerGlobal(JSObject* global);
--- a/gfx/2d/DrawEventRecorder.cpp
+++ b/gfx/2d/DrawEventRecorder.cpp
@@ -7,17 +7,17 @@
#include "PathRecording.h"
#include "RecordingTypes.h"
namespace mozilla {
namespace gfx {
using namespace std;
-DrawEventRecorderPrivate::DrawEventRecorderPrivate()
+DrawEventRecorderPrivate::DrawEventRecorderPrivate() : mExternalFonts(false)
{
}
void
DrawEventRecorderFile::RecordEvent(const RecordedEvent &aEvent)
{
WriteElement(mOutputStream, aEvent.mType);
@@ -74,29 +74,61 @@ DrawEventRecorderFile::Close()
mOutputStream.close();
}
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()
{
return mOutputStream.mLength;
}
void
DrawEventRecorderMemory::WipeRecording()
{
mOutputStream = MemStream();
+ mIndex = MemStream();
WriteHeader(mOutputStream);
}
} // namespace gfx
} // namespace mozilla
--- a/gfx/2d/DrawEventRecorder.h
+++ b/gfx/2d/DrawEventRecorder.h
@@ -8,40 +8,52 @@
#include "2D.h"
#include "RecordedEvent.h"
#include "RecordingTypes.h"
#include <ostream>
#include <fstream>
#include <unordered_set>
+#include <unordered_map>
+#include <functional>
namespace mozilla {
namespace gfx {
class PathRecording;
class DrawEventRecorderPrivate : public DrawEventRecorder
{
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(); ) {
auto oldFont = font++;
(*oldFont)->RemoveUserData(reinterpret_cast<UserDataKey*>(this));
}
for (auto surface = mStoredSurfaces.begin(); surface != mStoredSurfaces.end(); ) {
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>
void WriteHeader(S& aStream) {
WriteElement(aStream, kMagicInt);
WriteElement(aStream, kMajorRevision);
WriteElement(aStream, kMinorRevision);
}
@@ -80,23 +92,42 @@ public:
void AddStoredFontData(const uint64_t aFontDataKey) {
mStoredFontData.insert(aFontDataKey);
}
bool HasStoredFontData(const uint64_t aFontDataKey) {
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;
std::unordered_set<const void*> mStoredObjects;
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
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile, override)
explicit DrawEventRecorderFile(const char *aFilename);
~DrawEventRecorderFile();
@@ -123,44 +154,57 @@ public:
void Close();
private:
void Flush() override;
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
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderMemory, override)
/**
* Constructs a DrawEventRecorder that stores the recording in memory.
*/
DrawEventRecorderMemory();
+ explicit DrawEventRecorderMemory(const SerializeResourcesFn &aSerialize);
void RecordEvent(const RecordedEvent &aEvent) override;
/**
* @return the current size of the recording (in chars).
*/
size_t RecordingSize();
/**
* Wipes the internal recording buffer, but the recorder does NOT forget which
* objects it has recorded. This can be used so that a recording can be copied
* 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;
};
} // namespace gfx
} // namespace mozilla
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -327,42 +327,44 @@ DrawTargetRecording::FillGlyphs(ScaledFo
const DrawOptions &aOptions,
const GlyphRenderingOptions *aRenderingOptions)
{
EnsurePatternDependenciesStored(aPattern);
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;
aFont->AddUserData(userDataKey, userData, &RecordingFontUserDataDestroyFunc);
userData->recorder->AddScaledFont(aFont);
}
mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
--- a/gfx/2d/InlineTranslator.cpp
+++ b/gfx/2d/InlineTranslator.cpp
@@ -47,16 +47,17 @@ InlineTranslator::TranslateRecording(cha
return !eof();
}
char *mData;
char *mEnd;
};
MemReader reader(aData, aLen);
+
uint32_t magicInt;
ReadElement(reader, magicInt);
if (magicInt != mozilla::gfx::kMagicInt) {
return false;
}
uint16_t majorRevision;
ReadElement(reader, majorRevision);
--- a/gfx/2d/InlineTranslator.h
+++ b/gfx/2d/InlineTranslator.h
@@ -71,23 +71,29 @@ public:
ScaledFont* LookupScaledFont(ReferencePtr aRefPtr) final
{
ScaledFont* result = mScaledFonts.GetWeak(aRefPtr);
MOZ_ASSERT(result);
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);
MOZ_ASSERT(result);
return result;
}
void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) final
@@ -117,16 +123,17 @@ public:
void AddScaledFont(ReferencePtr aRefPtr, ScaledFont *aScaledFont) final
{
mScaledFonts.Put(aRefPtr, aScaledFont);
}
void AddUnscaledFont(ReferencePtr aRefPtr, UnscaledFont *aUnscaledFont) final
{
+ mUnscaledFontTable.push_back(aUnscaledFont);
mUnscaledFonts.Put(aRefPtr, aUnscaledFont);
}
void AddNativeFontResource(uint64_t aKey,
NativeFontResource *aScaledFontResouce) final
{
mNativeFontResources.Put(aKey, aScaledFontResouce);
}
@@ -174,16 +181,17 @@ public:
mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; }
void* GetFontContext() final { return mFontContext; }
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;
nsRefPtrHashtable<nsPtrHashKey<void>, FilterNode> mFilterNodes;
nsRefPtrHashtable<nsPtrHashKey<void>, GradientStops> mGradientStops;
nsRefPtrHashtable<nsPtrHashKey<void>, ScaledFont> mScaledFonts;
nsRefPtrHashtable<nsPtrHashKey<void>, UnscaledFont> mUnscaledFonts;
nsRefPtrHashtable<nsUint64HashKey, NativeFontResource> mNativeFontResources;
--- a/gfx/2d/RecordedEvent.cpp
+++ b/gfx/2d/RecordedEvent.cpp
@@ -83,16 +83,18 @@ RecordedEvent::GetEventName(EventType aT
case GRADIENTSTOPSCREATION:
return "GradientStopsCreation";
case GRADIENTSTOPSDESTRUCTION:
return "GradientStopsDestruction";
case SNAPSHOT:
return "Snapshot";
case SCALEDFONTCREATION:
return "ScaledFontCreation";
+ case SCALEDFONTCREATIONBYINDEX:
+ return "ScaledFontCreationByIndex";
case SCALEDFONTDESTRUCTION:
return "ScaledFontDestruction";
case MASKSURFACE:
return "MaskSurface";
case FILTERNODESETATTRIBUTE:
return "SetAttribute";
case FILTERNODESETINPUT:
return "SetInput";
@@ -110,16 +112,50 @@ RecordedEvent::GetEventName(EventType aT
return "UnscaledFontCreation";
case UNSCALEDFONTDESTRUCTION:
return "UnscaledFontDestruction";
default:
return "Unknown";
}
}
+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)
{
RefPtr<DrawTarget> newDT =
GetReferenceDrawTarget()->CreateSimilarDrawTarget(aSize, aFormat);
AddDrawTarget(aRefPtr, newDT);
return newDT.forget();
--- a/gfx/2d/RecordedEvent.h
+++ b/gfx/2d/RecordedEvent.h
@@ -84,16 +84,17 @@ public:
virtual DrawTarget *LookupDrawTarget(ReferencePtr aRefPtr) = 0;
virtual Path *LookupPath(ReferencePtr aRefPtr) = 0;
virtual SourceSurface *LookupSourceSurface(ReferencePtr aRefPtr) = 0;
virtual FilterNode *LookupFilterNode(ReferencePtr aRefPtr) = 0;
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;
virtual void AddPath(ReferencePtr aRefPtr, Path *aPath) = 0;
virtual void RemovePath(ReferencePtr aRefPtr) = 0;
virtual void AddSourceSurface(ReferencePtr aRefPtr, SourceSurface *aPath) = 0;
virtual void RemoveSourceSurface(ReferencePtr aRefPtr) = 0;
virtual void AddFilterNode(mozilla::gfx::ReferencePtr aRefPtr, FilterNode *aSurface) = 0;
@@ -236,16 +237,17 @@ public:
PATHCREATION,
PATHDESTRUCTION,
SOURCESURFACECREATION,
SOURCESURFACEDESTRUCTION,
GRADIENTSTOPSCREATION,
GRADIENTSTOPSDESTRUCTION,
SNAPSHOT,
SCALEDFONTCREATION,
+ SCALEDFONTCREATIONBYINDEX,
SCALEDFONTDESTRUCTION,
MASKSURFACE,
FILTERNODECREATION,
FILTERNODEDESTRUCTION,
DRAWFILTER,
FILTERNODESETATTRIBUTE,
FILTERNODESETINPUT,
CREATESIMILARDRAWTARGET,
@@ -306,16 +308,20 @@ public:
template<class S, class F>
static bool DoWithEvent(S &aStream, EventType aType, F f);
EventType GetType() const { return (EventType)mType; }
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)
{}
int32_t mType;
std::vector<Float> mDashPatternStorage;
};
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -17,16 +17,17 @@
#include "SFNTData.h"
namespace mozilla {
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);
}
void RecordToStream(EventStream& aStream) const {
static_cast<const Derived*>(this)->Record(aStream);
}
void RecordToStream(MemStream &aStream) const {
SizeCollector size;
@@ -1063,16 +1064,59 @@ private:
Float mGlyphSize;
std::vector<uint8_t> mInstanceData;
std::vector<FontVariation> mVariations;
template<class S>
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)
: RecordedEventDerived(SCALEDFONTDESTRUCTION), mRefPtr(aRefPtr)
{
}
virtual bool PlayEvent(Translator *aTranslator) const;
@@ -2950,16 +2994,78 @@ RecordedScaledFontCreation::RecordedScal
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
+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
{
aTranslator->RemoveScaledFont(mRefPtr);
return true;
}
template<class S>
void
@@ -3164,16 +3270,17 @@ RecordedFilterNodeSetInput::OutputSimple
f(SOURCESURFACECREATION, RecordedSourceSurfaceCreation); \
f(SOURCESURFACEDESTRUCTION, RecordedSourceSurfaceDestruction); \
f(FILTERNODECREATION, RecordedFilterNodeCreation); \
f(FILTERNODEDESTRUCTION, RecordedFilterNodeDestruction); \
f(GRADIENTSTOPSCREATION, RecordedGradientStopsCreation); \
f(GRADIENTSTOPSDESTRUCTION, RecordedGradientStopsDestruction); \
f(SNAPSHOT, RecordedSnapshot); \
f(SCALEDFONTCREATION, RecordedScaledFontCreation); \
+ f(SCALEDFONTCREATIONBYINDEX, RecordedScaledFontCreationByIndex); \
f(SCALEDFONTDESTRUCTION, RecordedScaledFontDestruction); \
f(MASKSURFACE, RecordedMaskSurface); \
f(FILTERNODESETATTRIBUTE, RecordedFilterNodeSetAttribute); \
f(FILTERNODESETINPUT, RecordedFilterNodeSetInput); \
f(CREATESIMILARDRAWTARGET, RecordedCreateSimilarDrawTarget); \
f(FONTDATA, RecordedFontData); \
f(FONTDESC, RecordedFontDescriptor); \
f(PUSHLAYER, RecordedPushLayer); \
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -76,18 +76,19 @@ BufferRecycleBin::RecycleBuffer(UniquePt
mRecycledBuffers.AppendElement(Move(aBuffer));
}
UniquePtr<uint8_t[]>
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]);
mRecycledBuffers.RemoveElementAt(last);
return result;
}
void
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -289,29 +289,22 @@ WebRenderBridgeChild::GetFontKeyForScale
(aScaledFont->GetType() == gfx::FontType::MAC) ||
(aScaledFont->GetType() == gfx::FontType::FONTCONFIG));
wr::FontInstanceKey instanceKey = { wr::IdNamespace { 0 }, 0 };
if (mFontInstanceKeys.Get(aScaledFont, &instanceKey)) {
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();
Maybe<wr::FontInstanceOptions> options;
Maybe<wr::FontInstancePlatformOptions> platformOptions;
std::vector<FontVariation> variations;
aScaledFont->GetWRFontInstanceOptions(&options, &platformOptions, &variations);
@@ -319,16 +312,37 @@ WebRenderBridgeChild::GetFontKeyForScale
resources.AddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(),
options.ptrOr(nullptr), platformOptions.ptrOr(nullptr),
Range<const FontVariation>(variations.data(), variations.size()));
UpdateResources(resources);
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
WebRenderBridgeChild::RemoveExpiredFontKeys()
{
uint32_t counter = gfx::ScaledFont::DeletionCounter();
wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
if (mFontInstanceKeysDeleted != counter) {
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -131,16 +131,17 @@ public:
void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<wr::GlyphInstance>& aGlyphs,
gfx::ScaledFont* aFont, const wr::ColorF& aColor,
const StackingContextHelper& aSc,
const wr::LayerRect& aBounds, const wr::LayerRect& aClip,
bool aBackfaceVisible,
const wr::GlyphOptions* aGlyphOptions = nullptr);
wr::FontInstanceKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
+ wr::FontKey GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaledFont);
void RemoveExpiredFontKeys();
void ClearReadLocks();
void BeginClearCachedResources();
void EndClearCachedResources();
void SetWebRenderLayerManager(WebRenderLayerManager* aManager);
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -777,16 +777,17 @@ WebRenderBridgeParent::RecvAddPipelineId
}
MOZ_ASSERT(host->AsWebRenderImageHost());
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
if (!wrHost) {
return IPC_OK();
}
wrHost->SetWrBridge(this);
+ wrHost->EnableUseAsyncImagePipeline();
mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost);
mAsyncImageManager->AddAsyncImagePipeline(aPipelineId, wrHost);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvRemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId)
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -20,16 +20,18 @@
#include "nsDisplayListInvalidation.h"
#include "WebRenderCanvasRenderer.h"
#include "LayersLogging.h"
#include "LayerTreeInvalidation.h"
namespace mozilla {
namespace layers {
+using namespace gfx;
+
void WebRenderCommandBuilder::Destroy()
{
mLastCanvasDatas.Clear();
RemoveUnusedAndResetWebRenderUserData();
}
void
WebRenderCommandBuilder::EmptyTransaction()
@@ -495,22 +497,30 @@ WebRenderCommandBuilder::GenerateFallbac
if (needPaint || !fallbackData->GetKey()) {
gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
if (gfxPrefs::WebRenderBlobImages()) {
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);
wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
if (!aResources.AddBlobImage(key, descriptor, bytes)) {
return nullptr;
}
--- a/gfx/layers/wr/WebRenderImageHost.cpp
+++ b/gfx/layers/wr/WebRenderImageHost.cpp
@@ -24,16 +24,17 @@ namespace layers {
class ISurfaceAllocator;
WebRenderImageHost::WebRenderImageHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)
, ImageComposite()
, mWrBridge(nullptr)
, mWrBridgeBindings(0)
+ , mUseAsyncImagePipeline(false)
{}
WebRenderImageHost::~WebRenderImageHost()
{
MOZ_ASSERT(!mWrBridge);
}
void
@@ -183,17 +184,17 @@ WebRenderImageHost::GetAsTextureHostForC
void
WebRenderImageHost::SetCurrentTextureHost(TextureHost* aTexture)
{
if (aTexture == mCurrentTextureHost.get()) {
return;
}
if (mWrBridge &&
- !mAsyncRef &&
+ !mUseAsyncImagePipeline &&
!!mCurrentTextureHost &&
mCurrentTextureHost != aTexture &&
mCurrentTextureHost->AsWebRenderTextureHost()) {
MOZ_ASSERT(mWrBridge->AsyncImageManager());
wr::PipelineId piplineId = mWrBridge->PipelineId();
wr::Epoch epoch = mWrBridge->WrEpoch();
mWrBridge->AsyncImageManager()->HoldExternalImage(
piplineId,
--- a/gfx/layers/wr/WebRenderImageHost.h
+++ b/gfx/layers/wr/WebRenderImageHost.h
@@ -68,27 +68,33 @@ public:
virtual WebRenderImageHost* AsWebRenderImageHost() override { return this; }
TextureHost* GetAsTextureHostForComposite();
void SetWrBridge(WebRenderBridgeParent* aWrBridge);
void ClearWrBridge();
+ void EnableUseAsyncImagePipeline()
+ {
+ mUseAsyncImagePipeline = true;
+ }
+
TextureHost* GetCurrentTextureHost() { return mCurrentTextureHost; }
protected:
// ImageComposite
virtual TimeStamp GetCompositionTime() const override;
void SetCurrentTextureHost(TextureHost* aTexture);
WebRenderBridgeParent* MOZ_NON_OWNING_REF mWrBridge;
uint32_t mWrBridgeBindings;
+ bool mUseAsyncImagePipeline;
CompositableTextureHostRef mCurrentTextureHost;
};
} // namespace layers
} // namespace mozilla
#endif // MOZILLA_GFX_WEBRENDERIMAGEHOST_H
--- a/gfx/webrender_bindings/Moz2DImageRenderer.cpp
+++ b/gfx/webrender_bindings/Moz2DImageRenderer.cpp
@@ -8,28 +8,112 @@
#include "mozilla/Range.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/InlineTranslator.h"
#include "mozilla/gfx/RecordedEvent.h"
#include "WebRenderTypes.h"
#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,
const uint16_t *aTileSize,
const mozilla::wr::TileOffset *aTileOffset,
Range<uint8_t> aOutput)
{
MOZ_ASSERT(aSize.width > 0 && aSize.height > 0);
@@ -81,19 +165,53 @@ static bool Moz2DRenderCallback(const Ra
gfx::Tile tile;
tile.mDrawTarget = dt;
tile.mTileOrigin = gfx::IntPoint(aTileOffset->x * *aTileSize, aTileOffset->y * *aTileSize);
tileset.mTiles = &tile;
tileset.mTileCount = 1;
dt = gfx::Factory::CreateTiledDrawTarget(tileset);
}
- gfx::InlineTranslator translator(dt, fontContext);
+ struct Reader {
+ const uint8_t *buf;
+ size_t len;
+ size_t pos;
+
+ 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);
- auto ret = translator.TranslateRecording((char*)aBlob.begin().get(), aBlob.length());
+ 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;
char filename[40];
sprintf(filename, "out%d.png", i++);
gfxUtils::WriteAsPNG(dt, filename);
#endif
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -33,17 +33,17 @@ type WrEpoch = Epoch;
/// cbindgen:derive-neq=true
type WrIdNamespace = IdNamespace;
/// cbindgen:field-names=[mNamespace, mHandle]
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]
type WrYuvColorSpace = YuvColorSpace;
fn make_slice<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
if ptr.is_null() {
&[]
--- a/gfx/webrender_bindings/src/moz2d_renderer.rs
+++ b/gfx/webrender_bindings/src/moz2d_renderer.rs
@@ -1,13 +1,15 @@
+#![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;
pub struct Moz2dImageRenderer {
blob_commands: HashMap<ImageKey, (Arc<BlobImageData>, Option<TileSize>)>,
// The images rendered in the current frame (not kept here between frames)
@@ -21,32 +23,74 @@ pub struct Moz2dImageRenderer {
fn option_to_nullable<T>(option: &Option<T>) -> *const T {
match option {
&Some(ref x) => { x as *const T }
&None => { ptr::null() }
}
}
+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));
}
fn update(&mut self, key: ImageKey, data: BlobImageData, _dirty_rect: Option<DeviceUintRect>) {
let entry = self.blob_commands.get_mut(&key).unwrap();
entry.0 = Arc::new(data);
}
fn delete(&mut self, key: ImageKey) {
self.blob_commands.remove(&key);
}
fn request(&mut self,
- _resources: &BlobImageResources,
+ resources: &BlobImageResources,
request: BlobImageRequest,
descriptor: &BlobImageDescriptor,
_dirty_rect: Option<DeviceUintRect>) {
debug_assert!(!self.rendered_images.contains_key(&request));
// TODO: implement tiling.
// Add None in the map of rendered images. This makes it possible to differentiate
// between commands that aren't finished yet (entry in the map is equal to None) and
@@ -56,16 +100,39 @@ impl BlobImageRenderer for Moz2dImageRen
let tx = self.tx.clone();
let descriptor = descriptor.clone();
let blob = &self.blob_commands[&request.key];
let tile_size = blob.1;
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
* descriptor.format.bytes_per_pixel()) as usize;
let mut output = vec![255u8; buf_size];
let result = unsafe {
if wr_moz2d_render_cb(
@@ -115,24 +182,31 @@ impl BlobImageRenderer for Moz2dImageRen
return result
}
self.rendered_images.insert(req, Some(result));
}
// 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();
Moz2dImageRenderer {
blob_commands: HashMap::new(),
rendered_images: HashMap::new(),
workers: workers,
tx: tx,
--- a/memory/build/moz.build
+++ b/memory/build/moz.build
@@ -34,17 +34,17 @@ if CONFIG['OS_TARGET'] == 'Darwin' and (
CONFIG['MOZ_MEMORY']):
SOURCES += [
'zone.c',
]
Library('memory')
if CONFIG['OS_TARGET'] == 'Android' and CONFIG['CC_TYPE'] == 'clang':
- CFLAGS += [
+ CXXFLAGS += [
'-Wno-tautological-pointer-compare',
]
FINAL_LIBRARY = 'mozglue'
if CONFIG['_MSC_VER']:
CXXFLAGS += ['-wd4273'] # inconsistent dll linkage (bug 558163)
--- a/mozglue/build/WindowsDllBlocklist.cpp
+++ b/mozglue/build/WindowsDllBlocklist.cpp
@@ -252,16 +252,19 @@ static const DllBlockInfo sWindowsDllBlo
{ "nahimicmsidevprops.dll", UNVERSIONED },
// Bug 1268470 - crashes with Kaspersky Lab on Windows 8
{ "klsihk64.dll", MAKE_VERSION(14, 0, 456, 0xffff), DllBlockInfo::BLOCK_WIN8_ONLY },
// 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 }
};
#ifndef STATUS_DLL_NOT_FOUND
#define STATUS_DLL_NOT_FOUND ((DWORD)0xC0000135L)
#endif
// define this for very verbose dll load debug spew
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -326,16 +326,35 @@ SystemElf::~SystemElf()
ElfLoader::Singleton.lastError = dlerror();
ElfLoader::Singleton.Forget(this);
}
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;
}
Mappable *
SystemElf::GetMappable() const
{
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -3619,16 +3619,20 @@ HttpChannelChild::OverrideWithSynthesize
if (!mSynthesizedInput) {
rv = NS_NewCStringInputStream(getter_AddRefs(mSynthesizedInput),
EmptyCString());
NS_ENSURE_SUCCESS_VOID(rv);
}
if (nsHttpChannel::WillRedirect(mResponseHead)) {
mShouldInterceptSubsequentRedirect = true;
+ if (mInterceptListener) {
+ mInterceptListener->Cleanup();
+ mInterceptListener = nullptr;
+ }
// Continue with the original cross-process request
rv = ContinueAsyncOpen();
return;
}
// For progress we trust the content-length for the "maximum" size.
// We can't determine the full size from the stream itself since we
// only receive the data incrementally. We can't trust Available()
--- a/taskcluster/ci/test/mochitest.yml
+++ b/taskcluster/ci/test/mochitest.yml
@@ -33,27 +33,26 @@ mochitest:
android.*: xlarge
default: default
chunks:
by-test-platform:
android-4.3-arm7-api-16/debug: 48
android.*: 20
linux.*/debug: 16
linux64-asan/opt: 10
- linux64-*cov/opt: 10
+ linux64-.*cov/opt: 10
default: 5
e10s:
by-test-platform:
linux64-jsdcov/opt: false
windows7-32/debug: both
default: true
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:
by-test-platform:
windows10-64-asan.*: 3
default: default
mozharness:
mochitest-flavor: plain
@@ -91,17 +90,16 @@ mochitest-browser-chrome:
linux64-jsdcov/opt: mochitest/browser-chrome-coverage
default: mochitest/browser-chrome-chunked
treeherder-symbol: tc-M(bc)
loopback-video: true
chunks:
by-test-platform:
linux.*/debug: 16
linux64-asan/opt: 16
- linux64-jsdcov/opt: 35
default: 7
e10s:
by-test-platform:
linux64-jsdcov/opt: false
windows7-32/debug: both
default: true
max-run-time:
by-test-platform:
--- a/testing/web-platform/meta/service-workers/service-worker/redirected-response.https.html.ini
+++ b/testing/web-platform/meta/service-workers/service-worker/redirected-response.https.html.ini
@@ -1,19 +1,8 @@
[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
[Fetch should not follow the redirect response 21 times.]
expected: FAIL