Bug 1575828: Ensure that CanvasChild::GetDataSurface is called on the main thread. r=jrmuizel

This also makes sure the SourceSurfaceCanvasRecording clean-up is done on the
main thread where required.

Differential Revision: https://phabricator.services.mozilla.com/D43077

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Bob Owen 2019-09-10 02:06:46 +00:00
parent 7d5ad55fe0
commit 4a393ad08e
2 changed files with 37 additions and 8 deletions

View File

@ -374,8 +374,8 @@ RecordedGetDataForSurface::RecordedGetDataForSurface(S& aStream)
class RecordedAddSurfaceAlias final class RecordedAddSurfaceAlias final
: public RecordedEventDerived<RecordedAddSurfaceAlias> { : public RecordedEventDerived<RecordedAddSurfaceAlias> {
public: public:
RecordedAddSurfaceAlias(const gfx::SourceSurface* aSurfaceAlias, RecordedAddSurfaceAlias(ReferencePtr aSurfaceAlias,
const gfx::SourceSurface* aActualSurface) const RefPtr<gfx::SourceSurface>& aActualSurface)
: RecordedEventDerived(ADD_SURFACE_ALIAS), : RecordedEventDerived(ADD_SURFACE_ALIAS),
mSurfaceAlias(aSurfaceAlias), mSurfaceAlias(aSurfaceAlias),
mActualSurface(aActualSurface) {} mActualSurface(aActualSurface) {}
@ -423,7 +423,7 @@ RecordedAddSurfaceAlias::RecordedAddSurfaceAlias(S& aStream)
class RecordedRemoveSurfaceAlias final class RecordedRemoveSurfaceAlias final
: public RecordedEventDerived<RecordedRemoveSurfaceAlias> { : public RecordedEventDerived<RecordedRemoveSurfaceAlias> {
public: public:
explicit RecordedRemoveSurfaceAlias(const gfx::SourceSurface* aSurfaceAlias) explicit RecordedRemoveSurfaceAlias(ReferencePtr aSurfaceAlias)
: RecordedEventDerived(REMOVE_SURFACE_ALIAS), : RecordedEventDerived(REMOVE_SURFACE_ALIAS),
mSurfaceAlias(aSurfaceAlias) {} mSurfaceAlias(aSurfaceAlias) {}

View File

@ -51,8 +51,8 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
} }
~SourceSurfaceCanvasRecording() { ~SourceSurfaceCanvasRecording() {
mRecorder->RemoveStoredObject(this); ReleaseOnMainThread(std::move(mRecorder), this, std::move(mRecordedSurface),
mRecorder->RecordEvent(RecordedRemoveSurfaceAlias(this)); std::move(mCanvasChild));
} }
gfx::SurfaceType GetType() const final { return mRecordedSurface->GetType(); } gfx::SurfaceType GetType() const final { return mRecordedSurface->GetType(); }
@ -64,11 +64,40 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
} }
already_AddRefed<gfx::DataSourceSurface> GetDataSurface() final { already_AddRefed<gfx::DataSourceSurface> GetDataSurface() final {
if (!mDataSourceSurface) { EnsureDataSurfaceOnMainThread();
return do_AddRef(mDataSourceSurface);
}
protected:
void GuaranteePersistance() final { EnsureDataSurfaceOnMainThread(); }
private:
void EnsureDataSurfaceOnMainThread() {
// The data can only be retrieved on the main thread.
if (!mDataSourceSurface && NS_IsMainThread()) {
mDataSourceSurface = mCanvasChild->GetDataSurface(mRecordedSurface); mDataSourceSurface = mCanvasChild->GetDataSurface(mRecordedSurface);
} }
}
return do_AddRef(mDataSourceSurface); // Used to ensure that clean-up that requires it is done on the main thread.
static void ReleaseOnMainThread(RefPtr<CanvasDrawEventRecorder> aRecorder,
ReferencePtr aSurfaceAlias,
RefPtr<gfx::SourceSurface> aAliasedSurface,
RefPtr<CanvasChild> aCanvasChild) {
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(NewRunnableFunction(
"SourceSurfaceCanvasRecording::ReleaseOnMainThread",
SourceSurfaceCanvasRecording::ReleaseOnMainThread,
std::move(aRecorder), aSurfaceAlias, std::move(aAliasedSurface),
std::move(aCanvasChild)));
return;
}
aRecorder->RemoveStoredObject(aSurfaceAlias);
aRecorder->RecordEvent(RecordedRemoveSurfaceAlias(aSurfaceAlias));
aAliasedSurface = nullptr;
aCanvasChild = nullptr;
aRecorder = nullptr;
} }
RefPtr<gfx::SourceSurface> mRecordedSurface; RefPtr<gfx::SourceSurface> mRecordedSurface;
@ -191,7 +220,7 @@ void CanvasChild::RecordEvent(const gfx::RecordedEvent& aEvent) {
already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface( already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
const gfx::SourceSurface* aSurface) { const gfx::SourceSurface* aSurface) {
MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSurface); MOZ_ASSERT(aSurface);
if (!mRecorder) { if (!mRecorder) {