Bug 1367538. Clear user data after we're done with the recorder. r=lsalzman

This helps keep us from accumulating all of the recorders.

The basic idea is to track weak references to the SourceSurfaces and Fonts that
we add UserData to in DrawEventRecorderPrivate and then clear these UserData's
when we're done recording.

This adds a RemoveAndDestroy helper to UserData to make this possible.
This commit is contained in:
Jeff Muizelaar 2017-06-07 10:28:28 -04:00
Родитель a256ce3b76
Коммит 0442ca87fb
5 изменённых файлов: 64 добавлений и 1 удалений

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

@ -408,6 +408,9 @@ public:
void *GetUserData(UserDataKey *key) {
return mUserData.Get(key);
}
void RemoveUserData(UserDataKey *key) {
mUserData.RemoveAndDestroy(key);
}
protected:
friend class DrawTargetCaptureImpl;
@ -812,6 +815,10 @@ public:
return mUserData.Get(key);
}
void RemoveUserData(UserDataKey *key) {
mUserData.RemoveAndDestroy(key);
}
const RefPtr<UnscaledFont>& GetUnscaledFont() const { return mUnscaledFont; }
protected:
@ -1413,6 +1420,7 @@ class DrawEventRecorder : public RefCounted<DrawEventRecorder>
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
virtual void Finish() = 0;
virtual ~DrawEventRecorder() { }
};

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

@ -28,6 +28,19 @@ public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate)
explicit DrawEventRecorderPrivate(std::ostream *aStream);
virtual ~DrawEventRecorderPrivate() { }
virtual void Finish() {
// 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));
}
}
void WriteHeader();
@ -42,6 +55,22 @@ public:
mStoredObjects.erase(aObject);
}
void AddScaledFont(ScaledFont* aFont) {
mStoredFonts.insert(aFont);
}
void RemoveScaledFont(ScaledFont* aFont) {
mStoredFonts.erase(aFont);
}
void AddSourceSurface(SourceSurface* aSurface) {
mStoredSurfaces.insert(aSurface);
}
void RemoveSourceSurface(SourceSurface* aSurface) {
mStoredSurfaces.erase(aSurface);
}
bool HasStoredObject(const ReferencePtr aObject) {
return mStoredObjects.find(aObject) != mStoredObjects.end();
}
@ -62,13 +91,19 @@ protected:
#if defined(_MSC_VER)
typedef std::unordered_set<const void*> ObjectSet;
typedef std::unordered_set<uint64_t> Uint64Set;
typedef std::unordered_set<ScaledFont*> FontSet;
typedef std::unordered_set<SourceSurface*> SurfaceSet;
#else
typedef std::set<const void*> ObjectSet;
typedef std::set<uint64_t> Uint64Set;
typedef std::set<ScaledFont*> FontSet;
typedef std::set<SourceSurface*> SurfaceSet;
#endif
ObjectSet mStoredObjects;
Uint64Set mStoredFontData;
FontSet mStoredFonts;
SurfaceSet mStoredSurfaces;
};
class DrawEventRecorderFile : public DrawEventRecorderPrivate

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

@ -28,6 +28,7 @@ void RecordingSourceSurfaceUserDataFunc(void *aUserData)
RecordingSourceSurfaceUserData *userData =
static_cast<RecordingSourceSurfaceUserData*>(aUserData);
userData->recorder->RemoveSourceSurface((SourceSurface*)userData->refPtr);
userData->recorder->RemoveStoredObject(userData->refPtr);
userData->recorder->RecordEvent(
RecordedSourceSurfaceDestruction(userData->refPtr));
@ -66,6 +67,7 @@ EnsureSurfaceStored(DrawEventRecorderPrivate *aRecorder, SourceSurface *aSurface
RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface();
StoreSourceSurface(aRecorder, aSurface, dataSurf, reason);
aRecorder->AddStoredObject(aSurface);
aRecorder->AddSourceSurface(aSurface);
RecordingSourceSurfaceUserData *userData = new RecordingSourceSurfaceUserData;
userData->refPtr = aSurface;
@ -375,7 +377,7 @@ void RecordingFontUserDataDestroyFunc(void *aUserData)
static_cast<RecordingFontUserData*>(aUserData);
userData->recorder->RecordEvent(RecordedScaledFontDestruction(userData->refPtr));
userData->recorder->RemoveScaledFont((ScaledFont*)userData->refPtr);
delete userData;
}
@ -421,6 +423,7 @@ DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
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));

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

@ -72,6 +72,21 @@ public:
return nullptr;
}
/* Remove and destroy a given key */
void RemoveAndDestroy(UserDataKey *key)
{
for (int i=0; i<count; i++) {
if (key == entries[i].key) {
entries[i].destroy(entries[i].userData);
// decrement before looping so entries[i+1] doesn't read past the end:
--count;
for (;i<count; i++) {
entries[i] = entries[i+1];
}
}
}
}
/* Retrives the userData for the associated key */
void *Get(UserDataKey *key) const
{

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

@ -67,6 +67,8 @@ WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
dt->FillRect(Rect(0, 0, imageSize.width, imageSize.height), ColorPattern(Color(1.0, 0.0, 0.0, 0.5)));
}
recorder->Finish();
wr::ByteBuffer bytes;
bytes.Allocate(recorder->RecordingSize());
DebugOnly<bool> ok = recorder->CopyRecording((char*)bytes.AsSlice().begin().get(), bytes.AsSlice().length());