зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
a256ce3b76
Коммит
0442ca87fb
|
@ -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());
|
||||
|
|
Загрузка…
Ссылка в новой задаче