Bug 1696967: Only snapshot before unlocking canvas texture when caching a data surface. r=jrmuizel

Doing this every frame causes issues for older GPUs with the extra bitmap
creation, copy and destruction. Instead the TextureRecorded now only takes a
snapshot when it is going to cache a data surface to improve getting data back
at the start of a frame.

Differential Revision: https://phabricator.services.mozilla.com/D108500
This commit is contained in:
Bob Owen 2021-03-16 14:17:50 +00:00
Родитель 2fcd4e7f72
Коммит 71ab76aea6
4 изменённых файлов: 22 добавлений и 33 удалений

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

@ -373,21 +373,15 @@ PersistentBufferProviderShared::BorrowDrawTarget(
mDrawTarget = tex->BorrowDrawTarget();
if (mBack != previousBackBuffer && !aPersistedRect.IsEmpty()) {
if (mPreviousSnapshot) {
mDrawTarget->CopySurface(mPreviousSnapshot, aPersistedRect,
gfx::IntPoint(0, 0));
} else {
TextureClient* previous = GetTexture(previousBackBuffer);
if (previous && previous->Lock(OpenMode::OPEN_READ)) {
DebugOnly<bool> success =
previous->CopyToTextureClient(tex, &aPersistedRect, nullptr);
MOZ_ASSERT(success);
TextureClient* previous = GetTexture(previousBackBuffer);
if (previous && previous->Lock(OpenMode::OPEN_READ)) {
DebugOnly<bool> success =
previous->CopyToTextureClient(tex, &aPersistedRect, nullptr);
MOZ_ASSERT(success);
previous->Unlock();
}
previous->Unlock();
}
}
mPreviousSnapshot = nullptr;
if (mDrawTarget) {
// This is simply to ensure the DrawTarget gets initialized, and will detect
@ -413,17 +407,6 @@ bool PersistentBufferProviderShared::ReturnDrawTarget(
TextureClient* back = GetTexture(mBack);
MOZ_ASSERT(back);
// If our TextureClients have internal synchronization then, if locks are
// needed for reading and writing, this can cause locking issues with the
// compositor. To prevent this we take a snapshot when the DrawTarget is
// returned, so this can be used when our own BorrowSnapshot is called and
// also for copying to the next TextureClient. Using this snapshot outside of
// the locks is safe, because the TextureClient calls DetachAllSnapshots on
// its DrawTarget when we Unlock below.
if (back->HasSynchronization()) {
mPreviousSnapshot = back->BorrowSnapshot();
}
mDrawTarget = nullptr;
dt = nullptr;
@ -448,11 +431,6 @@ TextureClient* PersistentBufferProviderShared::GetTextureClient() {
already_AddRefed<gfx::SourceSurface>
PersistentBufferProviderShared::BorrowSnapshot() {
if (mPreviousSnapshot) {
mSnapshot = mPreviousSnapshot;
return do_AddRef(mSnapshot);
}
if (mDrawTarget) {
auto back = GetTexture(mBack);
MOZ_ASSERT(back && back->IsLocked());
@ -483,7 +461,7 @@ void PersistentBufferProviderShared::ReturnSnapshot(
mSnapshot = nullptr;
snapshot = nullptr;
if (mPreviousSnapshot || mDrawTarget) {
if (mDrawTarget) {
return;
}
@ -525,7 +503,6 @@ void PersistentBufferProviderShared::ClearCachedResources() {
void PersistentBufferProviderShared::Destroy() {
mSnapshot = nullptr;
mPreviousSnapshot = nullptr;
mDrawTarget = nullptr;
for (auto& mTexture : mTextures) {

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

@ -187,7 +187,6 @@ class PersistentBufferProviderShared : public PersistentBufferProvider,
RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<gfx::SourceSurface> mSnapshot;
RefPtr<gfx::SourceSurface> mPreviousSnapshot;
size_t mMaxAllowedTextures = kMaxTexturesAllowed;
};

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

@ -51,6 +51,7 @@ bool RecordedTextureData::Lock(OpenMode aMode) {
// We lock the TextureData when we create it to get the remote DrawTarget.
mCanvasChild->OnTextureWriteLock();
mLockedMode = aMode;
return true;
}
@ -59,11 +60,19 @@ bool RecordedTextureData::Lock(OpenMode aMode) {
mCanvasChild->OnTextureWriteLock();
mSnapshot = nullptr;
}
mLockedMode = aMode;
return true;
}
void RecordedTextureData::Unlock() {
if ((mLockedMode & OpenMode::OPEN_WRITE) &&
mCanvasChild->ShouldCacheDataSurface()) {
mSnapshot = mDT->Snapshot();
mDT->DetachAllSnapshots();
}
mCanvasChild->RecordEvent(RecordedTextureUnlock(mTextureId));
mLockedMode = OpenMode::OPEN_NONE;
}
already_AddRefed<gfx::DrawTarget> RecordedTextureData::BorrowDrawTarget() {
@ -73,8 +82,11 @@ already_AddRefed<gfx::DrawTarget> RecordedTextureData::BorrowDrawTarget() {
already_AddRefed<gfx::SourceSurface> RecordedTextureData::BorrowSnapshot() {
MOZ_ASSERT(mDT);
mSnapshot = mDT->Snapshot();
return mCanvasChild->WrapSurface(mSnapshot);
if (mSnapshot) {
return mCanvasChild->WrapSurface(mSnapshot);
}
return mCanvasChild->WrapSurface(mDT->Snapshot());
}
void RecordedTextureData::Deallocate(LayersIPCChannel* aAllocator) {}

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

@ -49,6 +49,7 @@ class RecordedTextureData final : public TextureData {
gfx::SurfaceFormat mFormat;
RefPtr<gfx::DrawTarget> mDT;
RefPtr<gfx::SourceSurface> mSnapshot;
OpenMode mLockedMode;
};
} // namespace layers